1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * Copyright (C) 2011  Red Hat, Inc.
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or
5f08c3bdfSopenharmony_ci * modify it under the terms of version 2 of the GNU General Public
6f08c3bdfSopenharmony_ci * License as published by the Free Software Foundation.
7f08c3bdfSopenharmony_ci *
8f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful,
9f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
10f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * Further, this software is distributed without any warranty that it
13f08c3bdfSopenharmony_ci * is free of the rightful claim of any third person regarding
14f08c3bdfSopenharmony_ci * infringement or the like.  Any license provided herein, whether
15f08c3bdfSopenharmony_ci * implied or otherwise, applies only to this software file.  Patent
16f08c3bdfSopenharmony_ci * licenses, if any, provided herein do not apply to combinations of
17f08c3bdfSopenharmony_ci * this program with other software, or any other product whatsoever.
18f08c3bdfSopenharmony_ci *
19f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License
20f08c3bdfSopenharmony_ci * along with this program; if not, write the Free Software
21f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22f08c3bdfSopenharmony_ci * 02110-1301, USA.
23f08c3bdfSopenharmony_ci */
24f08c3bdfSopenharmony_ci
25f08c3bdfSopenharmony_ci/*
26f08c3bdfSopenharmony_ci * Basic tests for getxattr(2) and make sure getxattr(2) handles error
27f08c3bdfSopenharmony_ci * conditions correctly.
28f08c3bdfSopenharmony_ci *
29f08c3bdfSopenharmony_ci * There are 4 test cases:
30f08c3bdfSopenharmony_ci * 1. Get an non-existing attribute,
31f08c3bdfSopenharmony_ci *    getxattr(2) should return -1 and set errno to ENODATA
32f08c3bdfSopenharmony_ci * 2. Buffer size is smaller than attribute value size,
33f08c3bdfSopenharmony_ci *    getxattr(2) should return -1 and set errno to ERANGE
34f08c3bdfSopenharmony_ci * 3. Get attribute, getxattr(2) should succeed
35f08c3bdfSopenharmony_ci * 4. Verify the attribute got by getxattr(2) is same as the value we set
36f08c3bdfSopenharmony_ci */
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_ci#include "config.h"
39f08c3bdfSopenharmony_ci#include <sys/types.h>
40f08c3bdfSopenharmony_ci#include <sys/stat.h>
41f08c3bdfSopenharmony_ci#include <errno.h>
42f08c3bdfSopenharmony_ci#include <fcntl.h>
43f08c3bdfSopenharmony_ci#include <unistd.h>
44f08c3bdfSopenharmony_ci#include <stdio.h>
45f08c3bdfSopenharmony_ci#include <stdlib.h>
46f08c3bdfSopenharmony_ci#include <string.h>
47f08c3bdfSopenharmony_ci#ifdef HAVE_SYS_XATTR_H
48f08c3bdfSopenharmony_ci# include <sys/xattr.h>
49f08c3bdfSopenharmony_ci#endif
50f08c3bdfSopenharmony_ci#include "test.h"
51f08c3bdfSopenharmony_ci#include "safe_macros.h"
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_cichar *TCID = "getxattr01";
54f08c3bdfSopenharmony_ci
55f08c3bdfSopenharmony_ci#ifdef HAVE_SYS_XATTR_H
56f08c3bdfSopenharmony_ci#define XATTR_TEST_KEY "user.testkey"
57f08c3bdfSopenharmony_ci#define XATTR_TEST_VALUE "this is a test value"
58f08c3bdfSopenharmony_ci#define XATTR_TEST_VALUE_SIZE 20
59f08c3bdfSopenharmony_ci#define BUFFSIZE 64
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_cistatic void setup(void);
62f08c3bdfSopenharmony_cistatic void cleanup(void);
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_cichar filename[BUFSIZ];
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_cistruct test_case {
67f08c3bdfSopenharmony_ci	char *fname;
68f08c3bdfSopenharmony_ci	char *key;
69f08c3bdfSopenharmony_ci	char *value;
70f08c3bdfSopenharmony_ci	size_t size;
71f08c3bdfSopenharmony_ci	int exp_err;
72f08c3bdfSopenharmony_ci};
73f08c3bdfSopenharmony_cistruct test_case tc[] = {
74f08c3bdfSopenharmony_ci	{			/* case 00, get non-existing attribute */
75f08c3bdfSopenharmony_ci	 .fname = filename,
76f08c3bdfSopenharmony_ci	 .key = "user.nosuchkey",
77f08c3bdfSopenharmony_ci	 .value = NULL,
78f08c3bdfSopenharmony_ci	 .size = BUFFSIZE - 1,
79f08c3bdfSopenharmony_ci	 .exp_err = ENODATA,
80f08c3bdfSopenharmony_ci	 },
81f08c3bdfSopenharmony_ci	{			/* case 01, small value buffer */
82f08c3bdfSopenharmony_ci	 .fname = filename,
83f08c3bdfSopenharmony_ci	 .key = XATTR_TEST_KEY,
84f08c3bdfSopenharmony_ci	 .value = NULL,
85f08c3bdfSopenharmony_ci	 .size = 1,
86f08c3bdfSopenharmony_ci	 .exp_err = ERANGE,
87f08c3bdfSopenharmony_ci	 },
88f08c3bdfSopenharmony_ci	{			/* case 02, get existing attribute */
89f08c3bdfSopenharmony_ci	 .fname = filename,
90f08c3bdfSopenharmony_ci	 .key = XATTR_TEST_KEY,
91f08c3bdfSopenharmony_ci	 .value = NULL,
92f08c3bdfSopenharmony_ci	 .size = BUFFSIZE - 1,
93f08c3bdfSopenharmony_ci	 .exp_err = 0,
94f08c3bdfSopenharmony_ci	 },
95f08c3bdfSopenharmony_ci};
96f08c3bdfSopenharmony_ci
97f08c3bdfSopenharmony_ciint TST_TOTAL = sizeof(tc) / sizeof(tc[0]) + 1;
98f08c3bdfSopenharmony_ci
99f08c3bdfSopenharmony_ciint main(int argc, char *argv[])
100f08c3bdfSopenharmony_ci{
101f08c3bdfSopenharmony_ci	int lc;
102f08c3bdfSopenharmony_ci	int i;
103f08c3bdfSopenharmony_ci
104f08c3bdfSopenharmony_ci	tst_parse_opts(argc, argv, NULL, NULL);
105f08c3bdfSopenharmony_ci
106f08c3bdfSopenharmony_ci	setup();
107f08c3bdfSopenharmony_ci
108f08c3bdfSopenharmony_ci	for (lc = 0; TEST_LOOPING(lc); lc++) {
109f08c3bdfSopenharmony_ci		tst_count = 0;
110f08c3bdfSopenharmony_ci
111f08c3bdfSopenharmony_ci		for (i = 0; i < (int)ARRAY_SIZE(tc); i++) {
112f08c3bdfSopenharmony_ci			TEST(getxattr(tc[i].fname, tc[i].key, tc[i].value,
113f08c3bdfSopenharmony_ci				      tc[i].size));
114f08c3bdfSopenharmony_ci
115f08c3bdfSopenharmony_ci			if (TEST_ERRNO == tc[i].exp_err) {
116f08c3bdfSopenharmony_ci				tst_resm(TPASS | TTERRNO, "expected behavior");
117f08c3bdfSopenharmony_ci			} else {
118f08c3bdfSopenharmony_ci				tst_resm(TFAIL | TTERRNO, "unexpected behavior"
119f08c3bdfSopenharmony_ci					 "- expected errno %d - Got",
120f08c3bdfSopenharmony_ci					 tc[i].exp_err);
121f08c3bdfSopenharmony_ci			}
122f08c3bdfSopenharmony_ci		}
123f08c3bdfSopenharmony_ci
124f08c3bdfSopenharmony_ci		if (TEST_RETURN != XATTR_TEST_VALUE_SIZE) {
125f08c3bdfSopenharmony_ci			tst_resm(TFAIL,
126f08c3bdfSopenharmony_ci				 "getxattr() returned wrong size %ld expected %d",
127f08c3bdfSopenharmony_ci				 TEST_RETURN, XATTR_TEST_VALUE_SIZE);
128f08c3bdfSopenharmony_ci			continue;
129f08c3bdfSopenharmony_ci		}
130f08c3bdfSopenharmony_ci
131f08c3bdfSopenharmony_ci		if (memcmp(tc[i - 1].value, XATTR_TEST_VALUE, XATTR_TEST_VALUE_SIZE))
132f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "Wrong value, expect \"%s\" got \"%s\"",
133f08c3bdfSopenharmony_ci				 XATTR_TEST_VALUE, tc[i - 1].value);
134f08c3bdfSopenharmony_ci		else
135f08c3bdfSopenharmony_ci			tst_resm(TPASS, "Got the right value");
136f08c3bdfSopenharmony_ci	}
137f08c3bdfSopenharmony_ci
138f08c3bdfSopenharmony_ci	cleanup();
139f08c3bdfSopenharmony_ci	tst_exit();
140f08c3bdfSopenharmony_ci}
141f08c3bdfSopenharmony_ci
142f08c3bdfSopenharmony_cistatic void setup(void)
143f08c3bdfSopenharmony_ci{
144f08c3bdfSopenharmony_ci	int fd;
145f08c3bdfSopenharmony_ci	unsigned int i;
146f08c3bdfSopenharmony_ci
147f08c3bdfSopenharmony_ci	tst_require_root();
148f08c3bdfSopenharmony_ci
149f08c3bdfSopenharmony_ci	tst_tmpdir();
150f08c3bdfSopenharmony_ci
151f08c3bdfSopenharmony_ci	/* Create test file and setup initial xattr */
152f08c3bdfSopenharmony_ci	snprintf(filename, BUFSIZ, "getxattr01testfile");
153f08c3bdfSopenharmony_ci	fd = SAFE_CREAT(cleanup, filename, 0644);
154f08c3bdfSopenharmony_ci	close(fd);
155f08c3bdfSopenharmony_ci	if (setxattr(filename, XATTR_TEST_KEY, XATTR_TEST_VALUE,
156f08c3bdfSopenharmony_ci		     strlen(XATTR_TEST_VALUE), XATTR_CREATE) == -1) {
157f08c3bdfSopenharmony_ci		if (errno == ENOTSUP) {
158f08c3bdfSopenharmony_ci			tst_brkm(TCONF, cleanup, "No xattr support in fs or "
159f08c3bdfSopenharmony_ci				 "mount without user_xattr option");
160f08c3bdfSopenharmony_ci		}
161f08c3bdfSopenharmony_ci	}
162f08c3bdfSopenharmony_ci
163f08c3bdfSopenharmony_ci	/* Prepare test cases */
164f08c3bdfSopenharmony_ci	for (i = 0; i < ARRAY_SIZE(tc); i++) {
165f08c3bdfSopenharmony_ci		tc[i].value = malloc(BUFFSIZE);
166f08c3bdfSopenharmony_ci		if (tc[i].value == NULL) {
167f08c3bdfSopenharmony_ci			tst_brkm(TBROK | TERRNO, cleanup,
168f08c3bdfSopenharmony_ci				 "Cannot allocate memory");
169f08c3bdfSopenharmony_ci		}
170f08c3bdfSopenharmony_ci	}
171f08c3bdfSopenharmony_ci
172f08c3bdfSopenharmony_ci	TEST_PAUSE;
173f08c3bdfSopenharmony_ci}
174f08c3bdfSopenharmony_ci
175f08c3bdfSopenharmony_cistatic void cleanup(void)
176f08c3bdfSopenharmony_ci{
177f08c3bdfSopenharmony_ci	tst_rmdir();
178f08c3bdfSopenharmony_ci}
179f08c3bdfSopenharmony_ci#else /* HAVE_SYS_XATTR_H */
180f08c3bdfSopenharmony_ciint main(int argc, char *argv[])
181f08c3bdfSopenharmony_ci{
182f08c3bdfSopenharmony_ci	tst_brkm(TCONF, NULL, "<sys/xattr.h> does not exist.");
183f08c3bdfSopenharmony_ci}
184f08c3bdfSopenharmony_ci#endif
185