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 | 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(-) 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..ecb4cc9 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,17 @@ void setup(void); char *TCID = "getdents01"; int TST_TOTAL = 1; +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; @@ -79,9 +92,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(); @@ -92,21 +106,28 @@ int main(int ac, char **av) if ((dir_name = getcwd(dir_name, size)) == NULL) 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 (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); + } 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,7 +148,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, "file close failed"); diff --git a/testcases/kernel/syscalls/getdents/getdents02.c b/testcases/kernel/syscalls/getdents/getdents02.c index ee34de2..2299f30 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,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(); diff --git a/testcases/kernel/syscalls/getdents/getdents03.c b/testcases/kernel/syscalls/getdents/getdents03.c index 700e54b..0c2ef92 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,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"); diff --git a/testcases/kernel/syscalls/getdents/getdents04.c b/testcases/kernel/syscalls/getdents/getdents04.c index 89479a4..7ba8a3d 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,17 @@ int TST_TOTAL = 1; int exp_enos[] = { ENOTDIR, 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,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 " "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); + } 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 @@ -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); if ((rval = close(fd)) == -1) tst_brkm(TBROK, cleanup, "fd close failed"); -- 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
