syscalls/getdents: Add parameter to test getdents64 syscall
PATCH 1/1 syscalls/getdents: Add parameter to test getdents64 syscall
From: Markos Chandras <[email protected]>
Add new "-l" parameter to test the getdents64 syscall along with the getdents one. Use ltp_syscall() to call the system call to get proper return values when an architecture does not support any of the getdents{,64} syscalls. Modify runtest/syscalls to call getdentsXX tests with and without the "-l" parameter
--- runtest/syscalls | 9 ++++ testcases/kernel/syscalls/getdents/Makefile | 2 + testcases/kernel/syscalls/getdents/getdents.h | 48 ++++++++++++++++++++++- testcases/kernel/syscalls/getdents/getdents01.c | 42 +++++++++++++++---- testcases/kernel/syscalls/getdents/getdents02.c | 38 +++++++++++++++--- testcases/kernel/syscalls/getdents/getdents03.c | 35 ++++++++++++++-- testcases/kernel/syscalls/getdents/getdents04.c | 41 +++++++++++++++---- 7 files changed, 186 insertions(+), 29 deletions(-)
runtest/syscalls +9 -0
@@ -331,6 +331,15 @@ getdents03_64 getdents03_64 getdents04 getdents04 getdents04_64 getdents04_64 +getdents01_long getdents01 -l +getdents01_64_long getdents01_64 -l +getdents02_long getdents02 -l +getdents02_64_long getdents02_64 -l +getdents03_long getdents03 -l +getdents03_64_long getdents03_64 -l +getdents04_long getdents04 -l +getdents04_64_long getdents04_64 -l + getdomainname01 getdomainname01 getdtablesize01 getdtablesize01
testcases/kernel/syscalls/getdents/Makefile +2 -0
@@ -21,6 +21,8 @@ top_srcdir ?= ../../../.. include $(top_srcdir)/include/mk/testcases.mk include $(abs_srcdir)/../utils/newer_64.mk +CFLAGS += -D_LARGEFILE64_SOURCE + %_64: CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DOFF_T=__off64_t include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/getdents/getdents.h +47 -1
70 lines not on this page · raw message
testcases/kernel/syscalls/getdents/getdents01.c +33 -9
86 lines not on this page · raw message
testcases/kernel/syscalls/getdents/getdents02.c +32 -6
@@ -40,10 +40,12 @@* -e : Turn on errno logging. * -i n : Execute test n times. * -I x : Execute test for x seconds. +* -l : Test the getdents64 system call. * -P x : Pause for x seconds between iterations. * -t : Turn on syscall timing. * * HISTORY +* 03/2013 - Added -l option by Markos Chandras * 03/2001 - Written by Wayne Boyer * * RESTRICTIONS
@@ -69,6 +71,17 @@ int TST_TOTAL = 1;int exp_enos[] = {EBADF ,0 };/* 0 terminated list of expected errnos */ +int longsyscall; + +option_t Options[] = { + {"l" , &longsyscall,NULL },/* -l long option. Tests getdents64 */ + {NULL ,NULL ,NULL } +}; + +void help () { +printf (" -l Test the getdents64 system call\n" ); +} +int main (int ac,char **av) {int lc;
@@ -77,9 +90,10 @@ int main(int ac, char **av)int count;size_t size =0 ;char *dir_name =NULL ; +struct dirent64 *dirp64;struct dirent *dirp; -if ((msg =parse_opts (ac, av,NULL ,NULL )) !=NULL ) +if ((msg =parse_opts (ac, av, Options, &help)) !=NULL )tst_brkm (TBROK ,NULL ,"OPTION PARSING ERROR - %s" , msg);setup ();
@@ -91,16 +105,25 @@ int main(int ac, char **av)tst_brkm (TBROK , cleanup,"Can not get current " "directory name" ); -if ((dirp =malloc (sizeof (struct dirent ))) ==NULL ) -tst_brkm (TBROK , cleanup,"malloc failed" ); +if (longsyscall) { +if ((dirp64 =malloc (sizeof (struct dirent ))) ==NULL ) +tst_brkm (TBROK , cleanup,"malloc failed" ); + count = (int )sizeof (struct dirent64 ); - count = (int )sizeof (struct dirent ); + }else { +if ((dirp =malloc (sizeof (struct dirent ))) ==NULL ) +tst_brkm (TBROK , cleanup,"malloc failed" ); + count = (int )sizeof (struct dirent ); + }/* set up a bad file descriptor */ fd =-5 ; - rval =getdents (fd, dirp, count); +if (longsyscall) + rval =getdents64 (fd, dirp64, count); +else + rval =getdents (fd, dirp, count);/* * Hopefully we get an error due to the bad file descriptor.
@@ -124,7 +147,10 @@ int main(int ac, char **av)free (dir_name); dir_name =NULL ; -free (dirp); +if (longsyscall) +free (dirp64); +else +free (dirp); }cleanup ();
testcases/kernel/syscalls/getdents/getdents03.c +30 -5
@@ -43,10 +43,12 @@* -e : Turn on errno logging. * -i n : Execute test n times. * -I x : Execute test for x seconds. +* -l : Test the getdents64 system call. * -P x : Pause for x seconds between iterations. * -t : Turn on syscall timing. * * HISTORY +* 03/2013 - Added -l option by Markos Chandras * 03/2001 - Written by Wayne Boyer * * RESTRICTIONS
@@ -72,6 +74,17 @@ int TST_TOTAL = 1;int exp_enos[] = {EINVAL ,0 };/* 0 terminated list of expected errnos */ +int longsyscall; + +option_t Options[] = { + {"l" , &longsyscall,NULL },/* -l long option. Tests getdents64 */ + {NULL ,NULL ,NULL } +}; + +void help () { +printf (" -l Test the getdents64 system call\n" ); +} +int main (int ac,char **av) {int lc;
@@ -80,9 +93,10 @@ int main(int ac, char **av)int count;size_t size =0 ;char *dir_name =NULL ; +struct dirent64 *dirp64;struct dirent *dirp; -if ((msg =parse_opts (ac, av,NULL ,NULL )) !=NULL ) +if ((msg =parse_opts (ac, av, Options, &help)) !=NULL )tst_brkm (TBROK ,NULL ,"OPTION PARSING ERROR - %s" , msg);setup ();
@@ -94,8 +108,13 @@ int main(int ac, char **av)tst_brkm (TBROK , cleanup,"Can not get current " "directory name" ); -if ((dirp =malloc (sizeof (struct dirent ))) ==NULL ) -tst_brkm (TBROK , cleanup,"malloc failed" ); +if (longsyscall) { +if ((dirp64 =malloc (sizeof (struct dirent64 ))) ==NULL ) +tst_brkm (TBROK , cleanup,"malloc failed" ); + }else { +if ((dirp =malloc (sizeof (struct dirent ))) ==NULL ) +tst_brkm (TBROK , cleanup,"malloc failed" ); + }/* Set count to be very small. The result should be EINVAL */
@@ -104,7 +123,10 @@ int main(int ac, char **av)if ((fd =open (dir_name,O_RDONLY )) ==-1 )tst_brkm (TBROK , cleanup,"open of directory failed" ); - rval =getdents (fd, dirp, count); +if (longsyscall) + rval =getdents64 (fd, dirp64, count); +else + rval =getdents (fd, dirp, count);/* * Hopefully we get an error due to the small buffer.
@@ -129,7 +151,10 @@ int main(int ac, char **av)free (dir_name); dir_name =NULL ; -free (dirp); +if (longsyscall) +free (dirp64); +else +free (dirp);if ((rval =close (fd)) ==-1 )tst_brkm (TBROK , cleanup,"fd close failed" );
testcases/kernel/syscalls/getdents/getdents04.c +33 -8
84 lines not on this page · raw message
Signature · 13 lines
1.7.1 ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_mar _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
Hi!
testcases/kernel/syscalls/getdents/Makefile top_srcdir ?= ../../../.. · line 24
Quoted 9 lines
testcases/kernel/syscalls/getdents/Makefile +1
-0@@ -21,6 +21,8 @@ top_srcdir ?= ../../../.. include $(top_srcdir)/include/mk/testcases.mk include $(abs_srcdir)/../utils/newer_64.mk +CFLAGS += -D_LARGEFILE64_SOURCE
What exactly is this needed for? The getent64 function and linux_dirent64 are both declared in the getdents.h.
Quoted 50 lines
testcases/kernel/syscalls/getdents/Makefile +36
-1/* * The dirent struct that the C library exports is not the same@@ -45,6 +48,13 @@ struct linux_dirent { char d_name[]; }; +struct linux_dirent64 { + unsigned long long d_ino; + long long d_off; + unsigned short d_reclen; + char d_name[]; +}; + static inline int getdents(unsigned int fd, struct dirent *dirp, unsigned int count) {@@ -57,7 +67,43 @@ getdents(unsigned int fd, struct dirent *dirp, unsigned int count) unsigned int i; ptrs.buf = buf; - ret = syscall(SYS_getdents, fd, buf, count); + ret = ltp_syscall(__NR_getdents, fd, buf, count); + if (ret < 0) + return ret; + +#define kdircpy(field) memcpy(&dirp[i].field, &ptrs.dirp->field, sizeof(dirp[i].field)) + + i = 0; + while (i < count && i < ret) { + unsigned long reclen; + + kdircpy(d_ino); + kdircpy(d_reclen); + reclen = dirp[i].d_reclen; + kdircpy(d_off); + strcpy(dirp[i].d_name, ptrs.dirp->d_name); + + ptrs.buf += reclen; + + i += reclen; + } + + return ret; +} + +static inline int +getdents64(unsigned int fd, struct dirent64 *dirp, unsigned int count) +{ + union { + struct linux_dirent64 *dirp;
testcases/kernel/syscalls/getdents/Makefile getdents(unsigned int fd, struct dirent *dirp, unsigned int count) · line 108
Quoted 10 lines
testcases/kernel/syscalls/getdents/Makefile +8
-0+ char *buf; + } ptrs; + char buf[count]; + long ret; + unsigned int i; + + ptrs.buf = buf; + ret = ltp_syscall(__NR_getdents64, fd, buf, count); if (ret < 0) return ret;
Well my choice would be casting the buffer to the dirp pointer rather than using the union but looking at the original code, this has been there before...
Quoted 21 lines
testcases/kernel/syscalls/getdents/getdents04.c +2
-0@@ -43,10 +43,12 @@* -e : Turn on errno logging. * -i n : Execute test n times. * -I x : Execute test for x seconds. +* -l : Test the getdents64 system call. * -P x : Pause for x seconds between iterations. * -t : Turn on syscall timing. * * HISTORY +* 03/2013 - Added -l option by Markos Chandras * 03/2001 - Written by Wayne Boyer * * RESTRICTIONS @@ -73,6 +75,17 @@ int TST_TOTAL = 1;int exp_enos[] = {ENOTDIR ,0 };/* 0 terminated list of expected errnos */
testcases/kernel/syscalls/getdents/getdents04.c int TST_TOTAL = 1; · line 87
Quoted 10 lines
testcases/kernel/syscalls/getdents/getdents04.c +10
-0+int longsyscall; + +option_t Options[] = { + {"l" , &longsyscall,NULL },/* -l long option. Tests getdents64 */ + {NULL ,NULL ,NULL } +}; + +void help () { +printf (" -l Test the getdents64 system call\n" ); +}
Please use LKML coding style, i.e. add void to the function prototype and move the opening bracket on the new line (you can you chekpatch.pl bundled with the linux kernel sources to check for style violations).
Also I tend to declare global functions and variables static so that compiler can report them as unused when they are unused.
Quoted 20 lines
testcases/kernel/syscalls/getdents/getdents04.c +3
-2int main (int ac,char **av) {int lc;@@ -80,11 +93,12 @@ int main(int ac, char **av)int count, rval, fd;size_t size =0 ;char *dir_name =NULL ; -struct dirent *dirp;struct stat *sbuf;char *newfile; +struct dirent64 *dirp64; +struct dirent *dirp; -if ((msg =parse_opts (ac, av,NULL ,NULL )) !=NULL ) +if ((msg =parse_opts (ac, av, Options, &help)) !=NULL )tst_brkm (TBROK ,NULL ,"OPTION PARSING ERROR - %s" , msg);setup ();@@ -96,10 +110,15 @@ int main(int ac, char **av) tst_brkm(TBROK, cleanup, "Can not get current "
testcases/kernel/syscalls/getdents/getdents04.c int main(int ac, char **av) · line 116
Quoted 10 lines
testcases/kernel/syscalls/getdents/getdents04.c +4
-4"directory name"); -if ((dirp =malloc (sizeof (struct dirent ))) ==NULL ) -tst_brkm (TBROK , cleanup,"malloc failed" ); - - count = (int )sizeof (struct dirent ); +if (longsyscall) { +if ((dirp64 =malloc (sizeof (struct dirent64 ))) ==NULL ) +tst_brkm (TBROK , cleanup,"malloc failed" ); + count = (int )sizeof (struct dirent64 );
Does really assigment of size_t (return from sizeof) into the int (count) generate warning?
Quoted 21 lines
testcases/kernel/syscalls/getdents/getdents04.c +9
-1+ }else { +if ((dirp =malloc (sizeof (struct dirent ))) ==NULL ) +tst_brkm (TBROK , cleanup,"malloc failed" ); + count = (int )sizeof (struct dirent ); + }/* set up some space for a file name */ if ((newfile =malloc (sizeof (char ) *20 )) ==NULL )@@ -123,7 +142,10 @@ int main(int ac, char **av)if (S_ISDIR (sbuf->st_mode))tst_brkm (TBROK , cleanup,"fd is a directory" ); - rval =getdents (fd, dirp, count); +if (longsyscall) + rval =getdents64 (fd, dirp64, count); +else + rval =getdents (fd, dirp, count);/* * Calling with a non directory file descriptor should give
testcases/kernel/syscalls/getdents/getdents04.c int main(int ac, char **av) · line 177
Quoted 8 lines
testcases/kernel/syscalls/getdents/getdents04.c +4
-1@@ -149,7 +171,10 @@ int main(int ac, char **av)free (dir_name); dir_name =NULL ; -free (dirp); +if (longsyscall) +free (dirp64); +else +free (dirp);
Hmm allocatin and freeing the structure in each loop iteration seems pointless, what about defining it on the stack or allocating it once before the main test loop and not bother freeing it. That would simplify the code.
Signature · 12 lines
Cyril Hrubis [email protected] ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_mar _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
A message that is not in the archive (sent off-list or not yet received): CAG2jQ8ib0+MSxmYqZsj0jaJB5kJhJv9N4OMu_wfQpc9EY6_QkA@mail.gmail.com
Hi!
Quoted 6 lines
Quoted 2 lines
What exactly is this needed for? The getent64 function and
linux_dirent64are both declared in thegetdents.h.It's needed for getting the struct dirent64 definition. See
/usr/include/bits/dirent.h
Ah right, so we have dirent dirent64 linux_dirent and linux_dirent64 two for the userspace and two for the syscalls.
Signature · 12 lines
Cyril Hrubis [email protected] ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_mar _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list