/[meta-cvs]/meta-cvs/F-83F0E6A90D5BBCDFB58440970E850925.c
ViewVC logotype

Contents of /meta-cvs/F-83F0E6A90D5BBCDFB58440970E850925.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide annotations)
Wed Feb 26 03:54:39 2003 UTC (11 years, 1 month ago) by kaz
Branch: MAIN
Changes since 1.12: +4 -2 lines
File MIME type: text/plain
Merging from mcvs-1-0-branch.

* code/unix-bindings/wrap.c (mcvs_spawn): One more waitpid() bug!
The SIGCHLD signal handler was being set in the child process only,
so although we fixed the waitpid() behavior in the CVS child
process, we did not fix it in the Meta-CVS process. The ECHILD
problem was sporadically reproduced by Johannes Grødem on a fast
Athlon machine; it requires CVS to exit before Meta-CVS reaches
the waitpid() call.
1 kaz 1.1 #include <stdio.h>
2 kaz 1.3 #include <stdlib.h>
3 kaz 1.1 #include <string.h>
4     #include <errno.h>
5 kaz 1.11 #include <signal.h>
6 kaz 1.1 #include <dirent.h>
7 kaz 1.3 #include <unistd.h>
8 kaz 1.1 #include <sys/types.h>
9     #include <sys/stat.h>
10 kaz 1.5 #include <sys/wait.h>
11 kaz 1.12 #ifdef __CYGWIN__
12     #include <process.h>
13     #endif
14 kaz 1.1
15     /*
16 kaz 1.2 * Null pointer test
17     */
18    
19 kaz 1.8 int mcvs_null_pointer_p(void *ptr)
20 kaz 1.2 {
21     return ptr == 0;
22     }
23    
24     /*
25 kaz 1.1 * <errno.h> stuff
26     */
27    
28 kaz 1.8 int mcvs_get_errno(void)
29 kaz 1.1 {
30     return errno;
31     }
32    
33 kaz 1.8 int mcvs_set_errno(int value)
34 kaz 1.1 {
35     return errno = value;
36     }
37    
38     /*
39     * <dirent.h> stuff
40     */
41    
42     typedef struct {
43     unsigned long d_ino;
44     char d_name[1024];
45 kaz 1.8 } mcvs_dirent;
46 kaz 1.1
47 kaz 1.8 mcvs_dirent *mcvs_readdir(DIR *dir)
48 kaz 1.1 {
49 kaz 1.8 static mcvs_dirent dw;
50 kaz 1.1 struct dirent *de = readdir(dir);
51     if (de != 0) {
52     strncpy(dw.d_name, de->d_name, sizeof dw.d_name - 1);
53     dw.d_ino = de->d_ino;
54     return &dw;
55     }
56     return 0;
57     }
58    
59     /*
60 kaz 1.4 * <unistd.h> stuff
61     */
62    
63 kaz 1.8 char *mcvs_readlink(const char *path)
64 kaz 1.4 {
65     size_t size = 256;
66     char *str = malloc(size);
67     char *temp;
68    
69     if (str == 0)
70     goto bail;
71    
72     for (;;) {
73     int result = readlink(path, str, size);
74     if (result == -1)
75     goto bail;
76     if (result < size) {
77     str[result] = 0;
78     break;
79     }
80     if (size * 2 < size)
81     goto bail;
82     size *= 2;
83     if ((temp = realloc(str, size)) == 0)
84     goto bail;
85     str = temp;
86     }
87    
88     /* No need to realloc to actual size, since CLISP will free this anyway */
89     return str;
90    
91     bail:
92     free(str);
93     return 0;
94     }
95    
96     /*
97 kaz 1.1 * <sys/stat.h> stuff
98     */
99    
100 kaz 1.8 struct mcvs_stat {
101 kaz 1.1 unsigned long dev;
102     unsigned long ino;
103     unsigned long mode;
104     unsigned int nlink;
105     unsigned int uid;
106     unsigned int gid;
107     unsigned long rdev;
108     unsigned long blksize;
109     unsigned long blocks;
110     unsigned long atime;
111     unsigned long mtime;
112     unsigned long ctime;
113     };
114    
115 kaz 1.8 static void stat_to_wrap(struct mcvs_stat *out, const struct stat *in)
116 kaz 1.1 {
117     out->dev = in->st_dev;
118     out->ino = in->st_ino;
119     out->mode = in->st_mode;
120     out->nlink = in->st_nlink;
121     out->uid = in->st_uid;
122     out->gid = in->st_gid;
123     out->rdev = in->st_rdev;
124     out->blksize = in->st_blksize;
125     out->blocks = in->st_blocks;
126     out->atime = in->st_atime;
127     out->mtime = in->st_mtime;
128     out->ctime = in->st_ctime;
129     }
130    
131     #define IMPL_STAT(FUNC, ARGTYPE) \
132 kaz 1.8 int mcvs_ ## FUNC(ARGTYPE arg, struct mcvs_stat *buf) \
133 kaz 1.1 { \
134     struct stat sbuf; \
135     int retval = FUNC(arg, &sbuf); \
136     if (retval == 0) \
137 kaz 1.8 stat_to_wrap(buf, &sbuf); \
138 kaz 1.1 return retval; \
139     }
140    
141     IMPL_STAT(stat, const char *)
142     IMPL_STAT(lstat, const char *)
143     IMPL_STAT(fstat, int)
144 kaz 1.3
145     /*
146     * <unistd.h> -- getcwd
147     */
148    
149 kaz 1.8 const char *mcvs_getcwd(void)
150 kaz 1.3 {
151     size_t size = 256;
152     char *str = malloc(size);
153     char *temp;
154    
155     if (str == 0)
156     goto bail;
157    
158     while (getcwd(str, size) == 0) {
159 kaz 1.9 if (errno != ERANGE)
160     goto bail;
161 kaz 1.3 if (size * 2 < size)
162     goto bail;
163     size *= 2;
164     if ((temp = realloc(str, size)) == 0)
165     goto bail;
166     str = temp;
167     }
168    
169     /* No need to realloc to actual size, since CLISP will free this anyway */
170     return str;
171    
172     bail:
173     free(str);
174     return 0;
175 kaz 1.5 }
176    
177 kaz 1.12 /*
178     * We need this because CLISP sets it to SIG_IGN, which is
179     * inherited by the exec'd image, and causes the wait()
180     * functions to have behavior that programs don't expect.
181     */
182    
183     void mcvs_default_sigchld()
184     {
185     signal(SIGCHLD, SIG_DFL);
186     }
187    
188 kaz 1.5 /*
189     * <unistd.h> -- fork, wait*, exec*
190     */
191    
192 kaz 1.7 #ifdef __CYGWIN__
193     /*
194 kaz 1.12 * On Cygwin, we have a straightforward alternative to fork exec
195     * and wait, so let's use it.
196 kaz 1.7 */
197    
198 kaz 1.8 int mcvs_spawn(const char *name, const char *const *argv)
199 kaz 1.7 {
200     return spawnvp(_P_WAIT, name, argv);
201     }
202     #else
203 kaz 1.8 int mcvs_spawn(const char *name, char *const *argv)
204 kaz 1.5 {
205 kaz 1.7 int result = -1;
206     int status = 0;
207 kaz 1.13 pid_t child;
208 kaz 1.7
209 kaz 1.13 mcvs_default_sigchld();
210    
211     child = fork();
212 kaz 1.5
213     if (child == -1)
214     goto out;
215    
216     if (child == 0) {
217     execvp(name, argv);
218     _exit(EXIT_FAILURE);
219     }
220    
221 kaz 1.10 do {
222     result = waitpid(child, &status, 0);
223     } while (result == -1 && errno == EINTR);
224    
225     if (result == -1)
226 kaz 1.5 goto out;
227    
228     if (WIFEXITED(status))
229     result = WEXITSTATUS(status);
230    
231     out:
232 kaz 1.6 free((void *) argv);
233 kaz 1.5 return result;
234 kaz 1.3 }
235 kaz 1.7 #endif

  ViewVC Help
Powered by ViewVC 1.1.5