#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))
return 0;
}
+/*
+ * XXX this needs strengthening (for PerlIO)
+ * -- BKS, 11-11-200
+*/
+int mkstemp(const char *path)
+{
+ dTHX;
+ char buf[MAX_PATH+1];
+ int i = 0, fd = -1;
+
+retry:
+ if (i++ > 10) { /* give up */
+ errno = ENOENT;
+ return -1;
+ }
+ if (!GetTempFileNameA((LPCSTR)path, "plr", 1, buf)) {
+ errno = ENOENT;
+ return -1;
+ }
+ fd = PerlLIO_open3(buf, O_CREAT|O_RDWR|O_EXCL, 0600);
+ if (fd == -1)
+ goto retry;
+ return fd;
+}
+
static long
find_pid(int pid)
{
{
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__)
+#if (defined(__BORLANDC__)&&(__BORLANDC__<=0x520)) || defined(__MINGW32__)
switch (info.u.s.wProcessorArchitecture) {
#else
switch (info.wProcessorArchitecture) {
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;
}
}
}
#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 */
* -- 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
}
}
-
DllExport int
win32_fprintf(FILE *fp, const char *format, ...)
{
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
/*
* a popen() clone that respects PERL5SHELL
+ *
+ * changed to return PerlIO* rather than FILE * by BKS, 11-11-2000
*/
-DllExport FILE*
+DllExport PerlIO*
win32_popen(const char *command, const char *mode)
{
#ifdef USE_RTL_POPEN
}
/* we have an fd, return a file stream */
- return (win32_fdopen(p[parent], (char *)mode));
+ return (PerlIO_fdopen(p[parent], (char *)mode));
cleanup:
/* we don't need to check for errors here */
*/
DllExport int
-win32_pclose(FILE *pf)
+win32_pclose(PerlIO *pf)
{
#ifdef USE_RTL_POPEN
return _pclose(pf);
SV *sv;
LOCK_FDPID_MUTEX;
- sv = *av_fetch(w32_fdpid, win32_fileno(pf), TRUE);
+ sv = *av_fetch(w32_fdpid, PerlIO_fileno(pf), TRUE);
if (SvIOK(sv))
childpid = SvIVX(sv);
return -1;
}
- win32_fclose(pf);
+#ifdef USE_PERLIO
+ PerlIO_close(pf);
+#else
+ fclose(pf);
+#endif
SvIVX(sv) = 0;
UNLOCK_FDPID_MUTEX;
return open(PerlDir_mapA(path), flag, pmode);
}
+/* close() that understands socket */
+extern int my_close(int); /* in win32sck.c */
+
DllExport int
win32_close(int fd)
{
- return close(fd);
+ return my_close(fd);
}
DllExport int
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 {
{
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));
&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),
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 */