* [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: add new testcase
@ 2016-01-29 9:08 Xiao Yang
2016-01-29 9:08 ` [LTP] [PATCH 2/3] llistxattr/llistxattr02.c: " Xiao Yang
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: Xiao Yang @ 2016-01-29 9:08 UTC (permalink / raw)
To: ltp
The testcase checks the basic functionality of the llistxattr(2).
llistxattr(2) retrieves the list of extended attribute names
associated with the link itself in the filesystem.
Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com>
---
runtest/ltplite | 2 +
runtest/syscalls | 2 +
testcases/kernel/syscalls/.gitignore | 1 +
testcases/kernel/syscalls/llistxattr/Makefile | 23 +++
.../kernel/syscalls/llistxattr/llistxattr01.c | 168 +++++++++++++++++++++
5 files changed, 196 insertions(+)
create mode 100644 testcases/kernel/syscalls/llistxattr/Makefile
create mode 100644 testcases/kernel/syscalls/llistxattr/llistxattr01.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 6ca24c5..0a56c3a 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -388,6 +388,8 @@ link08 link08
listen01 listen01
+llistxattr01 llistxattr01
+
llseek01 llseek01
llseek02 llseek02
llseek03 llseek03
diff --git a/runtest/syscalls b/runtest/syscalls
index d206831..ffd8be3 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -514,6 +514,8 @@ linkat02 linkat02
listen01 listen01
+llistxattr01 llistxattr01
+
llseek01 llseek01
llseek02 llseek02
llseek03 llseek03
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 1e0a85f..b283761 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -474,6 +474,7 @@
/linkat/linkat01
/linkat/linkat02
/listen/listen01
+/llistxattr/llistxattr01
/llseek/llseek01
/llseek/llseek02
/llseek/llseek03
diff --git a/testcases/kernel/syscalls/llistxattr/Makefile b/testcases/kernel/syscalls/llistxattr/Makefile
new file mode 100644
index 0000000..ed05a48
--- /dev/null
+++ b/testcases/kernel/syscalls/llistxattr/Makefile
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2016 Fujitsu Ltd.
+# Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+# the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.
+#
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/llistxattr/llistxattr01.c b/testcases/kernel/syscalls/llistxattr/llistxattr01.c
new file mode 100644
index 0000000..1f4e6b3
--- /dev/null
+++ b/testcases/kernel/syscalls/llistxattr/llistxattr01.c
@@ -0,0 +1,168 @@
+/*
+* Copyright (c) 2016 Fujitsu Ltd.
+* Author: Xiao Yang <yangx.jy@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
+* alone with this program.
+*/
+
+/*
+* Test Name: llistxattr01
+*
+* Description:
+* The testcase checks the basic functionality of the llistxattr(2).
+* llistxattr(2) retrieves the list of extended attribute names
+* associated with the given path in the filesystem. In the case of
+* a symbolic, the path associated with the link itself, not the file
+* that it refers to. The list is the set of (NULL-terminated) names,
+* one after the other. The length of the attribute name list is returned.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+
+#include "test.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+
+char *TCID = "llistxattr01";
+
+#ifdef HAVE_ATTR_XATTR_H
+#define SECURITY_KEY "security.symtest"
+#define SECURITY_KEY_INIT "security.selinux"
+#define VALUE "test"
+#define VALUE_SIZE 4
+#define KEY_SIZE 17
+
+static void verify_llistxattr(void);
+static void setup(void);
+static void cleanup(void);
+
+int TST_TOTAL = 1;
+
+int main(int ac, char **av)
+{
+ int lc;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ verify_llistxattr();
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void verify_llistxattr(void)
+{
+ int n;
+ int se = 1;
+ int size = 64;
+ char buf[size];
+ char cmp_buf1[size];
+ char cmp_buf2[size];
+
+ /* check selinux initialized attr */
+ n = lgetxattr("symlink", SECURITY_KEY_INIT, NULL, 0);
+ if (n == -1) {
+ if (errno == ENOATTR) {
+ se = 0;
+ } else {
+ tst_brkm(TFAIL | TERRNO, cleanup,
+ "lgetxattr() failed");
+ }
+ }
+
+ TEST(llistxattr("symlink", buf, size));
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "llistxattr() failed");
+ return;
+ }
+
+ if (TEST_RETURN != KEY_SIZE*(1 + se)) {
+ tst_resm(TFAIL, "llistxattr() retrieved %li bytes, "
+ "expected %i", TEST_RETURN, KEY_SIZE*2);
+ return;
+ }
+
+ /*
+ * The list of names is returned as an unordered array of
+ * NULL-terminated character strings.
+ */
+ if (se == 1) {
+ memcpy(cmp_buf1, SECURITY_KEY, KEY_SIZE);
+ memcpy(cmp_buf1+KEY_SIZE, SECURITY_KEY_INIT, KEY_SIZE);
+ memcpy(cmp_buf2, SECURITY_KEY_INIT, KEY_SIZE);
+ memcpy(cmp_buf2+KEY_SIZE, SECURITY_KEY, KEY_SIZE);
+
+ if (memcmp(buf, cmp_buf1, KEY_SIZE*(1 + se)) && memcmp(buf, cmp_buf2, KEY_SIZE*(1 + se))) {
+ tst_resm(TFAIL, "name list mismatched");
+ return;
+ }
+ } else {
+ if (memcmp(buf, SECURITY_KEY, KEY_SIZE*(1 + se))) {
+ tst_resm(TFAIL, "name list mismatched");
+ return;
+ }
+ }
+
+ tst_resm(TPASS, "llistxattr() succeeded");
+}
+
+static void setup(void)
+{
+ int n;
+
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ tst_tmpdir();
+
+ SAFE_TOUCH(cleanup, "testfile", 0644, NULL);
+
+ SAFE_SYMLINK(cleanup, "testfile", "symlink");
+
+ n = lsetxattr("symlink", SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (n == -1) {
+ if (errno == ENOTSUP) {
+ tst_brkm(TCONF, cleanup,
+ "no xattr support in fs or mounted "
+ "without user_xattr option");
+ } else {
+ tst_brkm(TFAIL | TERRNO, cleanup,
+ "lsetxattr() failed");
+ }
+ }
+}
+
+static void cleanup(void)
+{
+ tst_rmdir();
+}
+
+#else /* HAVE_ATTR_XATTR_H */
+int main(int ac, char **av)
+{
+ tst_brkm(TCONF, NULL, "<attr/xattr.h> does not exist.");
+}
+#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [LTP] [PATCH 2/3] llistxattr/llistxattr02.c: add new testcase
2016-01-29 9:08 [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: add new testcase Xiao Yang
@ 2016-01-29 9:08 ` Xiao Yang
2016-02-10 13:41 ` Cyril Hrubis
2016-01-29 9:08 ` [LTP] [PATCH 3/3] llistxattr/llistxattr03.c: " Xiao Yang
2016-02-10 14:04 ` [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: " Cyril Hrubis
2 siblings, 1 reply; 17+ messages in thread
From: Xiao Yang @ 2016-01-29 9:08 UTC (permalink / raw)
To: ltp
1) llistxattr(2) fails if the size of the list buffer is too small to
hold the result and set errno to ERANGE.
2) llistxattr(2) fails if path is an empty string and set errno to ENOENT.
3) llistxattr(2) fails when attempted to read from a invalid address and
set set errno to EFAULT.
Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
.../kernel/syscalls/llistxattr/llistxattr02.c | 143 +++++++++++++++++++++
4 files changed, 146 insertions(+)
create mode 100644 testcases/kernel/syscalls/llistxattr/llistxattr02.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 0a56c3a..f752150 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -389,6 +389,7 @@ link08 link08
listen01 listen01
llistxattr01 llistxattr01
+llistxattr02 llistxattr02
llseek01 llseek01
llseek02 llseek02
diff --git a/runtest/syscalls b/runtest/syscalls
index ffd8be3..5652da1 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -515,6 +515,7 @@ linkat02 linkat02
listen01 listen01
llistxattr01 llistxattr01
+llistxattr02 llistxattr02
llseek01 llseek01
llseek02 llseek02
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index b283761..053c067 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -475,6 +475,7 @@
/linkat/linkat02
/listen/listen01
/llistxattr/llistxattr01
+/llistxattr/llistxattr02
/llseek/llseek01
/llseek/llseek02
/llseek/llseek03
diff --git a/testcases/kernel/syscalls/llistxattr/llistxattr02.c b/testcases/kernel/syscalls/llistxattr/llistxattr02.c
new file mode 100644
index 0000000..d40b619
--- /dev/null
+++ b/testcases/kernel/syscalls/llistxattr/llistxattr02.c
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2016 Fujitsu Ltd.
+* Author: Xiao Yang <yangx.jy@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
+* alone with this program.
+*/
+
+/*
+* Test Name: llistxattr02
+*
+* Description:
+* 1) llistxattr(2) fails if the size of the list buffer is too small
+* to hold the result.
+* 2) llistxattr(2) fails if path is an empty string.
+* 3) llistxattr(2) fails when attempted to read from a invalid address.
+*
+* Expected Result:
+* 1) llistxattr(2) should return -1 and set errno to ERANGE.
+* 2) llistxattr(2) should return -1 and set errno to ENOENT.
+* 3) llistxattr(2) should return -1 and set errno to EFAULT.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+
+#include "test.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+
+char *TCID = "llistxattr02";
+
+#ifdef HAVE_ATTR_XATTR_H
+#define SECURITY_KEY "security.symtest"
+#define VALUE "test"
+#define VALUE_SIZE 4
+
+static struct test_case {
+ const char *path;
+ size_t size;
+ int exp_err;
+} tc[] = {
+ /* test1 */
+ {"symlink", 1, ERANGE},
+ /* test2 */
+ {"", 20, ENOENT},
+ /* test3 */
+ {NULL, 20, EFAULT}
+};
+
+static void verify_llistxattr(struct test_case *tc);
+static void setup(void);
+static void cleanup(void);
+
+int TST_TOTAL = ARRAY_SIZE(tc);
+
+int main(int ac, char **av)
+{
+ int lc;
+ int i;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+ for (i = 0; i < TST_TOTAL; i++)
+ verify_llistxattr(&tc[i]);
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void verify_llistxattr(struct test_case *tc)
+{
+ char buf[tc->size];
+
+ TEST(llistxattr(tc->path, buf, tc->size));
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "llistxattr() succeeded unexpectedly");
+ } else {
+ if (TEST_ERRNO != tc->exp_err) {
+ tst_resm(TFAIL | TTERRNO, "llistxattr() failed "
+ "unexpectedlly, expected errno is %s",
+ tst_strerrno(tc->exp_err));
+ } else {
+ tst_resm(TPASS | TTERRNO,
+ "llistxattr() failed as expected");
+ }
+ }
+}
+
+static void setup(void)
+{
+ int n;
+
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ tst_tmpdir();
+
+ SAFE_TOUCH(cleanup, "testfile", 0644, NULL);
+
+ SAFE_SYMLINK(cleanup, "testfile", "symlink");
+
+ n = lsetxattr("symlink", SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (n == -1) {
+ if (errno == ENOTSUP) {
+ tst_brkm(TCONF, cleanup, "no xattr support in fs or "
+ "mounted without user_xattr option");
+ } else {
+ tst_brkm(TFAIL | TERRNO, cleanup, "lsetxattr() failed");
+ }
+ }
+}
+
+static void cleanup(void)
+{
+ tst_rmdir();
+}
+
+#else /* HAVE_ATTR_XATTR_H */
+int main(int ac, char **av)
+{
+ tst_brkm(TCONF, NULL, "<attr/xattr.h> does not exist.");
+}
+#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [LTP] [PATCH 3/3] llistxattr/llistxattr03.c: add new testcase
2016-01-29 9:08 [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: add new testcase Xiao Yang
2016-01-29 9:08 ` [LTP] [PATCH 2/3] llistxattr/llistxattr02.c: " Xiao Yang
@ 2016-01-29 9:08 ` Xiao Yang
2016-02-10 14:12 ` Cyril Hrubis
2016-02-10 14:04 ` [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: " Cyril Hrubis
2 siblings, 1 reply; 17+ messages in thread
From: Xiao Yang @ 2016-01-29 9:08 UTC (permalink / raw)
To: ltp
llistxattr(2) with an empty buffer of size zero can return
the current size of the list of extended attribute names.
Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
.../kernel/syscalls/llistxattr/llistxattr03.c | 133 +++++++++++++++++++++
4 files changed, 136 insertions(+)
create mode 100644 testcases/kernel/syscalls/llistxattr/llistxattr03.c
diff --git a/runtest/ltplite b/runtest/ltplite
index f752150..bc2541b 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -390,6 +390,7 @@ listen01 listen01
llistxattr01 llistxattr01
llistxattr02 llistxattr02
+llistxattr03 llistxattr03
llseek01 llseek01
llseek02 llseek02
diff --git a/runtest/syscalls b/runtest/syscalls
index 5652da1..06a8cc2 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -516,6 +516,7 @@ listen01 listen01
llistxattr01 llistxattr01
llistxattr02 llistxattr02
+llistxattr03 llistxattr03
llseek01 llseek01
llseek02 llseek02
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 053c067..e902ad8 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -476,6 +476,7 @@
/listen/listen01
/llistxattr/llistxattr01
/llistxattr/llistxattr02
+/llistxattr/llistxattr03
/llseek/llseek01
/llseek/llseek02
/llseek/llseek03
diff --git a/testcases/kernel/syscalls/llistxattr/llistxattr03.c b/testcases/kernel/syscalls/llistxattr/llistxattr03.c
new file mode 100644
index 0000000..dd5ab52
--- /dev/null
+++ b/testcases/kernel/syscalls/llistxattr/llistxattr03.c
@@ -0,0 +1,133 @@
+/*
+* Copyright (c) 2016 Fujitsu Ltd.
+* Author: Xiao Yang <yangx.jy@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
+* alone with this program.
+*/
+
+/*
+* Test Name: llistxattr03
+*
+* Description:
+* llistxattr(2) with an empty buffer of size zero can return
+* the current size of the list of extended attribute names.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+
+#include "test.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+
+char *TCID = "llistxattr03";
+
+#ifdef HAVE_ATTR_XATTR_H
+#define SECURITY_KEY "security.symtest"
+#define SECURITY_KEY_INIT "security.selinux"
+#define VALUE "test"
+#define VALUE_SIZE 4
+#define KEY_SIZE 17
+
+static void verify_llistxattr(void);
+static void setup(void);
+static void cleanup(void);
+
+int TST_TOTAL = 1;
+
+int main(int ac, char **av)
+{
+ int lc;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ verify_llistxattr();
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void verify_llistxattr(void)
+{
+ int se = 1;
+ int n;
+
+ /* check selinux initialized attr */
+ n = lgetxattr("symlink", SECURITY_KEY_INIT, NULL, 0);
+ if (n == -1) {
+ if (errno == ENOATTR) {
+ se = 0;
+ } else {
+ tst_brkm(TFAIL | TERRNO, cleanup,
+ "lgetxattr() failed");
+ }
+ }
+
+ TEST(llistxattr("symlink", NULL, 0));
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "llistxattr() failed");
+ return;
+ }
+
+ if (TEST_RETURN == KEY_SIZE*(1 + se))
+ tst_resm(TPASS, "llistxattr() returned the size successfully");
+ else
+ tst_resm(TFAIL, "llistxattr() failed to return the size");
+}
+
+static void setup(void)
+{
+ int n;
+
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ tst_tmpdir();
+
+ SAFE_TOUCH(cleanup, "testfile", 0644, NULL);
+
+ SAFE_SYMLINK(cleanup, "testfile", "symlink");
+
+ n = lsetxattr("symlink", SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (n == -1) {
+ if (errno == ENOTSUP) {
+ tst_brkm(TCONF, cleanup, "no xattr support in fs or "
+ "mounted without user_xattr option");
+ } else {
+ tst_brkm(TFAIL | TERRNO, cleanup, "lsetxattr() failed");
+ }
+ }
+}
+
+static void cleanup(void)
+{
+ tst_rmdir();
+}
+
+#else /* HAVE_ATTR_XATTR_H */
+int main(int ac, char **av)
+{
+ tst_brkm(TCONF, NULL, "<attr/xattr.h> does not exist.");
+}
+#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [LTP] [PATCH 3/3] llistxattr/llistxattr03.c: add new testcase
2016-01-29 9:08 ` [LTP] [PATCH 3/3] llistxattr/llistxattr03.c: " Xiao Yang
@ 2016-02-10 14:12 ` Cyril Hrubis
0 siblings, 0 replies; 17+ messages in thread
From: Cyril Hrubis @ 2016-02-10 14:12 UTC (permalink / raw)
To: ltp
Hi!
> diff --git a/testcases/kernel/syscalls/llistxattr/llistxattr03.c b/testcases/kernel/syscalls/llistxattr/llistxattr03.c
> new file mode 100644
> index 0000000..dd5ab52
> --- /dev/null
> +++ b/testcases/kernel/syscalls/llistxattr/llistxattr03.c
> @@ -0,0 +1,133 @@
> +/*
> +* Copyright (c) 2016 Fujitsu Ltd.
> +* Author: Xiao Yang <yangx.jy@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
> +* alone with this program.
> +*/
> +
> +/*
> +* Test Name: llistxattr03
> +*
> +* Description:
> +* llistxattr(2) with an empty buffer of size zero can return
> +* the current size of the list of extended attribute names.
> +*/
> +
> +#include "config.h"
> +#include <errno.h>
> +#include <sys/types.h>
> +
> +#ifdef HAVE_ATTR_XATTR_H
> +#include <attr/xattr.h>
> +#endif
> +
> +#include "test.h"
> +#include "safe_macros.h"
> +#include "safe_file_ops.h"
> +
> +char *TCID = "llistxattr03";
> +
> +#ifdef HAVE_ATTR_XATTR_H
> +#define SECURITY_KEY "security.symtest"
> +#define SECURITY_KEY_INIT "security.selinux"
> +#define VALUE "test"
> +#define VALUE_SIZE 4
> +#define KEY_SIZE 17
> +
> +static void verify_llistxattr(void);
> +static void setup(void);
> +static void cleanup(void);
> +
> +int TST_TOTAL = 1;
> +
> +int main(int ac, char **av)
> +{
> + int lc;
> +
> + tst_parse_opts(ac, av, NULL, NULL);
> +
> + setup();
> +
> + for (lc = 0; TEST_LOOPING(lc); lc++) {
> + tst_count = 0;
> +
> + verify_llistxattr();
> + }
> +
> + cleanup();
> + tst_exit();
> +}
> +
> +static void verify_llistxattr(void)
> +{
> + int se = 1;
> + int n;
> +
> + /* check selinux initialized attr */
> + n = lgetxattr("symlink", SECURITY_KEY_INIT, NULL, 0);
> + if (n == -1) {
> + if (errno == ENOATTR) {
> + se = 0;
> + } else {
> + tst_brkm(TFAIL | TERRNO, cleanup,
> + "lgetxattr() failed");
> + }
> + }
> +
> + TEST(llistxattr("symlink", NULL, 0));
> + if (TEST_RETURN == -1) {
> + tst_resm(TFAIL | TTERRNO, "llistxattr() failed");
> + return;
> + }
> +
> + if (TEST_RETURN == KEY_SIZE*(1 + se))
> + tst_resm(TPASS, "llistxattr() returned the size successfully");
> + else
> + tst_resm(TFAIL, "llistxattr() failed to return the size");
Hmm, why don't we just call llistxattr() with zero size and then check
that it succeds with allocated buffer of a size of the return value and
fails for a buffer that is one byte smaller?
There is no need for special cases like this.
> +}
> +
> +static void setup(void)
> +{
> + int n;
> +
> + tst_sig(NOFORK, DEF_HANDLER, cleanup);
> +
> + TEST_PAUSE;
> +
> + tst_tmpdir();
> +
> + SAFE_TOUCH(cleanup, "testfile", 0644, NULL);
> +
> + SAFE_SYMLINK(cleanup, "testfile", "symlink");
> +
> + n = lsetxattr("symlink", SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
Why the symlink here? I understand that in the first test you want to
make sure that the atrribute from symlink is read. (you should probably
add some attributes for the file there, and maybe try with broken
symlink as well)
But here you just check that it returns a size for a suitable buffer.
> + if (n == -1) {
> + if (errno == ENOTSUP) {
> + tst_brkm(TCONF, cleanup, "no xattr support in fs or "
> + "mounted without user_xattr option");
> + } else {
> + tst_brkm(TFAIL | TERRNO, cleanup, "lsetxattr() failed");
> + }
> + }
> +}
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 17+ messages in thread
* [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: add new testcase
2016-01-29 9:08 [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: add new testcase Xiao Yang
2016-01-29 9:08 ` [LTP] [PATCH 2/3] llistxattr/llistxattr02.c: " Xiao Yang
2016-01-29 9:08 ` [LTP] [PATCH 3/3] llistxattr/llistxattr03.c: " Xiao Yang
@ 2016-02-10 14:04 ` Cyril Hrubis
2016-02-18 10:02 ` Xiao Yang
2 siblings, 1 reply; 17+ messages in thread
From: Cyril Hrubis @ 2016-02-10 14:04 UTC (permalink / raw)
To: ltp
Hi!
> +#ifdef HAVE_ATTR_XATTR_H
> +#define SECURITY_KEY "security.symtest"
^
Why symtest, I would preffere to have 'ltp'
substring in everything that testcases create
so that is clear where it came from
> +#define SECURITY_KEY_INIT "security.selinux"
> +#define VALUE "test"
> +#define VALUE_SIZE 4
> +#define KEY_SIZE 17
> +static void verify_llistxattr(void)
> +{
> + int n;
> + int se = 1;
> + int size = 64;
> + char buf[size];
> + char cmp_buf1[size];
> + char cmp_buf2[size];
> +
> + /* check selinux initialized attr */
> + n = lgetxattr("symlink", SECURITY_KEY_INIT, NULL, 0);
> + if (n == -1) {
> + if (errno == ENOATTR) {
> + se = 0;
> + } else {
> + tst_brkm(TFAIL | TERRNO, cleanup,
> + "lgetxattr() failed");
> + }
> + }
I do not like the special case for seliux here. What we should do
instead is to:
* Create file/symlink and store it's attribute list
* Add an attribute
* Check that the list has exactly one more attribute
* Remove the file/symlink
And there should be a comment that selinux adds default attribute to
newly created files/symlinks.
> + TEST(llistxattr("symlink", buf, size));
> + if (TEST_RETURN == -1) {
> + tst_resm(TFAIL | TTERRNO, "llistxattr() failed");
> + return;
> + }
> +
> + if (TEST_RETURN != KEY_SIZE*(1 + se)) {
> + tst_resm(TFAIL, "llistxattr() retrieved %li bytes, "
> + "expected %i", TEST_RETURN, KEY_SIZE*2);
> + return;
> + }
> +
> + /*
> + * The list of names is returned as an unordered array of
> + * NULL-terminated character strings.
> + */
> + if (se == 1) {
> + memcpy(cmp_buf1, SECURITY_KEY, KEY_SIZE);
> + memcpy(cmp_buf1+KEY_SIZE, SECURITY_KEY_INIT, KEY_SIZE);
> + memcpy(cmp_buf2, SECURITY_KEY_INIT, KEY_SIZE);
> + memcpy(cmp_buf2+KEY_SIZE, SECURITY_KEY, KEY_SIZE);
> +
> + if (memcmp(buf, cmp_buf1, KEY_SIZE*(1 + se)) && memcmp(buf, cmp_buf2, KEY_SIZE*(1 + se))) {
> + tst_resm(TFAIL, "name list mismatched");
> + return;
> + }
> + } else {
> + if (memcmp(buf, SECURITY_KEY, KEY_SIZE*(1 + se))) {
> + tst_resm(TFAIL, "name list mismatched");
> + return;
> + }
> + }
If you have actually checked that the list has 2 attributes all you
need to do here is to check that it includes both attributes.
All you need is a function that takes attribute list and checks that
there is attribute included, i.e.
int has_attribute(const char *list, unsigned int llen, const char *attr)
{
unsigned int i;
for (i = 0; i < llen; i += strlen(list + i) + 1) {
if (!strcmp(list+i, attr))
return 1;
}
return 0;
}
...
if (!has_attribute(buf, size, attr_1)) {
tst_resm(TFAIL, "Missing attribute %s", attr_1);
return;
}
if (!has_attribute(buf, size, attr_2)) {
...
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 17+ messages in thread* [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: add new testcase
2016-02-10 14:04 ` [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: " Cyril Hrubis
@ 2016-02-18 10:02 ` Xiao Yang
2016-02-18 12:03 ` Cyril Hrubis
0 siblings, 1 reply; 17+ messages in thread
From: Xiao Yang @ 2016-02-18 10:02 UTC (permalink / raw)
To: ltp
? 2016/02/10 22:04, Cyril Hrubis ??:
> Hi!
>> +#ifdef HAVE_ATTR_XATTR_H
>> +#define SECURITY_KEY "security.symtest"
> ^
>
> Why symtest, I would preffere to have 'ltp'
> substring in everything that testcases create
> so that is clear where it came from
>
>> +#define SECURITY_KEY_INIT "security.selinux"
>> +#define VALUE "test"
>> +#define VALUE_SIZE 4
>> +#define KEY_SIZE 17
>
>> +static void verify_llistxattr(void)
>> +{
>> + int n;
>> + int se = 1;
>> + int size = 64;
>> + char buf[size];
>> + char cmp_buf1[size];
>> + char cmp_buf2[size];
>> +
>> + /* check selinux initialized attr */
>> + n = lgetxattr("symlink", SECURITY_KEY_INIT, NULL, 0);
>> + if (n == -1) {
>> + if (errno == ENOATTR) {
>> + se = 0;
>> + } else {
>> + tst_brkm(TFAIL | TERRNO, cleanup,
>> + "lgetxattr() failed");
>> + }
>> + }
> I do not like the special case for seliux here. What we should do
> instead is to:
>
> * Create file/symlink and store it's attribute list
>
> * Add an attribute
>
> * Check that the list has exactly one more attribute
>
> * Remove the file/symlink
>
>
If we don't check that selinux adds default attribute to symlinks, What
about the return value.
We're not going to judge the size of the extended attribute name list.
That's OK?
> And there should be a comment that selinux adds default attribute to
> newly created files/symlinks.
>
>
>> + TEST(llistxattr("symlink", buf, size));
>> + if (TEST_RETURN == -1) {
>> + tst_resm(TFAIL | TTERRNO, "llistxattr() failed");
>> + return;
>> + }
>> +
>> + if (TEST_RETURN != KEY_SIZE*(1 + se)) {
>> + tst_resm(TFAIL, "llistxattr() retrieved %li bytes, "
>> + "expected %i", TEST_RETURN, KEY_SIZE*2);
>> + return;
>> + }
>> +
>> + /*
>> + * The list of names is returned as an unordered array of
>> + * NULL-terminated character strings.
>> + */
>> + if (se == 1) {
>> + memcpy(cmp_buf1, SECURITY_KEY, KEY_SIZE);
>> + memcpy(cmp_buf1+KEY_SIZE, SECURITY_KEY_INIT, KEY_SIZE);
>> + memcpy(cmp_buf2, SECURITY_KEY_INIT, KEY_SIZE);
>> + memcpy(cmp_buf2+KEY_SIZE, SECURITY_KEY, KEY_SIZE);
>> +
>> + if (memcmp(buf, cmp_buf1, KEY_SIZE*(1 + se))&& memcmp(buf, cmp_buf2, KEY_SIZE*(1 + se))) {
>> + tst_resm(TFAIL, "name list mismatched");
>> + return;
>> + }
>> + } else {
>> + if (memcmp(buf, SECURITY_KEY, KEY_SIZE*(1 + se))) {
>> + tst_resm(TFAIL, "name list mismatched");
>> + return;
>> + }
>> + }
> If you have actually checked that the list has 2 attributes all you
> need to do here is to check that it includes both attributes.
>
> All you need is a function that takes attribute list and checks that
> there is attribute included, i.e.
>
> int has_attribute(const char *list, unsigned int llen, const char *attr)
> {
> unsigned int i;
>
> for (i = 0; i< llen; i += strlen(list + i) + 1) {
> if (!strcmp(list+i, attr))
> return 1;
> }
>
> return 0;
> }
>
> ...
> if (!has_attribute(buf, size, attr_1)) {
> tst_resm(TFAIL, "Missing attribute %s", attr_1);
> return;
> }
>
> if (!has_attribute(buf, size, attr_2)) {
> ...
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20160218/30c84406/attachment.html>
^ permalink raw reply [flat|nested] 17+ messages in thread* [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: add new testcase
2016-02-18 10:02 ` Xiao Yang
@ 2016-02-18 12:03 ` Cyril Hrubis
2016-02-19 4:55 ` [LTP] [PATCH v2 " Xiao Yang
0 siblings, 1 reply; 17+ messages in thread
From: Cyril Hrubis @ 2016-02-18 12:03 UTC (permalink / raw)
To: ltp
Hi!
> > I do not like the special case for seliux here. What we should do
> > instead is to:
> >
> > * Create file/symlink and store it's attribute list
> >
> > * Add an attribute
> >
> > * Check that the list has exactly one more attribute
> >
> > * Remove the file/symlink
> >
> >
> If we don't check that selinux adds default attribute to symlinks, What
> about the return value.
>
> We're not going to judge the size of the extended attribute name list.
> That's OK?
By "Check that the list has exactly one more attribute" I meant that we
compare the result to the previous state. If we store the attribute list
right after the symlink was created we can check if the increase in list
size is as expected. Or is there a reason why we can't do this?
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 17+ messages in thread
* [LTP] [PATCH v2 1/3] llistxattr/llistxattr01.c: add new testcase
2016-02-18 12:03 ` Cyril Hrubis
@ 2016-02-19 4:55 ` Xiao Yang
2016-02-19 4:55 ` [LTP] [PATCH v2 2/3] llistxattr/llistxattr02.c: " Xiao Yang
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: Xiao Yang @ 2016-02-19 4:55 UTC (permalink / raw)
To: ltp
The testcase checks the basic functionality of the llistxattr(2).
llistxattr(2) retrieves the list of extended attribute names
associated with the link itself in the filesystem.
Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com>
---
runtest/ltplite | 2 +
runtest/syscalls | 2 +
testcases/kernel/syscalls/.gitignore | 1 +
testcases/kernel/syscalls/llistxattr/Makefile | 23 +++
.../kernel/syscalls/llistxattr/llistxattr01.c | 159 +++++++++++++++++++++
5 files changed, 187 insertions(+)
create mode 100644 testcases/kernel/syscalls/llistxattr/Makefile
create mode 100644 testcases/kernel/syscalls/llistxattr/llistxattr01.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 89accc4..de7cecb 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -387,6 +387,8 @@ link08 link08
listen01 listen01
+llistxattr01 llistxattr01
+
llseek01 llseek01
llseek02 llseek02
llseek03 llseek03
diff --git a/runtest/syscalls b/runtest/syscalls
index 5f169a3..c48dd92 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -513,6 +513,8 @@ linkat02 linkat02
listen01 listen01
+llistxattr01 llistxattr01
+
llseek01 llseek01
llseek02 llseek02
llseek03 llseek03
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index de403e4..47f2fc8 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -473,6 +473,7 @@
/linkat/linkat01
/linkat/linkat02
/listen/listen01
+/llistxattr/llistxattr01
/llseek/llseek01
/llseek/llseek02
/llseek/llseek03
diff --git a/testcases/kernel/syscalls/llistxattr/Makefile b/testcases/kernel/syscalls/llistxattr/Makefile
new file mode 100644
index 0000000..ed05a48
--- /dev/null
+++ b/testcases/kernel/syscalls/llistxattr/Makefile
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2016 Fujitsu Ltd.
+# Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+# the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.
+#
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/llistxattr/llistxattr01.c b/testcases/kernel/syscalls/llistxattr/llistxattr01.c
new file mode 100644
index 0000000..0bf6f25
--- /dev/null
+++ b/testcases/kernel/syscalls/llistxattr/llistxattr01.c
@@ -0,0 +1,159 @@
+/*
+* Copyright (c) 2016 Fujitsu Ltd.
+* Author: Xiao Yang <yangx.jy@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
+* alone with this program.
+*/
+
+/*
+* Test Name: llistxattr01
+*
+* Description:
+* The testcase checks the basic functionality of the llistxattr(2).
+* llistxattr(2) retrieves the list of extended attribute names
+* associated with the link itself in the filesystem.
+*
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+
+#include "test.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+
+char *TCID = "llistxattr01";
+
+#ifdef HAVE_ATTR_XATTR_H
+#define SECURITY_KEY1 "security.ltptest1"
+#define SECURITY_KEY2 "security.ltptest2"
+#define VALUE "test"
+#define VALUE_SIZE 4
+#define KEY_SIZE 17
+
+static void verify_llistxattr(void);
+static void setup(void);
+static void set_xattr(const char *, const char *);
+static int has_attribute(const char *, int, const char *);
+static void cleanup(void);
+
+int TST_TOTAL = 1;
+
+int main(int ac, char **av)
+{
+ int lc;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ verify_llistxattr();
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void verify_llistxattr(void)
+{
+ int size = 64;
+ char buf[size];
+
+ TEST(llistxattr("symlink", buf, size));
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TERRNO, "llistxattr() failed");
+ return;
+ }
+
+ if (has_attribute(buf, size, SECURITY_KEY1)) {
+ tst_resm(TFAIL, "get file attribute %s unexpectlly",
+ SECURITY_KEY1);
+ return;
+ }
+
+ if (!has_attribute(buf, size, SECURITY_KEY2)) {
+ tst_resm(TFAIL, "missing attribute %s", SECURITY_KEY2);
+ return;
+ }
+
+ tst_resm(TPASS, "llistxattr() succeeded");
+}
+
+static void setup(void)
+{
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ tst_tmpdir();
+
+ SAFE_TOUCH(cleanup, "testfile", 0644, NULL);
+
+ SAFE_SYMLINK(cleanup, "testfile", "symlink");
+
+ set_xattr("testfile", SECURITY_KEY1);
+
+ set_xattr("symlink", SECURITY_KEY2);
+}
+
+static void set_xattr(const char *path, const char *key)
+{
+ int n;
+
+ n = lsetxattr(path, key, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (n == -1) {
+ if (errno == ENOTSUP) {
+ tst_brkm(TCONF, cleanup,
+ "no xattr support in fs or mounted "
+ "without user_xattr option");
+ }
+
+ if (errno == EEXIST) {
+ tst_brkm(TFAIL, cleanup, "exist attribute %s", key);
+ } else {
+ tst_brkm(TFAIL | TERRNO, cleanup,
+ "lsetxattr() failed");
+ }
+ }
+}
+
+static int has_attribute(const char *list, int llen, const char *attr)
+{
+ int i;
+
+ for (i = 0; i < llen; i += strlen(list + i) + 1) {
+ if (!strcmp(list + i, attr))
+ return 1;
+ }
+ return 0;
+}
+
+static void cleanup(void)
+{
+ tst_rmdir();
+}
+
+#else /* HAVE_ATTR_XATTR_H */
+int main(int ac, char **av)
+{
+ tst_brkm(TCONF, NULL, "<attr/xattr.h> does not exist.");
+}
+#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [LTP] [PATCH v2 2/3] llistxattr/llistxattr02.c: add new testcase
2016-02-19 4:55 ` [LTP] [PATCH v2 " Xiao Yang
@ 2016-02-19 4:55 ` Xiao Yang
2016-02-24 13:54 ` Cyril Hrubis
2016-02-19 4:55 ` [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: " Xiao Yang
2016-02-24 13:38 ` [LTP] [PATCH v2 1/3] llistxattr/llistxattr01.c: " Cyril Hrubis
2 siblings, 1 reply; 17+ messages in thread
From: Xiao Yang @ 2016-02-19 4:55 UTC (permalink / raw)
To: ltp
1) llistxattr(2) fails if the size of the list buffer is too small to
hold the result and set errno to ERANGE.
2) llistxattr(2) fails if path is an empty string and set errno to ENOENT.
3) llistxattr(2) fails when attempted to read from a invalid address and
set set errno to EFAULT.
Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
.../kernel/syscalls/llistxattr/llistxattr02.c | 143 +++++++++++++++++++++
4 files changed, 146 insertions(+)
create mode 100644 testcases/kernel/syscalls/llistxattr/llistxattr02.c
diff --git a/runtest/ltplite b/runtest/ltplite
index de7cecb..ea18c22 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -388,6 +388,7 @@ link08 link08
listen01 listen01
llistxattr01 llistxattr01
+llistxattr02 llistxattr02
llseek01 llseek01
llseek02 llseek02
diff --git a/runtest/syscalls b/runtest/syscalls
index c48dd92..a986a4e 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -514,6 +514,7 @@ linkat02 linkat02
listen01 listen01
llistxattr01 llistxattr01
+llistxattr02 llistxattr02
llseek01 llseek01
llseek02 llseek02
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 47f2fc8..1762c14 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -474,6 +474,7 @@
/linkat/linkat02
/listen/listen01
/llistxattr/llistxattr01
+/llistxattr/llistxattr02
/llseek/llseek01
/llseek/llseek02
/llseek/llseek03
diff --git a/testcases/kernel/syscalls/llistxattr/llistxattr02.c b/testcases/kernel/syscalls/llistxattr/llistxattr02.c
new file mode 100644
index 0000000..cf53275
--- /dev/null
+++ b/testcases/kernel/syscalls/llistxattr/llistxattr02.c
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2016 Fujitsu Ltd.
+* Author: Xiao Yang <yangx.jy@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
+* alone with this program.
+*/
+
+/*
+* Test Name: llistxattr02
+*
+* Description:
+* 1) llistxattr(2) fails if the size of the list buffer is too small
+* to hold the result.
+* 2) llistxattr(2) fails if path is an empty string.
+* 3) llistxattr(2) fails when attempted to read from a invalid address.
+*
+* Expected Result:
+* 1) llistxattr(2) should return -1 and set errno to ERANGE.
+* 2) llistxattr(2) should return -1 and set errno to ENOENT.
+* 3) llistxattr(2) should return -1 and set errno to EFAULT.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+
+#include "test.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+
+char *TCID = "llistxattr02";
+
+#ifdef HAVE_ATTR_XATTR_H
+#define SECURITY_KEY "security.ltptest"
+#define VALUE "test"
+#define VALUE_SIZE 4
+
+static struct test_case {
+ const char *path;
+ size_t size;
+ int exp_err;
+} tc[] = {
+ /* test1 */
+ {"symlink", 1, ERANGE},
+ /* test2 */
+ {"", 20, ENOENT},
+ /* test3 */
+ {(char *)-1, 20, EFAULT}
+};
+
+static void verify_llistxattr(struct test_case *tc);
+static void setup(void);
+static void cleanup(void);
+
+int TST_TOTAL = ARRAY_SIZE(tc);
+
+int main(int ac, char **av)
+{
+ int lc;
+ int i;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+ for (i = 0; i < TST_TOTAL; i++)
+ verify_llistxattr(&tc[i]);
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void verify_llistxattr(struct test_case *tc)
+{
+ char buf[tc->size];
+
+ TEST(llistxattr(tc->path, buf, tc->size));
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "llistxattr() succeeded unexpectedly");
+ } else {
+ if (TEST_ERRNO != tc->exp_err) {
+ tst_resm(TFAIL | TTERRNO, "llistxattr() failed "
+ "unexpectedlly, expected %s",
+ tst_strerrno(tc->exp_err));
+ } else {
+ tst_resm(TPASS | TTERRNO,
+ "llistxattr() failed as expected");
+ }
+ }
+}
+
+static void setup(void)
+{
+ int n;
+
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ tst_tmpdir();
+
+ SAFE_TOUCH(cleanup, "testfile", 0644, NULL);
+
+ SAFE_SYMLINK(cleanup, "testfile", "symlink");
+
+ n = lsetxattr("symlink", SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (n == -1) {
+ if (errno == ENOTSUP) {
+ tst_brkm(TCONF, cleanup, "no xattr support in fs or "
+ "mounted without user_xattr option");
+ } else {
+ tst_brkm(TFAIL | TERRNO, cleanup, "lsetxattr() failed");
+ }
+ }
+}
+
+static void cleanup(void)
+{
+ tst_rmdir();
+}
+
+#else /* HAVE_ATTR_XATTR_H */
+int main(int ac, char **av)
+{
+ tst_brkm(TCONF, NULL, "<attr/xattr.h> does not exist.");
+}
+#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: add new testcase
2016-02-19 4:55 ` [LTP] [PATCH v2 " Xiao Yang
2016-02-19 4:55 ` [LTP] [PATCH v2 2/3] llistxattr/llistxattr02.c: " Xiao Yang
@ 2016-02-19 4:55 ` Xiao Yang
2016-02-24 14:28 ` Cyril Hrubis
2016-02-24 13:38 ` [LTP] [PATCH v2 1/3] llistxattr/llistxattr01.c: " Cyril Hrubis
2 siblings, 1 reply; 17+ messages in thread
From: Xiao Yang @ 2016-02-19 4:55 UTC (permalink / raw)
To: ltp
llistxattr() is identical to listxattr(), we call llistxattr() with
zero size and check that it returns value which is suitable size of
buffer to hold the name list.
Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
.../kernel/syscalls/llistxattr/llistxattr03.c | 114 +++++++++++++++++++++
4 files changed, 117 insertions(+)
create mode 100644 testcases/kernel/syscalls/llistxattr/llistxattr03.c
diff --git a/runtest/ltplite b/runtest/ltplite
index ea18c22..d9a362d 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -389,6 +389,7 @@ listen01 listen01
llistxattr01 llistxattr01
llistxattr02 llistxattr02
+llistxattr03 llistxattr03
llseek01 llseek01
llseek02 llseek02
diff --git a/runtest/syscalls b/runtest/syscalls
index a986a4e..d1abf16 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -515,6 +515,7 @@ listen01 listen01
llistxattr01 llistxattr01
llistxattr02 llistxattr02
+llistxattr03 llistxattr03
llseek01 llseek01
llseek02 llseek02
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 1762c14..f5ea349 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -475,6 +475,7 @@
/listen/listen01
/llistxattr/llistxattr01
/llistxattr/llistxattr02
+/llistxattr/llistxattr03
/llseek/llseek01
/llseek/llseek02
/llseek/llseek03
diff --git a/testcases/kernel/syscalls/llistxattr/llistxattr03.c b/testcases/kernel/syscalls/llistxattr/llistxattr03.c
new file mode 100644
index 0000000..2c5792f
--- /dev/null
+++ b/testcases/kernel/syscalls/llistxattr/llistxattr03.c
@@ -0,0 +1,114 @@
+/*
+* Copyright (c) 2016 Fujitsu Ltd.
+* Author: Xiao Yang <yangx.jy@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
+* alone with this program.
+*/
+
+/*
+* Test Name: llistxattr03
+*
+* Description:
+* llistxattr is identical to listxattr. an empty buffer of size zero
+* can return the current size of the list of extended attribute names,
+* which can be used to estimate a suitable buffer.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+
+#include "test.h"
+#include "safe_macros.h"
+#include "safe_file_ops.h"
+
+char *TCID = "llistxattr03";
+
+#ifdef HAVE_ATTR_XATTR_H
+
+static void verify_llistxattr(void);
+static void setup(void);
+static int check_suitable_buf(long);
+static void cleanup(void);
+
+int TST_TOTAL = 1;
+
+int main(int ac, char **av)
+{
+ int lc;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ verify_llistxattr();
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void verify_llistxattr(void)
+{
+ TEST(llistxattr("testfile", NULL, 0));
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TERRNO, "llistxattr() failed");
+ return;
+ }
+
+ if (check_suitable_buf(TEST_RETURN))
+ tst_resm(TPASS, "llistxattr() succeed with suitable buffer");
+ else
+ tst_resm(TFAIL, "llistxattr() failed with small buffer");
+}
+
+static void setup(void)
+{
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ tst_tmpdir();
+
+ SAFE_TOUCH(cleanup, "testfile", 0644, NULL);
+}
+
+static int check_suitable_buf(long size)
+{
+ int n;
+ char buf[size];
+
+ n = llistxattr("testfile", buf, size);
+ if (n == -1)
+ return 0;
+ else
+ return 1;
+}
+
+static void cleanup(void)
+{
+ tst_rmdir();
+}
+
+#else /* HAVE_ATTR_XATTR_H */
+int main(int ac, char **av)
+{
+ tst_brkm(TCONF, NULL, "<attr/xattr.h> does not exist.");
+}
+#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 17+ messages in thread* [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: add new testcase
2016-02-19 4:55 ` [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: " Xiao Yang
@ 2016-02-24 14:28 ` Cyril Hrubis
2016-02-25 3:55 ` [LTP] [PATCH v3] " Xiao Yang
0 siblings, 1 reply; 17+ messages in thread
From: Cyril Hrubis @ 2016-02-24 14:28 UTC (permalink / raw)
To: ltp
Hi!
> +static void verify_llistxattr(void)
> +{
> + TEST(llistxattr("testfile", NULL, 0));
> + if (TEST_RETURN == -1) {
> + tst_resm(TFAIL | TERRNO, "llistxattr() failed");
> + return;
> + }
For me the call returns 0 here.
Can we create another file with some attribute in the setup as well so
that we can test both with no attributes (zero sized buffer) and with
non-zero one?
Otherwise it looks fine.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 17+ messages in thread* [LTP] [PATCH v3] llistxattr/llistxattr03.c: add new testcase
2016-02-24 14:28 ` Cyril Hrubis
@ 2016-02-25 3:55 ` Xiao Yang
2016-02-25 11:21 ` Cyril Hrubis
0 siblings, 1 reply; 17+ messages in thread
From: Xiao Yang @ 2016-02-25 3:55 UTC (permalink / raw)
To: ltp
llistxattr() is identical to listxattr(), we call llistxattr() with
zero size and check that it returns value which is suitable size of
buffer to hold the name list.
Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
.../kernel/syscalls/llistxattr/llistxattr03.c | 137 +++++++++++++++++++++
4 files changed, 140 insertions(+)
create mode 100644 testcases/kernel/syscalls/llistxattr/llistxattr03.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 7766404..3e32aef 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -391,6 +391,7 @@ listen01 listen01
llistxattr01 llistxattr01
llistxattr02 llistxattr02
+llistxattr03 llistxattr03
llseek01 llseek01
llseek02 llseek02
diff --git a/runtest/syscalls b/runtest/syscalls
index 375a810..cb1b3ef 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -516,6 +516,7 @@ listen01 listen01
llistxattr01 llistxattr01
llistxattr02 llistxattr02
+llistxattr03 llistxattr03
llseek01 llseek01
llseek02 llseek02
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index f53c76c..e61294b 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -476,6 +476,7 @@
/listen/listen01
/llistxattr/llistxattr01
/llistxattr/llistxattr02
+/llistxattr/llistxattr03
/llseek/llseek01
/llseek/llseek02
/llseek/llseek03
diff --git a/testcases/kernel/syscalls/llistxattr/llistxattr03.c b/testcases/kernel/syscalls/llistxattr/llistxattr03.c
new file mode 100644
index 0000000..300966b
--- /dev/null
+++ b/testcases/kernel/syscalls/llistxattr/llistxattr03.c
@@ -0,0 +1,137 @@
+/*
+* Copyright (c) 2016 Fujitsu Ltd.
+* Author: Xiao Yang <yangx.jy@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
+* alone with this program.
+*/
+
+/*
+* Test Name: llistxattr03
+*
+* Description:
+* llistxattr is identical to listxattr. an empty buffer of size zero
+* can return the current size of the list of extended attribute names,
+* which can be used to estimate a suitable buffer.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+
+#include "test.h"
+#include "safe_file_ops.h"
+
+char *TCID = "llistxattr03";
+
+#ifdef HAVE_ATTR_XATTR_H
+
+#define SECURITY_KEY "security.ltptest"
+#define VALUE "test"
+#define VALUE_SIZE 4
+
+static char *filename[2] = {"testfile1", "testfile2"};
+
+static void verify_llistxattr(char *);
+static void setup(void);
+static int check_suitable_buf(char *, long);
+static void cleanup(void);
+
+int TST_TOTAL = ARRAY_SIZE(filename);
+
+int main(int ac, char **av)
+{
+ int lc;
+ int i;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ for (i = 0; i < TST_TOTAL; i++)
+ verify_llistxattr(filename[i]);
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void verify_llistxattr(char *name)
+{
+ TEST(llistxattr(name, NULL, 0));
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TERRNO, "llistxattr() failed");
+ return;
+ }
+
+ if (check_suitable_buf(name, TEST_RETURN))
+ tst_resm(TPASS, "llistxattr() succeed with suitable buffer");
+ else
+ tst_resm(TFAIL, "llistxattr() failed with small buffer");
+}
+
+static void setup(void)
+{
+ int n;
+
+ tst_require_root();
+
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ tst_tmpdir();
+
+ SAFE_TOUCH(cleanup, filename[0], 0644, NULL);
+
+ SAFE_TOUCH(cleanup, filename[1], 0644, NULL);
+
+ n = lsetxattr(filename[1], SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (n == -1) {
+ if (errno == ENOTSUP) {
+ tst_brkm(TCONF, cleanup, "no xattr support in fs or "
+ "mounted without user_xattr option");
+ } else {
+ tst_brkm(TBROK | TERRNO, cleanup, "lsetxattr() failed");
+ }
+ }
+}
+
+static int check_suitable_buf(char *name, long size)
+{
+ int n;
+ char buf[size];
+
+ n = llistxattr(name, buf, size);
+ if (n == -1)
+ return 0;
+ else
+ return 1;
+}
+
+static void cleanup(void)
+{
+ tst_rmdir();
+}
+
+#else /* HAVE_ATTR_XATTR_H */
+int main(int ac, char **av)
+{
+ tst_brkm(TCONF, NULL, "<attr/xattr.h> does not exist.");
+}
+#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [LTP] [PATCH v2 1/3] llistxattr/llistxattr01.c: add new testcase
2016-02-19 4:55 ` [LTP] [PATCH v2 " Xiao Yang
2016-02-19 4:55 ` [LTP] [PATCH v2 2/3] llistxattr/llistxattr02.c: " Xiao Yang
2016-02-19 4:55 ` [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: " Xiao Yang
@ 2016-02-24 13:38 ` Cyril Hrubis
2 siblings, 0 replies; 17+ messages in thread
From: Cyril Hrubis @ 2016-02-24 13:38 UTC (permalink / raw)
To: ltp
Hi!
> The testcase checks the basic functionality of the llistxattr(2).
> llistxattr(2) retrieves the list of extended attribute names
> associated with the link itself in the filesystem.
I've added tst_require_root() into the test setup, since modifying
attrinbutes in security namespace requires it.
> +static void set_xattr(const char *path, const char *key)
> +{
> + int n;
> +
> + n = lsetxattr(path, key, VALUE, VALUE_SIZE, XATTR_CREATE);
> + if (n == -1) {
> + if (errno == ENOTSUP) {
> + tst_brkm(TCONF, cleanup,
> + "no xattr support in fs or mounted "
> + "without user_xattr option");
> + }
> +
> + if (errno == EEXIST) {
> + tst_brkm(TFAIL, cleanup, "exist attribute %s", key);
> + } else {
> + tst_brkm(TFAIL | TERRNO, cleanup,
> + "lsetxattr() failed");
And changed these two to TBROK since it's more "test broken in setup"
rather than "test assertion failed".
And pushed, thanks.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 17+ messages in thread
* [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: add new testcase
@ 2016-02-01 5:28 Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 " Guangwen Feng
0 siblings, 1 reply; 17+ messages in thread
From: Guangwen Feng @ 2016-02-01 5:28 UTC (permalink / raw)
To: ltp
Hi!
Thanks for your review!
I will modify these test cases according to your suggestion.
Best Regards,
Guangwen Feng
On 01/29/2016 12:19 AM, Cyril Hrubis wrote:
> Hi!
>> diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
>> new file mode 100644
>> index 0000000..46058a2
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
>> @@ -0,0 +1,263 @@
>> +/*
>> + * Copyright (c) 2015 Fujitsu Ltd.
>> + * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
>> + * the GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program.
>> + */
>> +
>> +/*
>> + * Description:
>> + * Basic test for epoll_wait(2).
>> + * Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
>> + * on a epoll instance and that struct epoll_event is set correctly.
>> + */
>> +
>> +#include <sys/epoll.h>
>> +#include <unistd.h>
>> +#include <fcntl.h>
>> +#include <poll.h>
>> +#include <errno.h>
>> +
>> +#include "test.h"
>> +#include "safe_macros.h"
>> +#include "lapi/fcntl.h"
>> +
>> +char *TCID = "epoll_wait01";
>> +int TST_TOTAL = 3;
>> +
>> +static int write_size, epfd, fds[2];
>> +static struct epoll_event epevs[2];
>> +
>> +static void setup(void);
>> +static int get_writesize(void);
>> +static void verify_epollout(void);
>> +static void verify_epollin(void);
>> +static void verify_epollio(void);
>> +static void cleanup(void);
>> +
>> +int main(int ac, char **av)
>> +{
>> + int lc;
>> +
>> + tst_parse_opts(ac, av, NULL, NULL);
>> +
>> + setup();
>> +
>> + for (lc = 0; TEST_LOOPING(lc); lc++) {
>> + tst_count = 0;
>> +
>> + verify_epollout();
>> + verify_epollin();
>> + verify_epollio();
>> + }
>> +
>> + cleanup();
>> + tst_exit();
>> +}
>> +
>> +static void setup(void)
>> +{
>> + int pipe_capacity;
>> +
>> + tst_sig(NOFORK, DEF_HANDLER, cleanup);
>> +
>> + TEST_PAUSE;
>> +
>> + SAFE_PIPE(NULL, fds);
>> +
>> + /* fcntl()'s F_GETPIPE_SZ flag availbility check */
>> + if ((tst_kvercmp(2, 6, 35)) < 0) {
>> + write_size = get_writesize();
>> + } else {
>> + pipe_capacity = fcntl(fds[1], F_GETPIPE_SZ);
>> + if (pipe_capacity == -1) {
>> + tst_brkm(TBROK | TERRNO, cleanup,
>> + "failed to get the pipe capacity");
>> + }
>> +
>> + write_size = pipe_capacity - getpagesize() + 1;
>> + }
>
> I would rather go with runtime detection even for newer kernels. Since
> otherwise we have two different codepaths to test.
>
>> + epfd = epoll_create(2);
>> + if (epfd == -1) {
>> + tst_brkm(TBROK | TERRNO, cleanup,
>> + "failed to create epoll instance");
>> + }
>> +
>> + epevs[0].events = EPOLLIN;
>> + epevs[0].data.fd = fds[0];
>> + epevs[1].events = EPOLLOUT;
>> + epevs[1].data.fd = fds[1];
>> +
>> + if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0]) ||
>> + epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[1])) {
>> + tst_brkm(TBROK | TERRNO, cleanup,
>> + "failed to register epoll target");
>> + }
>> +}
>> +
>> +/*
>> + * fcntl(fd, F_GETPIPE_SZ) not supported on kernels which
>> + * version lower than 2.6.35, so use this function instead
>> + */
>> +static int get_writesize(void)
>> +{
>> + int nfd, write_size;
>> +
>> + struct pollfd pfd[] = {
>> + {.fd = fds[0], .events = POLLIN},
>> + {.fd = fds[1], .events = POLLOUT},
>> + };
>> +
>> + write_size = 0;
>> + do {
>> + SAFE_WRITE(cleanup, 1, fds[1], "a", 1);
>> + write_size++;
>> + nfd = poll(pfd, 2, -1);
>> + if (nfd == -1)
>> + tst_brkm(TBROK | TERRNO, cleanup, "poll failed");
>> + } while (nfd == 2);
>
> Why don't we write larger chunks and add the return from SAFE_WRITE to
> the write_size? That should work if we pass 0 as len strict, the last
> write should just end up truncated.
>
>> + char buf[write_size];
>> +
>> + SAFE_READ(cleanup, 1, fds[0], buf, write_size);
>> +
>> + return write_size;
>> +}
>> +
>> +static void verify_epollout(void)
>> +{
>> + TEST(epoll_wait(epfd, epevs, 2, -1));
>> +
>> + if (TEST_RETURN == -1) {
>> + tst_resm(TFAIL | TTERRNO, "epoll_wait() epollout failed");
>> + return;
>> + }
>> +
>> + if (TEST_RETURN != 1) {
>> + tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");
> ^
> We should add the TEST_RETURN
> value to the output here
> I would go for:
> tst_resm(TFAIL, "epoll_wait() returned %i expected 1",
> TEST_RETURN);
>
>
>> + return;
>> + }
>> +
>> + if (epevs[0].data.fd != fds[1]) {
>> + tst_resm(TFAIL, "epoll_wait() failed to set write fd");
>
> And maybe write the actuall fds here:
>
> tst_resm(TFAIL, "epoll.data.fd %i expected %i", ...);
>
>> + return;
>> + }
>> +
>> + if (epevs[0].events != EPOLLOUT) {
>> + tst_resm(TFAIL, "epoll_wait() failed to set EPOLLOUT");
>
> And perhaps print the value of events as hexadecimal here.
>
>> + return;
>> + }
>> +
>> + tst_resm(TPASS, "epoll_wait() epollout");
>> +}
>> +
>> +static void verify_epollin(void)
>> +{
>> + char write_buf[write_size];
>> + char read_buf[sizeof(write_buf)];
>> +
>> + memset(write_buf, 'a', sizeof(write_buf));
>> +
>> + SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
>> +
>> + TEST(epoll_wait(epfd, epevs, 2, -1));
>> +
>> + if (TEST_RETURN == -1) {
>> + tst_resm(TFAIL | TTERRNO, "epoll_wait() epollin failed");
>> + goto end;
>> + }
>> +
>> + if (TEST_RETURN != 1) {
>> + tst_resm(TFAIL, "epoll_wait() failed to get one fd ready");
>> + goto end;
>> + }
>> +
>> + if (epevs[0].data.fd != fds[0]) {
>> + tst_resm(TFAIL, "epoll_wait() failed to set read fd");
>> + goto end;
>> + }
>> +
>> + if (epevs[0].events != EPOLLIN) {
>> + tst_resm(TFAIL, "epoll_wait() failed to set EPOLLIN");
>> + goto end;
>> + }
>
> And I would be more verbose about the values in these messages as well.
>
>> + tst_resm(TPASS, "epoll_wait() epollin");
>> +
>> +end:
>> + SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
>> +}
>> +
>> +static void verify_epollio(void)
>> +{
>> + int i, checked0, checked1;
>> + char write_buf[] = "Testing";
>> + char read_buf[sizeof(write_buf)];
>> +
>> + SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
>> +
>> + TEST(epoll_wait(epfd, epevs, 2, -1));
> ^
> Shouldn't we pass at least 3 here (and
> declare epevs to have three elements as
> well). Since if there were three events
> queued the epoll_wait() would return just
> 2 and the test will pass.
>
>> +
>> + if (TEST_RETURN == -1) {
>> + tst_resm(TFAIL | TTERRNO, "epoll_wait() epollio failed");
>> + goto end;
>> + }
>> +
>> + if (TEST_RETURN != 2) {
>> + tst_resm(TFAIL, "epoll_wait() failed to get two fds ready");
>> + goto end;
>> + }
>> +
>> + checked0 = 0;
>> + checked1 = 0;
>> + for (i = 0; i < TEST_RETURN; i++) {
>> + if (checked0 == 0 && epevs[i].data.fd == fds[0]) {
>> + if (epevs[i].events != EPOLLIN) {
>> + tst_resm(TFAIL, "epoll_wait()"
>> + "failed to set EPOLLIN");
>> + goto end;
>> + }
>> + checked0 = 1;
>> + } else if (checked1 == 0 && epevs[i].data.fd == fds[1]) {
>> + if (epevs[i].events != EPOLLOUT) {
>> + tst_resm(TFAIL, "epoll_wait()"
>> + "failed to set EPOLLOUT");
>> + goto end;
>> + }
>> + checked1 = 1;
>> + } else {
>> + tst_resm(TFAIL, "epoll_wait()"
>> + "failed to set write or read fd");
>> + goto end;
>> + }
>> + }
>
>
> Hmm, this is kind of messy. I would implement this as function that
> checks if the array has event with specific values and would have called
> it twice once with read fd and once with write fd.
>
> static int has_event(struct epoll_event *events, int events_len,
> int fd, uint32_t events)
> {
> ...
> }
>
> ...
> if (!has_event(epevs, 2, fds[0], EPOLLIN))
> tst_resm(TFAIL, ...);
>
> if (!has_event(epevs, 2, fds[1], EPOLLOUT))
> tst_resm(TFAIL, ...);
> ...
>
>
> And perhaps we can add a function to dump the epevs array with
> tst_resm(TINFO, "") and call it on the array whenever we find that
> something went wrong before we do tst_resm(TFAIL, ...);
>
>> + tst_resm(TPASS, "epoll_wait() epollio");
>> +
>> +end:
>> + SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
>> +}
>> +
>> +static void cleanup(void)
>> +{
>> + if (epfd > 0 && close(epfd))
>> + tst_resm(TWARN | TERRNO, "failed to close epfd");
>> +
>> + if (close(fds[0]))
>> + tst_resm(TWARN | TERRNO, "failed to close fds[0]");
>> +
>> + if (close(fds[1]))
>> + tst_resm(TWARN | TERRNO, "failed to close fds[1]");
>> +}
>
> The rest looks good.
>
^ permalink raw reply [flat|nested] 17+ messages in thread* [LTP] [PATCH v2 1/3] epoll_wait/epoll_wait01.c: add new testcase
2016-02-01 5:28 [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: " Guangwen Feng
@ 2016-02-17 10:51 ` Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
0 siblings, 1 reply; 17+ messages in thread
From: Guangwen Feng @ 2016-02-17 10:51 UTC (permalink / raw)
To: ltp
Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
on a epoll instance and that struct epoll_event is set correctly.
Signed-off-by: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
---
runtest/ltplite | 2 +
runtest/stress.part3 | 2 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
testcases/kernel/syscalls/epoll_wait/Makefile | 23 ++
.../kernel/syscalls/epoll_wait/epoll_wait01.c | 281 +++++++++++++++++++++
6 files changed, 310 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/Makefile
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
diff --git a/runtest/ltplite b/runtest/ltplite
index 89accc4..79ab6a1 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -159,6 +159,8 @@ dup203 dup203
dup204 dup204
dup205 dup205
+epoll_wait01 epoll_wait01
+
execl01 execl01
execle01 execle01
execlp01 execlp01
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index 85950bf..20fe314 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -100,6 +100,8 @@ dup203 dup203
dup204 dup204
dup205 dup205
+epoll_wait01 epoll_wait01
+
execl01 execl01
execle01 execle01
execlp01 execlp01
diff --git a/runtest/syscalls b/runtest/syscalls
index 5f169a3..a1591ec 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -122,6 +122,7 @@ dup3_02 dup3_02
epoll_create1_01 epoll_create1_01
epoll01 epoll-ltp
+epoll_wait01 epoll_wait01
eventfd01 eventfd01
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index de403e4..01a3cc0 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -97,6 +97,7 @@
/dup3/dup3_02
/epoll/epoll-ltp
/epoll_create1/epoll_create1_01
+/epoll_wait/epoll_wait01
/eventfd/eventfd01
/eventfd2/eventfd2_01
/eventfd2/eventfd2_02
diff --git a/testcases/kernel/syscalls/epoll_wait/Makefile b/testcases/kernel/syscalls/epoll_wait/Makefile
new file mode 100644
index 0000000..289aaaf
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/Makefile
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2016 Fujitsu Ltd.
+# Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+# the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.
+#
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
new file mode 100644
index 0000000..9ae7580
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait01.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2016 Fujitsu Ltd.
+ * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ * Basic test for epoll_wait(2).
+ * Check that epoll_wait(2) works for EPOLLOUT and EPOLLIN events
+ * on a epoll instance and that struct epoll_event is set correctly.
+ */
+
+#include <sys/epoll.h>
+#include <poll.h>
+#include <string.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+char *TCID = "epoll_wait01";
+int TST_TOTAL = 3;
+
+static int write_size, epfd, fds[2], fds2[2];
+static struct epoll_event epevs[3] = {
+ {.events = EPOLLIN},
+ {.events = EPOLLOUT},
+ {.events = EPOLLIN}
+};
+
+static void setup(void);
+static int get_writesize(void);
+static void verify_epollout(void);
+static void verify_epollin(void);
+static void verify_epollio(void);
+static int has_event(struct epoll_event *, int, int, uint32_t);
+static void dump_epevs(struct epoll_event *, int);
+static void cleanup(void);
+
+int main(int ac, char **av)
+{
+ int lc;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ verify_epollout();
+ verify_epollin();
+ verify_epollio();
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void setup(void)
+{
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ SAFE_PIPE(NULL, fds);
+ SAFE_PIPE(cleanup, fds2);
+
+ write_size = get_writesize();
+
+ epfd = epoll_create(3);
+ if (epfd == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to create epoll instance");
+ }
+
+ epevs[0].data.fd = fds[0];
+ epevs[1].data.fd = fds[1];
+ epevs[2].data.fd = fds2[0];
+
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[0], &epevs[0]) ||
+ epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[1]) ||
+ epoll_ctl(epfd, EPOLL_CTL_ADD, fds2[0], &epevs[2])) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to register epoll target");
+ }
+}
+
+static int get_writesize(void)
+{
+ int nfd, write_size;
+ char buf[4096];
+
+ memset(buf, 'a', sizeof(buf));
+
+ struct pollfd pfd[] = {
+ {.fd = fds[0], .events = POLLIN},
+ {.fd = fds[1], .events = POLLOUT},
+ };
+
+ write_size = 0;
+ do {
+ write_size += SAFE_WRITE(cleanup, 0, fds[1], buf, sizeof(buf));
+ nfd = poll(pfd, 2, -1);
+ if (nfd == -1)
+ tst_brkm(TBROK | TERRNO, cleanup, "poll failed");
+ } while (nfd == 2);
+
+ char read_buf[write_size];
+
+ SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(read_buf));
+
+ return write_size;
+}
+
+static void verify_epollout(void)
+{
+ TEST(epoll_wait(epfd, epevs, 3, -1));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() epollout failed");
+ return;
+ }
+
+ if (TEST_RETURN != 1) {
+ tst_resm(TFAIL, "epoll_wait() returned %li, expected 1",
+ TEST_RETURN);
+ return;
+ }
+
+ if (epevs[0].data.fd != fds[1]) {
+ tst_resm(TFAIL, "epoll.data.fd %i, expected %i",
+ epevs[0].data.fd, fds[1]);
+ return;
+ }
+
+ if (epevs[0].events != EPOLLOUT) {
+ tst_resm(TFAIL, "epoll.events %x, expected EPOLLOUT %x",
+ epevs[0].events, EPOLLOUT);
+ return;
+ }
+
+ tst_resm(TPASS, "epoll_wait() epollout");
+}
+
+static void verify_epollin(void)
+{
+ char write_buf[write_size];
+ char read_buf[sizeof(write_buf)];
+
+ memset(write_buf, 'a', sizeof(write_buf));
+
+ SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
+
+ TEST(epoll_wait(epfd, epevs, 3, -1));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() epollin failed");
+ goto end;
+ }
+
+ if (TEST_RETURN != 1) {
+ tst_resm(TFAIL, "epoll_wait() returned %li, expected 1",
+ TEST_RETURN);
+ goto end;
+ }
+
+ if (epevs[0].data.fd != fds[0]) {
+ tst_resm(TFAIL, "epoll.data.fd %i, expected %i",
+ epevs[0].data.fd, fds[0]);
+ goto end;
+ }
+
+ if (epevs[0].events != EPOLLIN) {
+ tst_resm(TFAIL, "epoll.events %x, expected EPOLLIN %x",
+ epevs[0].events, EPOLLIN);
+ goto end;
+ }
+
+ tst_resm(TPASS, "epoll_wait() epollin");
+
+end:
+ SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
+}
+
+static void verify_epollio(void)
+{
+ char write_buf[] = "Testing";
+ char read_buf[sizeof(write_buf)];
+
+ SAFE_WRITE(cleanup, 1, fds[1], write_buf, sizeof(write_buf));
+
+ TEST(epoll_wait(epfd, epevs, 3, -1));
+
+ if (TEST_RETURN == -1) {
+ tst_resm(TFAIL | TTERRNO, "epoll_wait() epollio failed");
+ goto end;
+ }
+
+ if (TEST_RETURN != 2) {
+ tst_resm(TFAIL, "epoll_wait() returned %li, expected 2",
+ TEST_RETURN);
+ goto end;
+ }
+
+ if (!has_event(epevs, 2, fds[0], EPOLLIN)) {
+ dump_epevs(epevs, 2);
+ tst_resm(TFAIL, "epoll_wait() expected %d and EPOLLIN %x",
+ fds[0], EPOLLIN);
+ goto end;
+ }
+
+ if (!has_event(epevs, 2, fds[1], EPOLLOUT)) {
+ dump_epevs(epevs, 2);
+ tst_resm(TFAIL, "epoll_wait() expected %d and EPOLLOUT %x",
+ fds[1], EPOLLOUT);
+ goto end;
+ }
+
+ tst_resm(TPASS, "epoll_wait() epollio");
+
+end:
+ SAFE_READ(cleanup, 1, fds[0], read_buf, sizeof(write_buf));
+}
+
+static int has_event(struct epoll_event *epevs, int epevs_len,
+ int fd, uint32_t events)
+{
+ int i, result;
+
+ result = 0;
+ for (i = 0; i < epevs_len; i++) {
+ if ((epevs[i].data.fd == fd) && (epevs[i].events == events)) {
+ result = 1;
+ break;
+ }
+ }
+
+ return result;
+}
+
+static void dump_epevs(struct epoll_event *epevs, int epevs_len)
+{
+ int i;
+
+ for (i = 0; i < epevs_len; i++) {
+ tst_resm(TINFO, "epevs[%d]: epoll.data.fd %d, epoll.events %x",
+ i, epevs[i].data.fd, epevs[i].events);
+ }
+}
+
+static void cleanup(void)
+{
+ if (epfd > 0 && close(epfd))
+ tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+ if (close(fds[0]))
+ tst_resm(TWARN | TERRNO, "failed to close fds[0]");
+
+ if (close(fds[1]))
+ tst_resm(TWARN | TERRNO, "failed to close fds[1]");
+
+ if (fds2[0] > 0 && close(fds2[0]))
+ tst_resm(TWARN | TERRNO, "failed to close fds2[0]");
+
+ if (fds2[1] > 0 && close(fds2[1]))
+ tst_resm(TWARN | TERRNO, "failed to close fds2[1]");
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [LTP] [PATCH v2 3/3] epoll_wait/epoll_wait03.c: add new testcase
2016-02-17 10:51 ` [LTP] [PATCH v2 " Guangwen Feng
@ 2016-02-17 10:51 ` Guangwen Feng
2016-02-25 13:52 ` [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: " Cyril Hrubis
0 siblings, 1 reply; 17+ messages in thread
From: Guangwen Feng @ 2016-02-17 10:51 UTC (permalink / raw)
To: ltp
Verify that:
1) epoll_wait(2) fails if epfd is not a valid file descriptor
2) epoll_wait(2) fails if epfd is not an epoll file descriptor
3) epoll_wait(2) fails if maxevents is less than zero
4) epoll_wait(2) fails if maxevents is equal to zero
5) epoll_wait(2) fails if the memory area pointed to by events
is not accessible with write permissions.
Expected result:
1) epoll_wait(2) should return -1 and set errno to EBADF
2) epoll_wait(2) should return -1 and set errno to EINVAL
3) epoll_wait(2) should return -1 and set errno to EINVAL
4) epoll_wait(2) should return -1 and set errno to EINVAL
5) epoll_wait(2) should return -1 and set errno to EFAULT
Signed-off-by: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
---
runtest/ltplite | 1 +
runtest/stress.part3 | 1 +
runtest/syscalls | 1 +
testcases/kernel/syscalls/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait03.c | 158 +++++++++++++++++++++
5 files changed, 162 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
diff --git a/runtest/ltplite b/runtest/ltplite
index aa4ebdc..ced593f 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -161,6 +161,7 @@ dup205 dup205
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
execl01 execl01
execle01 execle01
diff --git a/runtest/stress.part3 b/runtest/stress.part3
index 7d629c5..ab2c531 100644
--- a/runtest/stress.part3
+++ b/runtest/stress.part3
@@ -102,6 +102,7 @@ dup205 dup205
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
execl01 execl01
execle01 execle01
diff --git a/runtest/syscalls b/runtest/syscalls
index 23d7adc..dbef381 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -124,6 +124,7 @@ epoll_create1_01 epoll_create1_01
epoll01 epoll-ltp
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
+epoll_wait03 epoll_wait03
eventfd01 eventfd01
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 85feeac..97b8fd8 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -99,6 +99,7 @@
/epoll_create1/epoll_create1_01
/epoll_wait/epoll_wait01
/epoll_wait/epoll_wait02
+/epoll_wait/epoll_wait03
/eventfd/eventfd01
/eventfd2/eventfd2_01
/eventfd2/eventfd2_02
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
new file mode 100644
index 0000000..56b32da
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait03.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016 Fujitsu Ltd.
+ * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+/*
+ * Description:
+ * 1) epoll_wait(2) fails if epfd is not a valid file descriptor
+ * 2) epoll_wait(2) fails if epfd is not an epoll file descriptor
+ * 3) epoll_wait(2) fails if maxevents is less than zero
+ * 4) epoll_wait(2) fails if maxevents is equal to zero
+ * 5) epoll_wait(2) fails if the memory area pointed to by events
+ * is not accessible with write permissions.
+ *
+ * Expected Result:
+ * 1) epoll_wait(2) should return -1 and set errno to EBADF
+ * 2) epoll_wait(2) should return -1 and set errno to EINVAL
+ * 3) epoll_wait(2) should return -1 and set errno to EINVAL
+ * 4) epoll_wait(2) should return -1 and set errno to EINVAL
+ * 5) epoll_wait(2) should return -1 and set errno to EFAULT
+ */
+
+#include <sys/epoll.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+static int page_size, fds[2], epfd, inv_epfd, bad_epfd = -1;
+
+static struct epoll_event epevs[1] = {
+ {.events = EPOLLOUT}
+};
+
+static struct epoll_event *ev_rdwr = epevs;
+static struct epoll_event *ev_rdonly;
+
+static struct test_case_t {
+ int *epfd;
+ struct epoll_event **ev;
+ int maxevents;
+ int exp_errno;
+} tc[] = {
+ /* test1 */
+ {&bad_epfd, &ev_rdwr, 1, EBADF},
+ /* test2 */
+ {&inv_epfd, &ev_rdwr, 1, EINVAL},
+ /* test3 */
+ {&epfd, &ev_rdwr, -1, EINVAL},
+ /* test4 */
+ {&epfd, &ev_rdwr, 0, EINVAL},
+ /* test5 */
+ {&epfd, &ev_rdonly, 1, EFAULT}
+};
+
+char *TCID = "epoll_wait03";
+int TST_TOTAL = ARRAY_SIZE(tc);
+
+static void setup(void);
+static void verify_epoll_wait(struct test_case_t *tc);
+static void cleanup(void);
+
+int main(int ac, char **av)
+{
+ int lc, i;
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ tst_count = 0;
+
+ for (i = 0; i < TST_TOTAL; i++)
+ verify_epoll_wait(&tc[i]);
+ }
+
+ cleanup();
+ tst_exit();
+}
+
+static void setup(void)
+{
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ page_size = getpagesize();
+
+ ev_rdonly = SAFE_MMAP(NULL, NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ SAFE_PIPE(NULL, fds);
+
+ epfd = epoll_create(1);
+ if (epfd == -1) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to create epoll instance");
+ }
+
+ epevs[0].data.fd = fds[1];
+
+ if (mprotect(ev_rdonly, page_size, PROT_READ)) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to set memory area read-only");
+ }
+
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[0])) {
+ tst_brkm(TBROK | TERRNO, cleanup,
+ "failed to register epoll target");
+ }
+}
+
+static void verify_epoll_wait(struct test_case_t *tc)
+{
+ TEST(epoll_wait(*(tc->epfd), *(tc->ev), tc->maxevents, -1));
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "epoll_wait() succeed unexpectedly");
+ } else {
+ if (tc->exp_errno == TEST_ERRNO) {
+ tst_resm(TPASS | TTERRNO,
+ "epoll_wait() fails as expected");
+ } else {
+ tst_resm(TFAIL | TTERRNO,
+ "epoll_wait() fails unexpectedly, "
+ "expected %d: %s", tc->exp_errno,
+ tst_strerrno(tc->exp_errno));
+ }
+ }
+}
+
+static void cleanup(void)
+{
+ if (epfd > 0 && close(epfd))
+ tst_resm(TWARN | TERRNO, "failed to close epfd");
+
+ if (close(fds[0]))
+ tst_resm(TWARN | TERRNO, "close(fds[0]) failed");
+
+ if (close(fds[1]))
+ tst_resm(TWARN | TERRNO, "close(fds[1]) failed");
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 17+ messages in thread* [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: add new testcase
2016-02-17 10:51 ` [LTP] [PATCH v2 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
@ 2016-02-25 13:52 ` Cyril Hrubis
0 siblings, 0 replies; 17+ messages in thread
From: Cyril Hrubis @ 2016-02-25 13:52 UTC (permalink / raw)
To: ltp
Hi!
> + ev_rdonly = SAFE_MMAP(NULL, NULL, page_size, PROT_READ | PROT_WRITE,
> + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> +
...
> + if (mprotect(ev_rdonly, page_size, PROT_READ)) {
> + tst_brkm(TBROK | TERRNO, cleanup,
> + "failed to set memory area read-only");
> + }
I've removed the PROT_WRITE from the mmap() flags and the mprotect() and
pushed, thanks.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2016-02-25 13:52 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-29 9:08 [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: add new testcase Xiao Yang
2016-01-29 9:08 ` [LTP] [PATCH 2/3] llistxattr/llistxattr02.c: " Xiao Yang
2016-02-10 13:41 ` Cyril Hrubis
2016-01-29 9:08 ` [LTP] [PATCH 3/3] llistxattr/llistxattr03.c: " Xiao Yang
2016-02-10 14:12 ` Cyril Hrubis
2016-02-10 14:04 ` [LTP] [PATCH 1/3] llistxattr/llistxattr01.c: " Cyril Hrubis
2016-02-18 10:02 ` Xiao Yang
2016-02-18 12:03 ` Cyril Hrubis
2016-02-19 4:55 ` [LTP] [PATCH v2 " Xiao Yang
2016-02-19 4:55 ` [LTP] [PATCH v2 2/3] llistxattr/llistxattr02.c: " Xiao Yang
2016-02-24 13:54 ` Cyril Hrubis
2016-02-19 4:55 ` [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: " Xiao Yang
2016-02-24 14:28 ` Cyril Hrubis
2016-02-25 3:55 ` [LTP] [PATCH v3] " Xiao Yang
2016-02-25 11:21 ` Cyril Hrubis
2016-02-24 13:38 ` [LTP] [PATCH v2 1/3] llistxattr/llistxattr01.c: " Cyril Hrubis
-- strict thread matches above, loose matches on Subject: below --
2016-02-01 5:28 [LTP] [PATCH 1/3] epoll_wait/epoll_wait01.c: " Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 " Guangwen Feng
2016-02-17 10:51 ` [LTP] [PATCH v2 3/3] epoll_wait/epoll_wait03.c: " Guangwen Feng
2016-02-25 13:52 ` [LTP] [PATCH v2 3/3] llistxattr/llistxattr03.c: " Cyril Hrubis
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.