/[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.10 - (hide annotations)
Sun Feb 2 19:38:12 2003 UTC (11 years, 2 months ago) by kaz
Branch: MAIN
Changes since 1.9: +5 -1 lines
File MIME type: text/plain
Merging from mcvs-1-0-branch.

* 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 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     #include <dirent.h>
6 kaz 1.3 #include <unistd.h>
7 kaz 1.1 #include <sys/types.h>
8     #include <sys/stat.h>
9 kaz 1.5 #include <sys/wait.h>
10 kaz 1.1
11     /*
12 kaz 1.2 * Null pointer test
13     */
14    
15 kaz 1.8 int mcvs_null_pointer_p(void *ptr)
16 kaz 1.2 {
17     return ptr == 0;
18     }
19    
20     /*
21 kaz 1.1 * <errno.h> stuff
22     */
23    
24 kaz 1.8 int mcvs_get_errno(void)
25 kaz 1.1 {
26     return errno;
27     }
28    
29 kaz 1.8 int mcvs_set_errno(int value)
30 kaz 1.1 {
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 kaz 1.8 } mcvs_dirent;
42 kaz 1.1
43 kaz 1.8 mcvs_dirent *mcvs_readdir(DIR *dir)
44 kaz 1.1 {
45 kaz 1.8 static mcvs_dirent dw;
46 kaz 1.1 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 kaz 1.4 * <unistd.h> stuff
57     */
58    
59 kaz 1.8 char *mcvs_readlink(const char *path)
60 kaz 1.4 {
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 kaz 1.1 * <sys/stat.h> stuff
94     */
95    
96 kaz 1.8 struct mcvs_stat {
97 kaz 1.1 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 kaz 1.8 static void stat_to_wrap(struct mcvs_stat *out, const struct stat *in)
112 kaz 1.1 {
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 kaz 1.8 int mcvs_ ## FUNC(ARGTYPE arg, struct mcvs_stat *buf) \
129 kaz 1.1 { \
130     struct stat sbuf; \
131     int retval = FUNC(arg, &sbuf); \
132     if (retval == 0) \
133 kaz 1.8 stat_to_wrap(buf, &sbuf); \
134 kaz 1.1 return retval; \
135     }
136    
137     IMPL_STAT(stat, const char *)
138     IMPL_STAT(lstat, const char *)
139     IMPL_STAT(fstat, int)
140 kaz 1.3
141     /*
142     * <unistd.h> -- getcwd
143     */
144    
145 kaz 1.8 const char *mcvs_getcwd(void)
146 kaz 1.3 {
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 kaz 1.9 if (errno != ERANGE)
156     goto bail;
157 kaz 1.3 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 kaz 1.5 }
172    
173     /*
174     * <unistd.h> -- fork, wait*, exec*
175     */
176    
177 kaz 1.7 #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 kaz 1.8 int mcvs_spawn(const char *name, const char *const *argv)
186 kaz 1.7 {
187     return spawnvp(_P_WAIT, name, argv);
188     }
189     #else
190 kaz 1.8 int mcvs_spawn(const char *name, char *const *argv)
191 kaz 1.5 {
192 kaz 1.7 int result = -1;
193     int status = 0;
194    
195 kaz 1.5 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 kaz 1.10 do {
206     result = waitpid(child, &status, 0);
207     } while (result == -1 && errno == EINTR);
208    
209     if (result == -1)
210 kaz 1.5 goto out;
211    
212     if (WIFEXITED(status))
213     result = WEXITSTATUS(status);
214    
215     out:
216 kaz 1.6 free((void *) argv);
217 kaz 1.5 return result;
218 kaz 1.3 }
219 kaz 1.7 #endif

  ViewVC Help
Powered by ViewVC 1.1.5