1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2013 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *               Glenn Fowler <glenn.s.fowler@gmail.com>                *
18 *                    David Korn <dgkorn@gmail.com>                     *
19 *                     Phong Vo <phongvo@gmail.com>                     *
20 *                                                                      *
21 ***********************************************************************/
22 #include "FEATURE/lib"
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <unistd.h>
28 
29 int
main(int argc,char ** argv)30 main(int argc, char** argv)
31 {
32 #if defined(_fd_self_dir_fmt) || defined(_fd_pid_dir_fmt)
33 	int		dd;
34 	int		fd;
35 	int		r;
36 	char*		fmt;
37 	char		dir[256];
38 	char		dev[256];
39 	char		tst[256];
40 	char		dev_old[256];
41 	char		dir_old[256];
42 	char		dev_new[256];
43 	char		dir_new[256];
44 	struct stat	st;
45 
46 	static char*	res[] = { "fails", "works" };
47 
48 	snprintf(dir, sizeof(dir), "%s.dir", argv[1]);
49 	if (mkdir(dir, S_IRUSR|S_IWUSR|S_IXUSR))
50 		return 1;
51 	if ((dd = open(dir, O_RDONLY)) < 0)
52 		return 1;
53 	snprintf(dir_old, sizeof(dir_old), "%s/old", dir);
54 	if ((fd = open(dir_old, O_CREAT, S_IRUSR|S_IWUSR)) < 0)
55 		return 1;
56 	close(fd);
57 	snprintf(dir_new, sizeof(dir_new), "%s/new", dir);
58 #ifdef _fd_pid_dir_fmt
59 	fmt = _fd_pid_dir_fmt;
60 	snprintf(dev, sizeof(dev), fmt, getpid(), dd, "", "");
61 #else
62 	fmt = _fd_self_dir_fmt;
63 	snprintf(dev, sizeof(dev), fmt, dd, "", "");
64 #endif
65 	snprintf(dev_old, sizeof(dev_old), "%s/old", dev);
66 	snprintf(dev_new, sizeof(dev_new), "%s/new", dev);
67 #if !_lib_faccessat
68 	r = access(dev_old, 0) >= 0;
69 	printf("#define _fd_dir_access	%d	/* access(%s/old) %s */\n", r, fmt, res[r]);
70 #endif
71 #if !_lib_fchmodat
72 	r = chmod(dev_old, S_IRUSR|S_IWUSR|S_IXUSR) >= 0;
73 	printf("#define _fd_dir_chmod	%d	/* chmod(%s/old) %s */\n", r, fmt, res[r]);
74 #if _lib_lchmod && _lib_symlink
75 	if (r = symlink(dir_old, dir_new) >= 0)
76 	{
77 		r = lchmod(dev_new, S_IRUSR|S_IWUSR|S_IXUSR) >= 0;
78 		unlink(dir_new);
79 	}
80 	printf("#define _fd_dir_chmod	%d	/* lchmod(%s/old) %s */\n", r, fmt, res[r]);
81 #endif
82 #endif
83 #if !_lib_fchownat
84 	r = chown(dev_old, -1, -1) >= 0;
85 	printf("#define _fd_dir_chown	%d	/* chown(%s/old) %s */\n", r, fmt, res[r]);
86 #if _lib_lchown && _lib_symlink
87 	if (r = symlink(dir_old, dir_new) >= 0)
88 	{
89 		r = lchown(dev_new, -1, -1) >= 0;
90 		unlink(dir_new);
91 	}
92 	printf("#define _fd_dir_lchown	%d	/* lchown(%s/old) %s */\n", r, fmt, res[r]);
93 #endif
94 #endif
95 #if !_lib_fstatat
96 	r = stat(dev_old, &st) >= 0;
97 	printf("#define _fd_dir_stat	%d	/* stat(%s/old) %s */\n", r, fmt, res[r]);
98 #endif
99 #if !_lib_linkat
100 	if (r = link(dev_old, dev_new) >= 0)
101 		unlink(dev_new);
102 	printf("#define _fd_dir_link	%d	/* link(%s/old,%s/new) %s */\n", r, fmt, fmt, res[r]);
103 #endif
104 #if !_lib_mkdirat
105 	if (r = mkdir(dev_new, S_IRUSR|S_IWUSR|S_IXUSR) >= 0)
106 		rmdir(dir_new);
107 	printf("#define _fd_dir_mkdir	%d	/* mkdir(%s/new) %s */\n", r, fmt, res[r]);
108 #endif
109 #if !_lib_mknodat
110 #if _lib_mknod
111 	if (r = mknod(dev_new, S_IFREG, 0) >= 0)
112 		unlink(dir_new);
113 #else
114 	r = 0;
115 #endif
116 	printf("#define _fd_dir_mknod	%d	/* mknod(%s/new) %s */\n", r, fmt, res[r]);
117 #endif
118 #if !_lib_mkfifoat
119 #if _lib_mkfifo
120 	if (r = mkfifo(dev_new, S_IRUSR|S_IWUSR|S_IXUSR) >= 0)
121 		unlink(dir_new);
122 #elif _lib_mknod
123 	if (r = mknod(dev_new, S_IFIFO, 0) >= 0)
124 		unlink(dir_new);
125 #else
126 	r = 0;
127 #endif
128 	printf("#define _fd_dir_mkfifo	%d	/* mkfifo(%s/new) %s */\n", r, fmt, res[r]);
129 #endif
130 #if !_lib_openat
131 	if (r = (fd = open(dev_old, O_RDONLY)) >= 0)
132 		close(fd);
133 	printf("#define _fd_dir_open	%d	/* open(%s/old) %s */\n", r, fmt, res[r]);
134 #endif
135 #if !_lib_readlinkat
136 #if _lib_symlink && _lib_readlink
137 	if (r = symlink(dir_old, dir_new) >= 0)
138 	{
139 		r = readlink(dev_new, tst, sizeof(tst)) > 0;
140 		unlink(dir_new);
141 	}
142 #else
143 	r = 0;
144 #endif
145 	printf("#define _fd_dir_readlink	%d	/* readlink(%s/old) %s */\n", r, fmt, res[r]);
146 #endif
147 #if !_lib_renameat
148 	if (r = rename(dev_old, dev_new) >= 0)
149 		unlink(dev_new);
150 	printf("#define _fd_dir_rename	%d	/* rename(%s/old,%s/new) %s */\n", r, fmt, fmt, res[r]);
151 #endif
152 #if !_lib_symlinkat
153 #if _lib_symlink
154 	if (r = symlink(dir_old, dev_new) >= 0)
155 		unlink(dir_new);
156 #else
157 	r = 0;
158 #endif
159 	printf("#define _fd_dir_symlink	%d	/* symlink(old,%s/new) %s */\n", r, fmt, res[r]);
160 #endif
161 #if !_lib_unlinkat
162 	if (r = unlink(dev_old) >= 0)
163 		close(open(dir_old, O_CREAT, S_IRUSR|S_IWUSR));
164 	printf("#define _fd_dir_unlink	%d	/* unlink(%s/old) %s */\n", r, fmt, res[r]);
165 #endif
166 #endif
167 	return 0;
168 }
169