1*b30d1939SAndy Fiddaman #pragma prototyped noticed
2*b30d1939SAndy Fiddaman
3*b30d1939SAndy Fiddaman /*
4*b30d1939SAndy Fiddaman * workarounds to bring the native interface close to posix and x/open
5*b30d1939SAndy Fiddaman */
6*b30d1939SAndy Fiddaman
7*b30d1939SAndy Fiddaman #if defined(__STDPP__directive) && defined(__STDPP__hide)
8*b30d1939SAndy Fiddaman __STDPP__directive pragma pp:hide utime utimes
9*b30d1939SAndy Fiddaman #else
10*b30d1939SAndy Fiddaman #define utime ______utime
11*b30d1939SAndy Fiddaman #define utimes ______utimes
12*b30d1939SAndy Fiddaman #endif
13*b30d1939SAndy Fiddaman
14*b30d1939SAndy Fiddaman #include <ast.h>
15*b30d1939SAndy Fiddaman #include <error.h>
16*b30d1939SAndy Fiddaman #include <tm.h>
17*b30d1939SAndy Fiddaman
18*b30d1939SAndy Fiddaman #include "FEATURE/omitted"
19*b30d1939SAndy Fiddaman
20*b30d1939SAndy Fiddaman #undef OMITTED
21*b30d1939SAndy Fiddaman
22*b30d1939SAndy Fiddaman #if _win32_botch
23*b30d1939SAndy Fiddaman
24*b30d1939SAndy Fiddaman #define OMITTED 1
25*b30d1939SAndy Fiddaman
26*b30d1939SAndy Fiddaman #include <ls.h>
27*b30d1939SAndy Fiddaman #include <utime.h>
28*b30d1939SAndy Fiddaman
29*b30d1939SAndy Fiddaman #if __CYGWIN__
30*b30d1939SAndy Fiddaman #include <ast_windows.h>
31*b30d1939SAndy Fiddaman #if _win32_botch_execve || _lib_spawn_mode
32*b30d1939SAndy Fiddaman #define CONVERT 1
33*b30d1939SAndy Fiddaman #endif
34*b30d1939SAndy Fiddaman #endif
35*b30d1939SAndy Fiddaman
36*b30d1939SAndy Fiddaman #if defined(__STDPP__directive) && defined(__STDPP__hide)
37*b30d1939SAndy Fiddaman __STDPP__directive pragma pp:nohide utime utimes
38*b30d1939SAndy Fiddaman #else
39*b30d1939SAndy Fiddaman #undef utime
40*b30d1939SAndy Fiddaman #undef utimes
41*b30d1939SAndy Fiddaman #endif
42*b30d1939SAndy Fiddaman
43*b30d1939SAndy Fiddaman #ifndef MAX_PATH
44*b30d1939SAndy Fiddaman #define MAX_PATH PATH_MAX
45*b30d1939SAndy Fiddaman #endif
46*b30d1939SAndy Fiddaman
47*b30d1939SAndy Fiddaman /*
48*b30d1939SAndy Fiddaman * these workarounds assume each system call foo() has a _foo() entry
49*b30d1939SAndy Fiddaman * which is true for __CYGWIN__ and __EMX__ (both gnu based)
50*b30d1939SAndy Fiddaman *
51*b30d1939SAndy Fiddaman * the workarounds handle:
52*b30d1939SAndy Fiddaman *
53*b30d1939SAndy Fiddaman * (1) .exe suffix inconsistencies
54*b30d1939SAndy Fiddaman * (2) /bin/sh reference in execve() and spawnve()
55*b30d1939SAndy Fiddaman * (3) bogus getpagesize() return values
56*b30d1939SAndy Fiddaman * (4) a fork() bug that screws up shell fork()+script
57*b30d1939SAndy Fiddaman *
58*b30d1939SAndy Fiddaman * NOTE: Not all workarounds can be handled by unix syscall intercepts.
59*b30d1939SAndy Fiddaman * In particular, { ksh nmake } have workarounds for case-ignorant
60*b30d1939SAndy Fiddaman * filesystems and { libast } has workarounds for win32 locale info.
61*b30d1939SAndy Fiddaman */
62*b30d1939SAndy Fiddaman
63*b30d1939SAndy Fiddaman #undef _pathconf
64*b30d1939SAndy Fiddaman #undef pathconf
65*b30d1939SAndy Fiddaman #undef stat
66*b30d1939SAndy Fiddaman
67*b30d1939SAndy Fiddaman extern int _access(const char*, int);
68*b30d1939SAndy Fiddaman extern unsigned int _alarm(unsigned int);
69*b30d1939SAndy Fiddaman extern int _chmod(const char*, mode_t);
70*b30d1939SAndy Fiddaman extern int _close(int);
71*b30d1939SAndy Fiddaman extern pid_t _execve(const char*, char* const*, char* const*);
72*b30d1939SAndy Fiddaman extern uid_t _getuid(void);
73*b30d1939SAndy Fiddaman extern int _link(const char*, const char*);
74*b30d1939SAndy Fiddaman extern int _open(const char*, int, ...);
75*b30d1939SAndy Fiddaman extern long _pathconf(const char*, int);
76*b30d1939SAndy Fiddaman extern ssize_t _read(int, void*, size_t);
77*b30d1939SAndy Fiddaman extern int _rename(const char*, const char*);
78*b30d1939SAndy Fiddaman extern pid_t _spawnve(int, const char*, char* const*, char* const*);
79*b30d1939SAndy Fiddaman extern int _stat(const char*, struct stat*);
80*b30d1939SAndy Fiddaman extern int _unlink(const char*);
81*b30d1939SAndy Fiddaman extern int _utime(const char*, const struct utimbuf*);
82*b30d1939SAndy Fiddaman extern int _utimes(const char*, const struct timeval*);
83*b30d1939SAndy Fiddaman extern ssize_t _write(int, const void*, size_t);
84*b30d1939SAndy Fiddaman
85*b30d1939SAndy Fiddaman #if defined(__EXPORT__)
86*b30d1939SAndy Fiddaman #define extern __EXPORT__
87*b30d1939SAndy Fiddaman #endif
88*b30d1939SAndy Fiddaman
89*b30d1939SAndy Fiddaman #if _win32_botch_access
90*b30d1939SAndy Fiddaman #define sysaccess _access
91*b30d1939SAndy Fiddaman #else
92*b30d1939SAndy Fiddaman #define sysaccess access
93*b30d1939SAndy Fiddaman #endif
94*b30d1939SAndy Fiddaman #if _win32_botch_alarm
95*b30d1939SAndy Fiddaman #define sysalarm _alarm
96*b30d1939SAndy Fiddaman #else
97*b30d1939SAndy Fiddaman #define sysalarm alarm
98*b30d1939SAndy Fiddaman #endif
99*b30d1939SAndy Fiddaman #if _win32_botch_chmod
100*b30d1939SAndy Fiddaman #define syschmod _chmod
101*b30d1939SAndy Fiddaman #else
102*b30d1939SAndy Fiddaman #define syschmod chmod
103*b30d1939SAndy Fiddaman #endif
104*b30d1939SAndy Fiddaman #if _win32_botch_copy
105*b30d1939SAndy Fiddaman #define sysclose _close
106*b30d1939SAndy Fiddaman #else
107*b30d1939SAndy Fiddaman #define sysclose close
108*b30d1939SAndy Fiddaman #endif
109*b30d1939SAndy Fiddaman #if _win32_botch_execve || _lib_spawn_mode
110*b30d1939SAndy Fiddaman #define sysexecve _execve
111*b30d1939SAndy Fiddaman #else
112*b30d1939SAndy Fiddaman #define sysexecve execve
113*b30d1939SAndy Fiddaman #endif
114*b30d1939SAndy Fiddaman #if CONVERT
115*b30d1939SAndy Fiddaman #define sysgetuid _getuid
116*b30d1939SAndy Fiddaman #else
117*b30d1939SAndy Fiddaman #define sysgetuid getuid
118*b30d1939SAndy Fiddaman #endif
119*b30d1939SAndy Fiddaman #if _win32_botch_link
120*b30d1939SAndy Fiddaman #define syslink _link
121*b30d1939SAndy Fiddaman #else
122*b30d1939SAndy Fiddaman #define syslink link
123*b30d1939SAndy Fiddaman #endif
124*b30d1939SAndy Fiddaman #if _win32_botch_open || _win32_botch_copy
125*b30d1939SAndy Fiddaman #define sysopen _open
126*b30d1939SAndy Fiddaman #else
127*b30d1939SAndy Fiddaman #define sysopen open
128*b30d1939SAndy Fiddaman #endif
129*b30d1939SAndy Fiddaman #if _win32_botch_pathconf
130*b30d1939SAndy Fiddaman #define syspathconf _pathconf
131*b30d1939SAndy Fiddaman #else
132*b30d1939SAndy Fiddaman #define syspathconf pathconf
133*b30d1939SAndy Fiddaman #endif
134*b30d1939SAndy Fiddaman #define sysread _read
135*b30d1939SAndy Fiddaman #if _win32_botch_rename
136*b30d1939SAndy Fiddaman #define sysrename _rename
137*b30d1939SAndy Fiddaman #else
138*b30d1939SAndy Fiddaman #define sysrename rename
139*b30d1939SAndy Fiddaman #endif
140*b30d1939SAndy Fiddaman #if _lib_spawn_mode
141*b30d1939SAndy Fiddaman #define sysspawnve _spawnve
142*b30d1939SAndy Fiddaman #else
143*b30d1939SAndy Fiddaman #define sysspawnve spawnve
144*b30d1939SAndy Fiddaman #endif
145*b30d1939SAndy Fiddaman #if _win32_botch_stat
146*b30d1939SAndy Fiddaman #define sysstat _stat
147*b30d1939SAndy Fiddaman #else
148*b30d1939SAndy Fiddaman #define sysstat stat
149*b30d1939SAndy Fiddaman #endif
150*b30d1939SAndy Fiddaman #if _win32_botch_truncate
151*b30d1939SAndy Fiddaman #define systruncate _truncate
152*b30d1939SAndy Fiddaman #else
153*b30d1939SAndy Fiddaman #define systruncate truncate
154*b30d1939SAndy Fiddaman #endif
155*b30d1939SAndy Fiddaman #if _win32_botch_unlink
156*b30d1939SAndy Fiddaman #define sysunlink _unlink
157*b30d1939SAndy Fiddaman #else
158*b30d1939SAndy Fiddaman #define sysunlink unlink
159*b30d1939SAndy Fiddaman #endif
160*b30d1939SAndy Fiddaman #if _win32_botch_utime
161*b30d1939SAndy Fiddaman #define sysutime _utime
162*b30d1939SAndy Fiddaman #define sysutimes _utimes
163*b30d1939SAndy Fiddaman #else
164*b30d1939SAndy Fiddaman #define sysutime utime
165*b30d1939SAndy Fiddaman #define sysutimes utimes
166*b30d1939SAndy Fiddaman #endif
167*b30d1939SAndy Fiddaman #if _win32_botch_copy
168*b30d1939SAndy Fiddaman #define syswrite _write
169*b30d1939SAndy Fiddaman #else
170*b30d1939SAndy Fiddaman #define syswrite write
171*b30d1939SAndy Fiddaman #endif
172*b30d1939SAndy Fiddaman
173*b30d1939SAndy Fiddaman static char*
suffix(register const char * path)174*b30d1939SAndy Fiddaman suffix(register const char* path)
175*b30d1939SAndy Fiddaman {
176*b30d1939SAndy Fiddaman register const char* s = path + strlen(path);
177*b30d1939SAndy Fiddaman register int c;
178*b30d1939SAndy Fiddaman
179*b30d1939SAndy Fiddaman while (s > path)
180*b30d1939SAndy Fiddaman if ((c = *--s) == '.')
181*b30d1939SAndy Fiddaman return (char*)s + 1;
182*b30d1939SAndy Fiddaman else if (c == '/' || c == '\\')
183*b30d1939SAndy Fiddaman break;
184*b30d1939SAndy Fiddaman return 0;
185*b30d1939SAndy Fiddaman }
186*b30d1939SAndy Fiddaman
187*b30d1939SAndy Fiddaman static int
execrate(const char * path,char * buf,int size,int physical)188*b30d1939SAndy Fiddaman execrate(const char* path, char* buf, int size, int physical)
189*b30d1939SAndy Fiddaman {
190*b30d1939SAndy Fiddaman char* s;
191*b30d1939SAndy Fiddaman int n;
192*b30d1939SAndy Fiddaman int oerrno;
193*b30d1939SAndy Fiddaman
194*b30d1939SAndy Fiddaman if (suffix(path))
195*b30d1939SAndy Fiddaman return 0;
196*b30d1939SAndy Fiddaman oerrno = errno;
197*b30d1939SAndy Fiddaman if (physical || strlen(path) >= size || !(s = pathcanon(strcpy(buf, path), size, PATH_PHYSICAL|PATH_DOTDOT|PATH_EXISTS)))
198*b30d1939SAndy Fiddaman snprintf(buf, size, "%s.exe", path);
199*b30d1939SAndy Fiddaman else if (!suffix(buf) && ((buf + size) - s) >= 4)
200*b30d1939SAndy Fiddaman strcpy(s, ".exe");
201*b30d1939SAndy Fiddaman errno = oerrno;
202*b30d1939SAndy Fiddaman return 1;
203*b30d1939SAndy Fiddaman }
204*b30d1939SAndy Fiddaman
205*b30d1939SAndy Fiddaman /*
206*b30d1939SAndy Fiddaman * return 0 if path is magic, -1 otherwise
207*b30d1939SAndy Fiddaman * ux!=0 set to 1 if path is unix executable
208*b30d1939SAndy Fiddaman * ux!=0 also retains errno for -1 return
209*b30d1939SAndy Fiddaman */
210*b30d1939SAndy Fiddaman
211*b30d1939SAndy Fiddaman static int
magic(const char * path,int * ux)212*b30d1939SAndy Fiddaman magic(const char* path, int* ux)
213*b30d1939SAndy Fiddaman {
214*b30d1939SAndy Fiddaman int fd;
215*b30d1939SAndy Fiddaman int r;
216*b30d1939SAndy Fiddaman int n;
217*b30d1939SAndy Fiddaman int m;
218*b30d1939SAndy Fiddaman int oerrno;
219*b30d1939SAndy Fiddaman #if CONVERT
220*b30d1939SAndy Fiddaman unsigned char buf[512];
221*b30d1939SAndy Fiddaman #else
222*b30d1939SAndy Fiddaman unsigned char buf[2];
223*b30d1939SAndy Fiddaman #endif
224*b30d1939SAndy Fiddaman
225*b30d1939SAndy Fiddaman oerrno = errno;
226*b30d1939SAndy Fiddaman if ((fd = sysopen(path, O_RDONLY, 0)) >= 0)
227*b30d1939SAndy Fiddaman {
228*b30d1939SAndy Fiddaman #if CONVERT
229*b30d1939SAndy Fiddaman if (ux)
230*b30d1939SAndy Fiddaman n = sizeof(buf);
231*b30d1939SAndy Fiddaman else
232*b30d1939SAndy Fiddaman #endif
233*b30d1939SAndy Fiddaman n = 2;
234*b30d1939SAndy Fiddaman r = (m = sysread(fd, buf, n)) >= 2 && (buf[1] == 0x5a && (buf[0] == 0x4c || buf[0] == 0x4d) || ux && buf[0] == '#' && buf[1] == '!' && (*ux = 1) && !(ux = 0)) ? 0 : -1;
235*b30d1939SAndy Fiddaman sysclose(fd);
236*b30d1939SAndy Fiddaman if (ux)
237*b30d1939SAndy Fiddaman {
238*b30d1939SAndy Fiddaman if (r)
239*b30d1939SAndy Fiddaman oerrno = ENOEXEC;
240*b30d1939SAndy Fiddaman else if (m > 61 && (n = buf[60] | (buf[61]<<8) + 92) < (m - 1))
241*b30d1939SAndy Fiddaman *ux = (buf[n] | (buf[n+1]<<8)) == 3;
242*b30d1939SAndy Fiddaman else
243*b30d1939SAndy Fiddaman *ux = 0;
244*b30d1939SAndy Fiddaman }
245*b30d1939SAndy Fiddaman }
246*b30d1939SAndy Fiddaman else if (!ux)
247*b30d1939SAndy Fiddaman r = -1;
248*b30d1939SAndy Fiddaman else if (errno == ENOENT)
249*b30d1939SAndy Fiddaman {
250*b30d1939SAndy Fiddaman oerrno = errno;
251*b30d1939SAndy Fiddaman r = -1;
252*b30d1939SAndy Fiddaman }
253*b30d1939SAndy Fiddaman else
254*b30d1939SAndy Fiddaman {
255*b30d1939SAndy Fiddaman r = 0;
256*b30d1939SAndy Fiddaman *ux = 0;
257*b30d1939SAndy Fiddaman }
258*b30d1939SAndy Fiddaman errno = oerrno;
259*b30d1939SAndy Fiddaman return r;
260*b30d1939SAndy Fiddaman }
261*b30d1939SAndy Fiddaman
262*b30d1939SAndy Fiddaman #if _win32_botch_access
263*b30d1939SAndy Fiddaman
264*b30d1939SAndy Fiddaman extern int
access(const char * path,int op)265*b30d1939SAndy Fiddaman access(const char* path, int op)
266*b30d1939SAndy Fiddaman {
267*b30d1939SAndy Fiddaman int r;
268*b30d1939SAndy Fiddaman int oerrno;
269*b30d1939SAndy Fiddaman char buf[PATH_MAX];
270*b30d1939SAndy Fiddaman
271*b30d1939SAndy Fiddaman oerrno = errno;
272*b30d1939SAndy Fiddaman if ((r = sysaccess(path, op)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
273*b30d1939SAndy Fiddaman {
274*b30d1939SAndy Fiddaman errno = oerrno;
275*b30d1939SAndy Fiddaman r = sysaccess(buf, op);
276*b30d1939SAndy Fiddaman }
277*b30d1939SAndy Fiddaman return r;
278*b30d1939SAndy Fiddaman }
279*b30d1939SAndy Fiddaman
280*b30d1939SAndy Fiddaman #endif
281*b30d1939SAndy Fiddaman
282*b30d1939SAndy Fiddaman #if _win32_botch_alarm
283*b30d1939SAndy Fiddaman
284*b30d1939SAndy Fiddaman extern unsigned int
alarm(unsigned int s)285*b30d1939SAndy Fiddaman alarm(unsigned int s)
286*b30d1939SAndy Fiddaman {
287*b30d1939SAndy Fiddaman unsigned int n;
288*b30d1939SAndy Fiddaman unsigned int r;
289*b30d1939SAndy Fiddaman
290*b30d1939SAndy Fiddaman static unsigned int a;
291*b30d1939SAndy Fiddaman
292*b30d1939SAndy Fiddaman n = (unsigned int)time(NiL);
293*b30d1939SAndy Fiddaman if (a <= n)
294*b30d1939SAndy Fiddaman r = 0;
295*b30d1939SAndy Fiddaman else
296*b30d1939SAndy Fiddaman r = a - n;
297*b30d1939SAndy Fiddaman a = n + s - 1;
298*b30d1939SAndy Fiddaman (void)sysalarm(s);
299*b30d1939SAndy Fiddaman return r;
300*b30d1939SAndy Fiddaman }
301*b30d1939SAndy Fiddaman
302*b30d1939SAndy Fiddaman #endif
303*b30d1939SAndy Fiddaman
304*b30d1939SAndy Fiddaman #if _win32_botch_chmod
305*b30d1939SAndy Fiddaman
306*b30d1939SAndy Fiddaman extern int
chmod(const char * path,mode_t mode)307*b30d1939SAndy Fiddaman chmod(const char* path, mode_t mode)
308*b30d1939SAndy Fiddaman {
309*b30d1939SAndy Fiddaman int r;
310*b30d1939SAndy Fiddaman int oerrno;
311*b30d1939SAndy Fiddaman char buf[PATH_MAX];
312*b30d1939SAndy Fiddaman
313*b30d1939SAndy Fiddaman if ((r = syschmod(path, mode)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
314*b30d1939SAndy Fiddaman {
315*b30d1939SAndy Fiddaman errno = oerrno;
316*b30d1939SAndy Fiddaman return syschmod(buf, mode);
317*b30d1939SAndy Fiddaman }
318*b30d1939SAndy Fiddaman if (!(r = syschmod(path, mode)) &&
319*b30d1939SAndy Fiddaman (mode & (S_IXUSR|S_IXGRP|S_IXOTH)) &&
320*b30d1939SAndy Fiddaman !suffix(path) &&
321*b30d1939SAndy Fiddaman (strlen(path) + 4) < sizeof(buf))
322*b30d1939SAndy Fiddaman {
323*b30d1939SAndy Fiddaman oerrno = errno;
324*b30d1939SAndy Fiddaman if (!magic(path, NiL))
325*b30d1939SAndy Fiddaman {
326*b30d1939SAndy Fiddaman snprintf(buf, sizeof(buf), "%s.exe", path);
327*b30d1939SAndy Fiddaman sysrename(path, buf);
328*b30d1939SAndy Fiddaman }
329*b30d1939SAndy Fiddaman errno = oerrno;
330*b30d1939SAndy Fiddaman }
331*b30d1939SAndy Fiddaman return r;
332*b30d1939SAndy Fiddaman }
333*b30d1939SAndy Fiddaman
334*b30d1939SAndy Fiddaman #endif
335*b30d1939SAndy Fiddaman
336*b30d1939SAndy Fiddaman #if _win32_botch_execve || _lib_spawn_mode
337*b30d1939SAndy Fiddaman
338*b30d1939SAndy Fiddaman #if _lib_spawn_mode
339*b30d1939SAndy Fiddaman
340*b30d1939SAndy Fiddaman /*
341*b30d1939SAndy Fiddaman * can anyone get const prototype args straight?
342*b30d1939SAndy Fiddaman */
343*b30d1939SAndy Fiddaman
344*b30d1939SAndy Fiddaman #define execve ______execve
345*b30d1939SAndy Fiddaman #define spawnve ______spawnve
346*b30d1939SAndy Fiddaman
347*b30d1939SAndy Fiddaman #include <process.h>
348*b30d1939SAndy Fiddaman
349*b30d1939SAndy Fiddaman #undef execve
350*b30d1939SAndy Fiddaman #undef spawnve
351*b30d1939SAndy Fiddaman
352*b30d1939SAndy Fiddaman #endif
353*b30d1939SAndy Fiddaman
354*b30d1939SAndy Fiddaman #if CONVERT
355*b30d1939SAndy Fiddaman
356*b30d1939SAndy Fiddaman /*
357*b30d1939SAndy Fiddaman * this intercept converts dos env vars to unix
358*b30d1939SAndy Fiddaman * we'd rather intercept main but can't twist cc to do it
359*b30d1939SAndy Fiddaman * getuid() gets ksh to do the right thing and
360*b30d1939SAndy Fiddaman * that's our main concern
361*b30d1939SAndy Fiddaman *
362*b30d1939SAndy Fiddaman * DOSPATHVARS='a b c' convert { a b c }
363*b30d1939SAndy Fiddaman */
364*b30d1939SAndy Fiddaman
365*b30d1939SAndy Fiddaman static int convertinit;
366*b30d1939SAndy Fiddaman
367*b30d1939SAndy Fiddaman /*
368*b30d1939SAndy Fiddaman * convertvars[0] names the list of env var names
369*b30d1939SAndy Fiddaman * convertvars[i] are not converted
370*b30d1939SAndy Fiddaman */
371*b30d1939SAndy Fiddaman
372*b30d1939SAndy Fiddaman static const char* convertvars[] = { "DOSPATHVARS", "PATH" };
373*b30d1939SAndy Fiddaman
374*b30d1939SAndy Fiddaman static int
convert(register const char * d,const char * s)375*b30d1939SAndy Fiddaman convert(register const char* d, const char* s)
376*b30d1939SAndy Fiddaman {
377*b30d1939SAndy Fiddaman register const char* t;
378*b30d1939SAndy Fiddaman register const char* v;
379*b30d1939SAndy Fiddaman int i;
380*b30d1939SAndy Fiddaman
381*b30d1939SAndy Fiddaman for (i = 0; i < elementsof(convertvars); i++)
382*b30d1939SAndy Fiddaman {
383*b30d1939SAndy Fiddaman for (v = convertvars[i], t = s; *t && *t == *v; t++, v++);
384*b30d1939SAndy Fiddaman if (*t == '=' && *v == 0)
385*b30d1939SAndy Fiddaman return 0;
386*b30d1939SAndy Fiddaman }
387*b30d1939SAndy Fiddaman for (;;)
388*b30d1939SAndy Fiddaman {
389*b30d1939SAndy Fiddaman while (*d == ' ' || *d == '\t')
390*b30d1939SAndy Fiddaman d++;
391*b30d1939SAndy Fiddaman if (!*d)
392*b30d1939SAndy Fiddaman break;
393*b30d1939SAndy Fiddaman for (t = s; *t && *t == *d; d++, t++);
394*b30d1939SAndy Fiddaman if (*t == '=' && (*d == ' ' || *d == '\t' || *d == 0))
395*b30d1939SAndy Fiddaman return t - s + 1;
396*b30d1939SAndy Fiddaman while (*d && *d != ' ' && *d != '\t')
397*b30d1939SAndy Fiddaman d++;
398*b30d1939SAndy Fiddaman }
399*b30d1939SAndy Fiddaman return 0;
400*b30d1939SAndy Fiddaman }
401*b30d1939SAndy Fiddaman
402*b30d1939SAndy Fiddaman uid_t
getuid(void)403*b30d1939SAndy Fiddaman getuid(void)
404*b30d1939SAndy Fiddaman {
405*b30d1939SAndy Fiddaman register char* d;
406*b30d1939SAndy Fiddaman register char* s;
407*b30d1939SAndy Fiddaman register char* t;
408*b30d1939SAndy Fiddaman register char** e;
409*b30d1939SAndy Fiddaman int n;
410*b30d1939SAndy Fiddaman int m;
411*b30d1939SAndy Fiddaman
412*b30d1939SAndy Fiddaman if (!convertinit++ && (d = getenv(convertvars[0])))
413*b30d1939SAndy Fiddaman for (e = environ; s = *e; e++)
414*b30d1939SAndy Fiddaman if ((n = convert(d, s)) && (m = cygwin_win32_to_posix_path_list_buf_size(s + n)) > 0)
415*b30d1939SAndy Fiddaman {
416*b30d1939SAndy Fiddaman if (!(t = malloc(n + m + 1)))
417*b30d1939SAndy Fiddaman break;
418*b30d1939SAndy Fiddaman *e = t;
419*b30d1939SAndy Fiddaman memcpy(t, s, n);
420*b30d1939SAndy Fiddaman cygwin_win32_to_posix_path_list(s + n, t + n);
421*b30d1939SAndy Fiddaman }
422*b30d1939SAndy Fiddaman return sysgetuid();
423*b30d1939SAndy Fiddaman }
424*b30d1939SAndy Fiddaman
425*b30d1939SAndy Fiddaman #endif
426*b30d1939SAndy Fiddaman
427*b30d1939SAndy Fiddaman #ifndef _P_OVERLAY
428*b30d1939SAndy Fiddaman #define _P_OVERLAY (-1)
429*b30d1939SAndy Fiddaman #endif
430*b30d1939SAndy Fiddaman
431*b30d1939SAndy Fiddaman #define DEBUG 1
432*b30d1939SAndy Fiddaman
433*b30d1939SAndy Fiddaman static pid_t
runve(int mode,const char * path,char * const * argv,char * const * envv)434*b30d1939SAndy Fiddaman runve(int mode, const char* path, char* const* argv, char* const* envv)
435*b30d1939SAndy Fiddaman {
436*b30d1939SAndy Fiddaman register char* s;
437*b30d1939SAndy Fiddaman register char** p;
438*b30d1939SAndy Fiddaman register char** v;
439*b30d1939SAndy Fiddaman
440*b30d1939SAndy Fiddaman void* m1;
441*b30d1939SAndy Fiddaman void* m2;
442*b30d1939SAndy Fiddaman pid_t pid;
443*b30d1939SAndy Fiddaman int oerrno;
444*b30d1939SAndy Fiddaman int ux;
445*b30d1939SAndy Fiddaman int n;
446*b30d1939SAndy Fiddaman #if defined(_P_DETACH) && defined(_P_NOWAIT)
447*b30d1939SAndy Fiddaman int pgrp;
448*b30d1939SAndy Fiddaman #endif
449*b30d1939SAndy Fiddaman #if CONVERT
450*b30d1939SAndy Fiddaman char* d;
451*b30d1939SAndy Fiddaman char* t;
452*b30d1939SAndy Fiddaman int m;
453*b30d1939SAndy Fiddaman #endif
454*b30d1939SAndy Fiddaman struct stat st;
455*b30d1939SAndy Fiddaman char buf[PATH_MAX];
456*b30d1939SAndy Fiddaman char tmp[PATH_MAX];
457*b30d1939SAndy Fiddaman
458*b30d1939SAndy Fiddaman #if DEBUG
459*b30d1939SAndy Fiddaman static int trace;
460*b30d1939SAndy Fiddaman #endif
461*b30d1939SAndy Fiddaman
462*b30d1939SAndy Fiddaman #if defined(_P_DETACH) && defined(_P_NOWAIT)
463*b30d1939SAndy Fiddaman if (mode == _P_DETACH)
464*b30d1939SAndy Fiddaman {
465*b30d1939SAndy Fiddaman /*
466*b30d1939SAndy Fiddaman * 2004-02-29 cygwin _P_DETACH is useless:
467*b30d1939SAndy Fiddaman * spawn*() returns 0 instead of the spawned pid
468*b30d1939SAndy Fiddaman * spawned { pgid sid } are the same as the parent
469*b30d1939SAndy Fiddaman */
470*b30d1939SAndy Fiddaman
471*b30d1939SAndy Fiddaman mode = _P_NOWAIT;
472*b30d1939SAndy Fiddaman pgrp = 1;
473*b30d1939SAndy Fiddaman }
474*b30d1939SAndy Fiddaman else
475*b30d1939SAndy Fiddaman pgrp = 0;
476*b30d1939SAndy Fiddaman #endif
477*b30d1939SAndy Fiddaman if (!envv)
478*b30d1939SAndy Fiddaman envv = (char* const*)environ;
479*b30d1939SAndy Fiddaman m1 = m2 = 0;
480*b30d1939SAndy Fiddaman oerrno = errno;
481*b30d1939SAndy Fiddaman #if DEBUG
482*b30d1939SAndy Fiddaman if (!trace)
483*b30d1939SAndy Fiddaman trace = (s = getenv("_AST_exec_trace")) ? *s : 'n';
484*b30d1939SAndy Fiddaman #endif
485*b30d1939SAndy Fiddaman if (execrate(path, buf, sizeof(buf), 0))
486*b30d1939SAndy Fiddaman {
487*b30d1939SAndy Fiddaman if (!sysstat(buf, &st))
488*b30d1939SAndy Fiddaman path = (const char*)buf;
489*b30d1939SAndy Fiddaman else
490*b30d1939SAndy Fiddaman errno = oerrno;
491*b30d1939SAndy Fiddaman }
492*b30d1939SAndy Fiddaman if (path != (const char*)buf && sysstat(path, &st))
493*b30d1939SAndy Fiddaman return -1;
494*b30d1939SAndy Fiddaman if (!S_ISREG(st.st_mode) || !(st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
495*b30d1939SAndy Fiddaman {
496*b30d1939SAndy Fiddaman errno = EACCES;
497*b30d1939SAndy Fiddaman return -1;
498*b30d1939SAndy Fiddaman }
499*b30d1939SAndy Fiddaman if (magic(path, &ux))
500*b30d1939SAndy Fiddaman {
501*b30d1939SAndy Fiddaman #if _CYGWIN_fork_works
502*b30d1939SAndy Fiddaman errno = ENOEXEC;
503*b30d1939SAndy Fiddaman return -1;
504*b30d1939SAndy Fiddaman #else
505*b30d1939SAndy Fiddaman ux = 1;
506*b30d1939SAndy Fiddaman p = (char**)argv;
507*b30d1939SAndy Fiddaman while (*p++);
508*b30d1939SAndy Fiddaman if (!(v = (char**)malloc((p - (char**)argv + 2) * sizeof(char*))))
509*b30d1939SAndy Fiddaman {
510*b30d1939SAndy Fiddaman errno = EAGAIN;
511*b30d1939SAndy Fiddaman return -1;
512*b30d1939SAndy Fiddaman }
513*b30d1939SAndy Fiddaman m1 = v;
514*b30d1939SAndy Fiddaman p = v;
515*b30d1939SAndy Fiddaman *p++ = (char*)path;
516*b30d1939SAndy Fiddaman *p++ = (char*)path;
517*b30d1939SAndy Fiddaman path = (const char*)pathshell();
518*b30d1939SAndy Fiddaman if (*argv)
519*b30d1939SAndy Fiddaman argv++;
520*b30d1939SAndy Fiddaman while (*p++ = (char*)*argv++);
521*b30d1939SAndy Fiddaman argv = (char* const*)v;
522*b30d1939SAndy Fiddaman #endif
523*b30d1939SAndy Fiddaman }
524*b30d1939SAndy Fiddaman
525*b30d1939SAndy Fiddaman /*
526*b30d1939SAndy Fiddaman * the win32 dll search order is
527*b30d1939SAndy Fiddaman * (1) the directory of path
528*b30d1939SAndy Fiddaman * (2) .
529*b30d1939SAndy Fiddaman * (3) /c/(WINNT|WINDOWS)/system32 /c/(WINNT|WINDOWS)
530*b30d1939SAndy Fiddaman * (4) the directories on $PATH
531*b30d1939SAndy Fiddaman * there are no cygwin dlls in (3), so if (1) and (2) fail
532*b30d1939SAndy Fiddaman * to produce the required dlls its up to (4)
533*b30d1939SAndy Fiddaman *
534*b30d1939SAndy Fiddaman * the standard allows PATH to be anything once the path
535*b30d1939SAndy Fiddaman * to an executable is determined; this code ensures that PATH
536*b30d1939SAndy Fiddaman * contains /bin so that at least the cygwin dll, required
537*b30d1939SAndy Fiddaman * by all cygwin executables, will be found
538*b30d1939SAndy Fiddaman */
539*b30d1939SAndy Fiddaman
540*b30d1939SAndy Fiddaman if (p = (char**)envv)
541*b30d1939SAndy Fiddaman {
542*b30d1939SAndy Fiddaman n = 1;
543*b30d1939SAndy Fiddaman while (s = *p++)
544*b30d1939SAndy Fiddaman if (strneq(s, "PATH=", 5))
545*b30d1939SAndy Fiddaman {
546*b30d1939SAndy Fiddaman s += 5;
547*b30d1939SAndy Fiddaman do
548*b30d1939SAndy Fiddaman {
549*b30d1939SAndy Fiddaman s = pathcat(s, ':', NiL, "", tmp, sizeof(tmp));
550*b30d1939SAndy Fiddaman if (streq(tmp, "/usr/bin/") || streq(tmp, "/bin/"))
551*b30d1939SAndy Fiddaman {
552*b30d1939SAndy Fiddaman n = 0;
553*b30d1939SAndy Fiddaman break;
554*b30d1939SAndy Fiddaman }
555*b30d1939SAndy Fiddaman } while (s);
556*b30d1939SAndy Fiddaman if (n)
557*b30d1939SAndy Fiddaman {
558*b30d1939SAndy Fiddaman n = 0;
559*b30d1939SAndy Fiddaman snprintf(tmp, sizeof(tmp), "%s:/bin", *(p - 1));
560*b30d1939SAndy Fiddaman *(p - 1) = tmp;
561*b30d1939SAndy Fiddaman }
562*b30d1939SAndy Fiddaman break;
563*b30d1939SAndy Fiddaman }
564*b30d1939SAndy Fiddaman if (n)
565*b30d1939SAndy Fiddaman {
566*b30d1939SAndy Fiddaman n = p - (char**)envv + 1;
567*b30d1939SAndy Fiddaman p = (char**)envv;
568*b30d1939SAndy Fiddaman if (v = (char**)malloc(n * sizeof(char*)))
569*b30d1939SAndy Fiddaman {
570*b30d1939SAndy Fiddaman m2 = v;
571*b30d1939SAndy Fiddaman envv = (char* const*)v;
572*b30d1939SAndy Fiddaman *v++ = strcpy(tmp, "PATH=/bin");
573*b30d1939SAndy Fiddaman while (*v++ = *p++);
574*b30d1939SAndy Fiddaman }
575*b30d1939SAndy Fiddaman }
576*b30d1939SAndy Fiddaman #if CONVERT
577*b30d1939SAndy Fiddaman if (!ux && (d = getenv(convertvars[0])))
578*b30d1939SAndy Fiddaman for (p = (char**)envv; s = *p; p++)
579*b30d1939SAndy Fiddaman if ((n = convert(d, s)) && (m = cygwin_posix_to_win32_path_list_buf_size(s + n)) > 0)
580*b30d1939SAndy Fiddaman {
581*b30d1939SAndy Fiddaman if (!(t = malloc(n + m + 1)))
582*b30d1939SAndy Fiddaman break;
583*b30d1939SAndy Fiddaman *p = t;
584*b30d1939SAndy Fiddaman memcpy(t, s, n);
585*b30d1939SAndy Fiddaman cygwin_posix_to_win32_path_list(s + n, t + n);
586*b30d1939SAndy Fiddaman }
587*b30d1939SAndy Fiddaman #endif
588*b30d1939SAndy Fiddaman }
589*b30d1939SAndy Fiddaman
590*b30d1939SAndy Fiddaman #if DEBUG
591*b30d1939SAndy Fiddaman if (trace == 'a' || trace == 'e')
592*b30d1939SAndy Fiddaman {
593*b30d1939SAndy Fiddaman sfprintf(sfstderr, "%s %s [", mode == _P_OVERLAY ? "_execve" : "_spawnve", path);
594*b30d1939SAndy Fiddaman for (n = 0; argv[n]; n++)
595*b30d1939SAndy Fiddaman sfprintf(sfstderr, " '%s'", argv[n]);
596*b30d1939SAndy Fiddaman if (trace == 'e')
597*b30d1939SAndy Fiddaman {
598*b30d1939SAndy Fiddaman sfprintf(sfstderr, " ] [");
599*b30d1939SAndy Fiddaman for (n = 0; envv[n]; n++)
600*b30d1939SAndy Fiddaman sfprintf(sfstderr, " '%s'", envv[n]);
601*b30d1939SAndy Fiddaman }
602*b30d1939SAndy Fiddaman sfprintf(sfstderr, " ]\n");
603*b30d1939SAndy Fiddaman sfsync(sfstderr);
604*b30d1939SAndy Fiddaman }
605*b30d1939SAndy Fiddaman #endif
606*b30d1939SAndy Fiddaman #if _lib_spawn_mode
607*b30d1939SAndy Fiddaman if (mode != _P_OVERLAY)
608*b30d1939SAndy Fiddaman {
609*b30d1939SAndy Fiddaman pid = sysspawnve(mode, path, argv, envv);
610*b30d1939SAndy Fiddaman #if defined(_P_DETACH) && defined(_P_NOWAIT)
611*b30d1939SAndy Fiddaman if (pid > 0 && pgrp)
612*b30d1939SAndy Fiddaman setpgid(pid, 0);
613*b30d1939SAndy Fiddaman #endif
614*b30d1939SAndy Fiddaman }
615*b30d1939SAndy Fiddaman else
616*b30d1939SAndy Fiddaman #endif
617*b30d1939SAndy Fiddaman {
618*b30d1939SAndy Fiddaman #if defined(_P_DETACH) && defined(_P_NOWAIT)
619*b30d1939SAndy Fiddaman if (pgrp)
620*b30d1939SAndy Fiddaman setpgid(0, 0);
621*b30d1939SAndy Fiddaman #endif
622*b30d1939SAndy Fiddaman pid = sysexecve(path, argv, envv);
623*b30d1939SAndy Fiddaman }
624*b30d1939SAndy Fiddaman if (m1)
625*b30d1939SAndy Fiddaman free(m1);
626*b30d1939SAndy Fiddaman if (m2)
627*b30d1939SAndy Fiddaman free(m2);
628*b30d1939SAndy Fiddaman return pid;
629*b30d1939SAndy Fiddaman }
630*b30d1939SAndy Fiddaman
631*b30d1939SAndy Fiddaman #if _win32_botch_execve
632*b30d1939SAndy Fiddaman
633*b30d1939SAndy Fiddaman extern pid_t
execve(const char * path,char * const * argv,char * const * envv)634*b30d1939SAndy Fiddaman execve(const char* path, char* const* argv, char* const* envv)
635*b30d1939SAndy Fiddaman {
636*b30d1939SAndy Fiddaman return runve(_P_OVERLAY, path, argv, envv);
637*b30d1939SAndy Fiddaman }
638*b30d1939SAndy Fiddaman
639*b30d1939SAndy Fiddaman #endif
640*b30d1939SAndy Fiddaman
641*b30d1939SAndy Fiddaman #if _lib_spawn_mode
642*b30d1939SAndy Fiddaman
643*b30d1939SAndy Fiddaman extern pid_t
spawnve(int mode,const char * path,char * const * argv,char * const * envv)644*b30d1939SAndy Fiddaman spawnve(int mode, const char* path, char* const* argv, char* const* envv)
645*b30d1939SAndy Fiddaman {
646*b30d1939SAndy Fiddaman return runve(mode, path, argv, envv);
647*b30d1939SAndy Fiddaman }
648*b30d1939SAndy Fiddaman
649*b30d1939SAndy Fiddaman #endif
650*b30d1939SAndy Fiddaman
651*b30d1939SAndy Fiddaman #endif
652*b30d1939SAndy Fiddaman
653*b30d1939SAndy Fiddaman #if _win32_botch_getpagesize
654*b30d1939SAndy Fiddaman
655*b30d1939SAndy Fiddaman extern size_t
getpagesize(void)656*b30d1939SAndy Fiddaman getpagesize(void)
657*b30d1939SAndy Fiddaman {
658*b30d1939SAndy Fiddaman return 64 * 1024;
659*b30d1939SAndy Fiddaman }
660*b30d1939SAndy Fiddaman
661*b30d1939SAndy Fiddaman #endif
662*b30d1939SAndy Fiddaman
663*b30d1939SAndy Fiddaman #if _win32_botch_link
664*b30d1939SAndy Fiddaman
665*b30d1939SAndy Fiddaman extern int
link(const char * fp,const char * tp)666*b30d1939SAndy Fiddaman link(const char* fp, const char* tp)
667*b30d1939SAndy Fiddaman {
668*b30d1939SAndy Fiddaman int r;
669*b30d1939SAndy Fiddaman int oerrno;
670*b30d1939SAndy Fiddaman char fb[PATH_MAX];
671*b30d1939SAndy Fiddaman char tb[PATH_MAX];
672*b30d1939SAndy Fiddaman
673*b30d1939SAndy Fiddaman oerrno = errno;
674*b30d1939SAndy Fiddaman if ((r = syslink(fp, tp)) && errno == ENOENT && execrate(fp, fb, sizeof(fb), 1))
675*b30d1939SAndy Fiddaman {
676*b30d1939SAndy Fiddaman if (execrate(tp, tb, sizeof(tb), 1))
677*b30d1939SAndy Fiddaman tp = tb;
678*b30d1939SAndy Fiddaman errno = oerrno;
679*b30d1939SAndy Fiddaman r = syslink(fb, tp);
680*b30d1939SAndy Fiddaman }
681*b30d1939SAndy Fiddaman return r;
682*b30d1939SAndy Fiddaman }
683*b30d1939SAndy Fiddaman
684*b30d1939SAndy Fiddaman #endif
685*b30d1939SAndy Fiddaman
686*b30d1939SAndy Fiddaman #if _win32_botch_open || _win32_botch_copy
687*b30d1939SAndy Fiddaman
688*b30d1939SAndy Fiddaman #if _win32_botch_copy
689*b30d1939SAndy Fiddaman
690*b30d1939SAndy Fiddaman /*
691*b30d1939SAndy Fiddaman * this should intercept the important cases
692*b30d1939SAndy Fiddaman * dup*() and exec*() fd's will not be intercepted
693*b30d1939SAndy Fiddaman */
694*b30d1939SAndy Fiddaman
695*b30d1939SAndy Fiddaman typedef struct Exe_test_s
696*b30d1939SAndy Fiddaman {
697*b30d1939SAndy Fiddaman int test;
698*b30d1939SAndy Fiddaman ino_t ino;
699*b30d1939SAndy Fiddaman char path[PATH_MAX];
700*b30d1939SAndy Fiddaman } Exe_test_t;
701*b30d1939SAndy Fiddaman
702*b30d1939SAndy Fiddaman static Exe_test_t* exe[16];
703*b30d1939SAndy Fiddaman
704*b30d1939SAndy Fiddaman extern int
close(int fd)705*b30d1939SAndy Fiddaman close(int fd)
706*b30d1939SAndy Fiddaman {
707*b30d1939SAndy Fiddaman int r;
708*b30d1939SAndy Fiddaman int oerrno;
709*b30d1939SAndy Fiddaman struct stat st;
710*b30d1939SAndy Fiddaman char buf[PATH_MAX];
711*b30d1939SAndy Fiddaman
712*b30d1939SAndy Fiddaman if (fd >= 0 && fd < elementsof(exe) && exe[fd])
713*b30d1939SAndy Fiddaman {
714*b30d1939SAndy Fiddaman r = exe[fd]->test;
715*b30d1939SAndy Fiddaman exe[fd]->test = 0;
716*b30d1939SAndy Fiddaman if (r > 0 && !fstat(fd, &st) && st.st_ino == exe[fd]->ino)
717*b30d1939SAndy Fiddaman {
718*b30d1939SAndy Fiddaman if (r = sysclose(fd))
719*b30d1939SAndy Fiddaman return r;
720*b30d1939SAndy Fiddaman oerrno = errno;
721*b30d1939SAndy Fiddaman if (!stat(exe[fd]->path, &st) && st.st_ino == exe[fd]->ino)
722*b30d1939SAndy Fiddaman {
723*b30d1939SAndy Fiddaman snprintf(buf, sizeof(buf), "%s.exe", exe[fd]->path);
724*b30d1939SAndy Fiddaman sysrename(exe[fd]->path, buf);
725*b30d1939SAndy Fiddaman }
726*b30d1939SAndy Fiddaman errno = oerrno;
727*b30d1939SAndy Fiddaman return 0;
728*b30d1939SAndy Fiddaman }
729*b30d1939SAndy Fiddaman }
730*b30d1939SAndy Fiddaman return sysclose(fd);
731*b30d1939SAndy Fiddaman }
732*b30d1939SAndy Fiddaman
733*b30d1939SAndy Fiddaman extern ssize_t
write(int fd,const void * buf,size_t n)734*b30d1939SAndy Fiddaman write(int fd, const void* buf, size_t n)
735*b30d1939SAndy Fiddaman {
736*b30d1939SAndy Fiddaman if (fd >= 0 && fd < elementsof(exe) && exe[fd] && exe[fd]->test < 0)
737*b30d1939SAndy Fiddaman exe[fd]->test = n >= 2 && ((unsigned char*)buf)[1] == 0x5a && (((unsigned char*)buf)[0] == 0x4c || ((unsigned char*)buf)[0] == 0x4d) && !lseek(fd, (off_t)0, SEEK_CUR);
738*b30d1939SAndy Fiddaman return syswrite(fd, buf, n);
739*b30d1939SAndy Fiddaman }
740*b30d1939SAndy Fiddaman
741*b30d1939SAndy Fiddaman #endif
742*b30d1939SAndy Fiddaman
743*b30d1939SAndy Fiddaman extern int
open(const char * path,int flags,...)744*b30d1939SAndy Fiddaman open(const char* path, int flags, ...)
745*b30d1939SAndy Fiddaman {
746*b30d1939SAndy Fiddaman int fd;
747*b30d1939SAndy Fiddaman int mode;
748*b30d1939SAndy Fiddaman int oerrno;
749*b30d1939SAndy Fiddaman char buf[PATH_MAX];
750*b30d1939SAndy Fiddaman #if _win32_botch_copy
751*b30d1939SAndy Fiddaman struct stat st;
752*b30d1939SAndy Fiddaman #endif
753*b30d1939SAndy Fiddaman va_list ap;
754*b30d1939SAndy Fiddaman
755*b30d1939SAndy Fiddaman va_start(ap, flags);
756*b30d1939SAndy Fiddaman mode = (flags & O_CREAT) ? va_arg(ap, int) : 0;
757*b30d1939SAndy Fiddaman oerrno = errno;
758*b30d1939SAndy Fiddaman fd = sysopen(path, flags, mode);
759*b30d1939SAndy Fiddaman #if _win32_botch_open
760*b30d1939SAndy Fiddaman if (fd < 0 && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
761*b30d1939SAndy Fiddaman {
762*b30d1939SAndy Fiddaman errno = oerrno;
763*b30d1939SAndy Fiddaman fd = sysopen(buf, flags, mode);
764*b30d1939SAndy Fiddaman }
765*b30d1939SAndy Fiddaman #endif
766*b30d1939SAndy Fiddaman #if _win32_botch_copy
767*b30d1939SAndy Fiddaman if (fd >= 0 && fd < elementsof(exe) && strlen(path) < PATH_MAX &&
768*b30d1939SAndy Fiddaman (flags & (O_CREAT|O_TRUNC)) == (O_CREAT|O_TRUNC) && (mode & 0111))
769*b30d1939SAndy Fiddaman {
770*b30d1939SAndy Fiddaman if (!suffix(path) && !fstat(fd, &st) && (exe[fd] || (exe[fd] = (Exe_test_t*)malloc(sizeof(Exe_test_t)))))
771*b30d1939SAndy Fiddaman {
772*b30d1939SAndy Fiddaman exe[fd]->test = -1;
773*b30d1939SAndy Fiddaman exe[fd]->ino = st.st_ino;
774*b30d1939SAndy Fiddaman strcpy(exe[fd]->path, path);
775*b30d1939SAndy Fiddaman }
776*b30d1939SAndy Fiddaman errno = oerrno;
777*b30d1939SAndy Fiddaman }
778*b30d1939SAndy Fiddaman #endif
779*b30d1939SAndy Fiddaman va_end(ap);
780*b30d1939SAndy Fiddaman return fd;
781*b30d1939SAndy Fiddaman }
782*b30d1939SAndy Fiddaman
783*b30d1939SAndy Fiddaman #endif
784*b30d1939SAndy Fiddaman
785*b30d1939SAndy Fiddaman #if _win32_botch_pathconf
786*b30d1939SAndy Fiddaman
787*b30d1939SAndy Fiddaman extern long
pathconf(const char * path,int op)788*b30d1939SAndy Fiddaman pathconf(const char* path, int op)
789*b30d1939SAndy Fiddaman {
790*b30d1939SAndy Fiddaman if (sysaccess(path, F_OK))
791*b30d1939SAndy Fiddaman return -1;
792*b30d1939SAndy Fiddaman return syspathconf(path, op);
793*b30d1939SAndy Fiddaman }
794*b30d1939SAndy Fiddaman
795*b30d1939SAndy Fiddaman #endif
796*b30d1939SAndy Fiddaman
797*b30d1939SAndy Fiddaman #if _win32_botch_rename
798*b30d1939SAndy Fiddaman
799*b30d1939SAndy Fiddaman extern int
rename(const char * fp,const char * tp)800*b30d1939SAndy Fiddaman rename(const char* fp, const char* tp)
801*b30d1939SAndy Fiddaman {
802*b30d1939SAndy Fiddaman int r;
803*b30d1939SAndy Fiddaman int oerrno;
804*b30d1939SAndy Fiddaman char fb[PATH_MAX];
805*b30d1939SAndy Fiddaman char tb[PATH_MAX];
806*b30d1939SAndy Fiddaman
807*b30d1939SAndy Fiddaman oerrno = errno;
808*b30d1939SAndy Fiddaman if ((r = sysrename(fp, tp)) && errno == ENOENT && execrate(fp, fb, sizeof(fb), 1))
809*b30d1939SAndy Fiddaman {
810*b30d1939SAndy Fiddaman if (execrate(tp, tb, sizeof(tb), 1))
811*b30d1939SAndy Fiddaman tp = tb;
812*b30d1939SAndy Fiddaman errno = oerrno;
813*b30d1939SAndy Fiddaman r = sysrename(fb, tp);
814*b30d1939SAndy Fiddaman }
815*b30d1939SAndy Fiddaman return r;
816*b30d1939SAndy Fiddaman }
817*b30d1939SAndy Fiddaman
818*b30d1939SAndy Fiddaman #endif
819*b30d1939SAndy Fiddaman
820*b30d1939SAndy Fiddaman #if _win32_botch_stat
821*b30d1939SAndy Fiddaman
822*b30d1939SAndy Fiddaman extern int
stat(const char * path,struct stat * st)823*b30d1939SAndy Fiddaman stat(const char* path, struct stat* st)
824*b30d1939SAndy Fiddaman {
825*b30d1939SAndy Fiddaman int r;
826*b30d1939SAndy Fiddaman int oerrno;
827*b30d1939SAndy Fiddaman char buf[PATH_MAX];
828*b30d1939SAndy Fiddaman
829*b30d1939SAndy Fiddaman oerrno = errno;
830*b30d1939SAndy Fiddaman if ((r = sysstat(path, st)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
831*b30d1939SAndy Fiddaman {
832*b30d1939SAndy Fiddaman errno = oerrno;
833*b30d1939SAndy Fiddaman r = sysstat(buf, st);
834*b30d1939SAndy Fiddaman }
835*b30d1939SAndy Fiddaman return r;
836*b30d1939SAndy Fiddaman }
837*b30d1939SAndy Fiddaman
838*b30d1939SAndy Fiddaman #endif
839*b30d1939SAndy Fiddaman
840*b30d1939SAndy Fiddaman #if _win32_botch_truncate
841*b30d1939SAndy Fiddaman
842*b30d1939SAndy Fiddaman extern int
truncate(const char * path,off_t offset)843*b30d1939SAndy Fiddaman truncate(const char* path, off_t offset)
844*b30d1939SAndy Fiddaman {
845*b30d1939SAndy Fiddaman int r;
846*b30d1939SAndy Fiddaman int oerrno;
847*b30d1939SAndy Fiddaman char buf[PATH_MAX];
848*b30d1939SAndy Fiddaman
849*b30d1939SAndy Fiddaman oerrno = errno;
850*b30d1939SAndy Fiddaman if ((r = systruncate(path, offset)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
851*b30d1939SAndy Fiddaman {
852*b30d1939SAndy Fiddaman errno = oerrno;
853*b30d1939SAndy Fiddaman r = systruncate(buf, offset);
854*b30d1939SAndy Fiddaman }
855*b30d1939SAndy Fiddaman return r;
856*b30d1939SAndy Fiddaman }
857*b30d1939SAndy Fiddaman
858*b30d1939SAndy Fiddaman #endif
859*b30d1939SAndy Fiddaman
860*b30d1939SAndy Fiddaman #if _win32_botch_unlink
861*b30d1939SAndy Fiddaman
862*b30d1939SAndy Fiddaman extern int
unlink(const char * path)863*b30d1939SAndy Fiddaman unlink(const char* path)
864*b30d1939SAndy Fiddaman {
865*b30d1939SAndy Fiddaman int r;
866*b30d1939SAndy Fiddaman int drive;
867*b30d1939SAndy Fiddaman int mask;
868*b30d1939SAndy Fiddaman int suffix;
869*b30d1939SAndy Fiddaman int stop;
870*b30d1939SAndy Fiddaman int oerrno;
871*b30d1939SAndy Fiddaman unsigned long base;
872*b30d1939SAndy Fiddaman char buf[PATH_MAX];
873*b30d1939SAndy Fiddaman char tmp[MAX_PATH];
874*b30d1939SAndy Fiddaman
875*b30d1939SAndy Fiddaman #define DELETED_DIR_1 7
876*b30d1939SAndy Fiddaman #define DELETED_DIR_2 16
877*b30d1939SAndy Fiddaman
878*b30d1939SAndy Fiddaman static char deleted[] = "%c:\\temp\\.deleted\\%08x.%03x";
879*b30d1939SAndy Fiddaman
880*b30d1939SAndy Fiddaman static int count = 0;
881*b30d1939SAndy Fiddaman
882*b30d1939SAndy Fiddaman #if __CYGWIN__
883*b30d1939SAndy Fiddaman
884*b30d1939SAndy Fiddaman DWORD fattr = FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE;
885*b30d1939SAndy Fiddaman DWORD share = FILE_SHARE_DELETE;
886*b30d1939SAndy Fiddaman HANDLE hp;
887*b30d1939SAndy Fiddaman struct stat st;
888*b30d1939SAndy Fiddaman char nat[MAX_PATH];
889*b30d1939SAndy Fiddaman
890*b30d1939SAndy Fiddaman oerrno = errno;
891*b30d1939SAndy Fiddaman if (lstat(path, &st) || !S_ISREG(st.st_mode))
892*b30d1939SAndy Fiddaman goto try_unlink;
893*b30d1939SAndy Fiddaman cygwin_conv_to_full_win32_path(path, nat);
894*b30d1939SAndy Fiddaman if (!strncasecmp(nat + 1, ":\\temp\\", 7))
895*b30d1939SAndy Fiddaman goto try_unlink;
896*b30d1939SAndy Fiddaman drive = nat[0];
897*b30d1939SAndy Fiddaman path = (const char*)nat;
898*b30d1939SAndy Fiddaman for (;;)
899*b30d1939SAndy Fiddaman {
900*b30d1939SAndy Fiddaman hp = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE, NULL);
901*b30d1939SAndy Fiddaman if (hp != INVALID_HANDLE_VALUE)
902*b30d1939SAndy Fiddaman {
903*b30d1939SAndy Fiddaman CloseHandle(hp);
904*b30d1939SAndy Fiddaman errno = oerrno;
905*b30d1939SAndy Fiddaman return 0;
906*b30d1939SAndy Fiddaman }
907*b30d1939SAndy Fiddaman if (GetLastError() != ERROR_FILE_NOT_FOUND)
908*b30d1939SAndy Fiddaman break;
909*b30d1939SAndy Fiddaman if (path == (const char*)buf || !execrate(path, buf, sizeof(buf), 1))
910*b30d1939SAndy Fiddaman {
911*b30d1939SAndy Fiddaman errno = ENOENT;
912*b30d1939SAndy Fiddaman return -1;
913*b30d1939SAndy Fiddaman }
914*b30d1939SAndy Fiddaman path = (const char*)buf;
915*b30d1939SAndy Fiddaman }
916*b30d1939SAndy Fiddaman #else
917*b30d1939SAndy Fiddaman if (sysaccess(path, 0))
918*b30d1939SAndy Fiddaman #if _win32_botch_access
919*b30d1939SAndy Fiddaman {
920*b30d1939SAndy Fiddaman if (errno != ENOENT || !execrate(path, buf, sizeof(buf), 1) || sysaccess(buf, 0))
921*b30d1939SAndy Fiddaman return -1;
922*b30d1939SAndy Fiddaman path = (const char*)buf;
923*b30d1939SAndy Fiddaman }
924*b30d1939SAndy Fiddaman #else
925*b30d1939SAndy Fiddaman return -1;
926*b30d1939SAndy Fiddaman #endif
927*b30d1939SAndy Fiddaman drive = 'C':
928*b30d1939SAndy Fiddaman #endif
929*b30d1939SAndy Fiddaman
930*b30d1939SAndy Fiddaman /*
931*b30d1939SAndy Fiddaman * rename to a `deleted' path just in case the file is open
932*b30d1939SAndy Fiddaman * otherwise directory readers may choke on phantom entries
933*b30d1939SAndy Fiddaman */
934*b30d1939SAndy Fiddaman
935*b30d1939SAndy Fiddaman base = ((getuid() & 0xffff) << 16) | (time(NiL) & 0xffff);
936*b30d1939SAndy Fiddaman suffix = (getpid() & 0xfff) + count++;
937*b30d1939SAndy Fiddaman snprintf(tmp, sizeof(tmp), deleted, drive, base, suffix);
938*b30d1939SAndy Fiddaman if (!sysrename(path, tmp))
939*b30d1939SAndy Fiddaman {
940*b30d1939SAndy Fiddaman path = (const char*)tmp;
941*b30d1939SAndy Fiddaman goto try_delete;
942*b30d1939SAndy Fiddaman }
943*b30d1939SAndy Fiddaman if (errno != ENOTDIR && errno != ENOENT)
944*b30d1939SAndy Fiddaman goto try_unlink;
945*b30d1939SAndy Fiddaman tmp[DELETED_DIR_2] = 0;
946*b30d1939SAndy Fiddaman if (sysaccess(tmp, 0))
947*b30d1939SAndy Fiddaman {
948*b30d1939SAndy Fiddaman mask = umask(0);
949*b30d1939SAndy Fiddaman tmp[DELETED_DIR_1] = 0;
950*b30d1939SAndy Fiddaman if (sysaccess(tmp, 0) && mkdir(tmp, S_IRWXU|S_IRWXG|S_IRWXO))
951*b30d1939SAndy Fiddaman {
952*b30d1939SAndy Fiddaman umask(mask);
953*b30d1939SAndy Fiddaman goto try_unlink;
954*b30d1939SAndy Fiddaman }
955*b30d1939SAndy Fiddaman tmp[DELETED_DIR_1] = '\\';
956*b30d1939SAndy Fiddaman r = mkdir(tmp, S_IRWXU|S_IRWXG|S_IRWXO);
957*b30d1939SAndy Fiddaman umask(mask);
958*b30d1939SAndy Fiddaman if (r)
959*b30d1939SAndy Fiddaman goto try_unlink;
960*b30d1939SAndy Fiddaman errno = 0;
961*b30d1939SAndy Fiddaman }
962*b30d1939SAndy Fiddaman tmp[DELETED_DIR_2] = '\\';
963*b30d1939SAndy Fiddaman if (!errno && !sysrename(path, tmp))
964*b30d1939SAndy Fiddaman {
965*b30d1939SAndy Fiddaman path = (const char*)tmp;
966*b30d1939SAndy Fiddaman goto try_delete;
967*b30d1939SAndy Fiddaman }
968*b30d1939SAndy Fiddaman #if !__CYGWIN__
969*b30d1939SAndy Fiddaman if (errno == ENOENT)
970*b30d1939SAndy Fiddaman {
971*b30d1939SAndy Fiddaman #if !_win32_botch_access
972*b30d1939SAndy Fiddaman if (execrate(path, buf, sizeof(buf), 1) && !sysrename(buf, tmp))
973*b30d1939SAndy Fiddaman path = (const char*)tmp;
974*b30d1939SAndy Fiddaman #endif
975*b30d1939SAndy Fiddaman goto try_unlink;
976*b30d1939SAndy Fiddaman }
977*b30d1939SAndy Fiddaman #endif
978*b30d1939SAndy Fiddaman stop = suffix;
979*b30d1939SAndy Fiddaman do
980*b30d1939SAndy Fiddaman {
981*b30d1939SAndy Fiddaman snprintf(tmp, sizeof(tmp), deleted, drive, base, suffix);
982*b30d1939SAndy Fiddaman if (!sysrename(path, tmp))
983*b30d1939SAndy Fiddaman {
984*b30d1939SAndy Fiddaman path = (const char*)tmp;
985*b30d1939SAndy Fiddaman goto try_delete;
986*b30d1939SAndy Fiddaman }
987*b30d1939SAndy Fiddaman if (++suffix > 0xfff)
988*b30d1939SAndy Fiddaman suffix = 0;
989*b30d1939SAndy Fiddaman } while (suffix != stop);
990*b30d1939SAndy Fiddaman try_delete:
991*b30d1939SAndy Fiddaman #if __CYGWIN__
992*b30d1939SAndy Fiddaman hp = CreateFile(path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE, NULL);
993*b30d1939SAndy Fiddaman if (hp != INVALID_HANDLE_VALUE)
994*b30d1939SAndy Fiddaman {
995*b30d1939SAndy Fiddaman CloseHandle(hp);
996*b30d1939SAndy Fiddaman errno = oerrno;
997*b30d1939SAndy Fiddaman return 0;
998*b30d1939SAndy Fiddaman }
999*b30d1939SAndy Fiddaman #endif
1000*b30d1939SAndy Fiddaman try_unlink:
1001*b30d1939SAndy Fiddaman errno = oerrno;
1002*b30d1939SAndy Fiddaman return sysunlink(path);
1003*b30d1939SAndy Fiddaman }
1004*b30d1939SAndy Fiddaman
1005*b30d1939SAndy Fiddaman #endif
1006*b30d1939SAndy Fiddaman
1007*b30d1939SAndy Fiddaman #if _win32_botch_utime
1008*b30d1939SAndy Fiddaman
1009*b30d1939SAndy Fiddaman #if __CYGWIN__
1010*b30d1939SAndy Fiddaman
1011*b30d1939SAndy Fiddaman /*
1012*b30d1939SAndy Fiddaman * cygwin refuses to set st_ctime for some operations
1013*b30d1939SAndy Fiddaman * this rejects that refusal
1014*b30d1939SAndy Fiddaman */
1015*b30d1939SAndy Fiddaman
1016*b30d1939SAndy Fiddaman static void
ctime_now(const char * path)1017*b30d1939SAndy Fiddaman ctime_now(const char* path)
1018*b30d1939SAndy Fiddaman {
1019*b30d1939SAndy Fiddaman HANDLE hp;
1020*b30d1939SAndy Fiddaman SYSTEMTIME st;
1021*b30d1939SAndy Fiddaman FILETIME ct;
1022*b30d1939SAndy Fiddaman WIN32_FIND_DATA ff;
1023*b30d1939SAndy Fiddaman struct stat fs;
1024*b30d1939SAndy Fiddaman int oerrno;
1025*b30d1939SAndy Fiddaman char tmp[MAX_PATH];
1026*b30d1939SAndy Fiddaman
1027*b30d1939SAndy Fiddaman if (sysstat(path, &fs) || (fs.st_mode & S_IWUSR) || syschmod(path, (fs.st_mode | S_IWUSR) & S_IPERM))
1028*b30d1939SAndy Fiddaman fs.st_mode = 0;
1029*b30d1939SAndy Fiddaman cygwin_conv_to_win32_path(path, tmp);
1030*b30d1939SAndy Fiddaman hp = CreateFile(tmp, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1031*b30d1939SAndy Fiddaman if (hp && hp != INVALID_HANDLE_VALUE)
1032*b30d1939SAndy Fiddaman {
1033*b30d1939SAndy Fiddaman GetSystemTime(&st);
1034*b30d1939SAndy Fiddaman SystemTimeToFileTime(&st, &ct);
1035*b30d1939SAndy Fiddaman SetFileTime(hp, &ct, 0, 0);
1036*b30d1939SAndy Fiddaman CloseHandle(hp);
1037*b30d1939SAndy Fiddaman }
1038*b30d1939SAndy Fiddaman if (fs.st_mode)
1039*b30d1939SAndy Fiddaman syschmod(path, fs.st_mode & S_IPERM);
1040*b30d1939SAndy Fiddaman errno = oerrno;
1041*b30d1939SAndy Fiddaman }
1042*b30d1939SAndy Fiddaman
1043*b30d1939SAndy Fiddaman #else
1044*b30d1939SAndy Fiddaman
1045*b30d1939SAndy Fiddaman #define ctime_now(p)
1046*b30d1939SAndy Fiddaman
1047*b30d1939SAndy Fiddaman #endif
1048*b30d1939SAndy Fiddaman
1049*b30d1939SAndy Fiddaman extern int
utimes(const char * path,const struct timeval * ut)1050*b30d1939SAndy Fiddaman utimes(const char* path, const struct timeval* ut)
1051*b30d1939SAndy Fiddaman {
1052*b30d1939SAndy Fiddaman int r;
1053*b30d1939SAndy Fiddaman int oerrno;
1054*b30d1939SAndy Fiddaman char buf[PATH_MAX];
1055*b30d1939SAndy Fiddaman
1056*b30d1939SAndy Fiddaman oerrno = errno;
1057*b30d1939SAndy Fiddaman if ((r = sysutimes(path, ut)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
1058*b30d1939SAndy Fiddaman {
1059*b30d1939SAndy Fiddaman errno = oerrno;
1060*b30d1939SAndy Fiddaman r = sysutimes(path = buf, ut);
1061*b30d1939SAndy Fiddaman }
1062*b30d1939SAndy Fiddaman if (!r)
1063*b30d1939SAndy Fiddaman ctime_now(path);
1064*b30d1939SAndy Fiddaman return r;
1065*b30d1939SAndy Fiddaman }
1066*b30d1939SAndy Fiddaman
1067*b30d1939SAndy Fiddaman extern int
utime(const char * path,const struct utimbuf * ut)1068*b30d1939SAndy Fiddaman utime(const char* path, const struct utimbuf* ut)
1069*b30d1939SAndy Fiddaman {
1070*b30d1939SAndy Fiddaman int r;
1071*b30d1939SAndy Fiddaman int oerrno;
1072*b30d1939SAndy Fiddaman char buf[PATH_MAX];
1073*b30d1939SAndy Fiddaman
1074*b30d1939SAndy Fiddaman oerrno = errno;
1075*b30d1939SAndy Fiddaman if ((r = sysutime(path, ut)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
1076*b30d1939SAndy Fiddaman {
1077*b30d1939SAndy Fiddaman errno = oerrno;
1078*b30d1939SAndy Fiddaman r = sysutime(path = buf, ut);
1079*b30d1939SAndy Fiddaman }
1080*b30d1939SAndy Fiddaman if (!r)
1081*b30d1939SAndy Fiddaman ctime_now(path);
1082*b30d1939SAndy Fiddaman return r;
1083*b30d1939SAndy Fiddaman }
1084*b30d1939SAndy Fiddaman
1085*b30d1939SAndy Fiddaman #endif
1086*b30d1939SAndy Fiddaman
1087*b30d1939SAndy Fiddaman #endif
1088*b30d1939SAndy Fiddaman
1089*b30d1939SAndy Fiddaman /*
1090*b30d1939SAndy Fiddaman * some systems (sun) miss a few functions required by their
1091*b30d1939SAndy Fiddaman * own bsd-like macros
1092*b30d1939SAndy Fiddaman */
1093*b30d1939SAndy Fiddaman
1094*b30d1939SAndy Fiddaman #if !_lib_bzero || defined(bzero)
1095*b30d1939SAndy Fiddaman
1096*b30d1939SAndy Fiddaman #undef bzero
1097*b30d1939SAndy Fiddaman
1098*b30d1939SAndy Fiddaman void
bzero(void * b,size_t n)1099*b30d1939SAndy Fiddaman bzero(void* b, size_t n)
1100*b30d1939SAndy Fiddaman {
1101*b30d1939SAndy Fiddaman memset(b, 0, n);
1102*b30d1939SAndy Fiddaman }
1103*b30d1939SAndy Fiddaman
1104*b30d1939SAndy Fiddaman #endif
1105*b30d1939SAndy Fiddaman
1106*b30d1939SAndy Fiddaman #if !_lib_getpagesize || defined(getpagesize)
1107*b30d1939SAndy Fiddaman
1108*b30d1939SAndy Fiddaman #ifndef OMITTED
1109*b30d1939SAndy Fiddaman #define OMITTED 1
1110*b30d1939SAndy Fiddaman #endif
1111*b30d1939SAndy Fiddaman
1112*b30d1939SAndy Fiddaman #undef getpagesize
1113*b30d1939SAndy Fiddaman
1114*b30d1939SAndy Fiddaman #ifdef _SC_PAGESIZE
1115*b30d1939SAndy Fiddaman #undef _AST_PAGESIZE
1116*b30d1939SAndy Fiddaman #define _AST_PAGESIZE (int)sysconf(_SC_PAGESIZE)
1117*b30d1939SAndy Fiddaman #else
1118*b30d1939SAndy Fiddaman #ifndef _AST_PAGESIZE
1119*b30d1939SAndy Fiddaman #define _AST_PAGESIZE 4096
1120*b30d1939SAndy Fiddaman #endif
1121*b30d1939SAndy Fiddaman #endif
1122*b30d1939SAndy Fiddaman
1123*b30d1939SAndy Fiddaman int
getpagesize()1124*b30d1939SAndy Fiddaman getpagesize()
1125*b30d1939SAndy Fiddaman {
1126*b30d1939SAndy Fiddaman return _AST_PAGESIZE;
1127*b30d1939SAndy Fiddaman }
1128*b30d1939SAndy Fiddaman
1129*b30d1939SAndy Fiddaman #endif
1130*b30d1939SAndy Fiddaman
1131*b30d1939SAndy Fiddaman #if __CYGWIN__ && defined(__IMPORT__) && defined(__EXPORT__)
1132*b30d1939SAndy Fiddaman
1133*b30d1939SAndy Fiddaman #ifndef OMITTED
1134*b30d1939SAndy Fiddaman #define OMITTED 1
1135*b30d1939SAndy Fiddaman #endif
1136*b30d1939SAndy Fiddaman
1137*b30d1939SAndy Fiddaman /*
1138*b30d1939SAndy Fiddaman * a few _imp__FUNCTION symbols are needed to avoid
1139*b30d1939SAndy Fiddaman * static link multiple definitions
1140*b30d1939SAndy Fiddaman */
1141*b30d1939SAndy Fiddaman
1142*b30d1939SAndy Fiddaman #ifndef strtod
1143*b30d1939SAndy Fiddaman __EXPORT__ double (*_imp__strtod)(const char*, char**) = strtod;
1144*b30d1939SAndy Fiddaman #endif
1145*b30d1939SAndy Fiddaman
1146*b30d1939SAndy Fiddaman #endif
1147*b30d1939SAndy Fiddaman
1148*b30d1939SAndy Fiddaman #ifndef OMITTED
1149*b30d1939SAndy Fiddaman
1150*b30d1939SAndy Fiddaman NoN(omitted)
1151*b30d1939SAndy Fiddaman
1152*b30d1939SAndy Fiddaman #endif
1153