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 10 /* backward compat in case it's not defined */ 11 #ifndef O_TMPFILE 12 #define O_TMPFILE (020000000|O_DIRECTORY) 13 #endif 14 15 /* 16 * DESCRIPTION: 17 * Verify O_EXCL tmpfile cannot be linked. 18 * 19 * STRATEGY: 20 * 1. open(2) with O_TMPFILE|O_EXCL. 21 * 2. linkat(2). 22 * 3. stat(2) the path to verify it wasn't created. 23 * 24 */ 25 26 int 27 main(int argc, char *argv[]) 28 { 29 int i, fd; 30 char spath[1024], dpath[1024]; 31 char *penv[] = {"TESTDIR", "TESTFILE0"}; 32 struct stat sbuf; 33 34 (void) fprintf(stdout, "Verify O_EXCL tmpfile cannot be linked.\n"); 35 36 /* 37 * Get the environment variable values. 38 */ 39 for (i = 0; i < sizeof (penv) / sizeof (char *); i++) { 40 if ((penv[i] = getenv(penv[i])) == NULL) { 41 (void) fprintf(stderr, "getenv(penv[%d])\n", i); 42 exit(1); 43 } 44 } 45 46 fd = open(penv[0], O_RDWR|O_TMPFILE|O_EXCL, 0666); 47 if (fd < 0) { 48 perror("open"); 49 exit(2); 50 } 51 52 snprintf(spath, 1024, "/proc/self/fd/%d", fd); 53 snprintf(dpath, 1024, "%s/%s", penv[0], penv[1]); 54 if (linkat(AT_FDCWD, spath, AT_FDCWD, dpath, AT_SYMLINK_FOLLOW) == 0) { 55 fprintf(stderr, "linkat returns successfully\n"); 56 close(fd); 57 exit(3); 58 } 59 60 if (stat(dpath, &sbuf) == 0) { 61 fprintf(stderr, "stat returns successfully\n"); 62 close(fd); 63 exit(4); 64 } 65 close(fd); 66 67 return (0); 68 } 69