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 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