1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <string.h>
9 #include <err.h>
10
11 /* backward compat in case it's not defined */
12 #ifndef O_TMPFILE
13 #define O_TMPFILE (020000000|O_DIRECTORY)
14 #endif
15
16 /*
17 * DESCRIPTION:
18 * Verify O_EXCL tmpfile cannot be linked.
19 *
20 * STRATEGY:
21 * 1. open(2) with O_TMPFILE|O_EXCL.
22 * 2. linkat(2).
23 * 3. stat(2) the path to verify it wasn't created.
24 *
25 */
26
27 int
main(void)28 main(void)
29 {
30 int i, fd;
31 char spath[1024], dpath[1024];
32 const char *penv[] = {"TESTDIR", "TESTFILE0"};
33 struct stat sbuf;
34
35 (void) fprintf(stdout, "Verify O_EXCL tmpfile cannot be linked.\n");
36
37 /*
38 * Get the environment variable values.
39 */
40 for (i = 0; i < ARRAY_SIZE(penv); i++)
41 if ((penv[i] = getenv(penv[i])) == NULL)
42 errx(1, "getenv(penv[%d])", i);
43
44 fd = open(penv[0], O_RDWR|O_TMPFILE|O_EXCL, 0666);
45 if (fd < 0)
46 err(2, "open(%s)", penv[0]);
47
48 snprintf(spath, 1024, "/proc/self/fd/%d", fd);
49 snprintf(dpath, 1024, "%s/%s", penv[0], penv[1]);
50 if (linkat(AT_FDCWD, spath, AT_FDCWD, dpath, AT_SYMLINK_FOLLOW) == 0)
51 errx(3, "linkat returned successfully\n");
52
53 if (stat(dpath, &sbuf) == 0)
54 errx(4, "stat returned successfully\n");
55
56 return (0);
57 }
58