Blame src/lib/libast/comp/omitted.c

Packit Service a8c26c
#pragma prototyped noticed
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * workarounds to bring the native interface close to posix and x/open
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#if defined(__STDPP__directive) && defined(__STDPP__hide)
Packit Service a8c26c
__STDPP__directive pragma pp:hide utime utimes
Packit Service a8c26c
#else
Packit Service a8c26c
#define utime		______utime
Packit Service a8c26c
#define utimes		______utimes
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#include <ast.h>
Packit Service a8c26c
#include <error.h>
Packit Service a8c26c
#include <tm.h>
Packit Service a8c26c
Packit Service a8c26c
#include "FEATURE/omitted"
Packit Service a8c26c
Packit Service a8c26c
#undef	OMITTED
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch
Packit Service a8c26c
Packit Service a8c26c
#define	OMITTED	1
Packit Service a8c26c
Packit Service a8c26c
#include <ls.h>
Packit Service a8c26c
#include <utime.h>
Packit Service a8c26c
Packit Service a8c26c
#if __CYGWIN__
Packit Service a8c26c
#include <ast_windows.h>
Packit Service a8c26c
#if _win32_botch_execve || _lib_spawn_mode
Packit Service a8c26c
#define CONVERT		1
Packit Service a8c26c
#endif
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if defined(__STDPP__directive) && defined(__STDPP__hide)
Packit Service a8c26c
__STDPP__directive pragma pp:nohide utime utimes
Packit Service a8c26c
#else
Packit Service a8c26c
#undef	utime
Packit Service a8c26c
#undef	utimes
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#ifndef MAX_PATH
Packit Service a8c26c
#define MAX_PATH	PATH_MAX
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * these workarounds assume each system call foo() has a _foo() entry
Packit Service a8c26c
 * which is true for __CYGWIN__ and __EMX__ (both gnu based)
Packit Service a8c26c
 *
Packit Service a8c26c
 * the workarounds handle:
Packit Service a8c26c
 *
Packit Service a8c26c
 *	(1) .exe suffix inconsistencies
Packit Service a8c26c
 *	(2) /bin/sh reference in execve() and spawnve()
Packit Service a8c26c
 *	(3) bogus getpagesize() return values
Packit Service a8c26c
 *	(4) a fork() bug that screws up shell fork()+script
Packit Service a8c26c
 *
Packit Service a8c26c
 * NOTE: Not all workarounds can be handled by unix syscall intercepts.
Packit Service a8c26c
 *	 In particular, { ksh nmake } have workarounds for case-ignorant
Packit Service a8c26c
 *	 filesystems and { libast } has workarounds for win32 locale info.
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#undef _pathconf
Packit Service a8c26c
#undef pathconf
Packit Service a8c26c
#undef stat
Packit Service a8c26c
Packit Service a8c26c
extern int		_access(const char*, int);
Packit Service a8c26c
extern unsigned int	_alarm(unsigned int);
Packit Service a8c26c
extern int		_chmod(const char*, mode_t);
Packit Service a8c26c
extern int		_close(int);
Packit Service a8c26c
extern pid_t		_execve(const char*, char* const*, char* const*);
Packit Service a8c26c
extern uid_t		_getuid(void);
Packit Service a8c26c
extern int		_link(const char*, const char*);
Packit Service a8c26c
extern int		_open(const char*, int, ...);
Packit Service a8c26c
extern long		_pathconf(const char*, int);
Packit Service a8c26c
extern ssize_t		_read(int, void*, size_t);
Packit Service a8c26c
extern int		_rename(const char*, const char*);
Packit Service a8c26c
extern pid_t		_spawnve(int, const char*, char* const*, char* const*);
Packit Service a8c26c
extern int		_stat(const char*, struct stat*);
Packit Service a8c26c
extern int		_unlink(const char*);
Packit Service a8c26c
extern int		_utime(const char*, const struct utimbuf*);
Packit Service a8c26c
extern int		_utimes(const char*, const struct timeval*);
Packit Service a8c26c
extern ssize_t		_write(int, const void*, size_t);
Packit Service a8c26c
Packit Service a8c26c
#if defined(__EXPORT__)
Packit Service a8c26c
#define extern	__EXPORT__
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_access
Packit Service a8c26c
#define sysaccess		_access
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysaccess		access
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_alarm
Packit Service a8c26c
#define sysalarm		_alarm
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysalarm		alarm
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_chmod
Packit Service a8c26c
#define syschmod		_chmod
Packit Service a8c26c
#else
Packit Service a8c26c
#define syschmod		chmod
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_copy
Packit Service a8c26c
#define sysclose		_close
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysclose		close
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_execve || _lib_spawn_mode
Packit Service a8c26c
#define sysexecve		_execve
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysexecve		execve
Packit Service a8c26c
#endif
Packit Service a8c26c
#if CONVERT
Packit Service a8c26c
#define sysgetuid		_getuid
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysgetuid		getuid
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_link
Packit Service a8c26c
#define syslink			_link
Packit Service a8c26c
#else
Packit Service a8c26c
#define syslink			link
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_open || _win32_botch_copy
Packit Service a8c26c
#define sysopen			_open
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysopen			open
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_pathconf
Packit Service a8c26c
#define syspathconf		_pathconf
Packit Service a8c26c
#else
Packit Service a8c26c
#define syspathconf		pathconf
Packit Service a8c26c
#endif
Packit Service a8c26c
#define sysread			_read
Packit Service a8c26c
#if _win32_botch_rename
Packit Service a8c26c
#define sysrename		_rename
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysrename		rename
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _lib_spawn_mode
Packit Service a8c26c
#define sysspawnve		_spawnve
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysspawnve		spawnve
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_stat
Packit Service a8c26c
#define sysstat			_stat
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysstat			stat
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_truncate
Packit Service a8c26c
#define systruncate		_truncate
Packit Service a8c26c
#else
Packit Service a8c26c
#define systruncate		truncate
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_unlink
Packit Service a8c26c
#define sysunlink		_unlink
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysunlink		unlink
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_utime
Packit Service a8c26c
#define sysutime		_utime
Packit Service a8c26c
#define sysutimes		_utimes
Packit Service a8c26c
#else
Packit Service a8c26c
#define sysutime		utime
Packit Service a8c26c
#define sysutimes		utimes
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_copy
Packit Service a8c26c
#define syswrite		_write
Packit Service a8c26c
#else
Packit Service a8c26c
#define syswrite		write
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
static char*
Packit Service a8c26c
suffix(register const char* path)
Packit Service a8c26c
{
Packit Service a8c26c
	register const char*	s = path + strlen(path);
Packit Service a8c26c
	register int		c;
Packit Service a8c26c
Packit Service a8c26c
	while (s > path)
Packit Service a8c26c
		if ((c = *--s) == '.')
Packit Service a8c26c
			return (char*)s + 1;
Packit Service a8c26c
		else if (c == '/' || c == '\\')
Packit Service a8c26c
			break;
Packit Service a8c26c
	return 0;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static int
Packit Service a8c26c
execrate(const char* path, char* buf, int size, int physical)
Packit Service a8c26c
{
Packit Service a8c26c
	char*	s;
Packit Service a8c26c
	int	n;
Packit Service a8c26c
	int	oerrno;
Packit Service a8c26c
Packit Service a8c26c
	if (suffix(path))
Packit Service a8c26c
		return 0;
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	if (physical || strlen(path) >= size || !(s = pathcanon(strcpy(buf, path), size, PATH_PHYSICAL|PATH_DOTDOT|PATH_EXISTS)))
Packit Service a8c26c
		snprintf(buf, size, "%s.exe", path);
Packit Service a8c26c
	else if (!suffix(buf) && ((buf + size) - s) >= 4)
Packit Service a8c26c
		strcpy(s, ".exe");
Packit Service a8c26c
	errno = oerrno;
Packit Service a8c26c
	return 1;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * return 0 if path is magic, -1 otherwise
Packit Service a8c26c
 * ux!=0 set to 1 if path is unix executable
Packit Service a8c26c
 * ux!=0 also retains errno for -1 return
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
static int
Packit Service a8c26c
magic(const char* path, int* ux)
Packit Service a8c26c
{
Packit Service a8c26c
	int		fd;
Packit Service a8c26c
	int		r;
Packit Service a8c26c
	int		n;
Packit Service a8c26c
	int		m;
Packit Service a8c26c
	int		oerrno;
Packit Service a8c26c
#if CONVERT
Packit Service a8c26c
	unsigned char	buf[512];
Packit Service a8c26c
#else
Packit Service a8c26c
	unsigned char	buf[2];
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	if ((fd = sysopen(path, O_RDONLY, 0)) >= 0)
Packit Service a8c26c
	{
Packit Service a8c26c
#if CONVERT
Packit Service a8c26c
		if (ux)
Packit Service a8c26c
			n = sizeof(buf);
Packit Service a8c26c
		else
Packit Service a8c26c
#endif
Packit Service a8c26c
			n = 2;
Packit Service a8c26c
		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;
Packit Service a8c26c
		sysclose(fd);
Packit Service a8c26c
		if (ux)
Packit Service a8c26c
		{
Packit Service a8c26c
			if (r)
Packit Service a8c26c
				oerrno = ENOEXEC;
Packit Service a8c26c
			else if (m > 61 && (n = buf[60] | (buf[61]<<8) + 92) < (m - 1))
Packit Service a8c26c
				*ux = (buf[n] | (buf[n+1]<<8)) == 3;
Packit Service a8c26c
			else
Packit Service a8c26c
				*ux = 0;
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	else if (!ux)
Packit Service a8c26c
		r = -1;
Packit Service a8c26c
	else if (errno == ENOENT)
Packit Service a8c26c
	{
Packit Service a8c26c
		oerrno = errno;
Packit Service a8c26c
		r = -1;
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
	{
Packit Service a8c26c
		r = 0;
Packit Service a8c26c
		*ux = 0;
Packit Service a8c26c
	}
Packit Service a8c26c
	errno = oerrno;
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_access
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
access(const char* path, int op)
Packit Service a8c26c
{
Packit Service a8c26c
	int	r;
Packit Service a8c26c
	int	oerrno;
Packit Service a8c26c
	char	buf[PATH_MAX];
Packit Service a8c26c
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	if ((r = sysaccess(path, op)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
Packit Service a8c26c
	{
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
		r = sysaccess(buf, op);
Packit Service a8c26c
	}
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_alarm
Packit Service a8c26c
Packit Service a8c26c
extern unsigned int
Packit Service a8c26c
alarm(unsigned int s)
Packit Service a8c26c
{
Packit Service a8c26c
	unsigned int		n;
Packit Service a8c26c
	unsigned int		r;
Packit Service a8c26c
Packit Service a8c26c
	static unsigned int	a;
Packit Service a8c26c
Packit Service a8c26c
	n = (unsigned int)time(NiL);
Packit Service a8c26c
	if (a <= n)
Packit Service a8c26c
		r = 0;
Packit Service a8c26c
	else
Packit Service a8c26c
		r = a - n;
Packit Service a8c26c
	a = n + s - 1;
Packit Service a8c26c
	(void)sysalarm(s);
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_chmod
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
chmod(const char* path, mode_t mode)
Packit Service a8c26c
{
Packit Service a8c26c
	int	r;
Packit Service a8c26c
	int	oerrno;
Packit Service a8c26c
	char	buf[PATH_MAX];
Packit Service a8c26c
Packit Service a8c26c
	if ((r = syschmod(path, mode)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
Packit Service a8c26c
	{
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
		return syschmod(buf, mode);
Packit Service a8c26c
	}
Packit Service a8c26c
	if (!(r = syschmod(path, mode)) &&
Packit Service a8c26c
	    (mode & (S_IXUSR|S_IXGRP|S_IXOTH)) &&
Packit Service a8c26c
	    !suffix(path) &&
Packit Service a8c26c
	    (strlen(path) + 4) < sizeof(buf))
Packit Service a8c26c
	{
Packit Service a8c26c
		oerrno = errno;
Packit Service a8c26c
		if (!magic(path, NiL))
Packit Service a8c26c
		{
Packit Service a8c26c
			snprintf(buf, sizeof(buf), "%s.exe", path);
Packit Service a8c26c
			sysrename(path, buf);
Packit Service a8c26c
		}
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
	}
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_execve || _lib_spawn_mode
Packit Service a8c26c
Packit Service a8c26c
#if _lib_spawn_mode
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * can anyone get const prototype args straight?
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#define execve		______execve
Packit Service a8c26c
#define spawnve		______spawnve
Packit Service a8c26c
Packit Service a8c26c
#include <process.h>
Packit Service a8c26c
Packit Service a8c26c
#undef	execve
Packit Service a8c26c
#undef	spawnve
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if CONVERT
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * this intercept converts dos env vars to unix
Packit Service a8c26c
 * we'd rather intercept main but can't twist cc to do it
Packit Service a8c26c
 * getuid() gets ksh to do the right thing and
Packit Service a8c26c
 * that's our main concern
Packit Service a8c26c
 *
Packit Service a8c26c
 *	DOSPATHVARS='a b c'	convert { a b c }
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
static int		convertinit;
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * convertvars[0] names the list of env var names
Packit Service a8c26c
 * convertvars[i] are not converted
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
static const char*	convertvars[] = { "DOSPATHVARS", "PATH" };
Packit Service a8c26c
Packit Service a8c26c
static int
Packit Service a8c26c
convert(register const char* d, const char* s)
Packit Service a8c26c
{
Packit Service a8c26c
	register const char*	t;
Packit Service a8c26c
	register const char*	v;
Packit Service a8c26c
	int			i;
Packit Service a8c26c
Packit Service a8c26c
	for (i = 0; i < elementsof(convertvars); i++)
Packit Service a8c26c
	{
Packit Service a8c26c
		for (v = convertvars[i], t = s; *t && *t == *v; t++, v++);
Packit Service a8c26c
		if (*t == '=' && *v == 0)
Packit Service a8c26c
			return 0;
Packit Service a8c26c
	}
Packit Service a8c26c
	for (;;)
Packit Service a8c26c
	{
Packit Service a8c26c
		while (*d == ' ' || *d == '\t')
Packit Service a8c26c
			d++;
Packit Service a8c26c
		if (!*d)
Packit Service a8c26c
			break;
Packit Service a8c26c
		for (t = s; *t && *t == *d; d++, t++);
Packit Service a8c26c
		if (*t == '=' && (*d == ' ' || *d == '\t' || *d == 0))
Packit Service a8c26c
			return t - s + 1;
Packit Service a8c26c
		while (*d && *d != ' ' && *d != '\t')
Packit Service a8c26c
			d++;
Packit Service a8c26c
	}
Packit Service a8c26c
	return 0;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
uid_t
Packit Service a8c26c
getuid(void)
Packit Service a8c26c
{
Packit Service a8c26c
	register char*		d;
Packit Service a8c26c
	register char*		s;
Packit Service a8c26c
	register char*		t;
Packit Service a8c26c
	register char**		e;
Packit Service a8c26c
	int			n;
Packit Service a8c26c
	int			m;
Packit Service a8c26c
Packit Service a8c26c
	if (!convertinit++ && (d = getenv(convertvars[0])))
Packit Service a8c26c
		for (e = environ; s = *e; e++)
Packit Service a8c26c
			if ((n = convert(d, s)) && (m = cygwin_win32_to_posix_path_list_buf_size(s + n)) > 0)
Packit Service a8c26c
			{
Packit Service a8c26c
				if (!(t = malloc(n + m + 1)))
Packit Service a8c26c
					break;
Packit Service a8c26c
				*e = t;
Packit Service a8c26c
				memcpy(t, s, n);
Packit Service a8c26c
				cygwin_win32_to_posix_path_list(s + n, t + n);
Packit Service a8c26c
			}
Packit Service a8c26c
	return sysgetuid();
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#ifndef _P_OVERLAY
Packit Service a8c26c
#define _P_OVERLAY	(-1)
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#define DEBUG		1
Packit Service a8c26c
Packit Service a8c26c
static pid_t
Packit Service a8c26c
runve(int mode, const char* path, char* const* argv, char* const* envv)
Packit Service a8c26c
{
Packit Service a8c26c
	register char*	s;
Packit Service a8c26c
	register char**	p;
Packit Service a8c26c
	register char**	v;
Packit Service a8c26c
Packit Service a8c26c
	void*		m1;
Packit Service a8c26c
	void*		m2;
Packit Service a8c26c
	pid_t		pid;
Packit Service a8c26c
	int		oerrno;
Packit Service a8c26c
	int		ux;
Packit Service a8c26c
	int		n;
Packit Service a8c26c
#if defined(_P_DETACH) && defined(_P_NOWAIT)
Packit Service a8c26c
	int		pgrp;
Packit Service a8c26c
#endif
Packit Service a8c26c
#if CONVERT
Packit Service a8c26c
	char*		d;
Packit Service a8c26c
	char*		t;
Packit Service a8c26c
	int		m;
Packit Service a8c26c
#endif
Packit Service a8c26c
	struct stat	st;
Packit Service a8c26c
	char		buf[PATH_MAX];
Packit Service a8c26c
	char		tmp[PATH_MAX];
Packit Service a8c26c
Packit Service a8c26c
#if DEBUG
Packit Service a8c26c
	static int	trace;
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if defined(_P_DETACH) && defined(_P_NOWAIT)
Packit Service a8c26c
	if (mode == _P_DETACH)
Packit Service a8c26c
	{
Packit Service a8c26c
		/*
Packit Service a8c26c
		 * 2004-02-29 cygwin _P_DETACH is useless:
Packit Service a8c26c
		 *	spawn*() returns 0 instead of the spawned pid
Packit Service a8c26c
		 *	spawned { pgid sid } are the same as the parent
Packit Service a8c26c
		 */
Packit Service a8c26c
Packit Service a8c26c
		mode = _P_NOWAIT;
Packit Service a8c26c
		pgrp = 1;
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
		pgrp = 0;
Packit Service a8c26c
#endif
Packit Service a8c26c
	if (!envv)
Packit Service a8c26c
		envv = (char* const*)environ;
Packit Service a8c26c
	m1 = m2 = 0;
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
#if DEBUG
Packit Service a8c26c
	if (!trace)
Packit Service a8c26c
		trace = (s = getenv("_AST_exec_trace")) ? *s : 'n';
Packit Service a8c26c
#endif
Packit Service a8c26c
	if (execrate(path, buf, sizeof(buf), 0))
Packit Service a8c26c
	{
Packit Service a8c26c
		if (!sysstat(buf, &st))
Packit Service a8c26c
			path = (const char*)buf;
Packit Service a8c26c
		else
Packit Service a8c26c
			errno = oerrno;
Packit Service a8c26c
	}
Packit Service a8c26c
	if (path != (const char*)buf && sysstat(path, &st))
Packit Service a8c26c
		return -1;
Packit Service a8c26c
	if (!S_ISREG(st.st_mode) || !(st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
Packit Service a8c26c
	{
Packit Service a8c26c
		errno = EACCES;
Packit Service a8c26c
		return -1;
Packit Service a8c26c
	}
Packit Service a8c26c
	if (magic(path, &ux))
Packit Service a8c26c
	{
Packit Service a8c26c
#if _CYGWIN_fork_works
Packit Service a8c26c
		errno = ENOEXEC;
Packit Service a8c26c
		return -1;
Packit Service a8c26c
#else
Packit Service a8c26c
		ux = 1;
Packit Service a8c26c
		p = (char**)argv;
Packit Service a8c26c
		while (*p++);
Packit Service a8c26c
		if (!(v = (char**)malloc((p - (char**)argv + 2) * sizeof(char*))))
Packit Service a8c26c
		{
Packit Service a8c26c
			errno = EAGAIN;
Packit Service a8c26c
			return -1;
Packit Service a8c26c
		}
Packit Service a8c26c
		m1 = v;
Packit Service a8c26c
		p = v;
Packit Service a8c26c
		*p++ = (char*)path;
Packit Service a8c26c
		*p++ = (char*)path;
Packit Service a8c26c
		path = (const char*)pathshell();
Packit Service a8c26c
		if (*argv)
Packit Service a8c26c
			argv++;
Packit Service a8c26c
		while (*p++ = (char*)*argv++);
Packit Service a8c26c
		argv = (char* const*)v;
Packit Service a8c26c
#endif
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	/*
Packit Service a8c26c
	 * the win32 dll search order is
Packit Service a8c26c
	 *	(1) the directory of path
Packit Service a8c26c
	 *	(2) .
Packit Service a8c26c
	 *	(3) /c/(WINNT|WINDOWS)/system32 /c/(WINNT|WINDOWS)
Packit Service a8c26c
	 *	(4) the directories on $PATH
Packit Service a8c26c
	 * there are no cygwin dlls in (3), so if (1) and (2) fail
Packit Service a8c26c
	 * to produce the required dlls its up to (4)
Packit Service a8c26c
	 *
Packit Service a8c26c
	 * the standard allows PATH to be anything once the path
Packit Service a8c26c
	 * to an executable is determined; this code ensures that PATH
Packit Service a8c26c
	 * contains /bin so that at least the cygwin dll, required
Packit Service a8c26c
	 * by all cygwin executables, will be found
Packit Service a8c26c
	 */
Packit Service a8c26c
Packit Service a8c26c
	if (p = (char**)envv)
Packit Service a8c26c
	{
Packit Service a8c26c
		n = 1;
Packit Service a8c26c
		while (s = *p++)
Packit Service a8c26c
			if (strneq(s, "PATH=", 5))
Packit Service a8c26c
			{
Packit Service a8c26c
				s += 5;
Packit Service a8c26c
				do
Packit Service a8c26c
				{
Packit Service a8c26c
					s = pathcat(s, ':', NiL, "", tmp, sizeof(tmp));
Packit Service a8c26c
					if (streq(tmp, "/usr/bin/") || streq(tmp, "/bin/"))
Packit Service a8c26c
					{
Packit Service a8c26c
						n = 0;
Packit Service a8c26c
						break;
Packit Service a8c26c
					}
Packit Service a8c26c
				} while (s);
Packit Service a8c26c
				if (n)
Packit Service a8c26c
				{
Packit Service a8c26c
					n = 0;
Packit Service a8c26c
					snprintf(tmp, sizeof(tmp), "%s:/bin", *(p - 1));
Packit Service a8c26c
					*(p - 1) = tmp;
Packit Service a8c26c
				}
Packit Service a8c26c
				break;
Packit Service a8c26c
			}
Packit Service a8c26c
		if (n)
Packit Service a8c26c
		{
Packit Service a8c26c
			n = p - (char**)envv + 1;
Packit Service a8c26c
			p = (char**)envv;
Packit Service a8c26c
			if (v = (char**)malloc(n * sizeof(char*)))
Packit Service a8c26c
			{
Packit Service a8c26c
				m2 = v;
Packit Service a8c26c
				envv = (char* const*)v;
Packit Service a8c26c
				*v++ = strcpy(tmp, "PATH=/bin");
Packit Service a8c26c
				while (*v++ = *p++);
Packit Service a8c26c
			}
Packit Service a8c26c
		}
Packit Service a8c26c
#if CONVERT
Packit Service a8c26c
		if (!ux && (d = getenv(convertvars[0])))
Packit Service a8c26c
			for (p = (char**)envv; s = *p; p++)
Packit Service a8c26c
				if ((n = convert(d, s)) && (m = cygwin_posix_to_win32_path_list_buf_size(s + n)) > 0)
Packit Service a8c26c
				{
Packit Service a8c26c
					if (!(t = malloc(n + m + 1)))
Packit Service a8c26c
						break;
Packit Service a8c26c
					*p = t;
Packit Service a8c26c
					memcpy(t, s, n);
Packit Service a8c26c
					cygwin_posix_to_win32_path_list(s + n, t + n);
Packit Service a8c26c
				}
Packit Service a8c26c
#endif
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
#if DEBUG
Packit Service a8c26c
	if (trace == 'a' || trace == 'e')
Packit Service a8c26c
	{
Packit Service a8c26c
		sfprintf(sfstderr, "%s %s [", mode == _P_OVERLAY ? "_execve" : "_spawnve", path);
Packit Service a8c26c
		for (n = 0; argv[n]; n++)
Packit Service a8c26c
			sfprintf(sfstderr, " '%s'", argv[n]);
Packit Service a8c26c
		if (trace == 'e')
Packit Service a8c26c
		{
Packit Service a8c26c
			sfprintf(sfstderr, " ] [");
Packit Service a8c26c
			for (n = 0; envv[n]; n++)
Packit Service a8c26c
				sfprintf(sfstderr, " '%s'", envv[n]);
Packit Service a8c26c
		}
Packit Service a8c26c
		sfprintf(sfstderr, " ]\n");
Packit Service a8c26c
		sfsync(sfstderr);
Packit Service a8c26c
	}
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _lib_spawn_mode
Packit Service a8c26c
	if (mode != _P_OVERLAY)
Packit Service a8c26c
	{
Packit Service a8c26c
		pid = sysspawnve(mode, path, argv, envv);
Packit Service a8c26c
#if defined(_P_DETACH) && defined(_P_NOWAIT)
Packit Service a8c26c
		if (pid > 0 && pgrp)
Packit Service a8c26c
			setpgid(pid, 0);
Packit Service a8c26c
#endif
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
#endif
Packit Service a8c26c
	{
Packit Service a8c26c
#if defined(_P_DETACH) && defined(_P_NOWAIT)
Packit Service a8c26c
		if (pgrp)
Packit Service a8c26c
			setpgid(0, 0);
Packit Service a8c26c
#endif
Packit Service a8c26c
		pid = sysexecve(path, argv, envv);
Packit Service a8c26c
	}
Packit Service a8c26c
	if (m1)
Packit Service a8c26c
		free(m1);
Packit Service a8c26c
	if (m2)
Packit Service a8c26c
		free(m2);
Packit Service a8c26c
	return pid;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_execve
Packit Service a8c26c
Packit Service a8c26c
extern pid_t
Packit Service a8c26c
execve(const char* path, char* const* argv, char* const* envv)
Packit Service a8c26c
{
Packit Service a8c26c
	return runve(_P_OVERLAY, path, argv, envv);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _lib_spawn_mode
Packit Service a8c26c
Packit Service a8c26c
extern pid_t
Packit Service a8c26c
spawnve(int mode, const char* path, char* const* argv, char* const* envv)
Packit Service a8c26c
{
Packit Service a8c26c
	return runve(mode, path, argv, envv);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_getpagesize
Packit Service a8c26c
Packit Service a8c26c
extern size_t
Packit Service a8c26c
getpagesize(void)
Packit Service a8c26c
{
Packit Service a8c26c
	return 64 * 1024;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_link
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
link(const char* fp, const char* tp)
Packit Service a8c26c
{
Packit Service a8c26c
	int	r;
Packit Service a8c26c
	int	oerrno;
Packit Service a8c26c
	char	fb[PATH_MAX];
Packit Service a8c26c
	char	tb[PATH_MAX];
Packit Service a8c26c
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	if ((r = syslink(fp, tp)) && errno == ENOENT && execrate(fp, fb, sizeof(fb), 1))
Packit Service a8c26c
	{
Packit Service a8c26c
		if (execrate(tp, tb, sizeof(tb), 1))
Packit Service a8c26c
			tp = tb;
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
		r = syslink(fb, tp);
Packit Service a8c26c
	}
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_open || _win32_botch_copy
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_copy
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * this should intercept the important cases
Packit Service a8c26c
 * dup*() and exec*() fd's will not be intercepted
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
typedef struct Exe_test_s
Packit Service a8c26c
{
Packit Service a8c26c
	int		test;
Packit Service a8c26c
	ino_t		ino;
Packit Service a8c26c
	char		path[PATH_MAX];
Packit Service a8c26c
} Exe_test_t;
Packit Service a8c26c
Packit Service a8c26c
static Exe_test_t*	exe[16];
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
close(int fd)
Packit Service a8c26c
{
Packit Service a8c26c
	int		r;
Packit Service a8c26c
	int		oerrno;
Packit Service a8c26c
	struct stat	st;
Packit Service a8c26c
	char		buf[PATH_MAX];
Packit Service a8c26c
Packit Service a8c26c
	if (fd >= 0 && fd < elementsof(exe) && exe[fd])
Packit Service a8c26c
	{
Packit Service a8c26c
		r = exe[fd]->test;
Packit Service a8c26c
		exe[fd]->test = 0;
Packit Service a8c26c
		if (r > 0 && !fstat(fd, &st) && st.st_ino == exe[fd]->ino)
Packit Service a8c26c
		{
Packit Service a8c26c
			if (r = sysclose(fd))
Packit Service a8c26c
				return r;
Packit Service a8c26c
			oerrno = errno;
Packit Service a8c26c
			if (!stat(exe[fd]->path, &st) && st.st_ino == exe[fd]->ino)
Packit Service a8c26c
			{
Packit Service a8c26c
				snprintf(buf, sizeof(buf), "%s.exe", exe[fd]->path);
Packit Service a8c26c
				sysrename(exe[fd]->path, buf);
Packit Service a8c26c
			}
Packit Service a8c26c
			errno = oerrno;
Packit Service a8c26c
			return 0;
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	return sysclose(fd);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
extern ssize_t
Packit Service a8c26c
write(int fd, const void* buf, size_t n)
Packit Service a8c26c
{
Packit Service a8c26c
	if (fd >= 0 && fd < elementsof(exe) && exe[fd] && exe[fd]->test < 0)
Packit Service a8c26c
		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);
Packit Service a8c26c
	return syswrite(fd, buf, n);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
open(const char* path, int flags, ...)
Packit Service a8c26c
{
Packit Service a8c26c
	int		fd;
Packit Service a8c26c
	int		mode;
Packit Service a8c26c
	int		oerrno;
Packit Service a8c26c
	char		buf[PATH_MAX];
Packit Service a8c26c
#if _win32_botch_copy
Packit Service a8c26c
	struct stat	st;
Packit Service a8c26c
#endif
Packit Service a8c26c
	va_list		ap;
Packit Service a8c26c
Packit Service a8c26c
	va_start(ap, flags);
Packit Service a8c26c
	mode = (flags & O_CREAT) ? va_arg(ap, int) : 0;
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	fd = sysopen(path, flags, mode);
Packit Service a8c26c
#if _win32_botch_open
Packit Service a8c26c
	if (fd < 0 && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
Packit Service a8c26c
	{
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
		fd = sysopen(buf, flags, mode);
Packit Service a8c26c
	}
Packit Service a8c26c
#endif
Packit Service a8c26c
#if _win32_botch_copy
Packit Service a8c26c
	if (fd >= 0 && fd < elementsof(exe) && strlen(path) < PATH_MAX &&
Packit Service a8c26c
	    (flags & (O_CREAT|O_TRUNC)) == (O_CREAT|O_TRUNC) && (mode & 0111))
Packit Service a8c26c
	{
Packit Service a8c26c
		if (!suffix(path) && !fstat(fd, &st) && (exe[fd] || (exe[fd] = (Exe_test_t*)malloc(sizeof(Exe_test_t)))))
Packit Service a8c26c
		{
Packit Service a8c26c
			exe[fd]->test = -1;
Packit Service a8c26c
			exe[fd]->ino = st.st_ino;
Packit Service a8c26c
			strcpy(exe[fd]->path, path);
Packit Service a8c26c
		}
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
	}
Packit Service a8c26c
#endif
Packit Service a8c26c
	va_end(ap);
Packit Service a8c26c
	return fd;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_pathconf
Packit Service a8c26c
Packit Service a8c26c
extern long
Packit Service a8c26c
pathconf(const char* path, int op)
Packit Service a8c26c
{
Packit Service a8c26c
	if (sysaccess(path, F_OK))
Packit Service a8c26c
		return -1;
Packit Service a8c26c
	return syspathconf(path, op);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_rename
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
rename(const char* fp, const char* tp)
Packit Service a8c26c
{
Packit Service a8c26c
	int	r;
Packit Service a8c26c
	int	oerrno;
Packit Service a8c26c
	char	fb[PATH_MAX];
Packit Service a8c26c
	char	tb[PATH_MAX];
Packit Service a8c26c
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	if ((r = sysrename(fp, tp)) && errno == ENOENT && execrate(fp, fb, sizeof(fb), 1))
Packit Service a8c26c
	{
Packit Service a8c26c
		if (execrate(tp, tb, sizeof(tb), 1))
Packit Service a8c26c
			tp = tb;
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
		r = sysrename(fb, tp);
Packit Service a8c26c
	}
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_stat
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
stat(const char* path, struct stat* st)
Packit Service a8c26c
{
Packit Service a8c26c
	int	r;
Packit Service a8c26c
	int	oerrno;
Packit Service a8c26c
	char	buf[PATH_MAX];
Packit Service a8c26c
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	if ((r = sysstat(path, st)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
Packit Service a8c26c
	{
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
		r = sysstat(buf, st);
Packit Service a8c26c
	}
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_truncate
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
truncate(const char* path, off_t offset)
Packit Service a8c26c
{
Packit Service a8c26c
	int	r;
Packit Service a8c26c
	int	oerrno;
Packit Service a8c26c
	char	buf[PATH_MAX];
Packit Service a8c26c
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	if ((r = systruncate(path, offset)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
Packit Service a8c26c
	{
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
		r = systruncate(buf, offset);
Packit Service a8c26c
	}
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_unlink
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
unlink(const char* path)
Packit Service a8c26c
{
Packit Service a8c26c
	int		r;
Packit Service a8c26c
	int		drive;
Packit Service a8c26c
	int		mask;
Packit Service a8c26c
	int		suffix;
Packit Service a8c26c
	int		stop;
Packit Service a8c26c
	int		oerrno;
Packit Service a8c26c
	unsigned long	base;
Packit Service a8c26c
	char		buf[PATH_MAX];
Packit Service a8c26c
	char		tmp[MAX_PATH];
Packit Service a8c26c
Packit Service a8c26c
#define DELETED_DIR_1	7
Packit Service a8c26c
#define DELETED_DIR_2	16
Packit Service a8c26c
Packit Service a8c26c
	static char	deleted[] = "%c:\\temp\\.deleted\\%08x.%03x";
Packit Service a8c26c
Packit Service a8c26c
	static int	count = 0;
Packit Service a8c26c
Packit Service a8c26c
#if __CYGWIN__
Packit Service a8c26c
Packit Service a8c26c
	DWORD		fattr = FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE;
Packit Service a8c26c
	DWORD		share = FILE_SHARE_DELETE;
Packit Service a8c26c
	HANDLE		hp;
Packit Service a8c26c
	struct stat	st;
Packit Service a8c26c
	char		nat[MAX_PATH];
Packit Service a8c26c
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	if (lstat(path, &st) || !S_ISREG(st.st_mode))
Packit Service a8c26c
		goto try_unlink;
Packit Service a8c26c
	cygwin_conv_to_full_win32_path(path, nat);
Packit Service a8c26c
	if (!strncasecmp(nat + 1, ":\\temp\\", 7))
Packit Service a8c26c
		goto try_unlink;
Packit Service a8c26c
	drive = nat[0];
Packit Service a8c26c
	path = (const char*)nat;
Packit Service a8c26c
	for (;;)
Packit Service a8c26c
	{
Packit Service a8c26c
		hp = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE, NULL);
Packit Service a8c26c
		if (hp != INVALID_HANDLE_VALUE)
Packit Service a8c26c
		{
Packit Service a8c26c
			CloseHandle(hp);
Packit Service a8c26c
			errno = oerrno;
Packit Service a8c26c
			return 0;
Packit Service a8c26c
		}
Packit Service a8c26c
		if (GetLastError() != ERROR_FILE_NOT_FOUND)
Packit Service a8c26c
			break;
Packit Service a8c26c
		if (path == (const char*)buf || !execrate(path, buf, sizeof(buf), 1))
Packit Service a8c26c
		{
Packit Service a8c26c
			errno = ENOENT;
Packit Service a8c26c
			return -1;
Packit Service a8c26c
		}
Packit Service a8c26c
		path = (const char*)buf;
Packit Service a8c26c
	}
Packit Service a8c26c
#else
Packit Service a8c26c
	if (sysaccess(path, 0))
Packit Service a8c26c
#if _win32_botch_access
Packit Service a8c26c
	{
Packit Service a8c26c
		if (errno != ENOENT || !execrate(path, buf, sizeof(buf), 1) || sysaccess(buf, 0))
Packit Service a8c26c
			return -1;
Packit Service a8c26c
		path = (const char*)buf;
Packit Service a8c26c
	}
Packit Service a8c26c
#else
Packit Service a8c26c
		return -1;
Packit Service a8c26c
#endif
Packit Service a8c26c
	drive = 'C':
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
	/*
Packit Service a8c26c
	 * rename to a `deleted' path just in case the file is open
Packit Service a8c26c
	 * otherwise directory readers may choke on phantom entries
Packit Service a8c26c
	 */
Packit Service a8c26c
Packit Service a8c26c
	base = ((getuid() & 0xffff) << 16) | (time(NiL) & 0xffff);
Packit Service a8c26c
	suffix = (getpid() & 0xfff) + count++;
Packit Service a8c26c
	snprintf(tmp, sizeof(tmp), deleted, drive, base, suffix);
Packit Service a8c26c
	if (!sysrename(path, tmp))
Packit Service a8c26c
	{
Packit Service a8c26c
		path = (const char*)tmp;
Packit Service a8c26c
		goto try_delete;
Packit Service a8c26c
	}
Packit Service a8c26c
	if (errno != ENOTDIR && errno != ENOENT)
Packit Service a8c26c
		goto try_unlink;
Packit Service a8c26c
	tmp[DELETED_DIR_2] = 0;
Packit Service a8c26c
	if (sysaccess(tmp, 0))
Packit Service a8c26c
	{
Packit Service a8c26c
		mask = umask(0);
Packit Service a8c26c
		tmp[DELETED_DIR_1] = 0;
Packit Service a8c26c
		if (sysaccess(tmp, 0) && mkdir(tmp, S_IRWXU|S_IRWXG|S_IRWXO))
Packit Service a8c26c
		{
Packit Service a8c26c
			umask(mask);
Packit Service a8c26c
			goto try_unlink;
Packit Service a8c26c
		}
Packit Service a8c26c
		tmp[DELETED_DIR_1] = '\\';
Packit Service a8c26c
		r = mkdir(tmp, S_IRWXU|S_IRWXG|S_IRWXO);
Packit Service a8c26c
		umask(mask);
Packit Service a8c26c
		if (r)
Packit Service a8c26c
			goto try_unlink;
Packit Service a8c26c
		errno = 0;
Packit Service a8c26c
	}
Packit Service a8c26c
	tmp[DELETED_DIR_2] = '\\';
Packit Service a8c26c
	if (!errno && !sysrename(path, tmp))
Packit Service a8c26c
	{
Packit Service a8c26c
		path = (const char*)tmp;
Packit Service a8c26c
		goto try_delete;
Packit Service a8c26c
	}
Packit Service a8c26c
#if !__CYGWIN__
Packit Service a8c26c
	if (errno == ENOENT)
Packit Service a8c26c
	{
Packit Service a8c26c
#if !_win32_botch_access
Packit Service a8c26c
		if (execrate(path, buf, sizeof(buf), 1) && !sysrename(buf, tmp))
Packit Service a8c26c
			path = (const char*)tmp;
Packit Service a8c26c
#endif
Packit Service a8c26c
		goto try_unlink;
Packit Service a8c26c
	}
Packit Service a8c26c
#endif
Packit Service a8c26c
	stop = suffix;
Packit Service a8c26c
	do
Packit Service a8c26c
	{
Packit Service a8c26c
		snprintf(tmp, sizeof(tmp), deleted, drive, base, suffix);
Packit Service a8c26c
		if (!sysrename(path, tmp))
Packit Service a8c26c
		{
Packit Service a8c26c
			path = (const char*)tmp;
Packit Service a8c26c
			goto try_delete;
Packit Service a8c26c
		}
Packit Service a8c26c
		if (++suffix > 0xfff)
Packit Service a8c26c
			suffix = 0;
Packit Service a8c26c
	} while (suffix != stop);
Packit Service a8c26c
 try_delete:
Packit Service a8c26c
#if __CYGWIN__
Packit Service a8c26c
	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);
Packit Service a8c26c
	if (hp != INVALID_HANDLE_VALUE)
Packit Service a8c26c
	{
Packit Service a8c26c
		CloseHandle(hp);
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
		return 0;
Packit Service a8c26c
	}
Packit Service a8c26c
#endif
Packit Service a8c26c
 try_unlink:
Packit Service a8c26c
	errno = oerrno;
Packit Service a8c26c
	return sysunlink(path);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if _win32_botch_utime
Packit Service a8c26c
Packit Service a8c26c
#if __CYGWIN__
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * cygwin refuses to set st_ctime for some operations
Packit Service a8c26c
 * this rejects that refusal
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
static void
Packit Service a8c26c
ctime_now(const char* path)
Packit Service a8c26c
{
Packit Service a8c26c
	HANDLE		hp;
Packit Service a8c26c
	SYSTEMTIME	st;
Packit Service a8c26c
	FILETIME	ct;
Packit Service a8c26c
	WIN32_FIND_DATA	ff;
Packit Service a8c26c
	struct stat	fs;
Packit Service a8c26c
	int		oerrno;
Packit Service a8c26c
	char		tmp[MAX_PATH];
Packit Service a8c26c
Packit Service a8c26c
	if (sysstat(path, &fs) || (fs.st_mode & S_IWUSR) || syschmod(path, (fs.st_mode | S_IWUSR) & S_IPERM))
Packit Service a8c26c
		fs.st_mode = 0;
Packit Service a8c26c
	cygwin_conv_to_win32_path(path, tmp);
Packit Service a8c26c
	hp = CreateFile(tmp, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
Packit Service a8c26c
	if (hp && hp != INVALID_HANDLE_VALUE)
Packit Service a8c26c
	{
Packit Service a8c26c
		GetSystemTime(&st);
Packit Service a8c26c
		SystemTimeToFileTime(&st, &ct);
Packit Service a8c26c
		SetFileTime(hp, &ct, 0, 0);
Packit Service a8c26c
		CloseHandle(hp);
Packit Service a8c26c
	}
Packit Service a8c26c
	if (fs.st_mode)
Packit Service a8c26c
		syschmod(path, fs.st_mode & S_IPERM);
Packit Service a8c26c
	errno = oerrno;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#else
Packit Service a8c26c
Packit Service a8c26c
#define ctime_now(p)
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
utimes(const char* path, const struct timeval* ut)
Packit Service a8c26c
{
Packit Service a8c26c
	int	r;
Packit Service a8c26c
	int	oerrno;
Packit Service a8c26c
	char	buf[PATH_MAX];
Packit Service a8c26c
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	if ((r = sysutimes(path, ut)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
Packit Service a8c26c
	{
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
		r = sysutimes(path = buf, ut);
Packit Service a8c26c
	}
Packit Service a8c26c
	if (!r)
Packit Service a8c26c
		ctime_now(path);
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
extern int
Packit Service a8c26c
utime(const char* path, const struct utimbuf* ut)
Packit Service a8c26c
{
Packit Service a8c26c
	int	r;
Packit Service a8c26c
	int	oerrno;
Packit Service a8c26c
	char	buf[PATH_MAX];
Packit Service a8c26c
Packit Service a8c26c
	oerrno = errno;
Packit Service a8c26c
	if ((r = sysutime(path, ut)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
Packit Service a8c26c
	{
Packit Service a8c26c
		errno = oerrno;
Packit Service a8c26c
		r = sysutime(path = buf, ut);
Packit Service a8c26c
	}
Packit Service a8c26c
	if (!r)
Packit Service a8c26c
		ctime_now(path);
Packit Service a8c26c
	return r;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * some systems (sun) miss a few functions required by their
Packit Service a8c26c
 * own bsd-like macros
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#if !_lib_bzero || defined(bzero)
Packit Service a8c26c
Packit Service a8c26c
#undef	bzero
Packit Service a8c26c
Packit Service a8c26c
void
Packit Service a8c26c
bzero(void* b, size_t n)
Packit Service a8c26c
{
Packit Service a8c26c
	memset(b, 0, n);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if !_lib_getpagesize || defined(getpagesize)
Packit Service a8c26c
Packit Service a8c26c
#ifndef OMITTED
Packit Service a8c26c
#define OMITTED	1
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#undef	getpagesize
Packit Service a8c26c
Packit Service a8c26c
#ifdef	_SC_PAGESIZE
Packit Service a8c26c
#undef	_AST_PAGESIZE
Packit Service a8c26c
#define _AST_PAGESIZE	(int)sysconf(_SC_PAGESIZE)
Packit Service a8c26c
#else
Packit Service a8c26c
#ifndef _AST_PAGESIZE
Packit Service a8c26c
#define _AST_PAGESIZE	4096
Packit Service a8c26c
#endif
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
int
Packit Service a8c26c
getpagesize()
Packit Service a8c26c
{
Packit Service a8c26c
	return _AST_PAGESIZE;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#if __CYGWIN__ && defined(__IMPORT__) && defined(__EXPORT__)
Packit Service a8c26c
Packit Service a8c26c
#ifndef OMITTED
Packit Service a8c26c
#define OMITTED	1
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * a few _imp__FUNCTION symbols are needed to avoid
Packit Service a8c26c
 * static link multiple definitions
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#ifndef strtod
Packit Service a8c26c
__EXPORT__ double (*_imp__strtod)(const char*, char**) = strtod;
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#ifndef OMITTED
Packit Service a8c26c
Packit Service a8c26c
NoN(omitted)
Packit Service a8c26c
Packit Service a8c26c
#endif