#define Win32_Winsock
#endif
#include <windows.h>
+#ifndef __MINGW32__ /* GCC/Mingw32-2.95.2 forgot the WINAPI on CommandLineToArgvW() */
+# include <shellapi.h>
+#else
+ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCommandLine, int * pNumArgs);
+#endif
#include <winnt.h>
#include <io.h>
#endif
#include <string.h>
#include <stdarg.h>
-#include <stdlib.h> /* get a real declaration of sys_nerr */
#include <float.h>
#include <time.h>
#if defined(_MSC_VER) || defined(__MINGW32__)
#else
#include <utime.h>
#endif
-
#ifdef __GNUC__
/* Mingw32 defaults to globing command line
* So we turn it off like this:
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
(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))
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))
{
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;
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;
}
}
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;
char *arch;
GetSystemInfo(&info);
-#if defined(__BORLANDC__) || defined(__MINGW32__)
-#ifndef _STRUCT_NAME
-# define _STRUCT_NAME(s) s
-# define _UNION_NAME(u) u
-#endif
- switch (info._UNION_NAME(u.)_STRUCT_NAME(s.)wProcessorArchitecture) {
+#if (defined(__BORLANDC__)&&(__BORLANDC__<=0x520)) || defined(__MINGW32__)
+ switch (info.u.s.wProcessorArchitecture) {
#else
switch (info.wProcessorArchitecture) {
#endif
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 waitcode = WaitForSingleObject(hThread, INFINITE);
- if (waitcode != WAIT_FAILED) {
+ DWORD waitcode = WaitForSingleObject(hThread, timeout);
+ if (waitcode == WAIT_TIMEOUT) {
+ return 0;
+ }
+ else if (waitcode != WAIT_FAILED) {
if (GetExitCodeThread(hThread, &waitcode)) {
*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 waitcode = WaitForSingleObject(hProcess, INFINITE);
- if (waitcode != WAIT_FAILED) {
+ 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];
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;
*status = (int)((exitcode & 0xff) << 8);
retval = (int)w32_pseudo_child_pids[i];
remove_dead_pseudo_process(i);
- return retval;
+ return -retval;
}
}
}
DllExport char *
win32_strerror(int e)
{
+#ifndef __BORLANDC__ /* Borland intolerance */
+ extern int sys_nerr;
+#endif
DWORD source = 0;
if (e < 0 || e > sys_nerr) {
/* close saved handle */
win32_close(oldfd);
- FDPID_LOCK();
+ LOCK_FDPID_MUTEX;
sv_setiv(*av_fetch(w32_fdpid, p[parent], TRUE), childpid);
- FDPID_UNLOCK();
+ UNLOCK_FDPID_MUTEX;
/* set process id so that it can be returned by perl's open() */
PL_forkprocess = childpid;
int childpid, status;
SV *sv;
- FDPID_LOCK();
+ LOCK_FDPID_MUTEX;
sv = *av_fetch(w32_fdpid, win32_fileno(pf), TRUE);
- FDPID_UNLOCK();
+
if (SvIOK(sv))
childpid = SvIVX(sv);
else
win32_fclose(pf);
SvIVX(sv) = 0;
+ UNLOCK_FDPID_MUTEX;
if (win32_waitpid(childpid, &status, 0) == -1)
return -1;
StreamId.dwStreamAttributes = 0;
StreamId.dwStreamNameSize = 0;
#if defined(__BORLANDC__) || defined(__MINGW32__)
- StreamId.Size._UNION_NAME(u.)HighPart = 0;
- StreamId.Size._UNION_NAME(u.)LowPart = dwLen;
+ StreamId.Size.u.HighPart = 0;
+ StreamId.Size.u.LowPart = dwLen;
#else
StreamId.Size.HighPart = 0;
StreamId.Size.LowPart = dwLen;
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 {
&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);
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),
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),
# define Perl_sys_intern_init CPerlObj::Perl_sys_intern_init
# undef Perl_sys_intern_dup
# define Perl_sys_intern_dup CPerlObj::Perl_sys_intern_dup
+# undef Perl_sys_intern_clear
+# define Perl_sys_intern_clear CPerlObj::Perl_sys_intern_clear
# define pPerl this
# endif
w32_init_socktype = 0;
}
+void
+Perl_sys_intern_clear(pTHX)
+{
+ Safefree(w32_perlshell_tokens);
+ Safefree(w32_perlshell_vec);
+ /* NOTE: w32_fdpid is freed by sv_clean_all() */
+ Safefree(w32_children);
+# ifdef USE_ITHREADS
+ Safefree(w32_pseudo_children);
+# endif
+}
+
# ifdef USE_ITHREADS
void
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 */
}
}
-typedef LPWSTR* (WINAPI CLTARGVW)(LPCWSTR lpCommandLine, int * pNumArgs);
-/* load shell32.dll on demand (reduces number of DLLs loaded on startup by 1/3)
- -- BKS 5-28-2000 */
void
win32_argv2utf8(int argc, char** argv)
{
dTHXo;
char* psz;
int length, wargc;
- HANDLE hDll = LoadLibraryA("shell32.dll");
- CLTARGVW *pCommandLineToArgvW = NULL;
- LPWSTR* lpwStr = NULL;
- if (hDll && (pCommandLineToArgvW = (CLTARGVW*)GetProcAddress(hDll, "CommandLineToArgvW"))) {
- lpwStr = (*pCommandLineToArgvW)(GetCommandLineW(), &wargc);
- }
+ LPWSTR* lpwStr = CommandLineToArgvW(GetCommandLineW(), &wargc);
if (lpwStr && argc) {
while (argc--) {
length = WideCharToMultiByte(CP_UTF8, 0, lpwStr[--wargc], -1, NULL, 0, NULL, NULL);
}
call_atexit(win32_free_argvw, argv);
}
- if (hDll)
- FreeLibrary(hDll);
GlobalFree((HGLOBAL)lpwStr);
}
+