X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=win32%2Fwin32.c;h=2b31878a52959ffeec84fae6e073d9df6acfcd1b;hb=22d4bb9ccb8701e68f9243547d7e3a3c55f70908;hp=6856884472bef2831bf986613c50e89f773d3272;hpb=4b19af017623bfa3bb72bb164598a517f586e0d3;p=p5sagit%2Fp5-mst-13.2.git diff --git a/win32/win32.c b/win32/win32.c index 6856884..2b31878 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -436,12 +436,19 @@ win32_os_id(void) DllExport int win32_getpid(void) { + int pid; #ifdef USE_ITHREADS dTHXo; if (w32_pseudo_id) return -((int)w32_pseudo_id); #endif - return _getpid(); + pid = _getpid(); + /* Windows 9x appears to always reports a pid for threads and processes + * that has the high bit set. So we treat the lower 31 bits as the + * "real" PID for Perl's purposes. */ + if (IsWin95() && pid < 0) + pid = -pid; + return pid; } /* Tokenize a string. Words are null-separated, and the list @@ -568,7 +575,11 @@ do_aspawn(void *vreally, void **vmark, void **vsp) (const char* const*)argv); } - if (flag != P_NOWAIT) { + if (flag == P_NOWAIT) { + if (IsWin95()) + PL_statusvalue = -1; /* >16bits hint for pp_system() */ + } + else { if (status < 0) { dTHR; if (ckWARN(WARN_EXEC)) @@ -657,7 +668,11 @@ do_spawn2(char *cmd, int exectype) cmd = argv[0]; Safefree(argv); } - if (exectype != EXECF_SPAWN_NOWAIT) { + if (exectype == EXECF_SPAWN_NOWAIT) { + if (IsWin95()) + PL_statusvalue = -1; /* >16bits hint for pp_system() */ + } + else { if (status < 0) { dTHR; if (ckWARN(WARN_EXEC)) @@ -1021,10 +1036,11 @@ win32_kill(int pid, int sig) { dTHXo; HANDLE hProcess; + long child; #ifdef USE_ITHREADS if (pid < 0) { /* it is a pseudo-forked child */ - long child = find_pseudo_pid(-pid); + child = find_pseudo_pid(-pid); if (child >= 0) { if (!sig) return 0; @@ -1034,11 +1050,15 @@ win32_kill(int pid, int sig) return 0; } } + else if (IsWin95()) { + pid = -pid; + goto alien_process; + } } else #endif { - long child = find_pid(pid); + child = find_pid(pid); if (child >= 0) { if (!sig) return 0; @@ -1049,7 +1069,9 @@ win32_kill(int pid, int sig) } } else { - hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid); +alien_process: + hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, + (IsWin95() ? -pid : pid)); if (hProcess) { if (!sig) return 0; @@ -1611,7 +1633,7 @@ win32_uname(struct utsname *name) char *arch; GetSystemInfo(&info); -#if defined(__BORLANDC__) || defined(__MINGW32__) +#if (defined(__BORLANDC__)&&(__BORLANDC__<=0x520)) || defined(__MINGW32__) switch (info.u.s.wProcessorArchitecture) { #else switch (info.wProcessorArchitecture) { @@ -1636,15 +1658,16 @@ DllExport int win32_waitpid(int pid, int *status, int flags) { dTHXo; + DWORD timeout = (flags & WNOHANG) ? 0 : INFINITE; int retval = -1; + long child; if (pid == -1) /* XXX threadid == 1 ? */ return win32_wait(status); #ifdef USE_ITHREADS else if (pid < 0) { - long child = find_pseudo_pid(-pid); + child = find_pseudo_pid(-pid); if (child >= 0) { HANDLE hThread = w32_pseudo_child_handles[child]; - DWORD timeout = (flags & WNOHANG) ? 0 : INFINITE; DWORD waitcode = WaitForSingleObject(hThread, timeout); if (waitcode == WAIT_TIMEOUT) { return 0; @@ -1654,41 +1677,59 @@ win32_waitpid(int pid, int *status, int flags) *status = (int)((waitcode & 0xff) << 8); retval = (int)w32_pseudo_child_pids[child]; remove_dead_pseudo_process(child); - return retval; + return -retval; } } else errno = ECHILD; } + else if (IsWin95()) { + pid = -pid; + goto alien_process; + } } #endif else { - long child = find_pid(pid); + HANDLE hProcess; + DWORD waitcode; + child = find_pid(pid); if (child >= 0) { - HANDLE hProcess = w32_child_handles[child]; - DWORD timeout = (flags & WNOHANG) ? 0 : INFINITE; - DWORD waitcode = WaitForSingleObject(hProcess, timeout); + hProcess = w32_child_handles[child]; + waitcode = WaitForSingleObject(hProcess, timeout); if (waitcode == WAIT_TIMEOUT) { return 0; } else if (waitcode != WAIT_FAILED) { - if (GetExitCodeProcess(hProcess, &waitcode)) { - *status = (int)((waitcode & 0xff) << 8); - retval = (int)w32_child_pids[child]; - remove_dead_process(child); - return retval; - } + if (GetExitCodeProcess(hProcess, &waitcode)) { + *status = (int)((waitcode & 0xff) << 8); + retval = (int)w32_child_pids[child]; + remove_dead_process(child); + return retval; + } } else errno = ECHILD; } else { - retval = cwait(status, pid, WAIT_CHILD); - /* cwait() returns "correctly" on Borland */ -#ifndef __BORLANDC__ - if (status) - *status *= 256; -#endif +alien_process: + hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, + (IsWin95() ? -pid : pid)); + if (hProcess) { + waitcode = WaitForSingleObject(hProcess, timeout); + if (waitcode == WAIT_TIMEOUT) { + return 0; + } + else if (waitcode != WAIT_FAILED) { + if (GetExitCodeProcess(hProcess, &waitcode)) { + *status = (int)((waitcode & 0xff) << 8); + CloseHandle(hProcess); + return pid; + } + } + CloseHandle(hProcess); + } + else + errno = ECHILD; } } return retval >= 0 ? pid : retval; @@ -1720,7 +1761,7 @@ win32_wait(int *status) *status = (int)((exitcode & 0xff) << 8); retval = (int)w32_pseudo_child_pids[i]; remove_dead_pseudo_process(i); - return retval; + return -retval; } } } @@ -1817,53 +1858,6 @@ win32_crypt(const char *txt, const char *salt) #endif } -/* C doesn't like repeat struct definitions */ - -#if defined(USE_FIXED_OSFHANDLE) || defined(PERL_MSVCRT_READFIX) - -#ifndef _CRTIMP -#define _CRTIMP __declspec(dllimport) -#endif - -/* - * Control structure for lowio file handles - */ -typedef struct { - long osfhnd; /* underlying OS file HANDLE */ - char osfile; /* attributes of file (e.g., open in text mode?) */ - char pipech; /* one char buffer for handles opened on pipes */ - int lockinitflag; - CRITICAL_SECTION lock; -} ioinfo; - - -/* - * Array of arrays of control structures for lowio files. - */ -EXTERN_C _CRTIMP ioinfo* __pioinfo[]; - -/* - * Definition of IOINFO_L2E, the log base 2 of the number of elements in each - * array of ioinfo structs. - */ -#define IOINFO_L2E 5 - -/* - * Definition of IOINFO_ARRAY_ELTS, the number of elements in ioinfo array - */ -#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) - -/* - * Access macros for getting at an ioinfo struct and its fields from a - * file handle - */ -#define _pioinfo(i) (__pioinfo[(i) >> IOINFO_L2E] + ((i) & (IOINFO_ARRAY_ELTS - 1))) -#define _osfhnd(i) (_pioinfo(i)->osfhnd) -#define _osfile(i) (_pioinfo(i)->osfile) -#define _pipech(i) (_pioinfo(i)->pipech) - -#endif - #ifdef USE_FIXED_OSFHANDLE #define FOPEN 0x01 /* file handle open */ @@ -1902,10 +1896,6 @@ EXTERN_C _CRTIMP ioinfo* __pioinfo[]; * -- BKS, 1-23-2000 */ -/* since we are not doing a dup2(), this works fine */ - -#define _set_osfhnd(fh, osfh) (void)(_osfhnd(fh) = osfh) - /* create an ioinfo entry, kill its handle, and steal the entry */ static int @@ -2322,7 +2312,25 @@ win32_abort(void) DllExport int win32_fstat(int fd,struct stat *sbufptr) { +#ifdef __BORLANDC__ + /* A file designated by filehandle is not shown as accessible + * for write operations, probably because it is opened for reading. + * --Vadim Konovalov + */ + int rc = fstat(fd,sbufptr); + BY_HANDLE_FILE_INFORMATION bhfi; + if (GetFileInformationByHandle((HANDLE)_get_osfhandle(fd), &bhfi)) { + sbufptr->st_mode &= 0xFE00; + if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) + sbufptr->st_mode |= (S_IREAD + (S_IREAD >> 3) + (S_IREAD >> 6)); + else + sbufptr->st_mode |= ((S_IREAD|S_IWRITE) + ((S_IREAD|S_IWRITE) >> 3) + + ((S_IREAD|S_IWRITE) >> 6)); + } + return rc; +#else return fstat(fd,sbufptr); +#endif } DllExport int @@ -3273,9 +3281,12 @@ RETRY: if (mode == P_NOWAIT) { /* asynchronous spawn -- store handle, return PID */ - w32_child_handles[w32_num_children] = ProcessInformation.hProcess; - w32_child_pids[w32_num_children] = ProcessInformation.dwProcessId; ret = (int)ProcessInformation.dwProcessId; + if (IsWin95() && ret < 0) + ret = -ret; + + w32_child_handles[w32_num_children] = ProcessInformation.hProcess; + w32_child_pids[w32_num_children] = (DWORD)ret; ++w32_num_children; } else { @@ -3520,6 +3531,25 @@ win32_dynaload(const char* filename) { dTHXo; HMODULE hModule; + char buf[MAX_PATH+1]; + char *first; + + /* LoadLibrary() doesn't recognize forward slashes correctly, + * so turn 'em back. */ + first = strchr(filename, '/'); + if (first) { + STRLEN len = strlen(filename); + if (len <= MAX_PATH) { + strcpy(buf, filename); + filename = &buf[first - filename]; + while (*filename) { + if (*filename == '/') + *(char*)filename = '\\'; + ++filename; + } + filename = buf; + } + } if (USING_WIDE()) { WCHAR wfilename[MAX_PATH+1]; A2WHELPER(filename, wfilename, sizeof(wfilename)); @@ -3835,8 +3865,11 @@ XS(w32_Spawn) &stStartInfo, /* -> Startup info */ &stProcInfo)) /* <- Process info (if OK) */ { + int pid = (int)stProcInfo.dwProcessId; + if (IsWin95() && pid < 0) + pid = -pid; + sv_setiv(ST(2), pid); CloseHandle(stProcInfo.hThread);/* library source code does this. */ - sv_setiv(ST(2), stProcInfo.dwProcessId); bSuccess = TRUE; } XSRETURN_IV(bSuccess); @@ -3865,6 +3898,9 @@ XS(w32_GetShortPathName) shortpath = sv_mortalcopy(ST(0)); SvUPGRADE(shortpath, SVt_PV); + if (!SvPVX(shortpath) || !SvLEN(shortpath)) + XSRETURN_UNDEF; + /* src == target is allowed */ do { len = GetShortPathName(SvPVX(shortpath), @@ -3894,6 +3930,9 @@ XS(w32_GetFullPathName) filename = ST(0); fullpath = sv_mortalcopy(filename); SvUPGRADE(fullpath, SVt_PV); + if (!SvPVX(fullpath) || !SvLEN(fullpath)) + XSRETURN_UNDEF; + do { len = GetFullPathName(SvPVX(filename), SvLEN(fullpath), @@ -4090,7 +4129,7 @@ Perl_sys_intern_dup(pTHX_ struct interp_intern *src, struct interp_intern *dst) Newz(1313, dst->children, 1, child_tab); dst->pseudo_id = 0; Newz(1313, dst->pseudo_children, 1, child_tab); - dst->thr_intern.Winit_socktype = src->thr_intern.Winit_socktype; + dst->thr_intern.Winit_socktype = 0; } # endif /* USE_ITHREADS */ #endif /* HAVE_INTERP_INTERN */