3 * Copyright (C) 2019 Simone Piccardi
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /****************************************************************
21 * Program test_linkat.c:
22 * Program to test use of linkat with an O_TMPFILE or linking another file
23 * using AT_EMPTY_PATH or AT_SYMLINK_FOLLOW on /proc/self/fd/N
24 * giving the option to wait to remove source file
26 * Author: Simone Piccardi
29 * Usage: testlinkat -h give all info's
31 ****************************************************************/
33 * Include needed headers
36 #include <errno.h> /* error definitions and routines */
37 #include <stdlib.h> /* C standard library */
38 #include <unistd.h> /* unix standard library */
39 #include <stdio.h> /* standard I/O library */
40 #include <string.h> /* C strings library */
42 #include <libgen.h> /* needed for dirname e basename */
44 #include <sys/types.h>
48 /* Help printing routine */
51 int main(int argc, char *argv[])
54 * Variables definition
60 * Input section: decode command line parameters
63 opterr = 0; /* don't want writing to stderr */
64 while ( (i = getopt(argc, argv, "hw:f:")) != -1) {
69 case 'h': /* help option */
70 printf("Wrong -h option use\n");
74 case 'w': /* time to wait in s */
75 wait = strtol(optarg, NULL, 10); /* convert input */
77 case 'f': /* using a source file */
80 case '?': /* unrecognized options */
81 printf("Unrecognized options -%c\n",optopt);
83 default: /* should not reached */
87 /* ***********************************************************
89 * Options processing completed
93 * ***********************************************************/
94 /* There must be 1 remaing parameters */
95 if ( (argc-optind) != 1 ) {
96 printf("From %d arguments, removed %d options\n", argc, optind);
99 char *path, *dir, *file;
100 char pattern[] = "prova prova prova\n";
102 path = strdup(argv[optind]);
103 file = basename(argv[optind]);
104 dir = dirname(argv[optind]);
105 printf("Destination on dir %s file: %s\n with path: %s\n",
109 // temp file with O_TMPFILE
110 fd = open(dir, O_TMPFILE|O_RDWR,S_IRUSR|S_IWUSR);
112 perror("cannot open TMPFILE");
113 if ( (i = write(fd, pattern, sizeof(pattern))) < 0 )
114 perror("cannot write on TMPFILE");
116 printf("saved %d chars on fd %d\n", i, fd);
118 // user provided source
119 printf("source file is %s\n", srcfile);
120 if ( (fd = open(srcfile, O_RDONLY)) < 0 ) {
121 perror("cannot open source");
124 printf("waiting %d second to remove the file\n", wait);
127 newfd = open(dir, O_PATH|O_RDWR);
129 err = linkat(fd, "", newfd, file, AT_EMPTY_PATH);
131 perror("error on creating TMPFILE with AT_EMPTY_PATH");
132 printf("cannot link fd %d on fd %d/%s with AT_EMPTY_PATH\n",
134 char fdpath[PATH_MAX];
135 snprintf(fdpath, PATH_MAX, "/proc/self/fd/%d", fd);
136 printf("Attempt to use AT_SYMLINK_FOLLOW with path %s\n", fdpath);
137 err = linkat(AT_FDCWD, fdpath, newfd, file, AT_SYMLINK_FOLLOW);
139 perror("still error creating TMPFILE");
142 printf("Success, fd %d on fd %d/%s created\n", fd, newfd, file);
144 if ( fchmodat(newfd, file,S_IRUSR|S_IWUSR,0) < 0 )
145 perror("Cannot change permission to new file");
151 * routine to print usage info and exit
154 printf("Program testlinkat : test linkat for a file \n");
155 printf("Create a link to a tempfile or a link to -f indicated file");
157 printf(" testlinkat [-h] destfilepathname \n");
158 printf(" -h print this help\n");
159 printf(" -w [N] wait N seconds\n");
160 printf(" -f [file] use file as source\n");