xref: /illumos-gate/usr/src/contrib/ast/src/lib/libast/comp/omitted.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
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