1aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier/******************************************************************************
2aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *
3aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   Copyright (c) International Business Machines  Corp., 2006
4aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *
5aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   This program is free software;  you can redistribute it and/or modify
6aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   it under the terms of the GNU General Public License as published by
7aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   the Free Software Foundation; either version 2 of the License, or
8aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   (at your option) any later version.
9aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *
10aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   This program is distributed in the hope that it will be useful,
11aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   the GNU General Public License for more details.
14aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *
15aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   You should have received a copy of the GNU General Public License
16aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *   along with this program;  if not, write to the Free Software
174548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *
19aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier * NAME
20aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *      linkat01.c
21aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *
22aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier * DESCRIPTION
23aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *	This test case will verify basic function of linkat
24aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *	added by kernel 2.6.16 or up.
25aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *
26aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier * USAGE:  <for command-line>
27aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier * linkat01 [-c n] [-e] [-i n] [-I x] [-P x] [-t] [-p]
28aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier * where:
29aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *      -c n : Run n copies simultaneously.
30aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *      -e   : Turn on errno logging.
31aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *      -i n : Execute test n times.
32aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *      -I x : Execute test for x seconds.
33aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *      -p   : Pause for SIGUSR1 before starting
34aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *      -P x : Pause for x seconds between iterations.
35aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *      -t   : Turn on syscall timing.
36aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *
37aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier * Author
384bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak *	Yi Yang <yyangcdl@cn.ibm.com>
39aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *
40aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier * History
41aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *      08/25/2006      Created first by Yi Yang <yyangcdl@cn.ibm.com>
42aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *
43aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier *****************************************************************************/
44aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
45aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#define _GNU_SOURCE
46aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
47aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include <sys/types.h>
48aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include <sys/stat.h>
49aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include <sys/time.h>
50aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include <fcntl.h>
51b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya#include <unistd.h>
52aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include <error.h>
53aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include <stdlib.h>
54aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include <errno.h>
55aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include <string.h>
56aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include <signal.h>
57b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya#include <inttypes.h>
58b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya#include <limits.h>
59aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include "test.h"
60aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#include "linux_syscall_numbers.h"
610f66fc0b825d6f9ad4d6f274dd3b1208bf3aab83Garrett Cooper#include "rmobj.h"
620f66fc0b825d6f9ad4d6f274dd3b1208bf3aab83Garrett Cooper#include "safe_macros.h"
63aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
64aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#ifndef AT_FDCWD
65aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#define AT_FDCWD -100
66aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#endif
67421ddee22abbec348109248d78149a11801b5a60subrata_modak#ifndef AT_SYMLINK_FOLLOW
68421ddee22abbec348109248d78149a11801b5a60subrata_modak#define AT_SYMLINK_FOLLOW 0x400
69aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier#endif
70aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
71421ddee22abbec348109248d78149a11801b5a60subrata_modakstruct test_struct;
72421ddee22abbec348109248d78149a11801b5a60subrata_modakstatic void setup();
73421ddee22abbec348109248d78149a11801b5a60subrata_modakstatic void cleanup();
74421ddee22abbec348109248d78149a11801b5a60subrata_modakstatic void setup_every_copy();
75354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void mylinkat_test(struct test_struct *desc);
76421ddee22abbec348109248d78149a11801b5a60subrata_modak
77421ddee22abbec348109248d78149a11801b5a60subrata_modak#define TEST_DIR1 "olddir"
78421ddee22abbec348109248d78149a11801b5a60subrata_modak#define TEST_DIR2 "newdir"
79421ddee22abbec348109248d78149a11801b5a60subrata_modak#define TEST_DIR3 "deldir"
80421ddee22abbec348109248d78149a11801b5a60subrata_modak#define TEST_FILE1 "oldfile"
81421ddee22abbec348109248d78149a11801b5a60subrata_modak#define TEST_FILE2 "newfile"
82421ddee22abbec348109248d78149a11801b5a60subrata_modak#define TEST_FIFO "fifo"
83421ddee22abbec348109248d78149a11801b5a60subrata_modak
84b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya#define DPATHNAME_FMT	"%s/" TEST_DIR2 "/" TEST_FILE1
85b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya#define SPATHNAME_FMT	"%s/" TEST_DIR1 "/" TEST_FILE1
86b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya
87b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneyastatic char dpathname[PATH_MAX];
88b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneyastatic char spathname[PATH_MAX];
89354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int olddirfd, newdirfd = -1, cwd_fd = AT_FDCWD, stdinfd = 0, badfd =
90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    -1, deldirfd;
91421ddee22abbec348109248d78149a11801b5a60subrata_modak
92421ddee22abbec348109248d78149a11801b5a60subrata_modakstruct test_struct {
93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int *oldfd;
94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	const char *oldfn;
95354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int *newfd;
96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	const char *newfn;
97421ddee22abbec348109248d78149a11801b5a60subrata_modak	int flags;
98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	const char *referencefn1;
99354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	const char *referencefn2;
100421ddee22abbec348109248d78149a11801b5a60subrata_modak	int expected_errno;
101b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya} test_desc[] = {
102b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya	/* 1. relative paths */
103354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &newdirfd, TEST_FILE1, 0,
105354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    TEST_DIR1 "/" TEST_FILE1, TEST_DIR2 "/" TEST_FILE1, 0},
106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 2. abs path at source */
107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, spathname, &newdirfd, TEST_FILE1, 0, 0, 0, 0},
109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 3. abs path at dst */
110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &newdirfd, dpathname, 0,
112354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    TEST_DIR1 "/" TEST_FILE1, TEST_DIR2 "/" TEST_FILE1, 0},
113354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 4. relative paths to cwd */
114354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&cwd_fd, TEST_DIR1 "/" TEST_FILE1, &newdirfd, TEST_FILE1, 0,
116354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    TEST_DIR1 "/" TEST_FILE1, TEST_DIR2 "/" TEST_FILE1, 0},
117354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 5. relative paths to cwd */
118354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
119354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &cwd_fd, TEST_DIR2 "/" TEST_FILE1, 0,
120354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    TEST_DIR1 "/" TEST_FILE1, TEST_DIR2 "/" TEST_FILE1, 0},
121354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 6. abs path at source */
122354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
123354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&cwd_fd, spathname, &newdirfd, TEST_FILE1, 0, 0, 0, 0},
124354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 7. abs path at dst */
125354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
126354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &cwd_fd, dpathname, 0,
127354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    TEST_DIR1 "/" TEST_FILE1, TEST_DIR2 "/" TEST_FILE1, 0},
128354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 8. relative paths to invalid */
129354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&stdinfd, TEST_DIR1 "/" TEST_FILE1, &newdirfd, TEST_FILE1, 0,
131354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    0, 0, ENOTDIR},
132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 9. relative paths to invalid */
133354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
134354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &stdinfd, TEST_DIR2 "/" TEST_FILE1, 0,
135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    0, 0, ENOTDIR},
136354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 10. abs path at source */
137354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
138354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&stdinfd, spathname, &newdirfd, TEST_FILE1, 0, 0, 0, 0},
139354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 11. abs path at dst */
140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
141354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &stdinfd, dpathname, 0,
142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    TEST_DIR1 "/" TEST_FILE1, TEST_DIR2 "/" TEST_FILE1, 0},
143354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 12. relative paths to bad */
144354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
145354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&badfd, TEST_DIR1 "/" TEST_FILE1, &newdirfd, TEST_FILE1, 0,
146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    0, 0, EBADF},
147354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 13. relative paths to bad */
148354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &badfd, TEST_DIR2 "/" TEST_FILE1, 0,
150354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    0, 0, EBADF},
151354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 14. abs path at source */
152354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
153354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&badfd, spathname, &newdirfd, TEST_FILE1, 0, 0, 0, 0},
154354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 15. abs path at dst */
155354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &badfd, dpathname, 0,
157354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    TEST_DIR1 "/" TEST_FILE1, TEST_DIR2 "/" TEST_FILE1, 0},
158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 16. relative paths to deleted */
159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
160354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&deldirfd, TEST_DIR1 "/" TEST_FILE1, &newdirfd, TEST_FILE1, 0,
161354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    0, 0, ENOENT},
162354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 17. relative paths to deleted */
163354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
164354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &deldirfd, TEST_DIR2 "/" TEST_FILE1, 0,
165354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    0, 0, ENOENT},
166354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 18. abs path at source */
167354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
168354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&deldirfd, spathname, &newdirfd, TEST_FILE1, 0, 0, 0, 0},
169354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 19. abs path at dst */
170354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
171354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &deldirfd, dpathname, 0,
172354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    TEST_DIR1 "/" TEST_FILE1, TEST_DIR2 "/" TEST_FILE1, 0},
173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 20. x-device link */
174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
175354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&cwd_fd, "/proc/cpuinfo", &newdirfd, TEST_FILE1, 0, 0, 0, EXDEV},
176354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 21. directory link */
177354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
178354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, ".", &newdirfd, TEST_FILE1, 0, 0, 0, EPERM},
179354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 22. invalid flag */
180354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
181354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	&olddirfd, TEST_FILE1, &newdirfd, TEST_FILE1, 1, 0, 0, EINVAL},
182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* 23. fifo link */
183354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* XXX (garrcoop): Removed because it hangs the overall test. Need to
184354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	     * find a legitimate means to exercise this functionality, if in fact
185354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	     * it's a valid testcase -- which it should be.
186354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	     */
187354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    /* { &olddirfd, TEST_FIFO, &newdirfd, TEST_FILE1, 0,
188354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       TEST_DIR1"/"TEST_FIFO, TEST_DIR2"/"TEST_FILE1, 0 } */
189421ddee22abbec348109248d78149a11801b5a60subrata_modak};
190aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
191b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneyachar *TCID = "linkat01";
192b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneyaint TST_TOTAL = sizeof(test_desc) / sizeof(*test_desc);
193b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya
194b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya#define SUCCEED_OR_DIE(syscall, message, ...)		\
195b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya	(errno = 0,					\
196b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya	 ({int ret=syscall(__VA_ARGS__);		\
197b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya	 if (ret==-1)					\
198b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		tst_brkm(TBROK | TERRNO, cleanup,	\
199b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya			message, __VA_ARGS__);		\
200b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya	 ret; }))
201b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya
202b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneyastatic int mylinkat(int olddirfd, const char *oldfilename, int newdirfd,
203b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		    const char *newfilename, int flags)
204aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier{
205359980f68b19c77c698b121b57a071dfe6e3ca31Jan Stancek	return ltp_syscall(__NR_linkat, olddirfd, oldfilename, newdirfd,
206aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier		       newfilename, flags);
207aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier}
208aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
209aab2ac0d5621a5b0ad031df65793ce579d870aa9vapierint main(int ac, char **av)
210aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier{
21189af32a63ce8a780ea39337339e14caae244b5a4Cyril Hrubis	int lc;
212aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier	int i;
213aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
21456207cec7732e09c216c751c0b5f88a242bacae6subrata_modak	if ((tst_kvercmp(2, 6, 16)) < 0) {
21556207cec7732e09c216c751c0b5f88a242bacae6subrata_modak		tst_resm(TWARN, "This test can only run on kernels that are ");
21656207cec7732e09c216c751c0b5f88a242bacae6subrata_modak		tst_resm(TWARN, "2.6.16 and higher");
21756207cec7732e09c216c751c0b5f88a242bacae6subrata_modak		exit(0);
21856207cec7732e09c216c751c0b5f88a242bacae6subrata_modak	}
219807cfe51ec3e9637aaf19227a231af1cbc18bedfmreed
220d6d11d08678aac1ed2c370ea8e42e5f45aea07beCyril Hrubis	tst_parse_opts(ac, av, NULL, NULL);
221aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
222aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier	setup();
223aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
224aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier	for (lc = 0; TEST_LOOPING(lc); lc++) {
225aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
226d59a659cd639ca2780b00049d102acd2a783d585Caspar Zhang		tst_count = 0;
227aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
228aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier		for (i = 0; i < TST_TOTAL; i++) {
229421ddee22abbec348109248d78149a11801b5a60subrata_modak			setup_every_copy();
230421ddee22abbec348109248d78149a11801b5a60subrata_modak			mylinkat_test(&test_desc[i]);
231aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier		}
232aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
2332c28215423293e443469a07ae7011135d058b671Garrett Cooper	}
234aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
235aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier	cleanup();
2360f66fc0b825d6f9ad4d6f274dd3b1208bf3aab83Garrett Cooper	tst_exit();
2372c28215423293e443469a07ae7011135d058b671Garrett Cooper}
238aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
239c57fba5535abf457e33dd7a986b6c512d95cdef6Mike Frysingerstatic void setup_every_copy(void)
240aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier{
241421ddee22abbec348109248d78149a11801b5a60subrata_modak	close(newdirfd);
242421ddee22abbec348109248d78149a11801b5a60subrata_modak	rmobj(TEST_DIR2, NULL);
243aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
244354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	SUCCEED_OR_DIE(mkdir, "mkdir(%s, %o) failed", TEST_DIR2, 0700);
245b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya	newdirfd = SUCCEED_OR_DIE(open, "open(%s, 0x%x) failed",
246354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				  TEST_DIR2, O_DIRECTORY);
247aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier}
248aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
249354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void mylinkat_test(struct test_struct *desc)
250aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier{
251421ddee22abbec348109248d78149a11801b5a60subrata_modak	int fd;
252421ddee22abbec348109248d78149a11801b5a60subrata_modak
253354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	TEST(mylinkat
254354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	     (*desc->oldfd, desc->oldfn, *desc->newfd, desc->newfn,
255354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	      desc->flags));
256421ddee22abbec348109248d78149a11801b5a60subrata_modak
257421ddee22abbec348109248d78149a11801b5a60subrata_modak	if (TEST_ERRNO == desc->expected_errno) {
258e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis		if (TEST_RETURN == 0 && desc->referencefn1 != NULL) {
259e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			int tnum = rand(), vnum = ~tnum;
260e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			fd = SAFE_OPEN(cleanup, desc->referencefn1,
261e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis				       O_RDWR);
262e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			SAFE_WRITE(cleanup, 1, fd, &tnum, sizeof(tnum));
263e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			SAFE_CLOSE(cleanup, fd);
264e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis
265e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			fd = SAFE_OPEN(cleanup, desc->referencefn2,
266e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis				       O_RDONLY);
267e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			SAFE_READ(cleanup, 1, fd, &vnum, sizeof(vnum));
268e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			SAFE_CLOSE(cleanup, fd);
269e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis
270e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			if (tnum == vnum)
271e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis				tst_resm(TPASS,
272e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis					 "linkat is functionality correct");
273e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			else {
274e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis				tst_resm(TFAIL,
275e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis					 "The link file's content isn't "
276e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis					 "as same as the original file's "
277e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis					 "although linkat returned 0");
278421ddee22abbec348109248d78149a11801b5a60subrata_modak			}
279e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis		} else {
280e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			if (TEST_RETURN == 0)
281e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis				tst_resm(TPASS,
282e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis					 "linkat succeeded as expected");
283e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis			else
284e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis				tst_resm(TPASS | TTERRNO,
285e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis					 "linkat failed as expected");
286e38b961c385192f0d804914b77bd590734b42e75Cyril Hrubis		}
287aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier	} else {
2880f66fc0b825d6f9ad4d6f274dd3b1208bf3aab83Garrett Cooper		if (TEST_RETURN == 0)
2890f66fc0b825d6f9ad4d6f274dd3b1208bf3aab83Garrett Cooper			tst_resm(TFAIL, "linkat succeeded unexpectedly");
2900f66fc0b825d6f9ad4d6f274dd3b1208bf3aab83Garrett Cooper		else
291354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			tst_resm(TFAIL | TTERRNO,
292354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 "linkat failed unexpectedly; expected %d - %s",
293354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 desc->expected_errno,
294354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 strerror(desc->expected_errno));
295aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier	}
296aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier}
297aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
298c57fba5535abf457e33dd7a986b6c512d95cdef6Mike Frysingervoid setup(void)
299aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier{
300b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya	char *cwd;
301aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
302aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier	tst_sig(NOFORK, DEF_HANDLER, cleanup);
303aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
304421ddee22abbec348109248d78149a11801b5a60subrata_modak	tst_tmpdir();
305421ddee22abbec348109248d78149a11801b5a60subrata_modak
306b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya	cwd = get_current_dir_name();
3070f66fc0b825d6f9ad4d6f274dd3b1208bf3aab83Garrett Cooper	if (cwd == NULL)
308354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_brkm(TFAIL | TERRNO, cleanup,
309354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 "Failed to get current working directory");
3100f66fc0b825d6f9ad4d6f274dd3b1208bf3aab83Garrett Cooper	else {
311b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya
312b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		SUCCEED_OR_DIE(mkdir, "mkdir(%s, %o) failed", TEST_DIR1, 0700);
313b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		SUCCEED_OR_DIE(mkdir, "mkdir(%s, %o) failed", TEST_DIR3, 0700);
314b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		olddirfd = SUCCEED_OR_DIE(open, "open(%s, 0x%x) failed",
315354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					  TEST_DIR1, O_DIRECTORY);
316b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		deldirfd = SUCCEED_OR_DIE(open, "open(%s, 0x%x) failed",
317354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					  TEST_DIR3, O_DIRECTORY);
318b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		SUCCEED_OR_DIE(rmdir, "rmdir(%s) failed", TEST_DIR3);
319b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		SUCCEED_OR_DIE(close, "close(%d) failed",
320354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       SUCCEED_OR_DIE(open, "open(%s, 0x%x, %o) "
321354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					      "failed",
322354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					      TEST_DIR1 "/" TEST_FILE1,
323354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao					      O_CREAT | O_EXCL, 0600));
324421ddee22abbec348109248d78149a11801b5a60subrata_modak
325b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		SUCCEED_OR_DIE(mkfifo, "mkfifo(%s, %o) failed",
326354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       TEST_DIR1 "/" TEST_FIFO, 0600);
327421ddee22abbec348109248d78149a11801b5a60subrata_modak
328b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		snprintf(dpathname, sizeof(dpathname), DPATHNAME_FMT, cwd);
329b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		snprintf(spathname, sizeof(spathname), SPATHNAME_FMT, cwd);
330421ddee22abbec348109248d78149a11801b5a60subrata_modak
331b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		free(cwd);
332b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya
333b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya		TEST_PAUSE;
334b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya
335b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneya	}
3369c199afb1e4abe2d55bd608a06dba3cf52677cb7subrata_modak
3372c28215423293e443469a07ae7011135d058b671Garrett Cooper}
338aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier
339b15e55e23c24cd34c1e2fc6b3a738a3859d3c5e8yaberauneyastatic void cleanup(void)
340aab2ac0d5621a5b0ad031df65793ce579d870aa9vapier{
341421ddee22abbec348109248d78149a11801b5a60subrata_modak	tst_rmdir();
3420f66fc0b825d6f9ad4d6f274dd3b1208bf3aab83Garrett Cooper}
343