X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=win32%2Fwin32.c;h=5f7d4873bef34744b6c1dbe465897cace3f671cd;hb=df0003d4dd97bb27e464c2adb8c54893f719ec3c;hp=82b45b98b16bb44049558ff16a8412ee3969eebb;hpb=8c9208bc5764dada175aceff9d0b1938978d7db6;p=p5sagit%2Fp5-mst-13.2.git diff --git a/win32/win32.c b/win32/win32.c index 82b45b9..5f7d487 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -37,7 +37,14 @@ #include "EXTERN.h" #include "perl.h" + +#define NO_XSLOCKS +#ifdef PERL_OBJECT +extern CPerlObj* pPerl; +#endif #include "XSUB.h" + +#include "Win32iop.h" #include #include #ifndef __GNUC__ @@ -65,56 +72,54 @@ int _CRT_glob = 0; #define EXECF_SPAWN 2 #define EXECF_SPAWN_NOWAIT 3 +#if defined(PERL_OBJECT) +#undef win32_get_privlib +#define win32_get_privlib g_win32_get_privlib +#undef win32_get_sitelib +#define win32_get_sitelib g_win32_get_sitelib +#undef do_aspawn +#define do_aspawn g_do_aspawn +#undef do_spawn +#define do_spawn g_do_spawn +#undef do_exec +#define do_exec g_do_exec +#undef getlogin +#define getlogin g_getlogin +#endif + static DWORD os_id(void); static void get_shell(void); static long tokenize(char *str, char **dest, char ***destv); -static int do_spawn2(char *cmd, int exectype); -static BOOL has_redirection(char *ptr); + int do_spawn2(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); +static char * get_emd_part(char *leading, char *trailing, ...); +static void remove_dead_process(HANDLE deceased); -char * w32_perlshell_tokens = Nullch; -char ** w32_perlshell_vec; -long w32_perlshell_items = -1; -DWORD w32_platform = (DWORD)-1; -char w32_perllib_root[MAX_PATH+1]; HANDLE w32_perldll_handle = INVALID_HANDLE_VALUE; -#ifndef __BORLANDC__ -long w32_num_children = 0; -HANDLE w32_child_pids[MAXIMUM_WAIT_OBJECTS]; -#endif - -#ifndef FOPEN_MAX -# if defined(_NSTREAM_) -# define FOPEN_MAX _NSTREAM_ -# elsif defined(_NFILE_) -# define FOPEN_MAX _NFILE_ -# elsif defined(_NFILE) -# define FOPEN_MAX _NFILE -# endif -#endif - -#ifndef USE_CRT_POPEN -int w32_popen_pids[FOPEN_MAX]; -#endif +static DWORD w32_platform = (DWORD)-1; #ifdef USE_THREADS # ifdef USE_DECLSPEC_THREAD __declspec(thread) char strerror_buffer[512]; __declspec(thread) char getlogin_buffer[128]; +__declspec(thread) char w32_perllib_root[MAX_PATH+1]; # ifdef HAVE_DES_FCRYPT __declspec(thread) char crypt_buffer[30]; # endif # else # define strerror_buffer (thr->i.Wstrerror_buffer) # define getlogin_buffer (thr->i.Wgetlogin_buffer) +# define w32_perllib_root (thr->i.Ww32_perllib_root) # define crypt_buffer (thr->i.Wcrypt_buffer) # endif #else -char strerror_buffer[512]; -char getlogin_buffer[128]; +static char strerror_buffer[512]; +static char getlogin_buffer[128]; +static char w32_perllib_root[MAX_PATH+1]; # ifdef HAVE_DES_FCRYPT -char crypt_buffer[30]; +static char crypt_buffer[30]; # endif #endif @@ -128,44 +133,176 @@ IsWinNT(void) { return (os_id() == VER_PLATFORM_WIN32_NT); } -char * -win32_perllib_path(char *sfx,...) +char* +GetRegStrFromKey(HKEY hkey, const char *lpszValueName, char** ptr, DWORD* lpDataLen) +{ /* Retrieve a REG_SZ or REG_EXPAND_SZ from the registry */ + HKEY handle; + DWORD type; + const char *subkey = "Software\\Perl"; + long retval; + + retval = RegOpenKeyEx(hkey, subkey, 0, KEY_READ, &handle); + if (retval == ERROR_SUCCESS){ + retval = RegQueryValueEx(handle, lpszValueName, 0, &type, NULL, lpDataLen); + if (retval == ERROR_SUCCESS && type == REG_SZ) { + if (*ptr) { + Renew(*ptr, *lpDataLen, char); + } + else { + New(1312, *ptr, *lpDataLen, char); + } + retval = RegQueryValueEx(handle, lpszValueName, 0, NULL, (PBYTE)*ptr, lpDataLen); + if (retval != ERROR_SUCCESS) { + Safefree(*ptr); + *ptr = Nullch; + } + } + RegCloseKey(handle); + } + return *ptr; +} + +char* +GetRegStr(const char *lpszValueName, char** ptr, DWORD* lpDataLen) +{ + *ptr = GetRegStrFromKey(HKEY_CURRENT_USER, lpszValueName, ptr, lpDataLen); + if (*ptr == Nullch) + { + *ptr = GetRegStrFromKey(HKEY_LOCAL_MACHINE, lpszValueName, ptr, lpDataLen); + } + return *ptr; +} + +static char * +get_emd_part(char *prev_path, char *trailing_path, ...) { va_list ap; - char *end; - va_start(ap,sfx); - GetModuleFileName((w32_perldll_handle == INVALID_HANDLE_VALUE) + char mod_name[MAX_PATH+1]; + char *ptr; + char *optr; + char *strip; + int oldsize, newsize; + + va_start(ap, trailing_path); + strip = va_arg(ap, char *); + + GetModuleFileName((w32_perldll_handle == INVALID_HANDLE_VALUE) ? GetModuleHandle(NULL) - : w32_perldll_handle, - w32_perllib_root, - sizeof(w32_perllib_root)); - *(end = strrchr(w32_perllib_root, '\\')) = '\0'; - if (stricmp(end-4,"\\bin") == 0) - end -= 4; - strcpy(end,"\\lib"); - while (sfx) - { - strcat(end,"\\"); - strcat(end,sfx); - sfx = va_arg(ap,char *); - } - va_end(ap); - return (w32_perllib_root); + : w32_perldll_handle, mod_name, sizeof(mod_name)); + ptr = strrchr(mod_name, '\\'); + while (ptr && strip) { + /* look for directories to skip back */ + optr = ptr; + *ptr = '\0'; + ptr = strrchr(mod_name, '\\'); + if (!ptr || stricmp(ptr+1, strip) != 0) { + *optr = '\\'; + ptr = optr; + } + strip = va_arg(ap, char *); + } + if (!ptr) { + ptr = mod_name; + *ptr++ = '.'; + *ptr = '\\'; + } + va_end(ap); + strcpy(++ptr, trailing_path); + + newsize = strlen(mod_name) + 1; + if (prev_path) { + oldsize = strlen(prev_path) + 1; + newsize += oldsize; /* includes plus 1 for ';' */ + Renew(prev_path, newsize, char); + prev_path[oldsize-1] = ';'; + strcpy(&prev_path[oldsize], mod_name); + } + else { + New(1311, prev_path, newsize, char); + strcpy(prev_path, mod_name); + } + + return prev_path; +} + +char * +win32_get_privlib(char *pl) +{ + char *stdlib = "lib"; + char buffer[MAX_PATH+1]; + char *path = Nullch; + DWORD datalen; + + /* $stdlib = $HKCU{"lib-$]"} || $HKLM{"lib-$]"} || $HKCU{"lib"} || $HKLM{"lib"} || ""; */ + sprintf(buffer, "%s-%s", stdlib, pl); + path = GetRegStr(buffer, &path, &datalen); + if (!path) + path = GetRegStr(stdlib, &path, &datalen); + + /* $stdlib .= ";$EMD/../../lib" */ + return get_emd_part(path, stdlib, ARCHNAME, "bin", Nullch); +} + +char * +win32_get_sitelib(char *pl) +{ + char *sitelib = "sitelib"; + char regstr[40]; + char pathstr[MAX_PATH+1]; + DWORD datalen; + char *path1 = Nullch; + char *path2 = Nullch; + int len, newsize; + + /* $HKCU{"sitelib-$]"} || $HKLM{"sitelib-$]"} . ---; */ + sprintf(regstr, "%s-%s", sitelib, pl); + path1 = GetRegStr(regstr, &path1, &datalen); + + /* $sitelib .= + * ";$EMD/" . ((-d $EMD/../../../$]) ? "../../.." : "../.."). "/site/$]/lib"; */ + sprintf(pathstr, "site\\%s\\lib", pl); + path1 = get_emd_part(path1, pathstr, ARCHNAME, "bin", pl, Nullch); + + /* $HKCU{'sitelib'} || $HKLM{'sitelib'} . ---; */ + path2 = GetRegStr(sitelib, &path2, &datalen); + + /* $sitelib .= + * ";$EMD/" . ((-d $EMD/../../../$]) ? "../../.." : "../.."). "/site/lib"; */ + path2 = get_emd_part(path2, "site\\lib", ARCHNAME, "bin", pl, Nullch); + + if (!path1) + return path2; + + if (!path2) + return path1; + + len = strlen(path1); + newsize = len + strlen(path2) + 2; /* plus one for ';' */ + + Renew(path1, newsize, char); + path1[len++] = ';'; + strcpy(&path1[len], path2); + + Safefree(path2); + return path1; } static BOOL -has_redirection(char *ptr) +has_shell_metachars(char *ptr) { int inquote = 0; char quote = '\0'; /* * Scan string looking for redirection (< or >) or pipe - * characters (|) that are not in a quoted string + * characters (|) that are not in a quoted string. + * Shell variable interpolation (%VAR%) can also happen inside strings. */ while (*ptr) { switch(*ptr) { + case '%': + return TRUE; case '\'': case '\"': if (inquote) { @@ -192,6 +329,7 @@ has_redirection(char *ptr) return FALSE; } +#if !defined(PERL_OBJECT) /* since the current process environment is being updated in util.c * the library functions will get the correct environment */ @@ -224,6 +362,7 @@ my_pclose(PerlIO *fp) { return win32_pclose(fp); } +#endif static DWORD os_id(void) @@ -334,7 +473,7 @@ do_aspawn(void *vreally, void **vmark, void **vsp) } while (++mark <= sp) { - if (*mark && (str = SvPV(*mark, na))) + if (*mark && (str = SvPV(*mark, PL_na))) argv[index++] = str; else argv[index++] = ""; @@ -342,7 +481,7 @@ do_aspawn(void *vreally, void **vmark, void **vsp) argv[index++] = 0; status = win32_spawnvp(flag, - (really ? SvPV(really,na) : argv[0]), + (const char*)(really ? SvPV(really,PL_na) : argv[0]), (const char* const*)argv); if (status < 0 && errno == ENOEXEC) { @@ -355,25 +494,25 @@ do_aspawn(void *vreally, void **vmark, void **vsp) argv[sh_items] = w32_perlshell_vec[sh_items]; status = win32_spawnvp(flag, - (really ? SvPV(really,na) : argv[0]), + (const char*)(really ? SvPV(really,PL_na) : argv[0]), (const char* const*)argv); } if (flag != P_NOWAIT) { if (status < 0) { - if (dowarn) + if (PL_dowarn) warn("Can't spawn \"%s\": %s", argv[0], strerror(errno)); status = 255 * 256; } else status *= 256; - statusvalue = status; + PL_statusvalue = status; } Safefree(argv); return (status); } -static int +int do_spawn2(char *cmd, int exectype) { char **a; @@ -385,7 +524,7 @@ do_spawn2(char *cmd, int exectype) /* Save an extra exec if possible. See if there are shell * metacharacters in it */ - if (!has_redirection(cmd)) { + if (!has_shell_metachars(cmd)) { New(1301,argv, strlen(cmd) / 2 + 2, char*); New(1302,cmd2, strlen(cmd) + 1, char); strcpy(cmd2, cmd); @@ -448,7 +587,7 @@ do_spawn2(char *cmd, int exectype) } if (exectype != EXECF_SPAWN_NOWAIT) { if (status < 0) { - if (dowarn) + if (PL_dowarn) warn("Can't %s \"%s\": %s", (exectype == EXECF_EXEC ? "exec" : "spawn"), cmd, strerror(errno)); @@ -456,7 +595,7 @@ do_spawn2(char *cmd, int exectype) } else status *= 256; - statusvalue = status; + PL_statusvalue = status; } return (status); } @@ -485,7 +624,7 @@ do_exec(char *cmd) * return the pointer to the current file name. */ DIR * -opendir(char *filename) +win32_opendir(char *filename) { DIR *p; long len; @@ -500,12 +639,8 @@ opendir(char *filename) return NULL; /* check to see if filename is a directory */ - if (win32_stat(filename, &sbuf) < 0 || (sbuf.st_mode & S_IFDIR) == 0) { - /* CRT is buggy on sharenames, so make sure it really isn't */ - DWORD r = GetFileAttributes(filename); - if (r == 0xffffffff || !(r & FILE_ATTRIBUTE_DIRECTORY)) - return NULL; - } + if (win32_stat(filename, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode)) + return NULL; /* Get us a DIR structure */ Newz(1303, p, 1, DIR); @@ -563,7 +698,7 @@ opendir(char *filename) * string pointer to the nDllExport entry. */ struct direct * -readdir(DIR *dirp) +win32_readdir(DIR *dirp) { int len; static int dummy = 0; @@ -591,7 +726,7 @@ readdir(DIR *dirp) /* Telldir returns the current string pointer position */ long -telldir(DIR *dirp) +win32_telldir(DIR *dirp) { return (long) dirp->curr; } @@ -601,21 +736,21 @@ telldir(DIR *dirp) *(Saved by telldir). */ void -seekdir(DIR *dirp, long loc) +win32_seekdir(DIR *dirp, long loc) { dirp->curr = (char *)loc; } /* Rewinddir resets the string pointer to the start */ void -rewinddir(DIR *dirp) +win32_rewinddir(DIR *dirp) { dirp->curr = dirp->start; } /* free the memory allocated by opendir */ int -closedir(DIR *dirp) +win32_closedir(DIR *dirp) { Safefree(dirp->start); Safefree(dirp); @@ -691,10 +826,30 @@ chown(const char *path, uid_t owner, gid_t group) return 0; } -int -kill(int pid, int sig) +static void +remove_dead_process(HANDLE deceased) +{ +#ifndef USE_RTL_WAIT + int child; + for (child = 0 ; child < w32_num_children ; ++child) { + if (w32_child_pids[child] == deceased) { + Copy(&w32_child_pids[child+1], &w32_child_pids[child], + (w32_num_children-child-1), HANDLE); + w32_num_children--; + break; + } + } +#endif +} + +DllExport int +win32_kill(int pid, int sig) { +#ifdef USE_RTL_WAIT HANDLE hProcess= OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid); +#else + HANDLE hProcess = (HANDLE) pid; +#endif if (hProcess == NULL) { croak("kill process failed!\n"); @@ -703,10 +858,14 @@ kill(int pid, int sig) if (!TerminateProcess(hProcess, sig)) croak("kill process failed!\n"); CloseHandle(hProcess); + + /* WaitForMultipleObjects() on a pid that was killed returns error + * so if we know the pid is gone we remove it from process list */ + remove_dead_process(hProcess); } return 0; } - + /* * File system stuff */ @@ -721,7 +880,7 @@ win32_sleep(unsigned int t) DllExport int win32_stat(const char *path, struct stat *buffer) { - char t[MAX_PATH]; + char t[MAX_PATH+1]; const char *p = path; int l = strlen(path); int res; @@ -738,8 +897,22 @@ win32_stat(const char *path, struct stat *buffer) } } res = stat(p,buffer); + if (res < 0) { + /* CRT is buggy on sharenames, so make sure it really isn't. + * XXX using GetFileAttributesEx() will enable us to set + * buffer->st_*time (but note that's not available on the + * Windows of 1995) */ + DWORD r = GetFileAttributes(p); + if (r != 0xffffffff && (r & FILE_ATTRIBUTE_DIRECTORY)) { + buffer->st_mode |= S_IFDIR | S_IREAD; + errno = 0; + if (!(r & FILE_ATTRIBUTE_READONLY)) + buffer->st_mode |= S_IWRITE | S_IEXEC; + return 0; + } + } #ifdef __BORLANDC__ - if (res == 0) { + else { if (S_ISDIR(buffer->st_mode)) buffer->st_mode |= S_IWRITE | S_IEXEC; else if (S_ISREG(buffer->st_mode)) { @@ -766,18 +939,40 @@ win32_stat(const char *path, struct stat *buffer) DllExport char * win32_getenv(const char *name) { - static char *curitem = Nullch; - static DWORD curlen = 512; + static char *curitem = Nullch; /* XXX threadead */ + static DWORD curlen = 0; /* XXX threadead */ DWORD needlen; - if (!curitem) + if (!curitem) { + curlen = 512; New(1305,curitem,curlen,char); - if (!(needlen = GetEnvironmentVariable(name,curitem,curlen))) - return Nullch; - while (needlen > curlen) { - Renew(curitem,needlen,char); - curlen = needlen; - needlen = GetEnvironmentVariable(name,curitem,curlen); } + + needlen = GetEnvironmentVariable(name,curitem,curlen); + if (needlen != 0) { + while (needlen > curlen) { + Renew(curitem,needlen,char); + curlen = needlen; + needlen = GetEnvironmentVariable(name,curitem,curlen); + } + } + else { + /* allow any environment variables that begin with 'PERL' + to be stored in the registry */ + if (curitem) + *curitem = '\0'; + + if (strncmp(name, "PERL", 4) == 0) { + if (curitem) { + Safefree(curitem); + curitem = Nullch; + curlen = 0; + } + curitem = GetRegStr(name, &curitem, &curlen); + } + } + if (curitem && *curitem == '\0') + return Nullch; + return curitem; } @@ -880,9 +1075,27 @@ win32_utime(const char *filename, struct utimbuf *times) } DllExport int -win32_wait(int *status) +win32_waitpid(int pid, int *status, int flags) { + int rc; + if (pid == -1) + return win32_wait(status); + else { + rc = cwait(status, pid, WAIT_CHILD); + /* cwait() returns differently on Borland */ #ifdef __BORLANDC__ + if (status) + *status = (((*status >> 8) & 0xff) | ((*status << 8) & 0xff00)); +#endif + remove_dead_process((HANDLE)pid); + } + return rc >= 0 ? pid : rc; +} + +DllExport int +win32_wait(int *status) +{ +#ifdef USE_RTL_WAIT return wait(status); #else /* XXX this wait emulation only knows about processes @@ -963,14 +1176,21 @@ win32_alarm(unsigned int sec) return 0; } +#if defined(HAVE_DES_FCRYPT) || defined(PERL_OBJECT) #ifdef HAVE_DES_FCRYPT -extern char * des_fcrypt(char *cbuf, const char *txt, const char *salt); +extern char * des_fcrypt(const char *txt, const char *salt, char *cbuf); +#endif DllExport char * win32_crypt(const char *txt, const char *salt) { +#ifdef HAVE_DES_FCRYPT dTHR; - return des_fcrypt(crypt_buffer, txt, salt); + return des_fcrypt(txt, salt, crypt_buffer); +#else + die("The crypt() function is unimplemented due to excessive paranoia."); + return Nullch; +#endif } #endif @@ -1216,7 +1436,7 @@ win32_str_os_error(void *sv, DWORD dwErr) sMsg[dwLen]= '\0'; } if (0 == dwLen) { - sMsg = LocalAlloc(0, 64/**sizeof(TCHAR)*/); + sMsg = (char*)LocalAlloc(0, 64/**sizeof(TCHAR)*/); dwLen = sprintf(sMsg, "Unknown error #0x%lX (lookup 0x%lX)", dwErr, GetLastError()); @@ -1407,7 +1627,7 @@ win32_pipe(int *pfd, unsigned int size, int mode) DllExport FILE* win32_popen(const char *command, const char *mode) { -#ifdef USE_CRT_POPEN +#ifdef USE_RTL_POPEN return _popen(command, mode); #else int p[2]; @@ -1467,7 +1687,7 @@ win32_popen(const char *command, const char *mode) /* close saved handle */ win32_close(oldfd); - w32_popen_pids[p[parent]] = childpid; + sv_setiv(*av_fetch(w32_fdpid, p[parent], TRUE), childpid); /* we have an fd, return a file stream */ return (win32_fdopen(p[parent], (char *)mode)); @@ -1482,7 +1702,7 @@ cleanup: } return (NULL); -#endif /* USE_CRT_POPEN */ +#endif /* USE_RTL_POPEN */ } /* @@ -1492,13 +1712,18 @@ cleanup: DllExport int win32_pclose(FILE *pf) { -#ifdef USE_CRT_POPEN +#ifdef USE_RTL_POPEN return _pclose(pf); #else - int fd, childpid, status; - fd = win32_fileno(pf); - childpid = w32_popen_pids[fd]; + int childpid, status; + SV *sv; + + sv = *av_fetch(w32_fdpid, win32_fileno(pf), TRUE); + if (SvIOK(sv)) + childpid = SvIVX(sv); + else + childpid = 0; if (!childpid) { errno = EBADF; @@ -1506,7 +1731,9 @@ win32_pclose(FILE *pf) } win32_fclose(pf); - w32_popen_pids[fd] = 0; + SvIVX(sv) = 0; + + remove_dead_process((HANDLE)childpid); /* wait for the child */ if (cwait(&status, childpid, WAIT_CHILD) == -1) @@ -1518,7 +1745,57 @@ win32_pclose(FILE *pf) return (status); #endif -#endif /* USE_CRT_OPEN */ +#endif /* USE_RTL_POPEN */ +} + +DllExport int +win32_rename(const char *oname, const char *newname) +{ + char szNewWorkName[MAX_PATH+1]; + WIN32_FIND_DATA fdOldFile, fdNewFile; + HANDLE handle; + char *ptr; + + if ((strchr(oname, '\\') || strchr(oname, '/')) + && strchr(newname, '\\') == NULL + && strchr(newname, '/') == NULL) + { + strcpy(szNewWorkName, oname); + if ((ptr = strrchr(szNewWorkName, '\\')) == NULL) + ptr = strrchr(szNewWorkName, '/'); + strcpy(++ptr, newname); + } + else + strcpy(szNewWorkName, newname); + + if (stricmp(oname, szNewWorkName) != 0) { + // check that we're not being fooled by relative paths + // and only delete the new file + // 1) if it exists + // 2) it is not the same file as the old file + // 3) old file exist + // GetFullPathName does not return the long file name on some systems + handle = FindFirstFile(oname, &fdOldFile); + if (handle != INVALID_HANDLE_VALUE) { + FindClose(handle); + + handle = FindFirstFile(szNewWorkName, &fdNewFile); + + if (handle != INVALID_HANDLE_VALUE) + FindClose(handle); + else + fdNewFile.cFileName[0] = '\0'; + + if (strcmp(fdOldFile.cAlternateFileName, + fdNewFile.cAlternateFileName) != 0 + && strcmp(fdOldFile.cFileName, fdNewFile.cFileName) != 0) + { + // file exists and not same file + DeleteFile(szNewWorkName); + } + } + } + return rename(oname, newname); } DllExport int @@ -1613,8 +1890,13 @@ win32_spawnvp(int mode, const char *cmdname, const char *const *argv) { int status; +#ifndef USE_RTL_WAIT + if (mode == P_NOWAIT && w32_num_children >= MAXIMUM_WAIT_OBJECTS) + return -1; +#endif + status = spawnvp(mode, cmdname, (char * const *) argv); -#ifndef __BORLANDC__ +#ifndef USE_RTL_WAIT /* XXX For the P_NOWAIT case, Borland RTL returns pinfo.dwProcessId * while VC RTL returns pinfo.hProcess. For purposes of the custom * implementation of win32_wait(), we assume the latter. @@ -1626,6 +1908,12 @@ win32_spawnvp(int mode, const char *cmdname, const char *const *argv) } DllExport int +win32_execv(const char *cmdname, const char *const *argv) +{ + return execv(cmdname, (char *const *)argv); +} + +DllExport int win32_execvp(const char *cmdname, const char *const *argv) { return execvp(cmdname, (char *const *)argv); @@ -1851,7 +2139,7 @@ XS(w32_SetCwd) dXSARGS; if (items != 1) croak("usage: Win32::SetCurrentDirectory($cwd)"); - if (SetCurrentDirectory(SvPV(ST(0),na))) + if (SetCurrentDirectory(SvPV(ST(0),PL_na))) XSRETURN_YES; XSRETURN_NO; @@ -1923,7 +2211,7 @@ XS(w32_DomainName) char dname[256]; DWORD dnamelen = sizeof(dname); SID_NAME_USE snu; - if (LookupAccountName(NULL, name, &sid, &sidlen, + if (LookupAccountName(NULL, name, (PSID)&sid, &sidlen, dname, &dnamelen, &snu)) { XSRETURN_PV(dname); /* all that for this */ } @@ -2034,8 +2322,8 @@ XS(w32_Spawn) if (items != 3) croak("usage: Win32::Spawn($cmdName, $args, $PID)"); - cmd = SvPV(ST(0),na); - args = SvPV(ST(1), na); + cmd = SvPV(ST(0),PL_na); + args = SvPV(ST(1), PL_na); memset(&stStartInfo, 0, sizeof(stStartInfo)); /* Clear the block */ stStartInfo.cb = sizeof(stStartInfo); /* Set the structure size */ @@ -2091,7 +2379,7 @@ XS(w32_GetShortPathName) ST(0) = shortpath; } else - ST(0) = &sv_undef; + ST(0) = &PL_sv_undef; XSRETURN(1); } @@ -2111,6 +2399,13 @@ Perl_init_os_extras() char *file = __FILE__; dXSUB_SYS; + w32_perlshell_tokens = Nullch; + w32_perlshell_items = -1; + w32_fdpid = newAV(); /* XXX needs to be in Perl_win32_init()? */ +#ifndef USE_RTL_WAIT + w32_num_children = 0; +#endif + /* these names are Activeware compatible */ newXS("Win32::GetCwd", w32_GetCwd, file); newXS("Win32::SetCwd", w32_SetCwd, file); @@ -2153,7 +2448,7 @@ Perl_win32_init(int *argcp, char ***argvp) #if !defined(_ALPHA_) && !defined(__GNUC__) _control87(MCW_EM, MCW_EM); #endif - MALLOC_INIT; + MALLOC_INIT; } #ifdef USE_BINMODE_SCRIPTS