X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=win32%2Fwin32.c;h=9a0f910b42654d8826fe3893c906b9818f31f961;hb=3bf198a5e20d135d4136d3233d58cf49a70772d9;hp=7bb003d1691d3aaeafafe03d6fd04945c732ce7f;hpb=5aabfad66ac77650f584e2f07af91645e19fe296;p=p5sagit%2Fp5-mst-13.2.git diff --git a/win32/win32.c b/win32/win32.c index 7bb003d..9a0f910 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -31,45 +31,43 @@ #define CROAK croak #define WARN warn +static DWORD IdOS(void); + extern WIN32_IOSUBSYSTEM win32stdio; __declspec(thread) PWIN32_IOSUBSYSTEM pIOSubSystem = &win32stdio; /*__declspec(thread) PWIN32_IOSUBSYSTEM pIOSubSystem = NULL;*/ BOOL ProbeEnv = FALSE; -DWORD Win32System; +DWORD Win32System = (DWORD)-1; char szShellPath[MAX_PATH+1]; char szPerlLibRoot[MAX_PATH+1]; HANDLE PerlDllHandle = INVALID_HANDLE_VALUE; int IsWin95(void) { - return (Win32System == VER_PLATFORM_WIN32_WINDOWS); + return (IdOS() == VER_PLATFORM_WIN32_WINDOWS); } int IsWinNT(void) { - return (Win32System == VER_PLATFORM_WIN32_NT); + return (IdOS() == VER_PLATFORM_WIN32_NT); } void * SetIOSubSystem(void *p) { + PWIN32_IOSUBSYSTEM old = pIOSubSystem; if (p) { PWIN32_IOSUBSYSTEM pio = (PWIN32_IOSUBSYSTEM)p; - if (pio->signature_begin == 12345678L && pio->signature_end == 87654321L) { - PWIN32_IOSUBSYSTEM pold = pIOSubSystem; pIOSubSystem = pio; - return pold; } } else { - /* re-assign our stuff */ -/* pIOSubSystem = &win32stdio; */ - pIOSubSystem = NULL; + pIOSubSystem = &win32stdio; } - return pIOSubSystem; + return old; } char * @@ -302,16 +300,18 @@ my_pclose(PerlIO *fp) return win32_pclose(fp); } -static void +static DWORD IdOS(void) { - OSVERSIONINFO osver; + static OSVERSIONINFO osver; - memset(&osver, 0, sizeof(OSVERSIONINFO)); - osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osver); - Win32System = osver.dwPlatformId; - return; + if (osver.dwPlatformId != Win32System) { + memset(&osver, 0, sizeof(OSVERSIONINFO)); + osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osver); + Win32System = osver.dwPlatformId; + } + return (Win32System); } static char * @@ -322,7 +322,7 @@ GetShell(void) static char* szWinNTDefaultShell = "cmd.exe"; if (!ProbeEnv) { - IdOS(), ProbeEnv = TRUE; + ProbeEnv = TRUE; if (IsWin95()) { strcpy(szShellPath, szWin95DefaultShell); } @@ -345,7 +345,7 @@ do_aspawn(void* really, void** mark, void** arglast) SV *sv = (SV*)really; SV** pSv = (SV**)mark; - New(1110, argv, (arglast - mark) + 4, char*); + New(1310, argv, (arglast - mark) + 4, char*); if(sv != Nullsv) { cmd = SvPV(sv, length); @@ -392,8 +392,8 @@ do_spawn(char *cmd) /* see if there are shell metacharacters in it */ if(!HasRedirection(cmd)) { - New(1102,argv, strlen(cmd) / 2 + 2, char*); - New(1103,cmd2, strlen(cmd) + 1, char); + New(1301,argv, strlen(cmd) / 2 + 2, char*); + New(1302,cmd2, strlen(cmd) + 1, char); strcpy(cmd2, cmd); a = argv; for (s = cmd2; *s;) { @@ -477,7 +477,7 @@ opendir(char *filename) * } */ /* Get us a DIR structure */ - Newz(1501, p, 1, DIR); + Newz(1303, p, 1, DIR); if(p == NULL) return NULL; @@ -499,7 +499,7 @@ opendir(char *filename) * the filenames that we find. */ idx = strlen(FindData.cFileName)+1; - New(1502, p->start, idx, char); + New(1304, p->start, idx, char); if(p->start == NULL) { CROAK("opendir: malloc failed!\n"); } @@ -756,6 +756,12 @@ win32_errno(void) return (pIOSubSystem->pfnerrno()); } +DllExport char *** +win32_environ(void) +{ + return (pIOSubSystem->pfnenviron()); +} + /* the rest are the remapped stdio routines */ DllExport FILE * win32_stderr(void) @@ -839,6 +845,12 @@ win32_vfprintf(FILE *fp, const char *format, va_list args) return (pIOSubSystem->pfnvfprintf(fp, format, args)); } +DllExport int +win32_vprintf(const char *format, va_list args) +{ + return (pIOSubSystem->pfnvprintf(format, args)); +} + DllExport size_t win32_fread(void *buf, size_t size, size_t count, FILE *fp) { @@ -996,6 +1008,18 @@ win32_setmode(int fd, int mode) return pIOSubSystem->pfnsetmode(fd, mode); } +DllExport long +win32_lseek(int fd, long offset, int origin) +{ + return pIOSubSystem->pfnlseek(fd, offset, origin); +} + +DllExport long +win32_tell(int fd) +{ + return pIOSubSystem->pfntell(fd); +} + DllExport int win32_open(const char *path, int flag, ...) { @@ -1018,6 +1042,12 @@ win32_close(int fd) } DllExport int +win32_eof(int fd) +{ + return pIOSubSystem->pfneof(fd); +} + +DllExport int win32_dup(int fd) { return pIOSubSystem->pfndup(fd); @@ -1046,16 +1076,19 @@ win32_mkdir(const char *dir, int mode) { return pIOSubSystem->pfnmkdir(dir); /* just ignore mode */ } + DllExport int win32_rmdir(const char *dir) { return pIOSubSystem->pfnrmdir(dir); } + DllExport int win32_chdir(const char *dir) { return pIOSubSystem->pfnchdir(dir); } + DllExport int win32_spawnvpe(int mode, const char *cmdname, const char *const *argv, const char *const *envp) @@ -1087,3 +1120,57 @@ stolen_get_osfhandle(int fd) { return pIOSubSystem->pfn_get_osfhandle(fd); } + + +/* + * Extras. + */ + +/* simulate flock by locking a range on the file */ + +#define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError())) +#define LK_LEN 0xffff0000 + +DllExport int +win32_flock(int fd, int oper) +{ + OVERLAPPED o; + int i = -1; + HANDLE fh; + + if (!IsWinNT()) { + croak("flock() unimplemented on this platform"); + return -1; + } + + fh = (HANDLE)stolen_get_osfhandle(fd); + memset(&o, 0, sizeof(o)); + + switch(oper) { + case LOCK_SH: /* shared lock */ + LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, 0, &o),i); + break; + case LOCK_EX: /* exclusive lock */ + LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o),i); + break; + case LOCK_SH|LOCK_NB: /* non-blocking shared lock */ + LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o),i); + break; + case LOCK_EX|LOCK_NB: /* non-blocking exclusive lock */ + LK_ERR(LockFileEx(fh, + LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, + 0, LK_LEN, 0, &o),i); + break; + case LOCK_UN: /* unlock lock */ + LK_ERR(UnlockFileEx(fh, 0, LK_LEN, 0, &o),i); + break; + default: /* unknown */ + errno = EINVAL; + break; + } + return i; +} + +#undef LK_ERR +#undef LK_LEN +