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

Reply via email to