1/*-
2 * Copyright (c) 2007 Roman Divacky <rdivacky@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28#include <sys/param.h>
29#include <sys/stat.h>
30#include <sys/syscall.h>
31#include <sys/types.h>
32#include <errno.h>
33#include <fcntl.h>
34#include <stdbool.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <unistd.h>
39
40union param {
41	int		i;
42	char		*cp;
43	mode_t		m;
44	dev_t		d;
45	void		*vp;
46	uid_t		u;
47	gid_t		g;
48	char		**cpp;
49};
50
51struct testcase {
52	int		result;
53	union param	params[5];	// no *at syscall with more than 5 params
54};
55
56struct test {
57	int	syscall;
58	int	num_of_cases;
59	char	*name;
60	struct testcase	tests[10];	// no more than 10 tests
61
62};
63
64struct test *tests;
65#define	NUM_OF_TESTS	15
66
67char *absolute_path = NULL;
68char *relative_path = "tmp/";
69char *not_dir_path = "/bin/date";
70
71char *file = "foo";
72char *absolute_file = NULL;
73char *relative_file = NULL;
74char *symlinkf = "link";
75char *newlink = "nlink1";
76char *newlink2 = "nlink2";
77char *newlink3 = "nlink3";
78char *newdir = "newdir";
79char *fifo = "fifo";
80char *nod = "nod";
81char *newfile = "newfile";
82char *newslink = "nslink1";
83
84bool dir_exist = false;
85bool file_exist = false;
86bool link_exist = false;
87
88int rel_fd, abs_fd, notd_fd, exec_fd;
89
90struct timeval times[2];
91struct stat buf;
92char *pargv[2] = { "/bin/date", NULL };
93char cbuf[PATH_MAX];
94
95void
96setup()
97{
98	int i, error;
99	struct stat sb;
100
101	tests = calloc(NUM_OF_TESTS, sizeof(struct test));
102	if (tests == NULL) {
103		perror("");
104		exit(0);
105	}
106
107	absolute_path = getcwd(NULL, 0);
108	if (absolute_path == NULL) {
109		perror("getcwd");
110		exit(0);
111	}
112
113	absolute_path = realloc(absolute_path, strlen(absolute_path) + 5);
114	if (absolute_path == NULL) {
115		perror("realloc");
116		exit(0);
117	}
118
119	strcat(absolute_path, "/");
120	strcat(absolute_path, relative_path);
121
122	absolute_file = malloc(strlen(absolute_path) + 1 + strlen(file));
123	bzero(absolute_file, strlen(absolute_path) + 1 + strlen(file));
124	if (absolute_file == NULL) {
125		perror("malloc");
126		exit(0);
127	}
128	strcpy(absolute_file, absolute_path);
129	absolute_file[strlen(absolute_file)] = '/';
130	strcpy(absolute_file + strlen(absolute_path), file);
131
132	printf("XX: %s\n", absolute_file);
133
134	relative_file = malloc(strlen(relative_path) + 1 + strlen(file));
135	bzero(relative_file, strlen(relative_path) + 1 + strlen(file));
136	if (relative_file == NULL) {
137		perror("malloc");
138		exit(0);
139	}
140	strcpy(relative_file, relative_path);
141	relative_file[strlen(relative_file)] = '/';
142	strcpy(relative_file + strlen(relative_path), file);
143
144	printf("YY: %s\n", relative_file);
145
146	error = mkdir(relative_path, 0744);
147	dir_exist = (errno == EEXIST);
148	if (error && errno != EEXIST) {
149		perror("tmp");
150		exit(0);
151	}
152
153	error = stat("tmp/foo", &sb);
154	file_exist = (errno != ENOENT);
155	i = open("tmp/foo", O_RDONLY | O_CREAT, 0644);
156	if (i == -1) {
157		perror("foo");
158		exit(0);
159	}
160
161	rel_fd = open(relative_path, O_RDONLY);
162	if (rel_fd == -1) {
163		perror("relative path");
164		exit(0);
165	}
166
167	abs_fd = open(absolute_path, O_RDONLY);
168	if (abs_fd == -1) {
169		perror("absolute path");
170		exit(0);
171	}
172
173	notd_fd = open(not_dir_path, O_RDONLY);
174	if (notd_fd == -1) {
175		perror("not a directory");
176		exit(0);
177	}
178
179	exec_fd = open(not_dir_path, O_RDONLY);
180	if (exec_fd == -1) {
181		perror("not a directory");
182		exit(0);
183	}
184
185	error = symlink(absolute_file, symlinkf);
186	link_exist = (errno == EEXIST);
187	if (error && errno != EEXIST) {
188		perror("symlink");
189		exit(0);
190	}
191
192	// faccessat
193	tests[0].syscall = SYS_faccessat;
194	tests[0].num_of_cases = 6;
195	tests[0].name = "faccessat";
196	tests[0].tests[0].result = EBADF;
197	tests[0].tests[0].params[0].i = 106;	// invalid fd
198	tests[0].tests[0].params[1].cp = relative_path;
199	tests[0].tests[0].params[2].m = 0;
200	tests[0].tests[0].params[3].i = 0;
201	tests[0].tests[1].result = EBADF;
202	tests[0].tests[1].params[0].i = 106;	// invalid fd
203	tests[0].tests[1].params[1].cp = relative_path;
204	tests[0].tests[1].params[2].m = 0;
205	tests[0].tests[1].params[3].i = AT_EACCESS;
206	tests[0].tests[2].result = EINVAL;
207	tests[0].tests[2].params[0].i = rel_fd;
208	tests[0].tests[2].params[1].cp = absolute_path;
209	tests[0].tests[2].params[2].m = 0;
210	tests[0].tests[2].params[3].i = 123;	// invalid flag
211	tests[0].tests[3].result = ENOTDIR;
212	tests[0].tests[3].params[0].i = notd_fd;
213	tests[0].tests[3].params[1].cp = relative_file;
214	tests[0].tests[3].params[2].m = 0;
215	tests[0].tests[3].params[3].i = 0;
216	tests[0].tests[4].result = 0;
217	tests[0].tests[4].params[0].i = rel_fd;
218	tests[0].tests[4].params[1].cp = file;
219	tests[0].tests[4].params[2].m = 0;
220	tests[0].tests[4].params[3].i = 0;
221	tests[0].tests[5].result = 0;
222	tests[0].tests[5].params[0].i = rel_fd;
223	tests[0].tests[5].params[1].cp = file;
224	tests[0].tests[5].params[2].m = 0;
225	tests[0].tests[5].params[3].i = AT_EACCESS;
226	tests[0].tests[6].result = 0;
227	tests[0].tests[6].params[0].i = 106;	// invalid fd
228	tests[0].tests[6].params[1].cp = absolute_path;
229	tests[0].tests[6].params[2].m = 0;
230	tests[0].tests[6].params[3].i = 0;
231
232	// fchmodat
233	tests[1].syscall = SYS_fchmodat;
234	tests[1].num_of_cases = 6;
235	tests[1].name = "fchmodat";
236	tests[1].tests[0].result = EBADF;
237	tests[1].tests[0].params[0].i = 106;	// invalid fd
238	tests[1].tests[0].params[1].cp = relative_path;
239	tests[1].tests[0].params[2].m = 33190;
240	tests[1].tests[0].params[3].i = 0;
241	tests[1].tests[1].result = EINVAL;
242	tests[1].tests[1].params[0].i = rel_fd;
243	tests[1].tests[1].params[1].cp = absolute_path;
244	tests[1].tests[1].params[2].m = 33190;	// mode 646 translated
245	tests[1].tests[1].params[3].i = 123;	// invalid flag
246	tests[1].tests[2].result = ENOTDIR;
247	tests[1].tests[2].params[0].i = notd_fd;
248	tests[1].tests[2].params[1].cp = relative_file;
249	tests[1].tests[2].params[2].m = 33190;
250	tests[1].tests[2].params[3].i = 0;
251	tests[1].tests[3].result = 0;
252	tests[1].tests[3].params[0].i = notd_fd;
253	tests[1].tests[3].params[1].cp = absolute_file;
254	tests[1].tests[3].params[2].m = 33190;
255	tests[1].tests[3].params[3].i = 0;
256	tests[1].tests[4].result = 0;
257	tests[1].tests[4].params[0].i = AT_FDCWD;
258	tests[1].tests[4].params[1].cp = symlinkf;
259	tests[1].tests[4].params[2].m = 33190;
260	tests[1].tests[4].params[3].i = AT_SYMLINK_NOFOLLOW;
261	tests[1].tests[5].result = 0;
262	tests[1].tests[5].params[0].i = rel_fd;
263	tests[1].tests[5].params[1].cp = file;
264	tests[1].tests[5].params[2].m = 33190;
265	tests[1].tests[5].params[3].i = 0;
266
267	// fchownat
268	tests[2].syscall = SYS_fchownat;
269	tests[2].num_of_cases = 6;
270	tests[2].name = "fchownat";
271	tests[2].tests[0].result = EBADF;
272	tests[2].tests[0].params[0].i = 106;	// invalid fd
273	tests[2].tests[0].params[1].cp = relative_file;
274	tests[2].tests[0].params[2].u = 65534;
275	tests[2].tests[0].params[3].g = 65534;
276	tests[2].tests[0].params[4].i = 0;
277	tests[2].tests[1].result = EINVAL;
278	tests[2].tests[1].params[0].i = rel_fd;
279	tests[2].tests[1].params[1].cp = file;
280	tests[2].tests[1].params[2].u = 65534;
281	tests[2].tests[1].params[3].g = 65534;
282	tests[2].tests[1].params[4].i = 123;	// invalid flag
283	tests[2].tests[2].result = ENOTDIR;
284	tests[2].tests[2].params[0].i = notd_fd;
285	tests[2].tests[2].params[1].cp = relative_file;
286	tests[2].tests[2].params[2].u = 65534;
287	tests[2].tests[2].params[3].g = 65534;
288	tests[2].tests[2].params[4].i = 0;
289	tests[2].tests[3].result = 0;
290	tests[2].tests[3].params[0].i = notd_fd;
291	tests[2].tests[3].params[1].cp = absolute_file;
292	tests[2].tests[3].params[2].u = 65534;
293	tests[2].tests[3].params[3].g = 65534;
294	tests[2].tests[3].params[4].i = 0;
295	tests[2].tests[4].result = 0;
296	tests[2].tests[4].params[0].i = AT_FDCWD;
297	tests[2].tests[4].params[1].cp = symlinkf;
298	tests[2].tests[4].params[2].u = 65534;
299	tests[2].tests[4].params[3].g = 65534;
300	tests[2].tests[4].params[4].i = AT_SYMLINK_NOFOLLOW;
301	tests[2].tests[5].result = 0;
302	tests[2].tests[5].params[0].i = rel_fd;
303	tests[2].tests[5].params[1].cp = file;
304	tests[2].tests[5].params[2].u = 0;
305	tests[2].tests[5].params[3].g = 0;
306	tests[2].tests[5].params[4].i = 0;
307
308	// fstatat
309	tests[3].syscall = SYS_fstatat;
310	tests[3].num_of_cases = 5;
311	tests[3].name = "fstatat";
312	tests[3].tests[0].result = EBADF;
313	tests[3].tests[0].params[0].i = 106;	// invalid fd
314	tests[3].tests[0].params[1].cp = relative_file;
315	tests[3].tests[0].params[2].vp = &buf;
316	tests[3].tests[0].params[3].i = 0;
317	tests[3].tests[1].result = EINVAL;
318	tests[3].tests[1].params[0].i = rel_fd;
319	tests[3].tests[1].params[1].cp = relative_file;
320	tests[3].tests[1].params[2].vp = &buf;
321	tests[3].tests[1].params[3].i = 123;	// invalid flags
322	tests[3].tests[2].result = ENOTDIR;
323	tests[3].tests[2].params[0].i = notd_fd;
324	tests[3].tests[2].params[1].cp = relative_file;
325	tests[3].tests[2].params[2].vp = &buf;
326	tests[3].tests[2].params[3].i = 0;
327	tests[3].tests[2].result = 0;
328	tests[3].tests[2].params[0].i = rel_fd;
329	tests[3].tests[2].params[1].cp = file;
330	tests[3].tests[2].params[2].vp = &buf;
331	tests[3].tests[2].params[3].i = 0;
332	tests[3].tests[3].result = 0;
333	tests[3].tests[3].params[0].i = AT_FDCWD;
334	tests[3].tests[3].params[1].cp = symlinkf;
335	tests[3].tests[3].params[2].vp = &buf;
336	tests[3].tests[3].params[3].i = AT_SYMLINK_NOFOLLOW;
337	tests[3].tests[4].result = 0;
338	tests[3].tests[4].params[0].i = notd_fd;
339	tests[3].tests[4].params[1].cp = absolute_file;
340	tests[3].tests[4].params[2].vp = &buf;
341	tests[3].tests[4].params[3].i = 0;
342
343	// futimesat
344	tests[4].syscall = SYS_futimesat;
345	tests[4].num_of_cases = 4;
346	tests[4].name = "futimesat";
347	tests[4].tests[0].result = EBADF;
348	tests[4].tests[0].params[0].i = 106;	// invalid fd
349	tests[4].tests[0].params[1].cp = relative_file;
350	tests[4].tests[0].params[2].vp = times;
351	tests[4].tests[1].result = ENOTDIR;
352	tests[4].tests[1].params[0].i = notd_fd;
353	tests[4].tests[1].params[1].cp = relative_file;
354	tests[4].tests[1].params[2].vp = times;
355	tests[4].tests[2].result = 0;
356	tests[4].tests[2].params[0].i = rel_fd;
357	tests[4].tests[2].params[1].cp = file;
358	tests[4].tests[2].params[2].vp = times;
359	tests[4].tests[3].result = 0;
360	tests[4].tests[3].params[0].i = notd_fd;
361	tests[4].tests[3].params[1].cp = absolute_file;
362	tests[4].tests[3].params[2].vp = times;
363
364	// linkat
365	tests[5].syscall = SYS_linkat;
366	tests[5].num_of_cases = 7;
367	tests[5].name = "linkat";
368	tests[5].tests[0].result = EBADF;
369	tests[5].tests[0].params[0].i = 106;	// invalid fd
370	tests[5].tests[0].params[1].cp = relative_file;
371	tests[5].tests[0].params[2].i = AT_FDCWD;
372	tests[5].tests[0].params[3].cp = newlink;
373	tests[5].tests[0].params[4].i = 0;
374	tests[5].tests[1].result = EBADF;
375	tests[5].tests[1].params[0].i = AT_FDCWD;
376	tests[5].tests[1].params[1].cp = relative_file;
377	tests[5].tests[1].params[2].i = 106;	// invalid fd
378	tests[5].tests[1].params[3].cp = newlink;
379	tests[5].tests[1].params[4].i = 0;
380	tests[5].tests[2].result = EINVAL;
381	tests[5].tests[2].params[0].i = rel_fd;
382	tests[5].tests[2].params[1].cp = relative_file;
383	tests[5].tests[2].params[2].i = AT_FDCWD;
384	tests[5].tests[2].params[3].cp = newlink;
385	tests[5].tests[2].params[4].i = 123;	// invalid flag
386	tests[5].tests[3].result = ENOTDIR;
387	tests[5].tests[3].params[0].i = notd_fd;
388	tests[5].tests[3].params[1].cp = relative_file;
389	tests[5].tests[3].params[2].i = AT_FDCWD;
390	tests[5].tests[3].params[3].cp = newlink;
391	tests[5].tests[3].params[4].i = 0;
392	tests[5].tests[4].result = 0;
393	tests[5].tests[4].params[0].i = rel_fd;
394	tests[5].tests[4].params[1].cp = file;
395	tests[5].tests[4].params[2].i = rel_fd;
396	tests[5].tests[4].params[3].cp = newlink;
397	tests[5].tests[4].params[4].i = 0;
398	tests[5].tests[5].result = 0;
399	tests[5].tests[5].params[0].i = AT_FDCWD;
400	tests[5].tests[5].params[1].cp = symlinkf;
401	tests[5].tests[5].params[2].i = rel_fd;
402	tests[5].tests[5].params[3].cp = newlink2;
403	tests[5].tests[5].params[4].i = 0;
404	tests[5].tests[6].result = 0;
405	tests[5].tests[6].params[0].i = AT_FDCWD;
406	tests[5].tests[6].params[1].cp = symlinkf;
407	tests[5].tests[6].params[2].i = rel_fd;
408	tests[5].tests[6].params[3].cp = newlink3;
409	tests[5].tests[6].params[4].i = AT_SYMLINK_FOLLOW;
410
411	// mkdirat
412	tests[6].syscall = SYS_mkdirat;
413	tests[6].num_of_cases = 3;
414	tests[6].name = "mkdirat";
415	tests[6].tests[0].result = EBADF;
416	tests[6].tests[0].params[0].i = 106;	// invalid fd
417	tests[6].tests[0].params[1].cp = relative_file;
418	tests[6].tests[0].params[2].m = 33190;
419	tests[6].tests[1].result = ENOTDIR;
420	tests[6].tests[1].params[0].i = notd_fd;
421	tests[6].tests[1].params[1].cp = relative_file;
422	tests[6].tests[1].params[2].m = 33190;
423	tests[6].tests[2].result = 0;
424	tests[6].tests[2].params[0].i = rel_fd;
425	tests[6].tests[2].params[1].cp = newdir;
426	tests[6].tests[2].params[2].m = 33190;
427
428	// mkfifoat
429	tests[7].syscall = SYS_mkfifoat;
430	tests[7].num_of_cases = 3;
431	tests[7].name = "mkfifoat";
432	tests[7].tests[0].result = EBADF;
433	tests[7].tests[0].params[0].i = 107;	// invalid fd
434	tests[7].tests[0].params[1].cp = relative_file;
435	tests[7].tests[0].params[2].m = 33190;
436	tests[7].tests[1].result = ENOTDIR;
437	tests[7].tests[1].params[0].i = notd_fd;
438	tests[7].tests[1].params[1].cp = relative_file;
439	tests[7].tests[1].params[2].m = 33190;
440	tests[7].tests[2].result = 0;
441	tests[7].tests[2].params[0].i = rel_fd;
442	tests[7].tests[2].params[1].cp = fifo;
443	tests[7].tests[2].params[2].m = 33190;
444
445	// mknodat
446	tests[8].syscall = SYS_mknodat;
447	tests[8].num_of_cases = 3;
448	tests[8].name = "mknodat";
449	tests[8].tests[0].result = EBADF;
450	tests[8].tests[0].params[0].i = 108;	// invalid fd
451	tests[8].tests[0].params[1].cp = relative_file;
452	tests[8].tests[0].params[2].m = 0666 | S_IFCHR;
453	tests[8].tests[0].params[3].d = 15;
454	tests[8].tests[1].result = ENOTDIR;
455	tests[8].tests[1].params[0].i = notd_fd;
456	tests[8].tests[1].params[1].cp = relative_file;
457	tests[8].tests[1].params[2].m = 0666 | S_IFCHR;
458	tests[8].tests[1].params[3].d = 15;
459	tests[8].tests[2].result = 0;
460	tests[8].tests[2].params[0].i = rel_fd;
461	tests[8].tests[2].params[1].cp = nod;
462	tests[8].tests[2].params[2].m = 0666 | S_IFCHR;
463	tests[8].tests[2].params[3].d = 2570;
464
465	// openat
466	tests[9].syscall = SYS_openat;
467	tests[9].num_of_cases = 5;
468	tests[9].name = "openat";
469	tests[9].tests[0].result = EBADF;
470	tests[9].tests[0].params[0].i = 106;	// invalid fd
471	tests[9].tests[0].params[1].cp = relative_file;
472	tests[9].tests[0].params[2].i = O_RDONLY;
473	tests[9].tests[0].params[3].i = 0666;
474	tests[9].tests[1].result = ENOTDIR;
475	tests[9].tests[1].params[0].i = notd_fd;
476	tests[9].tests[1].params[1].cp = relative_file;
477	tests[9].tests[1].params[2].i = O_RDONLY;
478	tests[9].tests[1].params[3].i = 0666;
479	tests[9].tests[2].result = 7;		// hardcoded fd
480	tests[9].tests[2].params[0].i = rel_fd;
481	tests[9].tests[2].params[1].cp = file;
482	tests[9].tests[2].params[2].i = O_RDONLY;
483	tests[9].tests[2].params[3].i = 0400;
484	tests[9].tests[3].result = 8;		// hardcoded fd
485	tests[9].tests[3].params[0].i = notd_fd;
486	tests[9].tests[3].params[1].cp = absolute_file;
487	tests[9].tests[3].params[2].i = O_RDONLY;
488	tests[9].tests[3].params[3].i = 0400;
489	tests[9].tests[4].result = 9;		// hardcoded fd
490	tests[9].tests[4].params[0].i = rel_fd;
491	tests[9].tests[4].params[1].cp = newfile;
492	tests[9].tests[4].params[2].i = O_RDONLY | O_CREAT;
493	tests[9].tests[4].params[3].i = 0666;
494
495	// readlinkat
496	tests[10].syscall = SYS_readlinkat;
497	tests[10].num_of_cases = 3;
498	tests[10].name = "readlinkat";
499	tests[10].tests[0].result = EBADF;
500	tests[10].tests[0].params[0].i = 106;	// invalid fd
501	tests[10].tests[0].params[1].cp = relative_file;
502	tests[10].tests[0].params[2].vp = cbuf;
503	tests[10].tests[0].params[3].i = PATH_MAX;
504	tests[10].tests[1].result = ENOTDIR;
505	tests[10].tests[1].params[0].i = notd_fd;
506	tests[10].tests[1].params[1].cp = relative_file;
507	tests[10].tests[1].params[2].vp = cbuf;
508	tests[10].tests[1].params[3].i = PATH_MAX;
509	tests[10].tests[2].result = strlen(absolute_file);
510	tests[10].tests[2].params[0].i = AT_FDCWD;
511	tests[10].tests[2].params[1].cp = symlinkf;
512	tests[10].tests[2].params[2].vp = cbuf;
513	tests[10].tests[2].params[3].i = PATH_MAX;
514
515	// renameat
516	tests[11].syscall = SYS_renameat;
517	tests[11].num_of_cases = 5;
518	tests[11].name = "renameat";
519	tests[11].tests[0].result = EBADF;
520	tests[11].tests[0].params[0].i = 106;	// invalid fd
521	tests[11].tests[0].params[1].cp = file;
522	tests[11].tests[0].params[2].i = rel_fd;
523	tests[11].tests[0].params[3].cp = file;
524	tests[11].tests[1].result = EBADF;
525	tests[11].tests[1].params[0].i = rel_fd;
526	tests[11].tests[1].params[1].cp = file;
527	tests[11].tests[1].params[2].i = 106;	// invalid fd
528	tests[11].tests[1].params[3].cp = file;
529	tests[11].tests[2].result = ENOTDIR;
530	tests[11].tests[2].params[0].i = notd_fd;
531	tests[11].tests[2].params[1].cp = relative_file;
532	tests[11].tests[2].params[2].i = rel_fd;
533	tests[11].tests[2].params[3].cp = file;
534	tests[11].tests[3].result = ENOTDIR;
535	tests[11].tests[3].params[0].i = rel_fd;
536	tests[11].tests[3].params[1].cp = file;
537	tests[11].tests[3].params[2].i = notd_fd;
538	tests[11].tests[3].params[3].cp = relative_file;
539	tests[11].tests[4].result = 0;
540	tests[11].tests[4].params[0].i = rel_fd;
541	tests[11].tests[4].params[1].cp = newfile;
542	tests[11].tests[4].params[2].i = AT_FDCWD;
543	tests[11].tests[4].params[3].cp = newfile;
544
545	// symlinkat
546	tests[12].syscall = SYS_symlinkat;
547	tests[12].num_of_cases = 3;
548	tests[12].name = "symlinkat";
549	tests[12].tests[0].result = EBADF;
550	tests[12].tests[0].params[0].cp = file;
551	tests[12].tests[0].params[1].i = 106;	// invalid fd
552	tests[12].tests[0].params[2].cp = file;
553	tests[12].tests[1].result = ENOTDIR;
554	tests[12].tests[1].params[0].cp = file;
555	tests[12].tests[1].params[1].i = notd_fd;
556	tests[12].tests[1].params[2].cp = relative_file;
557	tests[12].tests[2].result = 0;
558	tests[12].tests[2].params[0].cp = absolute_file;
559	tests[12].tests[2].params[1].i = rel_fd;
560	tests[12].tests[2].params[2].cp = newslink;
561
562	// unlinkat
563	tests[13].syscall = SYS_unlinkat;
564	tests[13].num_of_cases = 7;
565	tests[13].name = "unlinkat";
566	tests[13].tests[0].result = EBADF;
567	tests[13].tests[0].params[0].i = 106;	// invalid fd
568	tests[13].tests[0].params[1].cp = relative_file;
569	tests[13].tests[0].params[2].i = 0;
570	tests[13].tests[1].result = ENOTDIR;
571	tests[13].tests[1].params[0].i = notd_fd;
572	tests[13].tests[1].params[1].cp = relative_file;
573	tests[13].tests[1].params[2].i = 0;
574	tests[13].tests[2].result = EINVAL;
575	tests[13].tests[2].params[0].i = rel_fd;
576	tests[13].tests[2].params[1].cp = file;
577	tests[13].tests[2].params[2].i = 123;	// invalid flag
578	tests[13].tests[3].result = ENOTDIR;
579	tests[13].tests[3].params[0].i = rel_fd;
580	tests[13].tests[3].params[1].cp = not_dir_path;
581	tests[13].tests[3].params[2].i = AT_REMOVEDIR;
582	tests[13].tests[4].result = ENOTEMPTY;
583	tests[13].tests[4].params[0].i = AT_FDCWD;
584	tests[13].tests[4].params[1].cp = relative_path;
585	tests[13].tests[4].params[2].i = AT_REMOVEDIR;
586	tests[13].tests[5].result = 0;
587	tests[13].tests[5].params[0].i = rel_fd;
588	tests[13].tests[5].params[1].cp = newdir;
589	tests[13].tests[5].params[2].i = AT_REMOVEDIR;
590	tests[13].tests[6].result = 0;
591	tests[13].tests[6].params[0].i = AT_FDCWD;
592	tests[13].tests[6].params[1].cp = newfile;
593	tests[13].tests[6].params[2].i = 0;
594
595	// fexecve
596	tests[14].syscall = SYS_fexecve;
597	tests[14].num_of_cases = 2;
598	tests[14].name = "fexecve";
599	tests[14].tests[0].result = EBADF;
600	tests[14].tests[0].params[0].i = 106;	// invalid fd
601	tests[14].tests[0].params[1].cpp = pargv;
602	tests[14].tests[0].params[2].cpp = NULL;
603	// This is EXPECTED to execve /bin/date, so dont expect OK output
604	tests[14].tests[1].result = 0;
605	tests[14].tests[1].params[0].i = exec_fd;
606	tests[14].tests[1].params[1].cpp = pargv;
607	tests[14].tests[1].params[2].cpp = NULL;
608}
609
610void
611cleanup()
612{
613	int error;
614
615	close(notd_fd);
616	close(rel_fd);
617	close(abs_fd);
618
619	if (!file_exist) {
620		error = unlink("tmp/foo");
621		if (error) {
622			perror("unlink");
623			exit(0);
624		}
625	}
626	if (!dir_exist) {
627		error = rmdir(absolute_path);
628		if (error) {
629			perror("rmdir");
630			exit(0);
631		}
632	}
633	if (link_exist) {
634		error = unlink(symlinkf);
635		if (error) {
636			perror("unlink");
637			exit(0);
638		}
639	}
640}
641
642void
643setup_once()
644{
645}
646
647int
648main(int argc, char *argv[])
649{
650	int i,j;
651	int error;
652
653	setup();
654
655	for (i = 0; i < NUM_OF_TESTS; i++) {
656		printf("\nTest: %s\n", tests[i].name);
657		for (j = 0; j < tests[i].num_of_cases; j++) {
658			error = syscall(tests[i].syscall,
659				tests[i].tests[j].params[0],
660				tests[i].tests[j].params[1],
661				tests[i].tests[j].params[2],
662				tests[i].tests[j].params[3],
663				tests[i].tests[j].params[4]);
664			if (error == 0) {
665				if (tests[i].tests[j].result == 0)
666					printf("#%i ... OK\n", j);
667				else {
668					printf("#%i ... BAD: ", j);
669					printf("expected %i, but got %i\n", tests[i].tests[j].result, error);
670				}
671			} else	{
672				if (tests[i].tests[j].result == errno)
673					printf("#%i ... OK\n", j);
674				else {
675					if (error != tests[i].tests[j].result) {
676						printf("#%i ... BAD: ", j);
677						printf("expected %i, but got %i\n", tests[i].tests[j].result, error);
678					} else
679						printf("#%i ... OK\n", j);
680				}
681			}
682
683		}
684	}
685
686
687	return (0);
688}
689