X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=win32%2Fwin32.c;h=41788273b732dc47bf4be9743e2b1eb98ce15f95;hb=abc0a0153433fe6596e1ca3a6b5572dc424d0f11;hp=67aeae68ecab0b164ebcdf02c0e8dd1f4af1457b;hpb=c623ac675720b3145d48cc2ea9474a0f3e0cbbca;p=p5sagit%2Fp5-mst-13.2.git diff --git a/win32/win32.c b/win32/win32.c index 67aeae6..4178827 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -85,15 +85,13 @@ int _fcloseall(); # define win32_get_sitelib g_win32_get_sitelib # undef win32_get_vendorlib # define win32_get_vendorlib g_win32_get_vendorlib -# undef do_spawn -# define do_spawn g_do_spawn # undef getlogin # define getlogin g_getlogin #endif static void get_shell(void); static long tokenize(const char *str, char **dest, char ***destv); - int do_spawn2(char *cmd, int exectype); +static int do_spawn2(pTHX_ char *cmd, int exectype); static BOOL has_shell_metachars(char *ptr); static long filetime_to_clock(PFILETIME ft); static BOOL filetime_from_time(PFILETIME ft, time_t t); @@ -208,7 +206,6 @@ get_emd_part(SV **prev_pathp, char *trailing_path, ...) char *ptr; char *optr; char *strip; - int oldsize, newsize; STRLEN baselen; va_start(ap, trailing_path); @@ -286,8 +283,6 @@ win32_get_xlib(const char *pl, const char *xlib, const char *libname) dTHX; char regstr[40]; char pathstr[MAX_PATH+1]; - DWORD datalen; - int len, newsize; SV *sv1 = Nullsv; SV *sv2 = Nullsv; @@ -519,12 +514,8 @@ get_shell(void) } int -do_aspawn(void *vreally, void **vmark, void **vsp) +Perl_do_aspawn(pTHX_ SV *really, SV **mark, SV **sp) { - dTHX; - SV *really = (SV*)vreally; - SV **mark = (SV**)vmark; - SV **sp = (SV**)vsp; char **argv; char *str; int status; @@ -610,10 +601,9 @@ find_next_space(const char *s) return (char*)s; } -int -do_spawn2(char *cmd, int exectype) +static int +do_spawn2(pTHX_ char *cmd, int exectype) { - dTHX; char **a; char *s; char **argv; @@ -703,21 +693,21 @@ do_spawn2(char *cmd, int exectype) } int -do_spawn(char *cmd) +Perl_do_spawn(pTHX_ char *cmd) { - return do_spawn2(cmd, EXECF_SPAWN); + return do_spawn2(aTHX_ cmd, EXECF_SPAWN); } int -do_spawn_nowait(char *cmd) +Perl_do_spawn_nowait(pTHX_ char *cmd) { - return do_spawn2(cmd, EXECF_SPAWN_NOWAIT); + return do_spawn2(aTHX_ cmd, EXECF_SPAWN_NOWAIT); } bool Perl_do_exec(pTHX_ char *cmd) { - do_spawn2(cmd, EXECF_EXEC); + do_spawn2(aTHX_ cmd, EXECF_EXEC); return FALSE; } @@ -1022,7 +1012,7 @@ find_pid(int pid) dTHX; long child = w32_num_children; while (--child >= 0) { - if (w32_child_pids[child] == pid) + if ((int)w32_child_pids[child] == pid) return child; } return -1; @@ -1049,7 +1039,7 @@ find_pseudo_pid(int pid) dTHX; long child = w32_num_pseudo_children; while (--child >= 0) { - if (w32_pseudo_child_pids[child] == pid) + if ((int)w32_pseudo_child_pids[child] == pid) return child; } return -1; @@ -1220,7 +1210,7 @@ win32_stat(const char *path, Stat_t *sbuf) #if defined(WIN64) || defined(USE_LARGE_FILES) res = _wstati64(pwbuffer, sbuf); #else - res = _wstat(pwbuffer, sbuf); + res = _wstat(pwbuffer, (struct _stat*)sbuf); #endif } else { @@ -1654,6 +1644,38 @@ win32_utime(const char *filename, struct utimbuf *times) return rc; } +typedef union { + unsigned __int64 ft_i64; + FILETIME ft_val; +} FT_t; + +#ifdef __GNUC__ +#define Const64(x) x##LL +#else +#define Const64(x) x##i64 +#endif +/* Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 */ +#define EPOCH_BIAS Const64(116444736000000000) + +/* NOTE: This does not compute the timezone info (doing so can be expensive, + * and appears to be unsupported even by glibc) */ +DllExport int +win32_gettimeofday(struct timeval *tp, void *not_used) +{ + FT_t ft; + + /* this returns time in 100-nanosecond units (i.e. tens of usecs) */ + GetSystemTimeAsFileTime(&ft.ft_val); + + /* seconds since epoch */ + tp->tv_sec = (long)((ft.ft_i64 - EPOCH_BIAS) / Const64(10000000)); + + /* microseconds remaining */ + tp->tv_usec = (long)((ft.ft_i64 / Const64(10)) % Const64(1000000)); + + return 0; +} + DllExport int win32_uname(struct utsname *name) { @@ -1720,15 +1742,17 @@ win32_uname(struct utsname *name) /* machine (architecture) */ { SYSTEM_INFO info; + DWORD procarch; char *arch; GetSystemInfo(&info); #if (defined(__BORLANDC__)&&(__BORLANDC__<=0x520)) \ || (defined(__MINGW32__) && !defined(_ANONYMOUS_UNION)) - switch (info.u.s.wProcessorArchitecture) { + procarch = info.u.s.wProcessorArchitecture; #else - switch (info.wProcessorArchitecture) { + procarch = info.wProcessorArchitecture; #endif + switch (procarch) { case PROCESSOR_ARCHITECTURE_INTEL: arch = "x86"; break; case PROCESSOR_ARCHITECTURE_MIPS: @@ -1737,10 +1761,45 @@ win32_uname(struct utsname *name) arch = "alpha"; break; case PROCESSOR_ARCHITECTURE_PPC: arch = "ppc"; break; - default: +#ifdef PROCESSOR_ARCHITECTURE_SHX + case PROCESSOR_ARCHITECTURE_SHX: + arch = "shx"; break; +#endif +#ifdef PROCESSOR_ARCHITECTURE_ARM + case PROCESSOR_ARCHITECTURE_ARM: + arch = "arm"; break; +#endif +#ifdef PROCESSOR_ARCHITECTURE_IA64 + case PROCESSOR_ARCHITECTURE_IA64: + arch = "ia64"; break; +#endif +#ifdef PROCESSOR_ARCHITECTURE_ALPHA64 + case PROCESSOR_ARCHITECTURE_ALPHA64: + arch = "alpha64"; break; +#endif +#ifdef PROCESSOR_ARCHITECTURE_MSIL + case PROCESSOR_ARCHITECTURE_MSIL: + arch = "msil"; break; +#endif +#ifdef PROCESSOR_ARCHITECTURE_AMD64 + case PROCESSOR_ARCHITECTURE_AMD64: + arch = "amd64"; break; +#endif +#ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 + case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: + arch = "ia32-64"; break; +#endif +#ifdef PROCESSOR_ARCHITECTURE_UNKNOWN + case PROCESSOR_ARCHITECTURE_UNKNOWN: arch = "unknown"; break; +#endif + default: + sprintf(name->machine, "unknown(0x%x)", procarch); + arch = name->machine; + break; } - strcpy(name->machine, arch); + if (name->machine != arch) + strcpy(name->machine, arch); } return 0; } @@ -1952,7 +2011,6 @@ win32_internal_wait(int *status, DWORD timeout) } } -FAILED: errno = GetLastError(); return -1; } @@ -2647,22 +2705,28 @@ win32_popen(const char *command, const char *mode) #ifdef USE_RTL_POPEN return _popen(command, mode); #else + dTHX; int p[2]; int parent, child; int stdfd, oldfd; int ourmode; int childpid; + DWORD nhandle; + HANDLE old_h; + int lock_held = 0; /* establish which ends read and write */ if (strchr(mode,'w')) { stdfd = 0; /* stdin */ parent = 1; child = 0; + nhandle = STD_INPUT_HANDLE; } else if (strchr(mode,'r')) { stdfd = 1; /* stdout */ parent = 0; child = 1; + nhandle = STD_OUTPUT_HANDLE; } else return NULL; @@ -2678,7 +2742,7 @@ win32_popen(const char *command, const char *mode) /* the child doesn't inherit handles */ ourmode |= O_NOINHERIT; - if (win32_pipe( p, 512, ourmode) == -1) + if (win32_pipe(p, 512, ourmode) == -1) return NULL; /* save current stdfd */ @@ -2693,12 +2757,25 @@ win32_popen(const char *command, const char *mode) /* close the child end in parent */ win32_close(p[child]); + /* save the old std handle, and set the std handle */ + OP_REFCNT_LOCK; + lock_held = 1; + old_h = GetStdHandle(nhandle); + SetStdHandle(nhandle, (HANDLE)_get_osfhandle(stdfd)); + /* start the child */ { dTHX; if ((childpid = do_spawn_nowait((char*)command)) == -1) goto cleanup; + /* restore the old std handle */ + if (lock_held) { + SetStdHandle(nhandle, old_h); + OP_REFCNT_UNLOCK; + lock_held = 0; + } + /* revert stdfd to whatever it was before */ if (win32_dup2(oldfd, stdfd) == -1) goto cleanup; @@ -2721,6 +2798,11 @@ cleanup: /* we don't need to check for errors here */ win32_close(p[0]); win32_close(p[1]); + if (lock_held) { + SetStdHandle(nhandle, old_h); + OP_REFCNT_UNLOCK; + lock_held = 0; + } if (oldfd != -1) { win32_dup2(oldfd, stdfd); win32_close(oldfd); @@ -3551,7 +3633,7 @@ qualified_path(const char *cmd) if (*pathstr == '"') { /* foo;"baz;etc";bar */ pathstr++; /* skip initial '"' */ while (*pathstr && *pathstr != '"') { - if (curfullcmd-fullcmd < MAX_PATH-cmdlen-5) + if ((STRLEN)(curfullcmd-fullcmd) < MAX_PATH-cmdlen-5) *curfullcmd++ = *pathstr; pathstr++; } @@ -3559,7 +3641,7 @@ qualified_path(const char *cmd) pathstr++; /* skip trailing '"' */ } else { - if (curfullcmd-fullcmd < MAX_PATH-cmdlen-5) + if ((STRLEN)(curfullcmd-fullcmd) < MAX_PATH-cmdlen-5) *curfullcmd++ = *pathstr; pathstr++; } @@ -3572,7 +3654,7 @@ qualified_path(const char *cmd) *curfullcmd++ = '\\'; } } -GIVE_UP: + Safefree(fullcmd); return Nullch; } @@ -3731,14 +3813,14 @@ win32_spawnvp(int mode, const char *cmdname, const char *const *argv) StartupInfo.hStdInput = tbl.childStdIn; StartupInfo.hStdOutput = tbl.childStdOut; StartupInfo.hStdError = tbl.childStdErr; - if (StartupInfo.hStdInput != INVALID_HANDLE_VALUE && - StartupInfo.hStdOutput != INVALID_HANDLE_VALUE && - StartupInfo.hStdError != INVALID_HANDLE_VALUE) + if (StartupInfo.hStdInput == INVALID_HANDLE_VALUE && + StartupInfo.hStdOutput == INVALID_HANDLE_VALUE && + StartupInfo.hStdError == INVALID_HANDLE_VALUE) { - StartupInfo.dwFlags |= STARTF_USESTDHANDLES; + create |= CREATE_NEW_CONSOLE; } else { - create |= CREATE_NEW_CONSOLE; + StartupInfo.dwFlags |= STARTF_USESTDHANDLES; } if (w32_use_showwindow) { StartupInfo.dwFlags |= STARTF_USESHOWWINDOW; @@ -4024,7 +4106,7 @@ win32_free(void *block) } -int +DllExport int win32_open_osfhandle(intptr_t handle, int flags) { #ifdef USE_FIXED_OSFHANDLE @@ -4034,12 +4116,64 @@ win32_open_osfhandle(intptr_t handle, int flags) return _open_osfhandle(handle, flags); } -intptr_t +DllExport intptr_t win32_get_osfhandle(int fd) { return (intptr_t)_get_osfhandle(fd); } +DllExport FILE * +win32_fdupopen(FILE *pf) +{ + FILE* pfdup; + fpos_t pos; + char mode[3]; + int fileno = win32_dup(win32_fileno(pf)); + + /* open the file in the same mode */ +#ifdef __BORLANDC__ + if((pf)->flags & _F_READ) { + mode[0] = 'r'; + mode[1] = 0; + } + else if((pf)->flags & _F_WRIT) { + mode[0] = 'a'; + mode[1] = 0; + } + else if((pf)->flags & _F_RDWR) { + mode[0] = 'r'; + mode[1] = '+'; + mode[2] = 0; + } +#else + if((pf)->_flag & _IOREAD) { + mode[0] = 'r'; + mode[1] = 0; + } + else if((pf)->_flag & _IOWRT) { + mode[0] = 'a'; + mode[1] = 0; + } + else if((pf)->_flag & _IORW) { + mode[0] = 'r'; + mode[1] = '+'; + mode[2] = 0; + } +#endif + + /* it appears that the binmode is attached to the + * file descriptor so binmode files will be handled + * correctly + */ + pfdup = win32_fdopen(fileno, mode); + + /* move the file pointer to the same position */ + if (!fgetpos(pf, &pos)) { + fsetpos(pfdup, &pos); + } + return pfdup; +} + DllExport void* win32_dynaload(const char* filename) { @@ -4605,20 +4739,25 @@ Perl_init_os_extras(void) */ } -#ifdef MULTIPLICITY - -PerlInterpreter * +void * win32_signal_context(void) { dTHX; +#ifdef MULTIPLICITY if (!my_perl) { my_perl = PL_curinterp; PERL_SET_THX(my_perl); } return my_perl; +#else +#ifdef USE_5005THREADS + return aTHX; +#else + return PL_curinterp; +#endif +#endif } -#endif BOOL WINAPI win32_ctrlhandler(DWORD dwCtrlType) @@ -4628,6 +4767,10 @@ win32_ctrlhandler(DWORD dwCtrlType) if (!my_perl) return FALSE; +#else +#ifdef USE_5005THREADS + dTHX; +#endif #endif switch(dwCtrlType) {