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
Signed-off-by: Markos Chandras <[email protected]> --- runtest/syscalls | 9 ++++ testcases/kernel/syscalls/getdents/Makefile | 2 + testcases/kernel/syscalls/getdents/getdents.h | 48 +++++++++++++++++++- testcases/kernel/syscalls/getdents/getdents01.c | 56 +++++++++++++++++------ testcases/kernel/syscalls/getdents/getdents02.c | 45 +++++++++++++++---- testcases/kernel/syscalls/getdents/getdents03.c | 42 ++++++++++++++--- testcases/kernel/syscalls/getdents/getdents04.c | 46 +++++++++++++++---- 7 files changed, 205 insertions(+), 43 deletions(-) diff --git a/runtest/syscalls b/runtest/syscalls index c70bcbd..191ad10 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -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 diff --git a/testcases/kernel/syscalls/getdents/Makefile b/testcases/kernel/syscalls/getdents/Makefile index df7b63f..8334aa7 100644 --- a/testcases/kernel/syscalls/getdents/Makefile +++ b/testcases/kernel/syscalls/getdents/Makefile @@ -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 diff --git a/testcases/kernel/syscalls/getdents/getdents.h b/testcases/kernel/syscalls/getdents/getdents.h index 1d5e584..ee19ad0 100644 --- a/testcases/kernel/syscalls/getdents/getdents.h +++ b/testcases/kernel/syscalls/getdents/getdents.h @@ -25,10 +25,13 @@ #define __GETDENTS_H 1 #include <dirent.h> +#include <features.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/syscall.h> +#include "test.h" +#include "linux_syscall_numbers.h" /* * 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; + 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; diff --git a/testcases/kernel/syscalls/getdents/getdents01.c b/testcases/kernel/syscalls/getdents/getdents01.c index af0ac1a..b9cd28c 100644 --- a/testcases/kernel/syscalls/getdents/getdents01.c +++ b/testcases/kernel/syscalls/getdents/getdents01.c @@ -44,10 +44,12 @@ * -f : Turn off functionality Testing. * -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 @@ -71,6 +73,18 @@ void setup(void); char *TCID = "getdents01"; int TST_TOTAL = 1; +static int longsyscall; + +option_t Options[] = { + {"l", &longsyscall, NULL}, /* -l long option. Tests getdents64 */ + {NULL, NULL, NULL} +}; + +void help(void) +{ + printf(" -l Test the getdents64 system call\n"); +} + int main(int ac, char **av) { int lc; @@ -79,13 +93,28 @@ int main(int ac, char **av) int count; size_t size = 0; char *dir_name = NULL; - struct dirent *dirp; + struct dirent64 *dirp64 = NULL; + struct dirent *dirp = NULL; - 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(); + /* + * Set up count to be equal to the sizeof struct dirent, + * just to pick a decent size. + */ + if (longsyscall) { + if ((dirp64 = malloc(sizeof(struct dirent64))) == NULL) + tst_brkm(TBROK, cleanup, "malloc failed"); + count = (int)sizeof(struct dirent64); + } else { + if ((dirp = malloc(sizeof(struct dirent))) == NULL) + tst_brkm(TBROK, cleanup, "malloc failed"); + count = (int)sizeof(struct dirent); + } + for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; @@ -93,20 +122,14 @@ 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"); - - /* - * Set up count to be equal to the sizeof struct dirent, - * just to pick a decent size. - */ - - count = (int)sizeof(struct dirent); - 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); + if (rval < 0) { TEST_ERROR_LOG(errno); @@ -127,12 +150,15 @@ int main(int ac, char **av) free(dir_name); dir_name = NULL; - free(dirp); - if ((rval = close(fd)) == -1) tst_brkm(TBROK, cleanup, "file close failed"); } + if (longsyscall) + free(dirp64); + else + free(dirp); + cleanup(); tst_exit(); diff --git a/testcases/kernel/syscalls/getdents/getdents02.c b/testcases/kernel/syscalls/getdents/getdents02.c index ee34de2..971b755 100644 --- a/testcases/kernel/syscalls/getdents/getdents02.c +++ b/testcases/kernel/syscalls/getdents/getdents02.c @@ -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,18 @@ int TST_TOTAL = 1; int exp_enos[] = { EBADF, 0 }; /* 0 terminated list of expected errnos */ +static int longsyscall; + +option_t Options[] = { + {"l", &longsyscall, NULL}, /* -l long option. Tests getdents64 */ + {NULL, NULL, NULL} +}; + +void help(void) +{ + printf(" -l Test the getdents64 system call\n"); +} + int main(int ac, char **av) { int lc; @@ -77,13 +91,24 @@ int main(int ac, char **av) int count; size_t size = 0; char *dir_name = NULL; - struct dirent *dirp; + struct dirent64 *dirp64 = NULL; + struct dirent *dirp = NULL; - 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(); + if (longsyscall) { + if ((dirp64 = malloc(sizeof(struct dirent))) == NULL) + tst_brkm(TBROK, cleanup, "malloc failed"); + count = (int)sizeof(struct dirent64); + } else { + if ((dirp = malloc(sizeof(struct dirent))) == NULL) + tst_brkm(TBROK, cleanup, "malloc failed"); + count = (int)sizeof(struct dirent); + } + for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; @@ -91,16 +116,14 @@ 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"); - - 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,9 +147,13 @@ int main(int ac, char **av) free(dir_name); dir_name = NULL; - free(dirp); } + if (longsyscall) + free(dirp64); + else + free(dirp); + cleanup(); tst_exit(); diff --git a/testcases/kernel/syscalls/getdents/getdents03.c b/testcases/kernel/syscalls/getdents/getdents03.c index 700e54b..6b4f88b 100644 --- a/testcases/kernel/syscalls/getdents/getdents03.c +++ b/testcases/kernel/syscalls/getdents/getdents03.c @@ -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,18 @@ int TST_TOTAL = 1; int exp_enos[] = { EINVAL, 0 }; /* 0 terminated list of expected errnos */ +static int longsyscall; + +option_t Options[] = { + {"l", &longsyscall, NULL}, /* -l long option. Tests getdents64 */ + {NULL, NULL, NULL} +}; + +void help(void) +{ + printf(" -l Test the getdents64 system call\n"); +} + int main(int ac, char **av) { int lc; @@ -80,13 +94,22 @@ int main(int ac, char **av) int count; size_t size = 0; char *dir_name = NULL; - struct dirent *dirp; + struct dirent64 *dirp64 = NULL; + struct dirent *dirp = NULL; - 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(); + 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"); + } + for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; @@ -94,9 +117,6 @@ 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"); - /* Set count to be very small. The result should be EINVAL */ count = 1; @@ -104,7 +124,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,12 +152,15 @@ int main(int ac, char **av) free(dir_name); dir_name = NULL; - free(dirp); - if ((rval = close(fd)) == -1) tst_brkm(TBROK, cleanup, "fd close failed"); } + if (longsyscall) + free(dirp64); + else + free(dirp); + cleanup(); tst_exit(); diff --git a/testcases/kernel/syscalls/getdents/getdents04.c b/testcases/kernel/syscalls/getdents/getdents04.c index 89479a4..3dc1030 100644 --- a/testcases/kernel/syscalls/getdents/getdents04.c +++ b/testcases/kernel/syscalls/getdents/getdents04.c @@ -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,18 @@ int TST_TOTAL = 1; int exp_enos[] = { ENOTDIR, 0 }; /* 0 terminated list of expected errnos */ +static int longsyscall; + +option_t Options[] = { + {"l", &longsyscall, NULL}, /* -l long option. Tests getdents64 */ + {NULL, NULL, NULL} +}; + +void help(void) +{ + printf(" -l Test the getdents64 system call\n"); +} + int main(int ac, char **av) { int lc; @@ -80,15 +94,26 @@ 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 = NULL; + struct dirent *dirp = NULL; - 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(); + if (longsyscall) { + if ((dirp64 = malloc(sizeof(struct dirent64))) == NULL) + tst_brkm(TBROK, cleanup, "malloc failed"); + count = (int)sizeof(struct dirent64); + } else { + if ((dirp = malloc(sizeof(struct dirent))) == NULL) + tst_brkm(TBROK, cleanup, "malloc failed"); + count = (int)sizeof(struct dirent); + } + for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; @@ -96,11 +121,6 @@ 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"); - - count = (int)sizeof(struct dirent); - /* set up some space for a file name */ if ((newfile = malloc(sizeof(char) * 20)) == NULL) tst_brkm(TBROK, cleanup, "newfile malloc failed"); @@ -123,7 +143,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 @@ -149,14 +172,17 @@ int main(int ac, char **av) free(dir_name); dir_name = NULL; - free(dirp); - if ((rval = close(fd)) == -1) tst_brkm(TBROK, cleanup, "fd close failed"); if ((rval = unlink(newfile)) == -1) tst_brkm(TBROK, cleanup, "file unlink failed"); } + if (longsyscall) + free(dirp64); + else + free(dirp); + cleanup(); tst_exit(); -- 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
