Basic test for O_PATH flag of open(2).
Obtain a file descriptor that can be used to perform operations
that act purely at the file descriptor level, the file itself is
not opened, the operations read(2), write(2), fchmod(2), fchown(2)
and fgetxattr(2) fail with the error EBADF.

Signed-off-by: Guangwen Feng <fenggw-f...@cn.fujitsu.com>
---
 include/lapi/fcntl.h                    |   4 +
 runtest/ltplite                         |   1 +
 runtest/stress.part3                    |   1 +
 runtest/syscalls                        |   1 +
 testcases/kernel/syscalls/.gitignore    |   1 +
 testcases/kernel/syscalls/open/open13.c | 168 ++++++++++++++++++++++++++++++++
 6 files changed, 176 insertions(+)
 create mode 100644 testcases/kernel/syscalls/open/open13.c

diff --git a/include/lapi/fcntl.h b/include/lapi/fcntl.h
index 200f574..3667b5e 100644
--- a/include/lapi/fcntl.h
+++ b/include/lapi/fcntl.h
@@ -59,6 +59,10 @@
 # define O_NOATIME 01000000
 #endif
 
+#ifndef O_PATH
+# define O_PATH 010000000
+#endif
+
 #ifndef FALLOC_FL_KEEP_SIZE
 # define FALLOC_FL_KEEP_SIZE 1
 #endif
diff --git a/runtest/ltplite b/runtest/ltplite
index 3bc681c..79be778 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -545,6 +545,7 @@ open09 open09
 open10 open10
 open11 open11
 open12 open12
+open13 open13
 
 mincore01 mincore01
 #mincore02 mincore02 currently hangs and does not exit correctly
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index 1ceeb8f..ab9af3c 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -467,6 +467,7 @@ open09 open09
 open10 open10
 open11 open11
 open12 open12
+open13 open13
 
 pathconf01 pathconf01
 
diff --git a/runtest/syscalls b/runtest/syscalls
index 70d4945..65a9ff2 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -711,6 +711,7 @@ open09 open09
 open10 open10
 open11 open11
 open12 open12
+open13 open13
 
 #openat test cases
 openat01 openat01
diff --git a/testcases/kernel/syscalls/.gitignore 
b/testcases/kernel/syscalls/.gitignore
index 172aeec..37c3755 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -615,6 +615,7 @@
 /open/open11
 /open/open12
 /open/open12_child
+/open/open13
 /openat/openat01
 /openat/openat02
 /openat/openat02_child
diff --git a/testcases/kernel/syscalls/open/open13.c 
b/testcases/kernel/syscalls/open/open13.c
new file mode 100644
index 0000000..1342dc2
--- /dev/null
+++ b/testcases/kernel/syscalls/open/open13.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Guangwen Feng <fenggw-f...@cn.fujitsu.com>
+ *
+ * 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.
+ */
+
+/*
+ * DESCRIPTION
+ *  Basic test for O_PATH flag of open(2).
+ *  "Obtain a file descriptor that can be used to perform operations
+ *   that act purely at the file descriptor level, the file itself is
+ *   not opened, the operations read(2), write(2), fchmod(2), fchown(2)
+ *   and fgetxattr(2) fail with the error EBADF."
+ *
+ *  The operations include but are not limited to the syscalls above.
+ */
+
+#define _GNU_SOURCE
+
+#include "config.h"
+
+#include <errno.h>
+#ifdef HAVE_ATTR_XATTR_H
+#include <sys/types.h>
+#include <attr/xattr.h>
+#endif
+
+#include "test.h"
+#include "safe_macros.h"
+#include "lapi/fcntl.h"
+
+#define TESTFILE       "testfile"
+#define FILE_MODE      (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID)
+
+static void setup(void);
+static void verify_read(void);
+static void verify_write(void);
+static void verify_fchmod(void);
+static void verify_fchown(void);
+#ifdef HAVE_ATTR_XATTR_H
+static void verify_fgetxattr(void);
+#endif
+static void check_result(const char *call_name);
+static void cleanup(void);
+
+static int fd;
+
+static void (*test_func[])(void) = {
+       verify_read,
+       verify_write,
+       verify_fchmod,
+       verify_fchown,
+#ifdef HAVE_ATTR_XATTR_H
+       verify_fgetxattr
+#endif
+};
+
+char *TCID = "open13";
+int TST_TOTAL = ARRAY_SIZE(test_func);
+
+int main(int ac, char **av)
+{
+       int lc;
+       int tc;
+
+       tst_parse_opts(ac, av, NULL, NULL);
+
+       setup();
+
+       for (lc = 0; TEST_LOOPING(lc); lc++) {
+               tst_count = 0;
+
+               fd = SAFE_OPEN(cleanup, TESTFILE, O_RDWR | O_PATH);
+
+               for (tc = 0; tc < TST_TOTAL; tc++)
+                       (*test_func[tc])();
+
+               SAFE_CLOSE(cleanup, fd);
+               fd = 0;
+       }
+
+       cleanup();
+       tst_exit();
+}
+
+static void setup(void)
+{
+       if ((tst_kvercmp(2, 6, 39)) < 0) {
+               tst_brkm(TCONF, NULL, "This test can only run on kernels "
+                       "that are 2.6.39 or higher");
+       }
+
+       tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+       tst_tmpdir();
+
+       SAFE_TOUCH(cleanup, TESTFILE, FILE_MODE, NULL);
+
+       TEST_PAUSE;
+}
+
+static void verify_read(void)
+{
+       char buf[255];
+
+       TEST(read(fd, buf, sizeof(buf)));
+       check_result("read(2)");
+}
+
+static void verify_write(void)
+{
+       TEST(write(fd, "w", 1));
+       check_result("write(2)");
+}
+
+static void verify_fchmod(void)
+{
+       TEST(fchmod(fd, 0666));
+       check_result("fchmod(2)");
+}
+
+static void verify_fchown(void)
+{
+       TEST(fchown(fd, 1000, 1000));
+       check_result("fchown(2)");
+}
+
+#ifdef HAVE_ATTR_XATTR_H
+static void verify_fgetxattr(void)
+{
+       TEST(fgetxattr(fd, "tkey", NULL, 1));
+       check_result("fgetxattr(2)");
+}
+#endif
+
+static void check_result(const char *call_name)
+{
+       if (TEST_RETURN == 0) {
+               tst_resm(TFAIL, "%s succeeded unexpectedly", call_name);
+               return;
+       }
+
+       if (TEST_ERRNO != EBADF) {
+               tst_resm(TFAIL | TTERRNO, "%s failed unexpectedly, "
+                       "expected EBADF", call_name);
+               return;
+       }
+
+       tst_resm(TPASS, "%s failed with EBADF", call_name);
+}
+
+static void cleanup(void)
+{
+       if (fd > 0 && close(fd))
+               tst_resm(TWARN | TERRNO, "failed to close file");
+
+       tst_rmdir();
+}
-- 
1.8.4.2


------------------------------------------------------------------------------
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to