/[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.4.2.6 - (show annotations)
Sun Feb 2 03:31:35 2003 UTC (11 years, 2 months ago) by kaz
Branch: mcvs-1-0-branch
CVS Tags: mcvs-1-0-2
Changes since 1.4.2.5: +5 -1 lines
File MIME type: text/plain
* code/unix-bindings/wrap.c (impl_spawn): Try waitpid again in a loop
while it returns -1, and errno is EINTR.
Reported by Johannes Grødem <johs@copyleft.no>.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <dirent.h>
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <sys/wait.h>
10
11 /*
12 * Null pointer test
13 */
14
15 int mcvs_null_pointer_p(void *ptr)
16 {
17 return ptr == 0;
18 }
19
20 /*
21 * <errno.h> stuff
22 */
23
24 int mcvs_get_errno(void)
25 {
26 return errno;
27 }
28
29 int mcvs_set_errno(int value)
30 {
31 return errno = value;
32 }
33
34 /*
35 * <dirent.h> stuff
36 */
37
38 typedef struct {
39 unsigned long d_ino;
40 char d_name[1024];
41 } mcvs_dirent;
42
43 mcvs_dirent *mcvs_readdir(DIR *dir)
44 {
45 static mcvs_dirent dw;
46 struct dirent *de = readdir(dir);
47 if (de != 0) {
48 strncpy(dw.d_name, de->d_name, sizeof dw.d_name - 1);
49 dw.d_ino = de->d_ino;
50 return &dw;
51 }
52 return 0;
53 }
54
55 /*
56 * <unistd.h> stuff
57 */
58
59 char *mcvs_readlink(const char *path)
60 {
61 size_t size = 256;
62 char *str = malloc(size);
63 char *temp;
64
65 if (str == 0)
66 goto bail;
67
68 for (;;) {
69 int result = readlink(path, str, size);
70 if (result == -1)
71 goto bail;
72 if (result < size) {
73 str[result] = 0;
74 break;
75 }
76 if (size * 2 < size)
77 goto bail;
78 size *= 2;
79 if ((temp = realloc(str, size)) == 0)
80 goto bail;
81 str = temp;
82 }
83
84 /* No need to realloc to actual size, since CLISP will free this anyway */
85 return str;
86
87 bail:
88 free(str);
89 return 0;
90 }
91
92 /*
93 * <sys/stat.h> stuff
94 */
95
96 struct mcvs_stat {
97 unsigned long dev;
98 unsigned long ino;
99 unsigned long mode;
100 unsigned int nlink;
101 unsigned int uid;
102 unsigned int gid;
103 unsigned long rdev;
104 unsigned long blksize;
105 unsigned long blocks;
106 unsigned long atime;
107 unsigned long mtime;
108 unsigned long ctime;
109 };
110
111 static void stat_to_wrap(struct mcvs_stat *out, const struct stat *in)
112 {
113 out->dev = in->st_dev;
114 out->ino = in->st_ino;
115 out->mode = in->st_mode;
116 out->nlink = in->st_nlink;
117 out->uid = in->st_uid;
118 out->gid = in->st_gid;
119 out->rdev = in->st_rdev;
120 out->blksize = in->st_blksize;
121 out->blocks = in->st_blocks;
122 out->atime = in->st_atime;
123 out->mtime = in->st_mtime;
124 out->ctime = in->st_ctime;
125 }
126
127 #define IMPL_STAT(FUNC, ARGTYPE) \
128 int mcvs_ ## FUNC(ARGTYPE arg, struct mcvs_stat *buf) \
129 { \
130 struct stat sbuf; \
131 int retval = FUNC(arg, &sbuf); \
132 if (retval == 0) \
133 stat_to_wrap(buf, &sbuf); \
134 return retval; \
135 }
136
137 IMPL_STAT(stat, const char *)
138 IMPL_STAT(lstat, const char *)
139 IMPL_STAT(fstat, int)
140
141 /*
142 * <unistd.h> -- getcwd
143 */
144
145 const char *mcvs_getcwd(void)
146 {
147 size_t size = 256;
148 char *str = malloc(size);
149 char *temp;
150
151 if (str == 0)
152 goto bail;
153
154 while (getcwd(str, size) == 0) {
155 if (errno != ERANGE)
156 goto bail;
157 if (size * 2 < size)
158 goto bail;
159 size *= 2;
160 if ((temp = realloc(str, size)) == 0)
161 goto bail;
162 str = temp;
163 }
164
165 /* No need to realloc to actual size, since CLISP will free this anyway */
166 return str;
167
168 bail:
169 free(str);
170 return 0;
171 }
172
173 /*
174 * <unistd.h> -- fork, wait*, exec*
175 */
176
177 #ifdef __CYGWIN__
178
179 /*
180 * waitpid is broken garbage on Cygwin, so we use its spawnvp function
181 * instead!
182 */
183
184 #include <process.h>
185 int mcvs_spawn(const char *name, const char *const *argv)
186 {
187 return spawnvp(_P_WAIT, name, argv);
188 }
189 #else
190 int mcvs_spawn(const char *name, char *const *argv)
191 {
192 int result = -1;
193 int status = 0;
194
195 pid_t child = fork();
196
197 if (child == -1)
198 goto out;
199
200 if (child == 0) {
201 execvp(name, argv);
202 _exit(EXIT_FAILURE);
203 }
204
205 do {
206 result = waitpid(child, &status, 0);
207 } while (result == -1 && errno == EINTR);
208
209 if (result == -1)
210 goto out;
211
212 if (WIFEXITED(status))
213 result = WEXITSTATUS(status);
214
215 out:
216 free((void *) argv);
217 return result;
218 }
219 #endif

  ViewVC Help
Powered by ViewVC 1.1.5