1 /*
2 * Copyright (c) International Business Machines Corp., 2001
3 * Author: Wayne Boyer
4 * Copyright (c) 2018 Cyril Hrubis <chrubis@suse.cz>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 * the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 /*
21 * Test that fchmod() fails and sets the proper errno values.
22 */
23
24 #ifndef _GNU_SOURCE
25 # define _GNU_SOURCE
26 #endif
27 #include <errno.h>
28 #include <sys/types.h>
29 #include <pwd.h>
30 #include "tst_test.h"
31
32 #define MNT_POINT "mntpoint"
33
34 static int fd1;
35 static int fd2;
36 static int fd3;
37
38 static struct tcase {
39 int *fd;
40 int mode;
41 int exp_errno;
42 } tcases[] = {
43 {&fd1, 0644, EPERM},
44 {&fd2, 0644, EBADF},
45 {&fd3, 0644, EROFS},
46 };
47
verify_fchmod(unsigned int i)48 static void verify_fchmod(unsigned int i)
49 {
50 struct tcase *tc = &tcases[i];
51
52 TEST(fchmod(*tc->fd, tc->mode));
53
54 if (TST_RET != -1) {
55 tst_res(TFAIL, "fchmod() passed unexpectedly (%li)",
56 TST_RET);
57 return;
58 }
59
60 if (TST_ERR == tcases[i].exp_errno) {
61 tst_res(TPASS | TTERRNO, "fchmod() failed expectedly");
62 return;
63 }
64
65 tst_res(TFAIL | TTERRNO,
66 "fchmod() failed unexpectedly, expected %i - %s",
67 TST_ERR, tst_strerrno(TST_ERR));
68 }
69
setup(void)70 static void setup(void)
71 {
72 struct passwd *ltpuser = SAFE_GETPWNAM("nobody");
73
74 fd3 = SAFE_OPEN(MNT_POINT"/file", O_RDONLY);
75 fd1 = SAFE_OPEN("tfile_1", O_RDWR | O_CREAT, 0666);
76 fd2 = SAFE_OPEN("tfile_2", O_RDWR | O_CREAT, 0666);
77 SAFE_CLOSE(fd2);
78
79 SAFE_SETEUID(ltpuser->pw_uid);
80 }
81
cleanup(void)82 static void cleanup(void)
83 {
84 if (fd1 > 0)
85 SAFE_CLOSE(fd1);
86
87 if (fd3 > 0)
88 SAFE_CLOSE(fd3);
89 }
90
91 static struct tst_test test = {
92 .setup = setup,
93 .cleanup = cleanup,
94 .test = verify_fchmod,
95 .tcnt = ARRAY_SIZE(tcases),
96 .needs_root = 1,
97 .needs_rofs = 1,
98 .mntpoint = MNT_POINT,
99 };
100