Hi,please review this v2 patch and ignore the previous:)

create a new case to test F_GETOWN, F_SETOWN, F_GETOWN_EX,
F_SETOWN_EX, F_GETSIG, F_SETSIG for fcntl(2)

Signed-off-by: Xiaoguang Wang <[email protected]>
---
 configure.ac                              |   1 +
 m4/ltp-fcntl.m4                           |  46 ++++
 runtest/ltplite                           |   1 +
 runtest/stress.part3                      |   1 +
 runtest/syscalls                          |   2 +
 testcases/kernel/syscalls/.gitignore      |   2 +
 testcases/kernel/syscalls/fcntl/fcntl31.c | 426 ++++++++++++++++++++++++++++++
 7 files changed, 479 insertions(+)
 create mode 100644 m4/ltp-fcntl.m4
 create mode 100644 testcases/kernel/syscalls/fcntl/fcntl31.c

diff --git a/configure.ac b/configure.ac
index 8a2a96a..d4578bf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -173,5 +173,6 @@ LTP_CHECK_KERNEL_DEVEL
 LTP_CHECK_XFS_QUOTACTL
 LTP_CHECK_CLONE_SUPPORTS_7_ARGS
 LTP_CHECK_MKDIRAT
+LTP_CHECK_SYSCALL_FCNTL
 
 AC_OUTPUT
diff --git a/m4/ltp-fcntl.m4 b/m4/ltp-fcntl.m4
new file mode 100644
index 0000000..2ec284b
--- /dev/null
+++ b/m4/ltp-fcntl.m4
@@ -0,0 +1,46 @@
+dnl
+dnl Copyright (c) 2014 Fujitsu Ltd.
+dnl Author: Xiaoguang Wang <[email protected]>
+dnl
+dnl This program is free software;  you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY;  without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+dnl the GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program;  if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
USA
+dnl
+
+dnl
+dnl LTP_CHECK_SYSCALL_FCNTL
+dnl ----------------------------
+dnl
+AC_DEFUN([LTP_CHECK_SYSCALL_FCNTL],[dnl
+       AC_MSG_CHECKING([for fcntl f_owner_ex])
+       AC_LINK_IFELSE([AC_LANG_SOURCE([
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+int main(void) {
+       struct f_owner_ex tst_own_ex;
+       FILE *fp;
+
+       fp = tmpfile();
+       fcntl(fileno(fp), F_GETOWN_EX, &tst_own_ex);
+       return 0;
+}])],[has_f_owner_ex="yes"])
+
+if test "x$has_f_owner_ex" = xyes; then
+       AC_DEFINE(HAVE_STRUCT_F_OWNER_EX,1,[Define to 1 if you have struct 
f_owner_ex])
+       AC_MSG_RESULT(yes)
+else
+       AC_MSG_RESULT(no)
+fi
+])
diff --git a/runtest/ltplite b/runtest/ltplite
index 80e9527..dff3542 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -225,6 +225,7 @@ fcntl26 fcntl26
 # fcntl28 fcntl28
 fcntl29 fcntl29
 fcntl30 fcntl30
+fcntl31 fcntl31
 
 fdatasync01 fdatasync01
 fdatasync02 fdatasync02
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index d593f92..906cbdd 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -164,6 +164,7 @@ fcntl26 fcntl26
 # fcntl28 fcntl28
 fcntl29 fcntl29
 fcntl30 fcntl30
+fcntl31 fcntl31
 
 fdatasync01 fdatasync01
 fdatasync02 fdatasync02
diff --git a/runtest/syscalls b/runtest/syscalls
index eec05a9..f775a36 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -256,6 +256,8 @@ fcntl29 fcntl29
 fcntl29_64 fcntl29_64
 fcntl30 fcntl30
 fcntl30_64 fcntl30_64
+fcntl31 fcntl31
+fcntl31_64 fcntl31_64
 
 fdatasync01 fdatasync01
 fdatasync02 fdatasync02
diff --git a/testcases/kernel/syscalls/.gitignore 
b/testcases/kernel/syscalls/.gitignore
index a5a999d..e616bdc 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -218,6 +218,8 @@
 /fcntl/fcntl29_64
 /fcntl/fcntl30
 /fcntl/fcntl30_64
+/fcntl/fcntl31
+/fcntl/fcntl31_64
 /fdatasync/fdatasync01
 /fdatasync/fdatasync02
 /flock/flock01
diff --git a/testcases/kernel/syscalls/fcntl/fcntl31.c 
b/testcases/kernel/syscalls/fcntl/fcntl31.c
new file mode 100644
index 0000000..5943385
--- /dev/null
+++ b/testcases/kernel/syscalls/fcntl/fcntl31.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2014 Fujitsu Ltd.
+ * Author: Xiaoguang Wang <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * Description:
+ * Verify that:
+ *     Basic test for fcntl(2) using F_GETOWN, F_SETOWN, F_GETOWN_EX,
+ *     F_SETOWN_EX, F_GETSIG, F_SETSIG argument.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <pwd.h>
+#include <sched.h>
+
+#include "test.h"
+#include "config.h"
+#include "usctest.h"
+#include "linux_syscall_numbers.h"
+#include "safe_macros.h"
+
+
+static void setup(void);
+static void cleanup(void);
+
+static void setown_pid_test(void);
+static void setown_pgrp_test(void);
+
+static void set_get_own_cleanup(void);
+
+#if defined(HAVE_STRUCT_F_OWNER_EX)
+static int setownex_pid_setup(void);
+static int setownex_pgrp_setup(void);
+static int setownex_tid_setup(void);
+
+static void setownex_test(void);
+static void setownex_cleanup(void);
+
+static struct f_owner_ex tst_own_ex;
+static struct f_owner_ex orig_own_ex;
+#endif
+
+static void sig_func(int signo);
+
+static void signal_parent(void);
+static void wait_io_ready(void);
+static void test_set_and_get_sig(int sig);
+
+static pid_t pid;
+static pid_t orig_pid;
+static pid_t pgrp_pid;
+
+static int test_fd;
+static int pipe_fds[2];
+static int ind;
+static int ownex_enabled;
+
+/* record the io events signal */
+static int io_signal_received;
+
+
+static struct test_case_t {
+       int cmd;
+       int (*setup)(void);
+       void (*testfunc)(void);
+       void (*cleanup)(void);
+       char *des;
+} test_cases[] = {
+       {F_SETOWN, NULL, setown_pid_test, set_get_own_cleanup,
+        "F_SETOWN for process ID"},
+       {F_SETOWN, NULL, setown_pgrp_test, set_get_own_cleanup,
+        "F_SETOWN for process group ID"},
+#if defined(HAVE_STRUCT_F_OWNER_EX)
+       {F_SETOWN_EX, setownex_tid_setup, setownex_test,
+        setownex_cleanup, "F_SETOWN_EX for thread ID"},
+       {F_SETOWN_EX, setownex_pid_setup, setownex_test,
+        setownex_cleanup, "F_SETOWN_EX for process ID"},
+       {F_SETOWN_EX, setownex_pgrp_setup, setownex_test,
+        setownex_cleanup, "F_SETOWN_EX for process group ID"},
+#endif
+};
+
+char *TCID = "fcntl31";
+int TST_TOTAL = ARRAY_SIZE(test_cases);
+
+
+int main(int ac, char **av)
+{
+       int lc;
+       char *msg;
+       int i;
+
+       msg = parse_opts(ac, av, NULL, NULL);
+       if (msg != NULL)
+               tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+       setup();
+
+       for (lc = 0; TEST_LOOPING(lc); lc++) {
+               tst_count = 0;
+
+               ind = -1;
+               for (i = 0; i < TST_TOTAL; i++) {
+                       ind++;
+                       if (test_cases[i].setup && test_cases[i].setup() != 0)
+                               continue;
+
+                       if (test_cases[i].testfunc)
+                               test_cases[i].testfunc();
+
+                       if (test_cases[i].cleanup)
+                               test_cases[i].cleanup();
+               }
+       }
+
+       cleanup();
+       tst_exit();
+}
+
+static void setup(void)
+{
+       int ret;
+
+       tst_sig(FORK, DEF_HANDLER, cleanup);
+
+       tst_tmpdir();
+
+       TEST_PAUSE;
+
+       /* we have the tests on pipe */
+       SAFE_PIPE(cleanup, pipe_fds);
+       test_fd = pipe_fds[0];
+       if (fcntl(test_fd, F_SETFL, O_ASYNC) < 0)
+               tst_brkm(TBROK | TERRNO, cleanup, "fcntl set O_ASYNC failed");
+
+       pid = getpid();
+
+       ret = setpgrp();
+       if (ret < 0)
+               tst_brkm(TBROK | TERRNO, cleanup, "setpgrp() failed");
+       pgrp_pid = getpgid(0);
+       if (pgrp_pid < 0)
+               tst_brkm(TBROK | TERRNO, cleanup, "getpgid() failed");
+
+#if defined(HAVE_STRUCT_F_OWNER_EX)
+       if ((tst_kvercmp(2, 6, 32)) < 0) {
+               tst_resm(TCONF, "F_GETOWN_EX and F_GETOWN_EX only run on "
+                        "kernels that are 2.6.32 and higher");
+       } else {
+               ownex_enabled = 1;
+
+               /* get original f_owner_ex info */
+               TEST(fcntl(test_fd, F_GETOWN_EX, &orig_own_ex));
+               if (TEST_RETURN < 0) {
+                       tst_brkm(TFAIL | TTERRNO, cleanup,
+                                "fcntl get original f_owner_ex info failed");
+               }
+       }
+#endif
+
+       /* get original pid info */
+       TEST(fcntl(test_fd, F_GETOWN));
+       if (TEST_RETURN < 0) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl get original pid info failed");
+       }
+       orig_pid = TEST_RETURN;
+
+       if (signal(SIGIO, sig_func) == SIG_ERR) {
+               tst_brkm(TBROK | TERRNO, cleanup,
+                        "set signal handler for SIGIO failed");
+       }
+       if (signal(SIGUSR1, sig_func) == SIG_ERR) {
+               tst_brkm(TBROK | TERRNO, cleanup,
+                        "set signal handler for SIGUSR1 failed");
+       }
+}
+
+static void sig_func(int signo)
+{
+       int ret;
+       pid_t signaled_pid;
+       char c;
+
+       signaled_pid = getpid();
+
+       /*
+        * just check the signal received in parent process, in case
+        * signal is sent to a process group.
+        */
+       if (signaled_pid != pid)
+               return;
+
+       switch (signo) {
+       case SIGUSR1:
+               io_signal_received = SIGUSR1;
+       break;
+       case SIGIO:
+               io_signal_received = SIGIO;
+       }
+
+       ret = read(pipe_fds[0], &c, 1);
+       if (ret < 0)
+               tst_resm(TINFO, "no data is read");
+}
+
+static void setown_pid_test(void)
+{
+       TEST(fcntl(test_fd, F_SETOWN, pid));
+       if (TEST_RETURN < 0) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl F_SETOWN set process id failed");
+       }
+       test_set_and_get_sig(SIGUSR1);
+}
+
+static void setown_pgrp_test(void)
+{
+       TEST(fcntl(test_fd, F_SETOWN, -pgrp_pid));
+       if (TEST_RETURN < 0) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl F_SETOWN set process group id failed");
+       }
+       test_set_and_get_sig(SIGUSR1);
+}
+
+static void set_get_own_cleanup(void)
+{
+       TEST(fcntl(test_fd, F_SETOWN, orig_pid));
+       if (TEST_RETURN < 0) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl F_SETOWN restore orig_pid failed");
+       }
+}
+
+#if defined(HAVE_STRUCT_F_OWNER_EX)
+static int setownex_pid_setup(void)
+{
+       if (ownex_enabled == 0)
+               return 1;
+
+       tst_own_ex.type = F_OWNER_PID;
+       tst_own_ex.pid = pid;
+       return 0;
+}
+
+static void setownex_test(void)
+{
+       TEST(fcntl(test_fd, F_SETOWN_EX, &tst_own_ex));
+       if (TEST_RETURN < 0) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl F_SETOWN_EX failed");
+       }
+       test_set_and_get_sig(SIGUSR1);
+}
+
+static void setownex_cleanup(void)
+{
+       TEST(fcntl(test_fd, F_SETOWN_EX, &orig_own_ex));
+       if (TEST_RETURN < 0) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl F_SETOWN_EX restore orig_own_ex failed");
+       }
+}
+
+static int setownex_pgrp_setup(void)
+{
+       if (ownex_enabled == 0)
+               return 1;
+
+       tst_own_ex.type = F_OWNER_PGRP;
+       tst_own_ex.pid = pgrp_pid;
+       return 0;
+}
+
+static int setownex_tid_setup(void)
+{
+       pid_t tid;
+
+       if (ownex_enabled == 0)
+               return 1;
+
+       tid = syscall(__NR_gettid);
+       tst_own_ex.type = F_OWNER_TID;
+       tst_own_ex.pid = tid;
+       return 0;
+}
+#endif
+
+static void test_set_and_get_sig(int sig)
+{
+       int orig_sig;
+
+       TEST(fcntl(test_fd, F_GETSIG));
+       if (TEST_RETURN < 0) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl(fd, F_GETSIG) get orig_sig failed");
+       }
+       orig_sig = TEST_RETURN;
+
+       if (orig_sig == 0 || orig_sig == SIGIO)
+               tst_resm(TINFO, "default io events signal is SIGIO");
+
+       TEST(fcntl(test_fd, F_SETSIG, sig));
+       if (TEST_RETURN < 0) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl(fd, F_SETSIG, SIG: %d) failed", sig);
+       }
+
+       TEST(fcntl(test_fd, F_GETSIG));
+       if (TEST_RETURN < 0) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl(fd, F_GETSIG) get the set signal failed");
+       }
+       if (TEST_RETURN != sig) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl F_SETSIG set SIG: %d failed", sig);
+       }
+
+       wait_io_ready();
+
+       /* restore the default signal*/
+       TEST(fcntl(test_fd, F_SETSIG, orig_sig));
+       if (TEST_RETURN < 0) {
+               tst_brkm(TFAIL | TTERRNO, cleanup,
+                        "fcntl restore default signal failed");
+       }
+}
+
+static void signal_parent(void)
+{
+       int ret, fd;
+
+       fd = pipe_fds[1];
+       close(pipe_fds[0]);
+
+       ret = write(fd, "c", 1);
+
+       switch (ret) {
+       case 0:
+               fprintf(stderr, "No data written, something is wrong");
+       break;
+       case -1:
+               fprintf(stderr, "Failed to write to pipe: %s\n",
+                       strerror(errno));
+       }
+
+       close(fd);
+       return;
+}
+
+static void wait_io_ready(void)
+{
+       pid_t child;
+       int i;
+
+       fflush(stdout);
+       child = FORK_OR_VFORK();
+       if (child < 0)
+               tst_brkm(TBROK | TERRNO, cleanup, "fork failed");
+
+       if (child == 0) {
+               signal_parent();
+               exit(0);
+       } else {
+               /*
+                * if io_signal_received is not changed by signal handler
+                * in 5 seconds, consider the test failed.
+                */
+               for (i = 0; i < 1000; i++) {
+                       /* SIGUSR1 or SIGIO is received*/
+                       if (io_signal_received > 0)
+                               break;
+                       sched_yield();
+                       usleep(5000);
+               }
+
+               switch (io_signal_received) {
+               case SIGUSR1:
+                       tst_resm(TPASS, "fcntl test %s success",
+                                test_cases[ind].des);
+               break;
+               case SIGIO:
+                       tst_resm(TFAIL, "received default SIGIO, fcntl test "
+                                "%s failed", test_cases[ind].des);
+               break;
+               default:
+                       tst_brkm(TBROK, cleanup, "fcntl io events "
+                                "signal mechanism work abnormally");
+               }
+               io_signal_received = 0;
+               wait(NULL);
+       }
+}
+
+static void cleanup(void)
+{
+       TEST_CLEANUP;
+
+       if (pipe_fds[0] > 0)
+               SAFE_CLOSE(NULL, pipe_fds[0]);
+       if (pipe_fds[1] > 0)
+               SAFE_CLOSE(NULL, pipe_fds[1]);
+
+       tst_rmdir();
+}
-- 
1.8.2.1

------------------------------------------------------------------------------
CenturyLink Cloud: The Leader in Enterprise Cloud Services.
Learn Why More Businesses Are Choosing CenturyLink Cloud For
Critical Workloads, Development Environments & Everything In Between.
Get a Quote or Start a Free Trial Today. 
http://pubads.g.doubleclick.net/gampad/clk?id=119420431&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to