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