*** empty log message ***
[arla.git] / tests / rename-under-feet.c
blob0e516344e3d47eac5ce2585edb12a8fd2ea5b11e
1 /*
2 * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <errno.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <sys/wait.h>
46 #include <unistd.h>
47 #include <dirent.h>
49 #include <roken.h>
51 #include <err.h>
53 RCSID("$Id$");
55 static void
56 emkdir (const char *path, mode_t mode)
58 int ret = mkdir (path, mode);
59 if (ret < 0)
60 err (1, "mkdir %s", path);
63 static pid_t child_pid;
65 static sig_atomic_t term_sig = 0;
67 static RETSIGTYPE
68 child_sigterm (int signo)
70 term_sig = 1;
73 static int
74 child_chdir (const char *path)
76 int ret;
77 int pfd[2];
79 ret = pipe (pfd);
80 if (ret < 0)
81 err (1, "pipe");
83 child_pid = fork ();
84 if (child_pid < 0)
85 err (1, "fork");
86 if (child_pid != 0) {
87 close (pfd[1]);
88 return pfd[0];
89 } else {
90 char buf[256];
91 struct sigaction sa;
92 FILE *fp;
94 sa.sa_handler = child_sigterm;
95 sigfillset(&sa.sa_mask);
96 sa.sa_flags = 0;
97 sigaction (SIGTERM, &sa, NULL);
99 close (pfd[0]);
100 ret = chdir (path);
101 if (ret < 0)
102 err (1, "chdir %s", path);
103 ret = write (pfd[1], "", 1);
104 if (ret != 1)
105 err (1, "write");
106 while (!term_sig)
107 pause ();
108 if(getcwd (buf, sizeof(buf)) == NULL)
109 err (1, "getcwd");
110 fp = fdopen (4, "w");
111 if (fp != NULL)
112 fprintf (fp, "child: cwd = %s\n", buf);
113 exit (0);
117 static void
118 kill_child (void)
120 kill (child_pid, SIGTERM);
124 main (int argc, char **argv)
126 struct stat sb;
127 int ret;
128 int fd;
129 char buf[1];
130 int status;
132 setprogname (argv[0]);
134 emkdir ("one", 0777);
135 emkdir ("two", 0777);
136 emkdir ("one/a", 0777);
138 fd = child_chdir ("one/a");
139 atexit (kill_child);
140 ret = read (fd, buf, 1);
141 if (ret < 0)
142 err(1, "read");
143 if (ret == 0)
144 errx(1, "EOF on read");
146 ret = rename ("one/a", "two/a");
147 if (ret < 0)
148 err (1, "rename one/a two");
149 ret = lstat ("two/a", &sb);
150 if (ret < 0)
151 err (1, "lstat two/a");
152 ret = lstat ("one/a", &sb);
153 if (ret != -1 || errno != ENOENT)
154 errx (1, "one/a still exists");
155 kill_child ();
156 waitpid (child_pid, &status, 0);
157 ret = lstat ("one/a", &sb);
158 if (ret != -1 || errno != ENOENT)
159 errx (1, "one/a still exists after child");
160 if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
161 return 0;
162 else
163 return 1;