[LTP] [PATCH 2/2] Added tests for flistxattr and listxattr.
Dejan Jovicevic
dejan.jovicevic@rt-rk.com
Thu Oct 6 14:08:39 CEST 2016
Tests for these system calls were not present. They are
implemented based on existing tests for llistxattr.
Signed-off-by: Dejan Jovicevic <dejan.jovicevic@rt-rk.com>
---
runtest/syscalls | 8 ++
testcases/kernel/syscalls/.gitignore | 6 +
testcases/kernel/syscalls/flistxattr/Makefile | 23 ++++
.../kernel/syscalls/flistxattr/flistxattr01.c | 124 ++++++++++++++++++++
.../kernel/syscalls/flistxattr/flistxattr02.c | 116 +++++++++++++++++++
.../kernel/syscalls/flistxattr/flistxattr03.c | 111 ++++++++++++++++++
testcases/kernel/syscalls/listxattr/Makefile | 23 ++++
testcases/kernel/syscalls/listxattr/listxattr01.c | 115 ++++++++++++++++++
testcases/kernel/syscalls/listxattr/listxattr02.c | 128 +++++++++++++++++++++
testcases/kernel/syscalls/listxattr/listxattr03.c | 101 ++++++++++++++++
10 files changed, 755 insertions(+)
create mode 100644 testcases/kernel/syscalls/flistxattr/Makefile
create mode 100644 testcases/kernel/syscalls/flistxattr/flistxattr01.c
create mode 100644 testcases/kernel/syscalls/flistxattr/flistxattr02.c
create mode 100644 testcases/kernel/syscalls/flistxattr/flistxattr03.c
create mode 100644 testcases/kernel/syscalls/listxattr/Makefile
create mode 100644 testcases/kernel/syscalls/listxattr/listxattr01.c
create mode 100644 testcases/kernel/syscalls/listxattr/listxattr02.c
create mode 100644 testcases/kernel/syscalls/listxattr/listxattr03.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 01839e8..009c2db 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -272,6 +272,10 @@ fcntl34_64 fcntl34_64
fdatasync01 fdatasync01
fdatasync02 fdatasync02
+flistxattr01 flistxattr01
+flistxattr02 flistxattr02
+flistxattr03 flistxattr03
+
flock01 flock01
flock02 flock02
flock03 flock03
@@ -523,6 +527,10 @@ linkat02 linkat02
listen01 listen01
+listxattr01 listxattr01
+listxattr02 listxattr02
+listxattr03 listxattr03
+
llistxattr01 llistxattr01
llistxattr02 llistxattr02
llistxattr03 llistxattr03
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index a13dbb3..408dc88 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -233,6 +233,9 @@
/fcntl/fcntl34_64
/fdatasync/fdatasync01
/fdatasync/fdatasync02
+/flistxattr/flistxattr01
+/flistxattr/flistxattr02
+/flistxattr/flistxattr03
/flock/flock01
/flock/flock02
/flock/flock03
@@ -482,6 +485,9 @@
/linkat/linkat01
/linkat/linkat02
/listen/listen01
+/listxattr/listxattr01
+/listxattr/listxattr02
+/listxattr/listxattr03
/llistxattr/llistxattr01
/llistxattr/llistxattr02
/llistxattr/llistxattr03
diff --git a/testcases/kernel/syscalls/flistxattr/Makefile b/testcases/kernel/syscalls/flistxattr/Makefile
new file mode 100644
index 0000000..ed05a48
--- /dev/null
+++ b/testcases/kernel/syscalls/flistxattr/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/flistxattr/flistxattr01.c b/testcases/kernel/syscalls/flistxattr/flistxattr01.c
new file mode 100644
index 0000000..75eb4db
--- /dev/null
+++ b/testcases/kernel/syscalls/flistxattr/flistxattr01.c
@@ -0,0 +1,124 @@
+/*
+* 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: verify_flistxattr01
+*
+* Description:
+* The testcase checks the basic functionality of the flistxattr(2).
+* flistxattr(2) retrieves the list of extended attribute names
+* associated with the file itself in the filesystem.
+*
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef HAVE_SYS_XATTR_H
+# include <sys/xattr.h>
+#endif
+
+#include "tst_test.h"
+
+#ifdef HAVE_SYS_XATTR_H
+
+#define SECURITY_KEY1 "security.ltptest1"
+#define VALUE "test"
+#define VALUE_SIZE 4
+#define KEY_SIZE 17
+
+int fd;
+
+static void set_xattr(int fd, const char *key)
+{
+ int n;
+
+ n = fsetxattr(fd, key, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (n == -1) {
+ if (errno == ENOTSUP) {
+ tst_brk(TCONF,
+ "no xattr support in fs or mounted "
+ "without user_xattr option");
+ }
+
+ if (errno == EEXIST) {
+ tst_brk(TBROK, "exist attribute %s", key);
+ } else {
+ tst_brk(TBROK | TERRNO,
+ "fsetxattr() 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 verify_flistxattr(void)
+{
+ int size = 64;
+ char buf[size];
+
+ TEST(flistxattr(fd, buf, size));
+ if (TEST_RETURN == -1) {
+ tst_res(TFAIL | TERRNO, "flistxattr() failed");
+ return;
+ }
+
+ if (!has_attribute(buf, size, SECURITY_KEY1)) {
+ tst_res(TFAIL, "missing attribute %s",
+ SECURITY_KEY1);
+ return;
+ }
+
+ tst_res(TPASS, "flistxattr() succeeded");
+}
+
+static void setup(void)
+{
+ fd = SAFE_OPEN("testfile", O_RDWR | O_CREAT, 0644);
+
+ set_xattr(fd, SECURITY_KEY1);
+}
+
+static void cleanup(void)
+{
+ if (fd > 0 && close(fd))
+ tst_res(TWARN | TERRNO, "failed to close file");
+}
+
+static struct tst_test test = {
+ .tid = "flistxattr01",
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .test_all = verify_flistxattr,
+ .setup = setup,
+ .cleanup = cleanup,
+};
+
+#else
+ TST_TEST_TCONF("<sys/xattr.h> does not exist.");
+#endif /* HAVE_SYS_XATTR_H */
+
diff --git a/testcases/kernel/syscalls/flistxattr/flistxattr02.c b/testcases/kernel/syscalls/flistxattr/flistxattr02.c
new file mode 100644
index 0000000..8bbf267
--- /dev/null
+++ b/testcases/kernel/syscalls/flistxattr/flistxattr02.c
@@ -0,0 +1,116 @@
+/*
+* 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: flistxattr02
+*
+* Description:
+* 1) flistxattr(2) fails if the size of the list buffer is too small
+* to hold the result.
+* 2) flistxattr(2) fails if fd is an invalid file descriptor.
+*
+* Expected Result:
+* 1) flistxattr(2) should return -1 and set errno to ERANGE.
+* 2) flistxattr(2) should return -1 and set errno to EBADF.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_XATTR_H
+# include <sys/xattr.h>
+#endif
+
+#include "tst_test.h"
+
+#ifdef HAVE_SYS_XATTR_H
+
+#define SECURITY_KEY "security.ltptest"
+#define VALUE "test"
+#define VALUE_SIZE 4
+
+static int fd1;
+static int fd2;
+
+static struct test_case {
+ int *fd;
+ size_t size;
+ int exp_err;
+} tc[] = {
+ /* test1 */
+ {&fd1, 1, ERANGE},
+ /* test2 */
+ {&fd2, 20, EBADF}
+};
+
+static void verify_flistxattr(unsigned int n)
+{
+ struct test_case *t = tc + n;
+ char buf[t->size];
+
+ TEST(flistxattr(*t->fd, buf, t->size));
+ if (TEST_RETURN != -1) {
+ tst_res(TFAIL, "flistxattr() succeeded unexpectedly");
+ } else {
+ if (TEST_ERRNO != t->exp_err) {
+ tst_res(TFAIL | TTERRNO, "flistxattr() failed "
+ "unexpectedlly, expected %s",
+ tst_strerrno(t->exp_err));
+ } else {
+ tst_res(TPASS | TTERRNO,
+ "flistxattr() failed as expected");
+ }
+ }
+}
+
+static void setup(void)
+{
+ int n;
+
+ fd1 = SAFE_OPEN("testfile", O_RDWR | O_CREAT, 0644);
+ fd2 = -1;
+
+ n = fsetxattr(fd1, SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (n == -1) {
+ if (errno == ENOTSUP) {
+ tst_brk(TCONF, "no xattr support in fs or "
+ "mounted without user_xattr option");
+ } else {
+ tst_brk(TBROK | TERRNO, "fsetxattr() failed");
+ }
+ }
+}
+
+static void cleanup(void)
+{
+ if (fd1 > 0 && close(fd1))
+ tst_res(TWARN | TERRNO, "failed to close file");
+}
+
+static struct tst_test test = {
+ .tid = "flistxattr02",
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .test = verify_flistxattr,
+ .tcnt = ARRAY_SIZE(tc),
+ .setup = setup,
+ .cleanup = cleanup,
+};
+
+#else /* HAVE_SYS_XATTR_H */
+ TST_TEST_TCONF("<sys/xattr.h> does not exist.");
+#endif
diff --git a/testcases/kernel/syscalls/flistxattr/flistxattr03.c b/testcases/kernel/syscalls/flistxattr/flistxattr03.c
new file mode 100644
index 0000000..691f869
--- /dev/null
+++ b/testcases/kernel/syscalls/flistxattr/flistxattr03.c
@@ -0,0 +1,111 @@
+/*
+* 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: flistxattr03
+*
+* Description:
+* flistxattr 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_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
+
+#include "tst_test.h"
+
+#ifdef HAVE_SYS_XATTR_H
+
+#define SECURITY_KEY "security.ltptest"
+#define VALUE "test"
+#define VALUE_SIZE 4
+
+static int fd[] = {0, 0};
+
+static int check_suitable_buf(const int file, long size)
+{
+ int n;
+ char buf[size];
+
+ n = flistxattr(file, buf, size);
+ if (n == -1)
+ return 0;
+ else
+ return 1;
+}
+
+static void verify_flistxattr(unsigned int n)
+{
+ const int file = fd[n];
+
+ TEST(flistxattr(file, NULL, 0));
+ if (TEST_RETURN == -1) {
+ tst_res(TFAIL | TERRNO, "flistxattr() failed");
+ return;
+ }
+
+ if (check_suitable_buf(file, TEST_RETURN))
+ tst_res(TPASS, "flistxattr() succeed with suitable buffer");
+ else
+ tst_res(TFAIL, "flistxattr() failed with small buffer");
+}
+
+static void setup(void)
+{
+ int ret;
+
+ fd[0] = SAFE_OPEN("testfile1", O_RDWR | O_CREAT, 0644);
+
+ fd[1] = SAFE_OPEN("testfile2", O_RDWR | O_CREAT, 0644);
+
+ ret = fsetxattr(fd[1], SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (ret == -1) {
+ if (errno == ENOTSUP) {
+ tst_brk(TCONF, "no xattr support in fs or "
+ "mounted without user_xattr option");
+ } else {
+ tst_brk(TBROK | TERRNO, "fsetxattr() failed");
+ }
+ }
+}
+
+static void cleanup(void)
+{
+ if (fd[0] > 0 && close(fd[0]))
+ tst_res(TWARN | TERRNO, "failed to close file");
+ if (fd[1] > 0 && close(fd[1]))
+ tst_res(TWARN | TERRNO, "failed to close file");
+}
+
+static struct tst_test test = {
+ .tid = "flistxattr03",
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .test = verify_flistxattr,
+ .tcnt = ARRAY_SIZE(fd),
+ .setup = setup,
+ .cleanup = cleanup,
+};
+
+#else /* HAVE_SYS_XATTR_H */
+ TST_TEST_TCONF("<sys/xattr.h> does not exist.");
+#endif
diff --git a/testcases/kernel/syscalls/listxattr/Makefile b/testcases/kernel/syscalls/listxattr/Makefile
new file mode 100644
index 0000000..ed05a48
--- /dev/null
+++ b/testcases/kernel/syscalls/listxattr/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/listxattr/listxattr01.c b/testcases/kernel/syscalls/listxattr/listxattr01.c
new file mode 100644
index 0000000..3159a7b
--- /dev/null
+++ b/testcases/kernel/syscalls/listxattr/listxattr01.c
@@ -0,0 +1,115 @@
+/*
+* 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: listxattr01
+*
+* Description:
+* The testcase checks the basic functionality of the listxattr(2).
+* listxattr(2) retrieves the list of extended attribute names
+* associated with the file itself in the filesystem.
+*
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef HAVE_SYS_XATTR_H
+# include <sys/xattr.h>
+#endif
+
+#include "tst_test.h"
+
+#ifdef HAVE_SYS_XATTR_H
+
+#define SECURITY_KEY1 "security.ltptest1"
+#define VALUE "test"
+#define VALUE_SIZE 4
+#define KEY_SIZE 17
+
+static void set_xattr(const char *path, const char *key)
+{
+ int n;
+
+ n = setxattr(path, key, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (n == -1) {
+ if (errno == ENOTSUP) {
+ tst_brk(TCONF,
+ "no xattr support in fs or mounted "
+ "without user_xattr option");
+ }
+
+ if (errno == EEXIST) {
+ tst_brk(TBROK, "exist attribute %s", key);
+ } else {
+ tst_brk(TBROK | TERRNO,
+ "setxattr() 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 verify_listxattr(void)
+{
+ int size = 64;
+ char buf[size];
+
+ TEST(listxattr("testfile", buf, size));
+ if (TEST_RETURN == -1) {
+ tst_res(TFAIL | TERRNO, "listxattr() failed");
+ return;
+ }
+
+ if (!has_attribute(buf, size, SECURITY_KEY1)) {
+ tst_res(TFAIL, "missing attribute %s",
+ SECURITY_KEY1);
+ return;
+ }
+
+ tst_res(TPASS, "listxattr() succeeded");
+}
+
+static void setup(void)
+{
+ SAFE_TOUCH("testfile", 0644, NULL);
+
+ set_xattr("testfile", SECURITY_KEY1);
+}
+
+static struct tst_test test = {
+ .tid = "listxattr01",
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .test_all = verify_listxattr,
+ .setup = setup,
+};
+
+#else
+ TST_TEST_TCONF("<sys/xattr.h> does not exist.");
+#endif /* HAVE_SYS_XATTR_H */
+
diff --git a/testcases/kernel/syscalls/listxattr/listxattr02.c b/testcases/kernel/syscalls/listxattr/listxattr02.c
new file mode 100644
index 0000000..baf4f0d
--- /dev/null
+++ b/testcases/kernel/syscalls/listxattr/listxattr02.c
@@ -0,0 +1,128 @@
+/*
+* 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: listxattr02
+*
+* Description:
+* 1) listxattr(2) fails if the size of the list buffer is too small
+* to hold the result.
+* 2) listxattr(2) fails if path is an empty string.
+* 3) listxattr(2) fails when attempted to read from a invalid address.
+* 4) listxattr(2) fails if path is longer the the max allowed path
+*
+* Expected Result:
+* 1) listxattr(2) should return -1 and set errno to ERANGE.
+* 2) listxattr(2) should return -1 and set errno to ENOENT.
+* 3) listxattr(2) should return -1 and set errno to EFAULT.
+* 4) listxattr(2) shoult return -1 and set errno to ENAMETOOLONG.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_XATTR_H
+# include <sys/xattr.h>
+#endif
+
+#include "tst_test.h"
+
+#ifdef HAVE_SYS_XATTR_H
+
+#define SECURITY_KEY "security.ltptest"
+#define VALUE "test"
+#define VALUE_SIZE 4
+
+static int longpath_setup(void);
+char longpathname[PATH_MAX + 2];
+
+static struct test_case {
+ const char *path;
+ size_t size;
+ int exp_err;
+} tc[] = {
+ /* test1 */
+ {"testfile", 1, ERANGE},
+ /* test2 */
+ {"", 20, ENOENT},
+ /* test3 */
+ {(char *)-1, 20, EFAULT},
+ /* test4 */
+ {longpathname, 20, ENAMETOOLONG}
+};
+
+static void verify_listxattr(unsigned int n)
+{
+ struct test_case *t = tc + n;
+ char buf[t->size];
+
+ TEST(listxattr(t->path, buf, t->size));
+ if (TEST_RETURN != -1) {
+ tst_res(TFAIL, "listxattr() succeeded unexpectedly");
+ } else {
+ if (TEST_ERRNO != t->exp_err) {
+ tst_res(TFAIL | TTERRNO, "listxattr() failed "
+ "unexpectedlly, expected %s",
+ tst_strerrno(t->exp_err));
+ } else {
+ tst_res(TPASS | TTERRNO,
+ "listxattr() failed as expected");
+ }
+ }
+}
+
+int longpath_setup(void)
+{
+ int i;
+
+ for (i = 0; i < PATH_MAX + 2; i++)
+ longpathname[i] = 'a';
+
+ return 0;
+}
+
+static void setup(void)
+{
+ int n;
+
+ SAFE_TOUCH("testfile", 0644, NULL);
+
+
+ n = setxattr("testfile", SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (n == -1) {
+ if (errno == ENOTSUP) {
+ tst_brk(TCONF, "no xattr support in fs or "
+ "mounted without user_xattr option");
+ } else {
+ tst_brk(TBROK | TERRNO, "setxattr() failed");
+ }
+ }
+ longpath_setup();
+}
+
+static struct tst_test test = {
+ .tid = "listxattr02",
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .test = verify_listxattr,
+ .tcnt = ARRAY_SIZE(tc),
+ .setup = setup,
+};
+
+#else /* HAVE_SYS_XATTR_H */
+ TST_TEST_TCONF("<sys/xattr.h> does not exist.");
+#endif
diff --git a/testcases/kernel/syscalls/listxattr/listxattr03.c b/testcases/kernel/syscalls/listxattr/listxattr03.c
new file mode 100644
index 0000000..cdaecfc
--- /dev/null
+++ b/testcases/kernel/syscalls/listxattr/listxattr03.c
@@ -0,0 +1,101 @@
+/*
+* 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: listxattr03
+*
+* Description:
+* 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_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
+
+#include "tst_test.h"
+
+#ifdef HAVE_SYS_XATTR_H
+
+#define SECURITY_KEY "security.ltptest"
+#define VALUE "test"
+#define VALUE_SIZE 4
+
+static const char *filename[] = {"testfile1", "testfile2"};
+
+static int check_suitable_buf(const char *name, long size)
+{
+ int n;
+ char buf[size];
+
+ n = listxattr(name, buf, size);
+ if (n == -1)
+ return 0;
+ else
+ return 1;
+}
+
+static void verify_listxattr(unsigned int n)
+{
+ const char *name = filename[n];
+
+ TEST(listxattr(name, NULL, 0));
+ if (TEST_RETURN == -1) {
+ tst_res(TFAIL | TERRNO, "listxattr() failed");
+ return;
+ }
+
+ if (check_suitable_buf(name, TEST_RETURN))
+ tst_res(TPASS, "listxattr() succeed with suitable buffer");
+ else
+ tst_res(TFAIL, "listxattr() failed with small buffer");
+}
+
+static void setup(void)
+{
+ int ret;
+
+ SAFE_TOUCH(filename[0], 0644, NULL);
+
+ SAFE_TOUCH(filename[1], 0644, NULL);
+
+ ret = setxattr(filename[1], SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
+ if (ret == -1) {
+ if (errno == ENOTSUP) {
+ tst_brk(TCONF, "no xattr support in fs or "
+ "mounted without user_xattr option");
+ } else {
+ tst_brk(TBROK | TERRNO, "setxattr() failed");
+ }
+ }
+}
+
+static struct tst_test test = {
+ .tid = "listxattr03",
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .test = verify_listxattr,
+ .tcnt = ARRAY_SIZE(filename),
+ .setup = setup,
+};
+
+#else /* HAVE_SYS_XATTR_H */
+ TST_TEST_TCONF("<sys/xattr.h> does not exist.");
+#endif
--
1.9.1
More information about the ltp
mailing list