summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1998-01-30 09:23:36 +0000
committerGurusamy Sarathy <gsar@cpan.org>1998-01-30 09:23:36 +0000
commit76e3520e1f6b7df33cd381a2cf4f1fce3d69c8a4 (patch)
tree1d4e5f5653fd9def6bd71cc0cb536400223f4d3e /win32
parent6ad3d225cec2692b410002582f5558652eea32c8 (diff)
downloadperl-76e3520e1f6b7df33cd381a2cf4f1fce3d69c8a4.tar.gz
[asperl] added AS patch#2
p4raw-id: //depot/asperl@443
Diffstat (limited to 'win32')
-rw-r--r--win32/Makefile10
-rw-r--r--win32/config_H.bc2
-rw-r--r--win32/config_H.vc40
-rw-r--r--win32/dl_win32.xs10
-rw-r--r--win32/include/sys/socket.h2
-rw-r--r--win32/ipdir.c186
-rw-r--r--win32/ipenv.c62
-rw-r--r--win32/iplio.c307
-rw-r--r--win32/ipmem.c39
-rw-r--r--win32/ipproc.c620
-rw-r--r--win32/ipsock.c681
-rw-r--r--win32/ipstdio.c447
-rw-r--r--win32/ipstdiowin.h22
-rw-r--r--win32/makedef.pl2
-rw-r--r--win32/perlobj.def4
-rw-r--r--win32/runperl.c172
-rw-r--r--win32/win32iop.h9
17 files changed, 2603 insertions, 12 deletions
diff --git a/win32/Makefile b/win32/Makefile
index 12410e21fb..b5413bdf46 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -21,6 +21,10 @@ BUILDOPT=-DUSE_THREADS
#CCTYPE=MSVC20
#
+# uncomment next line if you want to use the perl object
+#OBJECT=-DPERL_OBJECT
+
+#
# uncomment next line if you want debug version of perl (big,slow)
#CFG=Debug
@@ -70,7 +74,7 @@ RUNTIME = -MD
!ENDIF
INCLUDES = -I.\include -I. -I..
#PCHFLAGS = -Fp"$(INTDIR)/modules.pch" -YX
-DEFINES = -DWIN32 -D_CONSOLE $(BUILDOPT) $(CRYPT_FLAG)
+DEFINES = -DWIN32 -D_CONSOLE $(BUILDOPT) $(CRYPT_FLAG) $(OBJECT)
LOCDEFS = -DPERLDLL -DPERL_CORE
SUBSYS = console
@@ -104,7 +108,11 @@ LIBFILES = $(CRYPT_LIB) oldnames.lib kernel32.lib user32.lib gdi32.lib \
oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib \
version.lib odbc32.lib odbccp32.lib
+!IF "$(OBJECT)" == "-DPERL_OBJECT"
+CFLAGS = -nologo -Gf -W3 -TP $(INCLUDES) $(DEFINES) $(LOCDEFS) $(PCHFLAGS) $(OPTIMIZE)
+!ELSE
CFLAGS = -nologo -Gf -W3 $(INCLUDES) $(DEFINES) $(LOCDEFS) $(PCHFLAGS) $(OPTIMIZE)
+!ENDIF
LINK_FLAGS = -nologo $(LINK_DBG) -machine:$(PROCESSOR_ARCHITECTURE)
OBJOUT_FLAG = -Fo
EXEOUT_FLAG = -Fe
diff --git a/win32/config_H.bc b/win32/config_H.bc
index f587e019c8..6cdae5d536 100644
--- a/win32/config_H.bc
+++ b/win32/config_H.bc
@@ -1686,7 +1686,9 @@
/* MYMALLOC:
* This symbol, if defined, indicates that we're using our own malloc.
*/
+#ifndef PERL_OBJECT
#define MYMALLOC /**/
+#endif
/* OLDARCHLIB:
* This variable, if defined, holds the name of the directory in
diff --git a/win32/config_H.vc b/win32/config_H.vc
index 42578bad8e..4124b6188f 100644
--- a/win32/config_H.vc
+++ b/win32/config_H.vc
@@ -18,6 +18,14 @@
#ifndef _config_h_
#define _config_h_
+#ifdef PERL_OBJECT
+#ifdef PERL_GLOBAL_STRUCT
+#error PERL_GLOBAL_STRUCT cannot be defined with PERL_OBJECT
+#endif
+#define win32_perllib_path PerlEnv_lib_path
+#endif
+
+
/* MEM_ALIGNBYTES:
* This symbol contains the number of bytes required to align a
* double. Usual values are 2, 4 and 8.
@@ -57,8 +65,8 @@
* This symbol is the filename expanded version of the BIN symbol, for
* programs that do not want to deal with that at run-time.
*/
-#define BIN "c:\\perl\\bin" /**/
-#define BIN_EXP "c:\\perl\\bin" /**/
+#define BIN "c:\\perl5004.5x\\bin" /**/
+#define BIN_EXP "c:\\perl5004.5x\\bin" /**/
/* CAT2:
* This macro catenates 2 tokens together.
@@ -548,6 +556,12 @@
*/
/*#define HAS_POLL /**/
+/* HAS_PTHREAD_YIELD:
+ * This symbol, if defined, indicates that the pthread_yield routine is
+ * available to yield the execution of the current thread.
+ */
+#undef HAS_PTHREAD_YIELD
+
/* HAS_READDIR:
* This symbol, if defined, indicates that the readdir routine is
* available to read directory entries. You may have to include
@@ -555,6 +569,12 @@
*/
#define HAS_READDIR /**/
+/* HAS_SCHED_YIELD:
+ * This symbol, if defined, indicates that the sched_yield
+ * routine is available to yield the execution of the current thread.
+ */
+#undef HAS_SCHED_YIELD
+
/* HAS_SEEKDIR:
* This symbol, if defined, indicates that the seekdir routine is
* available. You may have to include <dirent.h>. See I_DIRENT.
@@ -1466,7 +1486,7 @@
* This symbol contains the ~name expanded version of ARCHLIB, to be used
* in programs that are not prepared to deal with ~ expansion at run-time.
*/
-#define ARCHLIB "c:\\perl\\lib\\MSWin32-x86-thread" /**/
+#define ARCHLIB "c:\\perl5004.5x\\lib" /**/
#define ARCHLIB_EXP (win32_perllib_path(ARCHNAME,NULL)) /**/
/* BINCOMPAT3:
@@ -1606,6 +1626,12 @@
*/
/*#define USE_SFIO /**/
+/* PTHREADS_CREATED_JOINABLE:
+ * This symbol, if defined, indicates that pthreads are created
+ * in the joinable (aka undetached) state.
+ */
+/*#define PTHREADS_CREATED_JOINABLE /**/
+
/* Sigjmp_buf:
* This is the buffer type to be used with Sigsetjmp and Siglongjmp.
*/
@@ -1686,7 +1712,9 @@
/* MYMALLOC:
* This symbol, if defined, indicates that we're using our own malloc.
*/
+#ifndef PERL_OBJECT
#define MYMALLOC /**/
+#endif
/* OLDARCHLIB:
* This variable, if defined, holds the name of the directory in
@@ -1713,7 +1741,7 @@
* This symbol contains the ~name expanded version of PRIVLIB, to be used
* in programs that are not prepared to deal with ~ expansion at run-time.
*/
-#define PRIVLIB "c:\\perl\\lib" /**/
+#define PRIVLIB "c:\\perl5004.5x\\lib" /**/
#define PRIVLIB_EXP (win32_perllib_path(NULL)) /**/
/* SH_PATH:
@@ -1769,7 +1797,7 @@
* This symbol contains the ~name expanded version of SITEARCH, to be used
* in programs that are not prepared to deal with ~ expansion at run-time.
*/
-#define SITEARCH "c:\\perl\\lib\\site" /**/
+#define SITEARCH "c:\\perl5004.5x\\lib\\site" /**/
#define SITEARCH_EXP (win32_perllib_path("site",ARCHNAME,NULL)) /**/
/* SITELIB:
@@ -1785,7 +1813,7 @@
* This symbol contains the ~name expanded version of SITELIB, to be used
* in programs that are not prepared to deal with ~ expansion at run-time.
*/
-#define SITELIB "c:\\perl\\lib\\site" /**/
+#define SITELIB "c:\\perl5004.5x\\lib\\site" /**/
#define SITELIB_EXP (win32_perllib_path("site",NULL)) /**/
/* STARTPERL:
diff --git a/win32/dl_win32.xs b/win32/dl_win32.xs
index 0f869e1f85..13d97211a3 100644
--- a/win32/dl_win32.xs
+++ b/win32/dl_win32.xs
@@ -57,12 +57,12 @@ dl_load_file(filename,flags=0)
int flags
PREINIT:
CODE:
- DLDEBUG(1,fprintf(stderr,"dl_load_file(%s):\n", filename));
+ DLDEBUG(1,PerlIO_printf(PerlIO_stderr(),"dl_load_file(%s):\n", filename));
if (dl_static_linked(filename) == 0)
RETVAL = (void*) LoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH ) ;
else
RETVAL = (void*) GetModuleHandle(NULL);
- DLDEBUG(2,fprintf(stderr," libref=%x\n", RETVAL));
+ DLDEBUG(2,PerlIO_printf(PerlIO_stderr()," libref=%x\n", RETVAL));
ST(0) = sv_newmortal() ;
if (RETVAL == NULL)
SaveError("%d",GetLastError()) ;
@@ -75,10 +75,10 @@ dl_find_symbol(libhandle, symbolname)
void * libhandle
char * symbolname
CODE:
- DLDEBUG(2,fprintf(stderr,"dl_find_symbol(handle=%x, symbol=%s)\n",
+ DLDEBUG(2,PerlIO_printf(PerlIO_stderr(),"dl_find_symbol(handle=%x, symbol=%s)\n",
libhandle, symbolname));
RETVAL = (void*) GetProcAddress((HINSTANCE) libhandle, symbolname);
- DLDEBUG(2,fprintf(stderr," symbolref = %x\n", RETVAL));
+ DLDEBUG(2,PerlIO_printf(PerlIO_stderr()," symbolref = %x\n", RETVAL));
ST(0) = sv_newmortal() ;
if (RETVAL == NULL)
SaveError("%d",GetLastError()) ;
@@ -100,7 +100,7 @@ dl_install_xsub(perl_name, symref, filename="$Package")
void * symref
char * filename
CODE:
- DLDEBUG(2,fprintf(stderr,"dl_install_xsub(name=%s, symref=%x)\n",
+ DLDEBUG(2,PerlIO_printf(PerlIO_stderr(),"dl_install_xsub(name=%s, symref=%x)\n",
perl_name, symref));
ST(0)=sv_2mortal(newRV((SV*)newXS(perl_name, (void(*)(CV*))symref, filename)));
diff --git a/win32/include/sys/socket.h b/win32/include/sys/socket.h
index 40a5485343..6ffb0ac269 100644
--- a/win32/include/sys/socket.h
+++ b/win32/include/sys/socket.h
@@ -142,6 +142,7 @@ void win32_endprotoent(void);
void win32_endservent(void);
#ifndef WIN32SCK_IS_STDSCK
+#ifndef PERL_OBJECT
//
// direct to our version
//
@@ -203,6 +204,7 @@ void win32_endservent(void);
#define FD_ZERO(p) PERL_FD_ZERO(p)
#endif /* USE_SOCKETS_AS_HANDLES */
+#endif /* PERL_OBJECT */
#endif /* WIN32SCK_IS_STDSCK */
#ifdef __cplusplus
diff --git a/win32/ipdir.c b/win32/ipdir.c
new file mode 100644
index 0000000000..29702c8f26
--- /dev/null
+++ b/win32/ipdir.c
@@ -0,0 +1,186 @@
+/*
+
+ ipdir.c
+ Interface for perl directory functions
+
+*/
+
+#include <ipdir.h>
+
+class CPerlDir : public IPerlDir
+{
+public:
+ CPerlDir() { pPerl = NULL; };
+ virtual int MKdir(const char *dirname, int mode, int &err);
+ virtual int Chdir(const char *dirname, int &err);
+ virtual int Rmdir(const char *dirname, int &err);
+ virtual int Close(DIR *dirp, int &err);
+ virtual DIR *Open(char *filename, int &err);
+ virtual struct direct *Read(DIR *dirp, int &err);
+ virtual void Rewind(DIR *dirp, int &err);
+ virtual void Seek(DIR *dirp, long loc, int &err);
+ virtual long Tell(DIR *dirp, int &err);
+
+ inline void SetPerlObj(CPerlObj *p) { pPerl = p; };
+protected:
+ CPerlObj *pPerl;
+};
+
+int CPerlDir::MKdir(const char *dirname, int mode, int &err)
+{
+ return mkdir(dirname); /* just ignore mode */
+}
+
+int CPerlDir::Chdir(const char *dirname, int &err)
+{
+ return chdir(dirname);
+}
+
+int CPerlDir::Rmdir(const char *dirname, int &err)
+{
+ return rmdir(dirname);
+}
+
+#define PATHLEN 1024
+// The idea here is to read all the directory names into a string table
+// (separated by nulls) and when one of the other dir functions is called
+// return the pointer to the current file name.
+DIR *CPerlDir::Open(char *filename, int &err)
+{
+ DIR *p;
+ long len;
+ long idx;
+ char scannamespc[PATHLEN];
+ char *scanname = scannamespc;
+ struct stat sbuf;
+ WIN32_FIND_DATA FindData;
+ HANDLE fh;
+
+ // Create the search pattern
+ strcpy(scanname, filename);
+
+ len = strlen(scanname);
+ if(len > 1 && ((scanname[len-1] == '/') || (scanname[len-1] == '\\')))
+ {
+ // allow directory names of 'x:\' to pass
+ if(!(len == 3 && scanname[1] == ':'))
+ scanname[len-1] = '\0';
+ }
+
+ // check to see if filename is a directory
+ if(stat(scanname, &sbuf) < 0 || sbuf.st_mode & _S_IFDIR == 0)
+ {
+ DWORD dTemp = GetFileAttributes(scanname);
+ if(dTemp == 0xffffffff || !(dTemp & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ return NULL;
+ }
+ }
+
+ if((scanname[len-1] == '/') || (scanname[len-1] == '\\'))
+ scanname[len-1] = '\0';
+
+ strcat(scanname, "/*");
+
+ // Get a DIR structure
+ Newz(1501, p, 1, DIR);
+ if(p == NULL)
+ return NULL;
+
+ // do the FindFirstFile call
+ fh = FindFirstFile(scanname, &FindData);
+ if(fh == INVALID_HANDLE_VALUE)
+ {
+ Safefree(p);
+ return NULL;
+ }
+
+ // now allocate the first part of the string table for the filenames that we find.
+ idx = strlen(FindData.cFileName)+1;
+ New(1502, p->start, idx, char);
+ if(p->start == NULL)
+ {
+ FindClose(fh);
+ croak("opendir: malloc failed!\n");
+ }
+ strcpy(p->start, FindData.cFileName);
+ p->nfiles++;
+
+ // loop finding all the files that match the wildcard
+ // (which should be all of them in this directory!).
+ // the variable idx should point one past the null terminator
+ // of the previous string found.
+ //
+ while(FindNextFile(fh, &FindData))
+ {
+ len = strlen(FindData.cFileName);
+ // bump the string table size by enough for the
+ // new name and it's null terminator
+ Renew(p->start, idx+len+1, char);
+ if(p->start == NULL)
+ {
+ FindClose(fh);
+ croak("opendir: malloc failed!\n");
+ }
+ strcpy(&p->start[idx], FindData.cFileName);
+ p->nfiles++;
+ idx += len+1;
+ }
+ FindClose(fh);
+ p->size = idx;
+ p->curr = p->start;
+ return p;
+}
+
+int CPerlDir::Close(DIR *dirp, int &err)
+{
+ Safefree(dirp->start);
+ Safefree(dirp);
+ return 1;
+}
+
+// Readdir just returns the current string pointer and bumps the
+// string pointer to the next entry.
+struct direct *CPerlDir::Read(DIR *dirp, int &err)
+{
+ int len;
+ static int dummy = 0;
+
+ if(dirp->curr)
+ { // first set up the structure to return
+ len = strlen(dirp->curr);
+ strcpy(dirp->dirstr.d_name, dirp->curr);
+ dirp->dirstr.d_namlen = len;
+
+ // Fake an inode
+ dirp->dirstr.d_ino = dummy++;
+
+ // Now set up for the next call to readdir
+ dirp->curr += len + 1;
+ if(dirp->curr >= (dirp->start + dirp->size))
+ {
+ dirp->curr = NULL;
+ }
+
+ return &(dirp->dirstr);
+ }
+ else
+ return NULL;
+}
+
+void CPerlDir::Rewind(DIR *dirp, int &err)
+{
+ dirp->curr = dirp->start;
+}
+
+void CPerlDir::Seek(DIR *dirp, long loc, int &err)
+{
+ dirp->curr = (char *)loc;
+}
+
+long CPerlDir::Tell(DIR *dirp, int &err)
+{
+ return (long) dirp->curr;
+}
+
+
diff --git a/win32/ipenv.c b/win32/ipenv.c
new file mode 100644
index 0000000000..9033b55138
--- /dev/null
+++ b/win32/ipenv.c
@@ -0,0 +1,62 @@
+/*
+
+ ipenv.c
+ Interface for perl environment functions
+
+*/
+
+#include <ipenv.h>
+#include <stdlib.h>
+
+class CPerlEnv : public IPerlEnv
+{
+public:
+ CPerlEnv() { w32_perldll_handle = INVALID_HANDLE_VALUE; pPerl = NULL; };
+ virtual char *Getenv(const char *varname, int &err);
+ virtual int Putenv(const char *envstring, int &err);
+ virtual char* LibPath(char *sfx, ...);
+
+ inline void SetPerlObj(CPerlObj *p) { pPerl = p; };
+protected:
+ char w32_perllib_root[MAX_PATH+1];
+ HANDLE w32_perldll_handle;
+ CPerlObj *pPerl;
+};
+
+char *CPerlEnv::Getenv(const char *varname, int &err)
+{
+ return getenv(varname);
+}
+
+int CPerlEnv::Putenv(const char *envstring, int &err)
+{
+ return _putenv(envstring);
+}
+
+char* CPerlEnv::LibPath(char *sfx, ...)
+{
+ va_list ap;
+ char *end;
+ va_start(ap,sfx);
+ 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);
+}
+
+
+
+
diff --git a/win32/iplio.c b/win32/iplio.c
new file mode 100644
index 0000000000..3522284219
--- /dev/null
+++ b/win32/iplio.c
@@ -0,0 +1,307 @@
+/*
+
+ iplio.c
+ Interface for perl Low IO functions
+
+*/
+
+#include <iplio.h>
+#include <sys/utime.h>
+
+
+class CPerlLIO : public IPerlLIO
+{
+public:
+ CPerlLIO() { w32_platform = (-1); pPerl = NULL; pSock = NULL; pStdIO = NULL; };
+
+ virtual int Access(const char *path, int mode, int &err);
+ virtual int Chmod(const char *filename, int pmode, int &err);
+ virtual int Chsize(int handle, long size, int &err);
+ virtual int Close(int handle, int &err);
+ virtual int Dup(int handle, int &err);
+ virtual int Dup2(int handle1, int handle2, int &err);
+ virtual int Flock(int fd, int oper, int &err);
+ virtual int FStat(int handle, struct stat *buffer, int &err);
+ virtual int IOCtl(int i, unsigned int u, char *data, int &err);
+ virtual int Isatty(int handle, int &err);
+ virtual long Lseek(int handle, long offset, int origin, int &err);
+ virtual int Lstat(const char *path, struct stat *buffer, int &err);
+ virtual char *Mktemp(char *Template, int &err);
+ virtual int Open(const char *filename, int oflag, int &err);
+ virtual int Open(const char *filename, int oflag, int pmode, int &err);
+ virtual int Read(int handle, void *buffer, unsigned int count, int &err);
+ virtual int Rename(const char *oldname, const char *newname, int &err);
+ virtual int Setmode(int handle, int mode, int &err);
+ virtual int STat(const char *path, struct stat *buffer, int &err);
+ virtual char *Tmpnam(char *string, int &err);
+ virtual int Umask(int pmode, int &err);
+ virtual int Unlink(const char *filename, int &err);
+ virtual int Utime(char *filename, struct utimbuf *times, int &err);
+ virtual int Write(int handle, const void *buffer, unsigned int count, int &err);
+
+ inline void SetPerlObj(CPerlObj *p) { pPerl = p; };
+ inline void SetSockCtl(CPerlSock *p) { pSock = p; };
+ inline void SetStdObj(IPerlStdIOWin *p) { pStdIO = p; };
+protected:
+ inline int IsWin95(void)
+ {
+ return (os_id() == VER_PLATFORM_WIN32_WINDOWS);
+ };
+ inline int IsWinNT(void)
+ {
+ return (os_id() == VER_PLATFORM_WIN32_NT);
+ };
+ int GetOSfhandle(int filenum)
+ {
+ return pStdIO->GetOSfhandle(filenum);
+ };
+ DWORD os_id(void)
+ {
+ if((-1) == w32_platform)
+ {
+ OSVERSIONINFO osver;
+
+ memset(&osver, 0, sizeof(OSVERSIONINFO));
+ osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osver);
+ w32_platform = osver.dwPlatformId;
+ }
+ return (w32_platform);
+ }
+
+ DWORD w32_platform;
+ CPerlObj *pPerl;
+ CPerlSock *pSock;
+ IPerlStdIOWin *pStdIO;
+};
+
+#define CALLFUNCRET(x)\
+ int ret = x;\
+ if(ret)\
+ err = errno;\
+ return ret;
+
+#define CALLFUNCERR(x)\
+ int ret = x;\
+ if(errno)\
+ err = errno;\
+ return ret;
+
+#define LCALLFUNCERR(x)\
+ long ret = x;\
+ if(errno)\
+ err = errno;\
+ return ret;
+
+int CPerlLIO::Access(const char *path, int mode, int &err)
+{
+ CALLFUNCRET(access(path, mode))
+}
+
+int CPerlLIO::Chmod(const char *filename, int pmode, int &err)
+{
+ CALLFUNCRET(chmod(filename, pmode))
+}
+
+int CPerlLIO::Chsize(int handle, long size, int &err)
+{
+ CALLFUNCRET(chsize(handle, size))
+}
+
+int CPerlLIO::Close(int fd, int &err)
+{
+ CALLFUNCRET(close(fd))
+}
+
+int CPerlLIO::Dup(int fd, int &err)
+{
+ CALLFUNCERR(dup(fd))
+}
+
+int CPerlLIO::Dup2(int handle1, int handle2, int &err)
+{
+ CALLFUNCERR(dup2(handle1, handle2))
+}
+
+
+#define LK_ERR(f,i) ((f) ? (i = 0) : (err = GetLastError()))
+#define LK_LEN 0xffff0000
+#define LOCK_SH 1
+#define LOCK_EX 2
+#define LOCK_NB 4
+#define LOCK_UN 8
+
+int CPerlLIO::Flock(int fd, int oper, int &err)
+{
+ OVERLAPPED o;
+ int i = -1;
+ HANDLE fh;
+
+ if (!IsWinNT()) {
+ croak("flock() unimplemented on this platform");
+ return -1;
+ }
+ fh = (HANDLE)GetOSfhandle(fd);
+ memset(&o, 0, sizeof(o));
+
+ switch(oper) {
+ case LOCK_SH: /* shared lock */
+ LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, 0, &o),i);
+ break;
+ case LOCK_EX: /* exclusive lock */
+ LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o),i);
+ break;
+ case LOCK_SH|LOCK_NB: /* non-blocking shared lock */
+ LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o),i);
+ break;
+ case LOCK_EX|LOCK_NB: /* non-blocking exclusive lock */
+ LK_ERR(LockFileEx(fh,
+ LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
+ 0, LK_LEN, 0, &o),i);
+ break;
+ case LOCK_UN: /* unlock lock */
+ LK_ERR(UnlockFileEx(fh, 0, LK_LEN, 0, &o),i);
+ break;
+ default: /* unknown */
+ err = EINVAL;
+ break;
+ }
+ return i;
+}
+
+int CPerlLIO::FStat(int fd, struct stat *sbufptr, int &err)
+{
+ int ret = fstat(fd, sbufptr);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlLIO::IOCtl(int i, unsigned int u, char *data, int &err)
+{
+ return pSock->IoctlSocket((SOCKET)i, (long)u, (u_long*)data, err);
+}
+
+int CPerlLIO::Isatty(int fd, int &err)
+{
+ return isatty(fd);
+}
+
+long CPerlLIO::Lseek(int fd, long offset, int origin, int &err)
+{
+ LCALLFUNCERR(lseek(fd, offset, origin))
+}
+
+int CPerlLIO::Lstat(const char *path, struct stat *sbufptr, int &err)
+{
+ return stat(path, sbufptr);
+}
+
+char *CPerlLIO::Mktemp(char *Template, int &err)
+{
+ return mktemp(Template);
+}
+
+int CPerlLIO::Open(const char *filename, int oflag, int &err)
+{
+ CALLFUNCERR(open(filename, oflag))
+}
+
+int CPerlLIO::Open(const char *filename, int oflag, int pmode, int &err)
+{
+ CALLFUNCERR(open(filename, oflag, pmode))
+}
+
+int CPerlLIO::Read(int fd, void *buffer, unsigned int cnt, int &err)
+{
+ CALLFUNCERR(read(fd, buffer, cnt))
+}
+
+int CPerlLIO::Rename(const char *OldFileName, const char *newname, int &err)
+{
+ char szNewWorkName[MAX_PATH+1];
+ WIN32_FIND_DATA fdOldFile, fdNewFile;
+ HANDLE handle;
+ char *ptr;
+
+ if((strchr(OldFileName, '\\') || strchr(OldFileName, '/'))
+ && strchr(newname, '\\') == NULL
+ && strchr(newname, '/') == NULL)
+ {
+ strcpy(szNewWorkName, OldFileName);
+ if((ptr = strrchr(szNewWorkName, '\\')) == NULL)
+ ptr = strrchr(szNewWorkName, '/');
+ strcpy(++ptr, newname);
+ }
+ else
+ strcpy(szNewWorkName, newname);
+
+ if(stricmp(OldFileName, 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(OldFileName, &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);
+ }
+ }
+ }
+ int ret = rename(OldFileName, szNewWorkName);
+ if(ret)
+ err = errno;
+
+ return ret;
+}
+
+int CPerlLIO::Setmode(int fd, int mode, int &err)
+{
+ CALLFUNCRET(setmode(fd, mode))
+}
+
+int CPerlLIO::STat(const char *path, struct stat *sbufptr, int &err)
+{
+ return stat(path, sbufptr);
+}
+
+char *CPerlLIO::Tmpnam(char *string, int &err)
+{
+ return tmpnam(string);
+}
+
+int CPerlLIO::Umask(int pmode, int &err)
+{
+ return umask(pmode);
+}
+
+int CPerlLIO::Unlink(const char *filename, int &err)
+{
+ chmod(filename, _S_IREAD | _S_IWRITE);
+ CALLFUNCRET(unlink(filename))
+}
+
+int CPerlLIO::Utime(char *filename, struct utimbuf *times, int &err)
+{
+ CALLFUNCRET(utime(filename, times))
+}
+
+int CPerlLIO::Write(int fd, const void *buffer, unsigned int cnt, int &err)
+{
+ CALLFUNCERR(write(fd, buffer, cnt))
+}
+
diff --git a/win32/ipmem.c b/win32/ipmem.c
new file mode 100644
index 0000000000..62e72ab8db
--- /dev/null
+++ b/win32/ipmem.c
@@ -0,0 +1,39 @@
+/*
+
+ ipmem.c
+ Interface for perl memory allocation
+
+*/
+
+#include <ipmem.h>
+
+class CPerlMem : public IPerlMem
+{
+public:
+ CPerlMem() { pPerl = NULL; };
+ virtual void* Malloc(size_t);
+ virtual void* Realloc(void*, size_t);
+ virtual void Free(void*);
+
+ inline void SetPerlObj(CPerlObj *p) { pPerl = p; };
+protected:
+ CPerlObj *pPerl;
+};
+
+void* CPerlMem::Malloc(size_t size)
+{
+ return malloc(size);
+}
+
+void* CPerlMem::Realloc(void* ptr, size_t size)
+{
+ return realloc(ptr, size);
+}
+
+void CPerlMem::Free(void* ptr)
+{
+ free(ptr);
+}
+
+
+
diff --git a/win32/ipproc.c b/win32/ipproc.c
new file mode 100644
index 0000000000..f6445291d1
--- /dev/null
+++ b/win32/ipproc.c
@@ -0,0 +1,620 @@
+/*
+
+ ipproc.c
+ Interface for perl process functions
+
+*/
+
+#include <ipproc.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#define EXECF_EXEC 1
+#define EXECF_SPAWN 2
+#define EXECF_SPAWN_NOWAIT 3
+
+class CPerlProc : public IPerlProc
+{
+public:
+ CPerlProc()
+ {
+ pPerl = NULL;
+ w32_perlshell_tokens = NULL;
+ w32_perlshell_items = -1;
+ w32_platform = -1;
+#ifndef __BORLANDC__
+ w32_num_children = 0;
+#endif
+ };
+ virtual void Abort(void);
+ virtual void Exit(int status);
+ virtual void _Exit(int status);
+ virtual int Execl(const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3);
+ virtual int Execv(const char *cmdname, const char *const *argv);
+ virtual int Execvp(const char *cmdname, const char *const *argv);
+ virtual uid_t Getuid(void);
+ virtual uid_t Geteuid(void);
+ virtual gid_t Getgid(void);
+ virtual gid_t Getegid(void);
+ virtual char *Getlogin(void);
+ virtual int Kill(int pid, int sig);
+ virtual int Killpg(int pid, int sig);
+ virtual int PauseProc(void);
+ virtual PerlIO* Popen(const char *command, const char *mode);
+ virtual int Pclose(PerlIO *stream);
+ virtual int Pipe(int *phandles);
+ virtual int Setuid(uid_t u);
+ virtual int Setgid(gid_t g);
+ virtual int Sleep(unsigned int);
+ virtual int Times(struct tms *timebuf);
+ virtual int Wait(int *status);
+ virtual Sighandler_t Signal(int sig, Sighandler_t subcode);
+ virtual void GetSysMsg(char*& msg, DWORD& dwLen, DWORD dwErr);
+ virtual void FreeBuf(char* msg);
+ virtual BOOL DoCmd(char *cmd);
+ virtual int Spawn(char*cmds);
+ virtual int Spawnvp(int mode, const char *cmdname, const char *const *argv);
+ virtual int ASpawn(void *vreally, void **vmark, void **vsp);
+
+ inline void SetPerlObj(CPerlObj *p) { pPerl = p; };
+protected:
+ int Spawn(char *cmd, int exectype);
+ void GetShell(void);
+ long Tokenize(char *str, char **dest, char ***destv);
+
+ inline int IsWin95(void)
+ {
+ return (os_id() == VER_PLATFORM_WIN32_WINDOWS);
+ };
+ inline int IsWinNT(void)
+ {
+ return (os_id() == VER_PLATFORM_WIN32_NT);
+ };
+
+ inline long filetime_to_clock(PFILETIME ft)
+ {
+ __int64 qw = ft->dwHighDateTime;
+ qw <<= 32;
+ qw |= ft->dwLowDateTime;
+ qw /= 10000; /* File time ticks at 0.1uS, clock at 1mS */
+ return (long) qw;
+ };
+
+ DWORD os_id(void)
+ {
+ if((-1) == w32_platform)
+ {
+ OSVERSIONINFO osver;
+
+ memset(&osver, 0, sizeof(OSVERSIONINFO));
+ osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osver);
+ w32_platform = osver.dwPlatformId;
+ }
+ return (w32_platform);
+ };
+
+ DWORD w32_platform;
+ char szLoginNameStr[128];
+ char *w32_perlshell_tokens;
+ long w32_perlshell_items;
+ char **w32_perlshell_vec;
+#ifndef __BORLANDC__
+ long w32_num_children;
+ HANDLE w32_child_pids[MAXIMUM_WAIT_OBJECTS];
+#endif
+ CPerlObj *pPerl;
+};
+
+
+static BOOL
+has_redirection(char *ptr)
+{
+ int inquote = 0;
+ char quote = '\0';
+
+ /*
+ * Scan string looking for redirection (< or >) or pipe
+ * characters (|) that are not in a quoted string
+ */
+ while(*ptr) {
+ switch(*ptr) {
+ case '\'':
+ case '\"':
+ if(inquote) {
+ if(quote == *ptr) {
+ inquote = 0;
+ quote = '\0';
+ }
+ }
+ else {
+ quote = *ptr;
+ inquote++;
+ }
+ break;
+ case '>':
+ case '<':
+ case '|':
+ if(!inquote)
+ return TRUE;
+ default:
+ break;
+ }
+ ++ptr;
+ }
+ return FALSE;
+}
+
+/* Tokenize a string. Words are null-separated, and the list
+ * ends with a doubled null. Any character (except null and
+ * including backslash) may be escaped by preceding it with a
+ * backslash (the backslash will be stripped).
+ * Returns number of words in result buffer.
+ */
+long
+CPerlProc::Tokenize(char *str, char **dest, char ***destv)
+{
+ char *retstart = Nullch;
+ char **retvstart = 0;
+ int items = -1;
+ if (str) {
+ int slen = strlen(str);
+ register char *ret;
+ register char **retv;
+ New(1307, ret, slen+2, char);
+ New(1308, retv, (slen+3)/2, char*);
+
+ retstart = ret;
+ retvstart = retv;
+ *retv = ret;
+ items = 0;
+ while (*str) {
+ *ret = *str++;
+ if (*ret == '\\' && *str)
+ *ret = *str++;
+ else if (*ret == ' ') {
+ while (*str == ' ')
+ str++;
+ if (ret == retstart)
+ ret--;
+ else {
+ *ret = '\0';
+ ++items;
+ if (*str)
+ *++retv = ret+1;
+ }
+ }
+ else if (!*str)
+ ++items;
+ ret++;
+ }
+ retvstart[items] = Nullch;
+ *ret++ = '\0';
+ *ret = '\0';
+ }
+ *dest = retstart;
+ *destv = retvstart;
+ return items;
+}
+
+
+void
+CPerlProc::GetShell(void)
+{
+ if (!w32_perlshell_tokens) {
+ /* we don't use COMSPEC here for two reasons:
+ * 1. the same reason perl on UNIX doesn't use SHELL--rampant and
+ * uncontrolled unportability of the ensuing scripts.
+ * 2. PERL5SHELL could be set to a shell that may not be fit for
+ * interactive use (which is what most programs look in COMSPEC
+ * for).
+ */
+ char* defaultshell = (IsWinNT() ? "cmd.exe /x/c" : "command.com /c");
+ char* usershell = getenv("PERL5SHELL");
+ w32_perlshell_items = Tokenize(usershell ? usershell : defaultshell,
+ &w32_perlshell_tokens,
+ &w32_perlshell_vec);
+ }
+}
+
+int
+CPerlProc::ASpawn(void *vreally, void **vmark, void **vsp)
+{
+ SV *really = (SV*)vreally;
+ SV **mark = (SV**)vmark;
+ SV **sp = (SV**)vsp;
+ char **argv;
+ char *str;
+ int status;
+ int flag = P_WAIT;
+ int index = 0;
+
+ if (sp <= mark)
+ return -1;
+
+ GetShell();
+ New(1306, argv, (sp - mark) + w32_perlshell_items + 2, char*);
+
+ if (SvNIOKp(*(mark+1)) && !SvPOKp(*(mark+1))) {
+ ++mark;
+ flag = SvIVx(*mark);
+ }
+
+ while(++mark <= sp) {
+ if (*mark && (str = SvPV(*mark, na)))
+ argv[index++] = str;
+ else
+ argv[index++] = "";
+ }
+ argv[index++] = 0;
+
+ status = Spawnvp(flag,
+ (really ? SvPV(really,na) : argv[0]),
+ (const char* const*)argv);
+
+ if (status < 0 && errno == ENOEXEC) {
+ /* possible shell-builtin, invoke with shell */
+ int sh_items;
+ sh_items = w32_perlshell_items;
+ while (--index >= 0)
+ argv[index+sh_items] = argv[index];
+ while (--sh_items >= 0)
+ argv[sh_items] = w32_perlshell_vec[sh_items];
+
+ status = Spawnvp(flag,
+ (really ? SvPV(really,na) : argv[0]),
+ (const char* const*)argv);
+ }
+
+ if (status < 0) {
+ if (pPerl->Perl_dowarn)
+ warn("Can't spawn \"%s\": %s", argv[0], strerror(errno));
+ status = 255 * 256;
+ }
+ else if (flag != P_NOWAIT)
+ status *= 256;
+ Safefree(argv);
+ return (pPerl->Perl_statusvalue = status);
+}
+
+
+int
+CPerlProc::Spawn(char *cmd, int exectype)
+{
+ char **a;
+ char *s;
+ char **argv;
+ int status = -1;
+ BOOL needToTry = TRUE;
+ char *cmd2;
+
+ /* Save an extra exec if possible. See if there are shell
+ * metacharacters in it */
+ if(!has_redirection(cmd)) {
+ New(1301,argv, strlen(cmd) / 2 + 2, char*);
+ New(1302,cmd2, strlen(cmd) + 1, char);
+ strcpy(cmd2, cmd);
+ a = argv;
+ for (s = cmd2; *s;) {
+ while (*s && isspace(*s))
+ s++;
+ if (*s)
+ *(a++) = s;
+ while(*s && !isspace(*s))
+ s++;
+ if(*s)
+ *s++ = '\0';
+ }
+ *a = Nullch;
+ if (argv[0]) {
+ switch (exectype) {
+ case EXECF_SPAWN:
+ status = Spawnvp(P_WAIT, argv[0],
+ (const char* const*)argv);
+ break;
+ case EXECF_SPAWN_NOWAIT:
+ status = Spawnvp(P_NOWAIT, argv[0],
+ (const char* const*)argv);
+ break;
+ case EXECF_EXEC:
+ status = Execvp(argv[0], (const char* const*)argv);
+ break;
+ }
+ if (status != -1 || errno == 0)
+ needToTry = FALSE;
+ }
+ Safefree(argv);
+ Safefree(cmd2);
+ }
+ if (needToTry) {
+ char **argv;
+ int i = -1;
+ GetShell();
+ New(1306, argv, w32_perlshell_items + 2, char*);
+ while (++i < w32_perlshell_items)
+ argv[i] = w32_perlshell_vec[i];
+ argv[i++] = cmd;
+ argv[i] = Nullch;
+ switch (exectype) {
+ case EXECF_SPAWN:
+ status = Spawnvp(P_WAIT, argv[0],
+ (const char* const*)argv);
+ break;
+ case EXECF_SPAWN_NOWAIT:
+ status = Spawnvp(P_NOWAIT, argv[0],
+ (const char* const*)argv);
+ break;
+ case EXECF_EXEC:
+ status = Execvp(argv[0], (const char* const*)argv);
+ break;
+ }
+ cmd = argv[0];
+ Safefree(argv);
+ }
+ if (status < 0) {
+ if (pPerl->Perl_dowarn)
+ warn("Can't %s \"%s\": %s",
+ (exectype == EXECF_EXEC ? "exec" : "spawn"),
+ cmd, strerror(errno));
+ status = 255 * 256;
+ }
+ else if (exectype != EXECF_SPAWN_NOWAIT)
+ status *= 256;
+ return (pPerl->Perl_statusvalue = status);
+}
+
+
+void CPerlProc::Abort(void)
+{
+ abort();
+}
+
+void CPerlProc::Exit(int status)
+{
+ exit(status);
+}
+
+void CPerlProc::_Exit(int status)
+{
+ _exit(status);
+}
+
+int CPerlProc::Execl(const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3)
+{
+ return execl(cmdname, arg0, arg1, arg2, arg3);
+}
+
+int CPerlProc::Execv(const char *cmdname, const char *const *argv)
+{
+ return execv(cmdname, argv);
+}
+
+int CPerlProc::Execvp(const char *cmdname, const char *const *argv)
+{
+ return execvp(cmdname, argv);
+}
+
+#define ROOT_UID ((uid_t)0)
+#define ROOT_GID ((gid_t)0)
+
+uid_t CPerlProc::Getuid(void)
+{
+ return ROOT_UID;
+}
+
+uid_t CPerlProc::Geteuid(void)
+{
+ return ROOT_UID;
+}
+
+gid_t CPerlProc::Getgid(void)
+{
+ return ROOT_GID;
+}
+
+gid_t CPerlProc::Getegid(void)
+{
+ return ROOT_GID;
+}
+
+
+char *CPerlProc::Getlogin(void)
+{
+ char unknown[] = "<Unknown>";
+ unsigned long len;
+
+ len = sizeof(szLoginNameStr);
+ if(!GetUserName(szLoginNameStr, &len))
+ {
+ strcpy(szLoginNameStr, unknown);
+ }
+ return szLoginNameStr;
+}
+
+int CPerlProc::Kill(int pid, int sig)
+{
+ HANDLE hProcess;
+
+ hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
+ if(hProcess == NULL)
+ croak("kill process failed!\n");
+
+ if(TerminateProcess(hProcess, 0) == FALSE)
+ croak("kill process failed!\n");
+
+ CloseHandle(hProcess);
+ return 0;
+}
+
+int CPerlProc::Killpg(int pid, int sig)
+{
+ croak("killpg not implemented!\n");
+ return 0;
+}
+
+int CPerlProc::PauseProc(void)
+{
+ Sleep((unsigned int)((32767L << 16) + 32767));
+ return 0;
+}
+
+PerlIO* CPerlProc::Popen(const char *command, const char *mode)
+{
+ return (PerlIO*)_popen(command, mode);
+}
+
+int CPerlProc::Pclose(PerlIO *pf)
+{
+ return _pclose((FILE*)pf);
+}
+
+int CPerlProc::Pipe(int *phandles)
+{
+ return _pipe(phandles, 512, O_BINARY);
+}
+
+int CPerlProc::Sleep(unsigned int s)
+{
+ ::Sleep(s*1000);
+ return 0;
+}
+
+int CPerlProc::Times(struct tms *timebuf)
+{
+ FILETIME user;
+ FILETIME kernel;
+ FILETIME dummy;
+ if (GetProcessTimes(GetCurrentProcess(), &dummy, &dummy,
+ &kernel,&user)) {
+ timebuf->tms_utime = filetime_to_clock(&user);
+ timebuf->tms_stime = filetime_to_clock(&kernel);
+ timebuf->tms_cutime = 0;
+ timebuf->tms_cstime = 0;
+
+ } else {
+ /* That failed - e.g. Win95 fallback to clock() */
+ clock_t t = clock();
+ timebuf->tms_utime = t;
+ timebuf->tms_stime = 0;
+ timebuf->tms_cutime = 0;
+ timebuf->tms_cstime = 0;
+ }
+ return 0;
+}
+
+int CPerlProc::Wait(int *status)
+{
+#ifdef __BORLANDC__
+ return wait(status);
+#else
+ /* XXX this wait emulation only knows about processes
+ * spawned via win32_spawnvp(P_NOWAIT, ...).
+ */
+ int i, retval;
+ DWORD exitcode, waitcode;
+
+ if (!w32_num_children) {
+ errno = ECHILD;
+ return -1;
+ }
+
+ /* if a child exists, wait for it to die */
+ waitcode = WaitForMultipleObjects(w32_num_children,
+ w32_child_pids,
+ FALSE,
+ INFINITE);
+ if (waitcode != WAIT_FAILED) {
+ if (waitcode >= WAIT_ABANDONED_0
+ && waitcode < WAIT_ABANDONED_0 + w32_num_children)
+ i = waitcode - WAIT_ABANDONED_0;
+ else
+ i = waitcode - WAIT_OBJECT_0;
+ if (GetExitCodeProcess(w32_child_pids[i], &exitcode) ) {
+ CloseHandle(w32_child_pids[i]);
+ *status = (int)((exitcode & 0xff) << 8);
+ retval = (int)w32_child_pids[i];
+ Copy(&w32_child_pids[i+1], &w32_child_pids[i],
+ (w32_num_children-i-1), HANDLE);
+ w32_num_children--;
+ return retval;
+ }
+ }
+
+FAILED:
+ errno = GetLastError();
+ return -1;
+
+#endif
+}
+
+int CPerlProc::Setuid(uid_t u)
+{
+ return (u == ROOT_UID ? 0 : -1);
+}
+
+int CPerlProc::Setgid(gid_t g)
+{
+ return (g == ROOT_GID ? 0 : -1);
+}
+
+Sighandler_t CPerlProc::Signal(int sig, Sighandler_t subcode)
+{
+ return 0;
+}
+
+void CPerlProc::GetSysMsg(char*& sMsg, DWORD& dwLen, DWORD dwErr)
+{
+ dwLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
+ |FORMAT_MESSAGE_IGNORE_INSERTS
+ |FORMAT_MESSAGE_FROM_SYSTEM, NULL,
+ dwErr, 0, (char *)&sMsg, 1, NULL);
+ if (0 < dwLen) {
+ while (0 < dwLen && isspace(sMsg[--dwLen]))
+ ;
+ if ('.' != sMsg[dwLen])
+ dwLen++;
+ sMsg[dwLen]= '\0';
+ }
+ if (0 == dwLen) {
+ sMsg = (char*)LocalAlloc(0, 64/**sizeof(TCHAR)*/);
+ dwLen = sprintf(sMsg,
+ "Unknown error #0x%lX (lookup 0x%lX)",
+ dwErr, GetLastError());
+ }
+}
+
+void CPerlProc::FreeBuf(char* sMsg)
+{
+ LocalFree(sMsg);
+}
+
+BOOL CPerlProc::DoCmd(char *cmd)
+{
+ Spawn(cmd, EXECF_EXEC);
+ return FALSE;
+}
+
+int CPerlProc::Spawn(char* cmd)
+{
+ return Spawn(cmd, EXECF_SPAWN);
+}
+
+int CPerlProc::Spawnvp(int mode, const char *cmdname, const char *const *argv)
+{
+ int status;
+
+ status = spawnvp(mode, cmdname, (char * const *)argv);
+#ifndef __BORLANDC__
+ /* 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.
+ */
+ if (mode == P_NOWAIT && status >= 0)
+ w32_child_pids[w32_num_children++] = (HANDLE)status;
+#endif
+ return status;
+}
+
+
+
+
diff --git a/win32/ipsock.c b/win32/ipsock.c
new file mode 100644
index 0000000000..a6510b9d83
--- /dev/null
+++ b/win32/ipsock.c
@@ -0,0 +1,681 @@
+/*
+
+ ipsock.c
+ Interface for perl socket functions
+
+*/
+
+#include <ipsock.h>
+#include <fcntl.h>
+
+#define USE_SOCKETS_AS_HANDLES
+
+class CPerlSock : public IPerlSock
+{
+public:
+ CPerlSock();
+ ~CPerlSock();
+ virtual u_long Htonl(u_long hostlong);
+ virtual u_short Htons(u_short hostshort);
+ virtual u_long Ntohl(u_long netlong);
+ virtual u_short Ntohs(u_short netshort);
+ virtual SOCKET Accept(SOCKET s, struct sockaddr* addr, int* addrlen, int &err);
+ virtual int Bind(SOCKET s, const struct sockaddr* name, int namelen, int &err);
+ virtual int Connect(SOCKET s, const struct sockaddr* name, int namelen, int &err);
+ virtual void Endhostent(int &err);
+ virtual void Endnetent(int &err);
+ virtual void Endprotoent(int &err);
+ virtual void Endservent(int &err);
+ virtual struct hostent* Gethostbyaddr(const char* addr, int len, int type, int &err);
+ virtual struct hostent* Gethostbyname(const char* name, int &err);
+ virtual struct hostent* Gethostent(int &err);
+ virtual int Gethostname(char* name, int namelen, int &err);
+ virtual struct netent *Getnetbyaddr(long net, int type, int &err);
+ virtual struct netent *Getnetbyname(const char *, int &err);
+ virtual struct netent *Getnetent(int &err);
+ virtual int Getpeername(SOCKET s, struct sockaddr* name, int* namelen, int &err);
+ virtual struct protoent* Getprotobyname(const char* name, int &err);
+ virtual struct protoent* Getprotobynumber(int number, int &err);
+ virtual struct protoent* Getprotoent(int &err);
+ virtual struct servent* Getservbyname(const char* name, const char* proto, int &err);
+ virtual struct servent* Getservbyport(int port, const char* proto, int &err);
+ virtual struct servent* Getservent(int &err);
+ virtual int Getsockname(SOCKET s, struct sockaddr* name, int* namelen, int &err);
+ virtual int Getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen, int &err);
+ virtual unsigned long InetAddr(const char* cp, int &err);
+ virtual char* InetNtoa(struct in_addr in, int &err);
+ virtual int IoctlSocket(SOCKET s, long cmd, u_long *argp, int& err);
+ virtual int Listen(SOCKET s, int backlog, int &err);
+ virtual int Recvfrom(SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen, int &err);
+ virtual int Select(int nfds, char* readfds, char* writefds, char* exceptfds, const struct timeval* timeout, int &err);
+ virtual int Send(SOCKET s, const char* buffer, int len, int flags, int &err);
+ virtual int Sendto(SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen, int &err);
+ virtual void Sethostent(int stayopen, int &err);
+ virtual void Setnetent(int stayopen, int &err);
+ virtual void Setprotoent(int stayopen, int &err);
+ virtual void Setservent(int stayopen, int &err);
+ virtual int Setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen, int &err);
+ virtual int Shutdown(SOCKET s, int how, int &err);
+ virtual SOCKET Socket(int af, int type, int protocol, int &err);
+ virtual int Socketpair(int domain, int type, int protocol, int* fds, int &err);
+
+ void CloseSocket(int fh, int& err);
+ void* GetAddress(HINSTANCE hInstance, char *lpFunctionName);
+ void LoadWinSock(void);
+
+ inline void SetPerlObj(CPerlObj *p) { pPerl = p; };
+ inline void SetStdObj(IPerlStdIOWin *p) { pStdIO = p; };
+protected:
+ void Start(void);
+
+ inline int OpenOSfhandle(long osfhandle)
+ {
+ return pStdIO->OpenOSfhandle(osfhandle, O_RDWR|O_BINARY);
+ };
+ int GetOSfhandle(int filenum)
+ {
+ return pStdIO->GetOSfhandle(filenum);
+ };
+
+ inline void StartSockets(void)
+ {
+ if(!bStarted)
+ Start();
+ };
+
+ BOOL bStarted;
+ CPerlObj *pPerl;
+ IPerlStdIOWin *pStdIO;
+};
+
+
+#define SOCKETAPI PASCAL
+
+typedef SOCKET (SOCKETAPI *LPSOCKACCEPT)(SOCKET, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKBIND)(SOCKET, const struct sockaddr *, int);
+typedef int (SOCKETAPI *LPSOCKCLOSESOCKET)(SOCKET);
+typedef int (SOCKETAPI *LPSOCKCONNECT)(SOCKET, const struct sockaddr *, int);
+typedef unsigned long (SOCKETAPI *LPINETADDR)(const char *);
+typedef char* (SOCKETAPI *LPINETNTOA)(struct in_addr);
+typedef int (SOCKETAPI *LPSOCKIOCTLSOCKET)(SOCKET, long, u_long *);
+typedef int (SOCKETAPI *LPSOCKGETPEERNAME)(SOCKET, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKGETSOCKNAME)(SOCKET, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKGETSOCKOPT)(SOCKET, int, int, char *, int *);
+typedef u_long (SOCKETAPI *LPSOCKHTONL)(u_long);
+typedef u_short (SOCKETAPI *LPSOCKHTONS)(u_short);
+typedef int (SOCKETAPI *LPSOCKLISTEN)(SOCKET, int);
+typedef u_long (SOCKETAPI *LPSOCKNTOHL)(u_long);
+typedef u_short (SOCKETAPI *LPSOCKNTOHS)(u_short);
+typedef int (SOCKETAPI *LPSOCKRECV)(SOCKET, char *, int, int);
+typedef int (SOCKETAPI *LPSOCKRECVFROM)(SOCKET, char *, int, int, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKSELECT)(int, fd_set *, fd_set *, fd_set *, const struct timeval *);
+typedef int (SOCKETAPI *LPSOCKSEND)(SOCKET, const char *, int, int);
+typedef int (SOCKETAPI *LPSOCKSENDTO)(SOCKET, const char *, int, int, const struct sockaddr *, int);
+typedef int (SOCKETAPI *LPSOCKSETSOCKOPT)(SOCKET, int, int, const char *, int);
+typedef int (SOCKETAPI *LPSOCKSHUTDOWN)(SOCKET, int);
+typedef SOCKET (SOCKETAPI *LPSOCKSOCKET)(int, int, int);
+
+/* Database function prototypes */
+typedef struct hostent *(SOCKETAPI *LPSOCKGETHOSTBYADDR)(const char *, int, int);
+typedef struct hostent *(SOCKETAPI *LPSOCKGETHOSTBYNAME)(const char *);
+typedef int (SOCKETAPI *LPSOCKGETHOSTNAME)(char *, int);
+typedef struct servent *(SOCKETAPI *LPSOCKGETSERVBYPORT)(int, const char *);
+typedef struct servent *(SOCKETAPI *LPSOCKGETSERVBYNAME)(const char *, const char *);
+typedef struct protoent *(SOCKETAPI *LPSOCKGETPROTOBYNUMBER)(int);
+typedef struct protoent *(SOCKETAPI *LPSOCKGETPROTOBYNAME)(const char *);
+
+/* Microsoft Windows Extension function prototypes */
+typedef int (SOCKETAPI *LPSOCKWSASTARTUP)(unsigned short, LPWSADATA);
+typedef int (SOCKETAPI *LPSOCKWSACLEANUP)(void);
+typedef int (SOCKETAPI *LPSOCKWSAGETLASTERROR)(void);
+typedef int (SOCKETAPI *LPWSAFDIsSet)(SOCKET, fd_set *);
+
+static HINSTANCE hWinSockDll = 0;
+
+static LPSOCKACCEPT paccept = 0;
+static LPSOCKBIND pbind = 0;
+static LPSOCKCLOSESOCKET pclosesocket = 0;
+static LPSOCKCONNECT pconnect = 0;
+static LPINETADDR pinet_addr = 0;
+static LPINETNTOA pinet_ntoa = 0;
+static LPSOCKIOCTLSOCKET pioctlsocket = 0;
+static LPSOCKGETPEERNAME pgetpeername = 0;
+static LPSOCKGETSOCKNAME pgetsockname = 0;
+static LPSOCKGETSOCKOPT pgetsockopt = 0;
+static LPSOCKHTONL phtonl = 0;
+static LPSOCKHTONS phtons = 0;
+static LPSOCKLISTEN plisten = 0;
+static LPSOCKNTOHL pntohl = 0;
+static LPSOCKNTOHS pntohs = 0;
+static LPSOCKRECV precv = 0;
+static LPSOCKRECVFROM precvfrom = 0;
+static LPSOCKSELECT pselect = 0;
+static LPSOCKSEND psend = 0;
+static LPSOCKSENDTO psendto = 0;
+static LPSOCKSETSOCKOPT psetsockopt = 0;
+static LPSOCKSHUTDOWN pshutdown = 0;
+static LPSOCKSOCKET psocket = 0;
+static LPSOCKGETHOSTBYADDR pgethostbyaddr = 0;
+static LPSOCKGETHOSTBYNAME pgethostbyname = 0;
+static LPSOCKGETHOSTNAME pgethostname = 0;
+static LPSOCKGETSERVBYPORT pgetservbyport = 0;
+static LPSOCKGETSERVBYNAME pgetservbyname = 0;
+static LPSOCKGETPROTOBYNUMBER pgetprotobynumber = 0;
+static LPSOCKGETPROTOBYNAME pgetprotobyname = 0;
+static LPSOCKWSASTARTUP pWSAStartup = 0;
+static LPSOCKWSACLEANUP pWSACleanup = 0;
+static LPSOCKWSAGETLASTERROR pWSAGetLastError = 0;
+static LPWSAFDIsSet pWSAFDIsSet = 0;
+
+void* CPerlSock::GetAddress(HINSTANCE hInstance, char *lpFunctionName)
+{
+ char buffer[512];
+ FARPROC proc = GetProcAddress(hInstance, lpFunctionName);
+ if(proc == 0)
+ {
+ sprintf(buffer, "Unable to get address of %s in WSock32.dll", lpFunctionName);
+ croak(buffer);
+ }
+ return proc;
+}
+
+void CPerlSock::LoadWinSock(void)
+{
+ if(hWinSockDll == NULL)
+ {
+ HINSTANCE hLib = LoadLibrary("WSock32.DLL");
+ if(hLib == NULL)
+ croak("Could not load WSock32.dll\n");
+
+ paccept = (LPSOCKACCEPT)GetAddress(hLib, "accept");
+ pbind = (LPSOCKBIND)GetAddress(hLib, "bind");
+ pclosesocket = (LPSOCKCLOSESOCKET)GetAddress(hLib, "closesocket");
+ pconnect = (LPSOCKCONNECT)GetAddress(hLib, "connect");
+ pinet_addr = (LPINETADDR)GetAddress(hLib, "inet_addr");
+ pinet_ntoa = (LPINETNTOA)GetAddress(hLib, "inet_ntoa");
+ pioctlsocket = (LPSOCKIOCTLSOCKET)GetAddress(hLib, "ioctlsocket");
+ pgetpeername = (LPSOCKGETPEERNAME)GetAddress(hLib, "getpeername");
+ pgetsockname = (LPSOCKGETSOCKNAME)GetAddress(hLib, "getsockname");
+ pgetsockopt = (LPSOCKGETSOCKOPT)GetAddress(hLib, "getsockopt");
+ phtonl = (LPSOCKHTONL)GetAddress(hLib, "htonl");
+ phtons = (LPSOCKHTONS)GetAddress(hLib, "htons");
+ plisten = (LPSOCKLISTEN)GetAddress(hLib, "listen");
+ pntohl = (LPSOCKNTOHL)GetAddress(hLib, "ntohl");
+ pntohs = (LPSOCKNTOHS)GetAddress(hLib, "ntohs");
+ precv = (LPSOCKRECV)GetAddress(hLib, "recv");
+ precvfrom = (LPSOCKRECVFROM)GetAddress(hLib, "recvfrom");
+ pselect = (LPSOCKSELECT)GetAddress(hLib, "select");
+ psend = (LPSOCKSEND)GetAddress(hLib, "send");
+ psendto = (LPSOCKSENDTO)GetAddress(hLib, "sendto");
+ psetsockopt = (LPSOCKSETSOCKOPT)GetAddress(hLib, "setsockopt");
+ pshutdown = (LPSOCKSHUTDOWN)GetAddress(hLib, "shutdown");
+ psocket = (LPSOCKSOCKET)GetAddress(hLib, "socket");
+ pgethostbyaddr = (LPSOCKGETHOSTBYADDR)GetAddress(hLib, "gethostbyaddr");
+ pgethostbyname = (LPSOCKGETHOSTBYNAME)GetAddress(hLib, "gethostbyname");
+ pgethostname = (LPSOCKGETHOSTNAME)GetAddress(hLib, "gethostname");
+ pgetservbyport = (LPSOCKGETSERVBYPORT)GetAddress(hLib, "getservbyport");
+ pgetservbyname = (LPSOCKGETSERVBYNAME)GetAddress(hLib, "getservbyname");
+ pgetprotobynumber = (LPSOCKGETPROTOBYNUMBER)GetAddress(hLib, "getprotobynumber");
+ pgetprotobyname = (LPSOCKGETPROTOBYNAME)GetAddress(hLib, "getprotobyname");
+ pWSAStartup = (LPSOCKWSASTARTUP)GetAddress(hLib, "WSAStartup");
+ pWSACleanup = (LPSOCKWSACLEANUP)GetAddress(hLib, "WSACleanup");
+ pWSAGetLastError = (LPSOCKWSAGETLASTERROR)GetAddress(hLib, "WSAGetLastError");
+ pWSAFDIsSet = (LPWSAFDIsSet)GetAddress(hLib, "__WSAFDIsSet");
+ hWinSockDll = hLib;
+ }
+}
+
+
+CPerlSock::CPerlSock()
+{
+ bStarted = FALSE;
+ pPerl = NULL;
+ pStdIO = NULL;
+}
+
+CPerlSock::~CPerlSock()
+{
+ if(bStarted)
+ pWSACleanup();
+}
+
+void
+CPerlSock::Start(void)
+{
+ unsigned short version;
+ WSADATA retdata;
+ int ret;
+ int iSockOpt = SO_SYNCHRONOUS_NONALERT;
+
+ LoadWinSock();
+ /*
+ * initalize the winsock interface and insure that it is
+ * cleaned up at exit.
+ */
+ version = 0x101;
+ if(ret = pWSAStartup(version, &retdata))
+ croak("Unable to locate winsock library!\n");
+ if(retdata.wVersion != version)
+ croak("Could not find version 1.1 of winsock dll\n");
+
+ /* atexit((void (*)(void)) EndSockets); */
+
+#ifdef USE_SOCKETS_AS_HANDLES
+ /*
+ * Enable the use of sockets as filehandles
+ */
+ psetsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
+ (char *)&iSockOpt, sizeof(iSockOpt));
+#endif /* USE_SOCKETS_AS_HANDLES */
+ bStarted = TRUE;
+}
+
+
+u_long
+CPerlSock::Htonl(u_long hostlong)
+{
+ StartSockets();
+ return phtonl(hostlong);
+}
+
+u_short
+CPerlSock::Htons(u_short hostshort)
+{
+ StartSockets();
+ return phtons(hostshort);
+}
+
+u_long
+CPerlSock::Ntohl(u_long netlong)
+{
+ StartSockets();
+ return pntohl(netlong);
+}
+
+u_short
+CPerlSock::Ntohs(u_short netshort)
+{
+ StartSockets();
+ return pntohs(netshort);
+}
+
+
+/* thanks to Beverly Brown (beverly@datacube.com) */
+#ifdef USE_SOCKETS_AS_HANDLES
+# define OPEN_SOCKET(x) OpenOSfhandle(x)
+# define TO_SOCKET(x) GetOSfhandle(x)
+#else
+# define OPEN_SOCKET(x) (x)
+# define TO_SOCKET(x) (x)
+#endif /* USE_SOCKETS_AS_HANDLES */
+
+#define SOCKET_TEST(x, y) \
+ STMT_START { \
+ StartSockets(); \
+ if((x) == (y)) \
+ err = pWSAGetLastError(); \
+ } STMT_END
+
+#define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR)
+
+SOCKET
+CPerlSock::Accept(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
+{
+ SOCKET r;
+
+ SOCKET_TEST((r = paccept(TO_SOCKET(s), addr, addrlen)), INVALID_SOCKET);
+ return OPEN_SOCKET(r);
+}
+
+int
+CPerlSock::Bind(SOCKET s, const struct sockaddr* addr, int addrlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pbind(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+void
+CPerlSock::CloseSocket(int fh, int& err)
+{
+ SOCKET_TEST_ERROR(pclosesocket(TO_SOCKET(fh)));
+}
+
+int
+CPerlSock::Connect(SOCKET s, const struct sockaddr* addr, int addrlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pconnect(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+void CPerlSock::Endhostent(int &err)
+{
+ croak("endhostent not implemented!\n");
+}
+
+void CPerlSock::Endnetent(int &err)
+{
+ croak("endnetent not implemented!\n");
+}
+
+void CPerlSock::Endprotoent(int &err)
+{
+ croak("endprotoent not implemented!\n");
+}
+
+void CPerlSock::Endservent(int &err)
+{
+ croak("endservent not implemented!\n");
+}
+
+struct hostent*
+CPerlSock::Gethostbyaddr(const char* addr, int len, int type, int &err)
+{
+ struct hostent *r;
+
+ SOCKET_TEST(r = pgethostbyaddr(addr, len, type), NULL);
+ return r;
+}
+
+struct hostent*
+CPerlSock::Gethostbyname(const char* name, int &err)
+{
+ struct hostent *r;
+
+ SOCKET_TEST(r = pgethostbyname(name), NULL);
+ return r;
+}
+
+struct hostent* CPerlSock::Gethostent(int &err)
+{
+ croak("gethostent not implemented!\n");
+ return NULL;
+}
+
+int
+CPerlSock::Gethostname(char* name, int len, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgethostname(name, len));
+ return r;
+}
+
+struct netent *CPerlSock::Getnetbyaddr(long net, int type, int &err)
+{
+ croak("getnetbyaddr not implemented!\n");
+ return NULL;
+}
+
+struct netent *CPerlSock::Getnetbyname(const char *, int &err)
+{
+ croak("getnetbyname not implemented!\n");
+ return NULL;
+}
+
+struct netent *CPerlSock::Getnetent(int &err)
+{
+ croak("getnetent not implemented!\n");
+ return NULL;
+}
+
+int
+CPerlSock::Getpeername(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgetpeername(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+struct protoent*
+CPerlSock::Getprotobyname(const char* name, int &err)
+{
+ struct protoent *r;
+
+ SOCKET_TEST(r = pgetprotobyname(name), NULL);
+ return r;
+}
+
+struct protoent*
+CPerlSock::Getprotobynumber(int number, int &err)
+{
+ struct protoent *r;
+
+ SOCKET_TEST(r = pgetprotobynumber(number), NULL);
+ return r;
+}
+
+struct protoent* CPerlSock::Getprotoent(int &err)
+{
+ croak("getprotoent not implemented!\n");
+ return NULL;
+}
+
+struct servent*
+CPerlSock::Getservbyname(const char* name, const char* proto, int &err)
+{
+ struct servent *r;
+ dTHR;
+
+ SOCKET_TEST(r = pgetservbyname(name, proto), NULL);
+// if (r) {
+// r = win32_savecopyservent(&myservent, r, proto);
+// }
+ return r;
+}
+
+struct servent*
+CPerlSock::Getservbyport(int port, const char* proto, int &err)
+{
+ struct servent *r;
+ dTHR;
+
+ SOCKET_TEST(r = pgetservbyport(port, proto), NULL);
+// if (r) {
+// r = win32_savecopyservent(&myservent, r, proto);
+// }
+ return r;
+}
+
+struct servent* CPerlSock::Getservent(int &err)
+{
+ croak("getservent not implemented!\n");
+ return NULL;
+}
+
+int
+CPerlSock::Getsockname(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgetsockname(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+int
+CPerlSock::Getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgetsockopt(TO_SOCKET(s), level, optname, optval, optlen));
+ return r;
+}
+
+unsigned long
+CPerlSock::InetAddr(const char* cp, int &err)
+{
+ unsigned long r;
+
+ SOCKET_TEST(r = pinet_addr(cp), INADDR_NONE);
+ return r;
+}
+
+char*
+CPerlSock::InetNtoa(struct in_addr in, int &err)
+{
+ char* r;
+
+ SOCKET_TEST(r = pinet_ntoa(in), NULL);
+ return r;
+}
+
+int
+CPerlSock::IoctlSocket(SOCKET s, long cmd, u_long *argp, int& err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pioctlsocket(TO_SOCKET(s), cmd, argp));
+ return r;
+}
+
+int
+CPerlSock::Listen(SOCKET s, int backlog, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = plisten(TO_SOCKET(s), backlog));
+ return r;
+}
+
+int
+CPerlSock::Recvfrom(SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = precvfrom(TO_SOCKET(s), buffer, len, flags, from, fromlen));
+ return r;
+}
+
+int
+CPerlSock::Select(int nfds, char* rd, char* wr, char* ex, const struct timeval* timeout, int &err)
+{
+ long r;
+ int i, fd, bit, offset;
+ FD_SET nrd, nwr, nex;
+
+ FD_ZERO(&nrd);
+ FD_ZERO(&nwr);
+ FD_ZERO(&nex);
+ for (i = 0; i < nfds; i++)
+ {
+ fd = TO_SOCKET(i);
+ bit = 1L<<(i % (sizeof(char)*8));
+ offset = i / (sizeof(char)*8);
+ if(rd != NULL && (rd[offset] & bit))
+ FD_SET(fd, &nrd);
+ if(wr != NULL && (wr[offset] & bit))
+ FD_SET(fd, &nwr);
+ if(ex != NULL && (ex[offset] & bit))
+ FD_SET(fd, &nex);
+ }
+ SOCKET_TEST_ERROR(r = pselect(nfds, &nrd, &nwr, &nex, timeout));
+
+ for(i = 0; i < nfds; i++)
+ {
+ fd = TO_SOCKET(i);
+ bit = 1L<<(i % (sizeof(char)*8));
+ offset = i / (sizeof(char)*8);
+ if(rd != NULL && (rd[offset] & bit))
+ {
+ if(!pWSAFDIsSet(fd, &nrd))
+ rd[offset] &= ~bit;
+ }
+ if(wr != NULL && (wr[offset] & bit))
+ {
+ if(!pWSAFDIsSet(fd, &nwr))
+ wr[offset] &= ~bit;
+ }
+ if(ex != NULL && (ex[offset] & bit))
+ {
+ if(!pWSAFDIsSet(fd, &nex))
+ ex[offset] &= ~bit;
+ }
+ }
+ return r;
+}
+
+int
+CPerlSock::Send(SOCKET s, const char* buffer, int len, int flags, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = psend(TO_SOCKET(s), buffer, len, flags));
+ return r;
+}
+
+int
+CPerlSock::Sendto(SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = psendto(TO_SOCKET(s), buffer, len, flags, to, tolen));
+ return r;
+}
+
+void CPerlSock::Sethostent(int stayopen, int &err)
+{
+ croak("sethostent not implemented!\n");
+}
+
+void CPerlSock::Setnetent(int stayopen, int &err)
+{
+ croak("setnetent not implemented!\n");
+}
+
+void CPerlSock::Setprotoent(int stayopen, int &err)
+{
+ croak("setprotoent not implemented!\n");
+}
+
+void CPerlSock::Setservent(int stayopen, int &err)
+{
+ croak("setservent not implemented!\n");
+}
+
+int
+CPerlSock::Setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = psetsockopt(TO_SOCKET(s), level, optname, optval, optlen));
+ return r;
+}
+
+int
+CPerlSock::Shutdown(SOCKET s, int how, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pshutdown(TO_SOCKET(s), how));
+ return r;
+}
+
+SOCKET
+CPerlSock::Socket(int af, int type, int protocol, int &err)
+{
+ SOCKET s;
+
+#ifdef USE_SOCKETS_AS_HANDLES
+ StartSockets();
+ if((s = psocket(af, type, protocol)) == INVALID_SOCKET)
+ err = pWSAGetLastError();
+ else
+ s = OPEN_SOCKET(s);
+#else
+ SOCKET_TEST(s = psocket(af, type, protocol), INVALID_SOCKET);
+#endif /* USE_SOCKETS_AS_HANDLES */
+
+ return s;
+}
+
+int CPerlSock::Socketpair(int domain, int type, int protocol, int* fds, int &err)
+{
+ croak("socketpair not implemented!\n");
+ return 0;
+}
+
+
diff --git a/win32/ipstdio.c b/win32/ipstdio.c
new file mode 100644
index 0000000000..7d37373b9a
--- /dev/null
+++ b/win32/ipstdio.c
@@ -0,0 +1,447 @@
+/*
+
+ ipstdio.c
+ Interface for perl stdio functions
+
+*/
+
+#include "ipstdiowin.h"
+#include <stdio.h>
+
+class CPerlStdIO : public IPerlStdIOWin
+{
+public:
+ CPerlStdIO()
+ {
+ pPerl = NULL;
+ pSock = NULL;
+ w32_platform = -1;
+ };
+ virtual PerlIO* Stdin(void);
+ virtual PerlIO* Stdout(void);
+ virtual PerlIO* Stderr(void);
+ virtual PerlIO* Open(const char *, const char *, int &err);
+ virtual int Close(PerlIO*, int &err);
+ virtual int Eof(PerlIO*, int &err);
+ virtual int Error(PerlIO*, int &err);
+ virtual void Clearerr(PerlIO*, int &err);
+ virtual int Getc(PerlIO*, int &err);
+ virtual char* GetBase(PerlIO *, int &err);
+ virtual int GetBufsiz(PerlIO *, int &err);
+ virtual int GetCnt(PerlIO *, int &err);
+ virtual char* GetPtr(PerlIO *, int &err);
+ virtual int Putc(PerlIO*, int, int &err);
+ virtual int Puts(PerlIO*, const char *, int &err);
+ virtual int Flush(PerlIO*, int &err);
+ virtual int Ungetc(PerlIO*,int, int &err);
+ virtual int Fileno(PerlIO*, int &err);
+ virtual PerlIO* Fdopen(int, const char *, int &err);
+ virtual SSize_t Read(PerlIO*,void *,Size_t, int &err);
+ virtual SSize_t Write(PerlIO*,const void *,Size_t, int &err);
+ virtual void SetCnt(PerlIO *, int, int &err);
+ virtual void SetPtrCnt(PerlIO *, char *, int, int& err);
+ virtual void Setlinebuf(PerlIO*, int &err);
+ virtual int Printf(PerlIO*, int &err, const char *,...);
+ virtual int Vprintf(PerlIO*, int &err, const char *, va_list);
+ virtual long Tell(PerlIO*, int &err);
+ virtual int Seek(PerlIO*, off_t, int, int &err);
+ virtual void Rewind(PerlIO*, int &err);
+ virtual PerlIO* Tmpfile(int &err);
+ virtual int Getpos(PerlIO*, Fpos_t *, int &err);
+ virtual int Setpos(PerlIO*, const Fpos_t *, int &err);
+ virtual void Init(int &err);
+ virtual void InitOSExtras(void* p);
+ virtual int OpenOSfhandle(long osfhandle, int flags);
+ virtual int GetOSfhandle(int filenum);
+
+ void ShutDown(void);
+
+ inline void SetPerlObj(CPerlObj *p) { pPerl = p; };
+ inline void SetSockCtl(CPerlSock *p) { pSock = p; };
+protected:
+ inline int IsWin95(void)
+ {
+ return (os_id() == VER_PLATFORM_WIN32_WINDOWS);
+ };
+ inline int IsWinNT(void)
+ {
+ return (os_id() == VER_PLATFORM_WIN32_NT);
+ };
+ inline void AddToSocketTable(int fh)
+ {
+ if(fh < _NSTREAM_)
+ bSocketTable[fh] = TRUE;
+ };
+ inline BOOL InSocketTable(int fh)
+ {
+ if(fh < _NSTREAM_)
+ return bSocketTable[fh];
+ return FALSE;
+ };
+ inline void RemoveFromSocketTable(int fh)
+ {
+ if(fh < _NSTREAM_)
+ bSocketTable[fh] = FALSE;
+ };
+ DWORD os_id(void)
+ {
+ if((-1) == w32_platform)
+ {
+ OSVERSIONINFO osver;
+
+ memset(&osver, 0, sizeof(OSVERSIONINFO));
+ osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osver);
+ w32_platform = osver.dwPlatformId;
+ }
+ return (w32_platform);
+ };
+
+
+ CPerlObj *pPerl;
+ CPerlSock *pSock;
+ DWORD w32_platform;
+ BOOL bSocketTable[_NSTREAM_];
+};
+
+void CPerlStdIO::ShutDown(void)
+{
+ int i, err;
+ for(i = 0; i < _NSTREAM_; ++i)
+ {
+ if(InSocketTable(i))
+ pSock->CloseSocket(i, err);
+ }
+};
+
+#ifdef _X86_
+extern "C" int __cdecl _alloc_osfhnd(void);
+extern "C" int __cdecl _set_osfhnd(int fh, long value);
+extern "C" void __cdecl _unlock(int);
+
+#if (_MSC_VER >= 1000)
+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 */
+} ioinfo;
+extern "C" ioinfo * __pioinfo[];
+#define IOINFO_L2E 5
+#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
+#define _pioinfo(i) (__pioinfo[i >> IOINFO_L2E] + (i & (IOINFO_ARRAY_ELTS - 1)))
+#define _osfile(i) (_pioinfo(i)->osfile)
+#else
+extern "C" extern char _osfile[];
+#endif // (_MSC_VER >= 1000)
+
+#define FOPEN 0x01 // file handle open
+#define FAPPEND 0x20 // file handle opened O_APPEND
+#define FDEV 0x40 // file handle refers to device
+#define FTEXT 0x80 // file handle is in text mode
+
+#define _STREAM_LOCKS 26 // Table of stream locks
+#define _LAST_STREAM_LOCK (_STREAM_LOCKS+_NSTREAM_-1) // Last stream lock
+#define _FH_LOCKS (_LAST_STREAM_LOCK+1) // Table of fh locks
+#endif // _X86_
+
+int CPerlStdIO::OpenOSfhandle(long osfhandle, int flags)
+{
+ int fh;
+
+#ifdef _X86_
+ if(IsWin95())
+ {
+ // all this is here to handle Win95's GetFileType bug.
+ char fileflags; // _osfile flags
+
+ // copy relevant flags from second parameter
+ fileflags = FDEV;
+
+ if(flags & _O_APPEND)
+ fileflags |= FAPPEND;
+
+ if(flags & _O_TEXT)
+ fileflags |= FTEXT;
+
+ // attempt to allocate a C Runtime file handle
+ if((fh = _alloc_osfhnd()) == -1)
+ {
+ errno = EMFILE; // too many open files
+ _doserrno = 0L; // not an OS error
+ return -1; // return error to caller
+ }
+
+ // the file is open. now, set the info in _osfhnd array
+ _set_osfhnd(fh, osfhandle);
+
+ fileflags |= FOPEN; // mark as open
+
+#if (_MSC_VER >= 1000)
+ _osfile(fh) = fileflags; // set osfile entry
+#else
+ _osfile[fh] = fileflags; // set osfile entry
+#endif
+ }
+ else
+#endif // _X86_
+ fh = _open_osfhandle(osfhandle, flags);
+
+ if(fh >= 0)
+ AddToSocketTable(fh);
+
+ return fh; // return handle
+}
+
+int CPerlStdIO::GetOSfhandle(int filenum)
+{
+ return _get_osfhandle(filenum);
+}
+
+PerlIO* CPerlStdIO::Stdin(void)
+{
+ return (PerlIO*)(&_iob[0]);
+}
+
+PerlIO* CPerlStdIO::Stdout(void)
+{
+ return (PerlIO*)(&_iob[1]);
+}
+
+PerlIO* CPerlStdIO::Stderr(void)
+{
+ return (PerlIO*)(&_iob[2]);
+}
+
+PerlIO* CPerlStdIO::Open(const char *path, const char *mode, int &err)
+{
+ PerlIO* ret = NULL;
+ if(*path != '\0')
+ {
+ ret = (PerlIO*)fopen(path, mode);
+ if(errno)
+ err = errno;
+ }
+ else
+ err = EINVAL;
+ return ret;
+}
+
+extern "C" int _free_osfhnd(int fh);
+int CPerlStdIO::Close(PerlIO* pf, int &err)
+{
+ int ret = 0, fileNo = fileno((FILE*)pf);
+ if(InSocketTable(fileNo))
+ {
+ RemoveFromSocketTable(fileNo);
+ pSock->CloseSocket(fileNo, err);
+ _free_osfhnd(fileNo);
+ fclose((FILE*)pf);
+ }
+ else
+ ret = fclose((FILE*)pf);
+
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlStdIO::Eof(PerlIO* pf, int &err)
+{
+ int ret = feof((FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlStdIO::Error(PerlIO* pf, int &err)
+{
+ int ret = ferror((FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+void CPerlStdIO::Clearerr(PerlIO* pf, int &err)
+{
+ clearerr((FILE*)pf);
+ err = 0;
+}
+
+int CPerlStdIO::Getc(PerlIO* pf, int &err)
+{
+ int ret = fgetc((FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlStdIO::Putc(PerlIO* pf, int c, int &err)
+{
+ int ret = fputc(c, (FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlStdIO::Puts(PerlIO* pf, const char *s, int &err)
+{
+ int ret = fputs(s, (FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlStdIO::Flush(PerlIO* pf, int &err)
+{
+ int ret = fflush((FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlStdIO::Ungetc(PerlIO* pf,int c, int &err)
+{
+ int ret = ungetc(c, (FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlStdIO::Fileno(PerlIO* pf, int &err)
+{
+ int ret = fileno((FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+PerlIO* CPerlStdIO::Fdopen(int fh, const char *mode, int &err)
+{
+ PerlIO* ret = (PerlIO*)fdopen(fh, mode);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+SSize_t CPerlStdIO::Read(PerlIO* pf, void * buffer, Size_t count, int &err)
+{
+ size_t ret = fread(buffer, 1, count, (FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+SSize_t CPerlStdIO::Write(PerlIO* pf, const void * buffer, Size_t count, int &err)
+{
+ size_t ret = fwrite(buffer, 1, count, (FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+void CPerlStdIO::Setlinebuf(PerlIO*, int &err)
+{
+ croak("setlinebuf not implemented!\n");
+}
+
+int CPerlStdIO::Printf(PerlIO* pf, int &err, const char *format, ...)
+{
+ va_list(arglist);
+ va_start(arglist, format);
+ int ret = Vprintf(pf, err, format, arglist);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlStdIO::Vprintf(PerlIO* pf, int &err, const char * format, va_list arg)
+{
+ int ret = vfprintf((FILE*)pf, format, arg);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+long CPerlStdIO::Tell(PerlIO* pf, int &err)
+{
+ long ret = ftell((FILE*)pf);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlStdIO::Seek(PerlIO* pf, off_t offset, int origin, int &err)
+{
+ int ret = fseek((FILE*)pf, offset, origin);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+void CPerlStdIO::Rewind(PerlIO* pf, int &err)
+{
+ rewind((FILE*)pf);
+}
+
+PerlIO* CPerlStdIO::Tmpfile(int &err)
+{
+ return (PerlIO*)tmpfile();
+}
+
+int CPerlStdIO::Getpos(PerlIO* pf, Fpos_t *p, int &err)
+{
+ int ret = fgetpos((FILE*)pf, (fpos_t*)p);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+int CPerlStdIO::Setpos(PerlIO* pf, const Fpos_t *p, int &err)
+{
+ int ret = fsetpos((FILE*)pf, (fpos_t*)p);
+ if(errno)
+ err = errno;
+ return ret;
+}
+
+char* CPerlStdIO::GetBase(PerlIO *pf, int &err)
+{
+ return ((FILE*)pf)->_base;
+}
+
+int CPerlStdIO::GetBufsiz(PerlIO *pf, int &err)
+{
+ return ((FILE*)pf)->_bufsiz;
+}
+
+int CPerlStdIO::GetCnt(PerlIO *pf, int &err)
+{
+ return ((FILE*)pf)->_cnt;
+}
+
+char* CPerlStdIO::GetPtr(PerlIO *pf, int &err)
+{
+ return ((FILE*)pf)->_ptr;
+}
+
+void CPerlStdIO::SetCnt(PerlIO *pf, int n, int &err)
+{
+ ((FILE*)pf)->_cnt = n;
+}
+
+void CPerlStdIO::SetPtrCnt(PerlIO *pf, char *ptr, int n, int& err)
+{
+ ((FILE*)pf)->_ptr = ptr;
+ ((FILE*)pf)->_cnt = n;
+}
+
+void CPerlStdIO::Init(int &err)
+{
+}
+
+void CPerlStdIO::InitOSExtras(void* p)
+{
+}
+
+
diff --git a/win32/ipstdiowin.h b/win32/ipstdiowin.h
new file mode 100644
index 0000000000..e4895272c0
--- /dev/null
+++ b/win32/ipstdiowin.h
@@ -0,0 +1,22 @@
+/*
+
+ ipstdiowin.h
+ Interface for perl stdio functions
+
+*/
+
+#ifndef __Inc__IPerlStdIOWin___
+#define __Inc__IPerlStdIOWin___
+
+#include <ipstdio.h>
+
+
+class IPerlStdIOWin : public IPerlStdIO
+{
+public:
+ virtual int OpenOSfhandle(long osfhandle, int flags) = 0;
+ virtual int GetOSfhandle(int filenum) = 0;
+};
+
+#endif /* __Inc__IPerlStdIOWin___ */
+
diff --git a/win32/makedef.pl b/win32/makedef.pl
index ddf01fdab8..b4097d5c23 100644
--- a/win32/makedef.pl
+++ b/win32/makedef.pl
@@ -104,6 +104,7 @@ Perl_dump_packsubs
Perl_dump_pm
Perl_dump_sub
Perl_expectterm
+Perl_error_no
Perl_fetch_gv
Perl_fetch_io
Perl_force_ident
@@ -156,6 +157,7 @@ Perl_scan_trans
Perl_scan_word
Perl_setenv_getix
Perl_skipspace
+Perl_sort_mutex
Perl_sublex_done
Perl_sublex_start
Perl_sv_ref
diff --git a/win32/perlobj.def b/win32/perlobj.def
new file mode 100644
index 0000000000..6b0f65dad8
--- /dev/null
+++ b/win32/perlobj.def
@@ -0,0 +1,4 @@
+LIBRARY Perl500
+DESCRIPTION 'Perl interpreter'
+EXPORTS
+ perl_alloc
diff --git a/win32/runperl.c b/win32/runperl.c
index 954460739f..76f9ea0b93 100644
--- a/win32/runperl.c
+++ b/win32/runperl.c
@@ -1,3 +1,173 @@
+
+#ifdef PERL_OBJECT
+#define USE_SOCKETS_AS_HANDLES
+#include "EXTERN.h"
+#include "perl.h"
+
+#include "XSUB.H"
+
+#include <ipdir.h>
+#include <ipenv.h>
+#include <ipsock.h>
+#include <iplio.h>
+#include <ipmem.h>
+#include <ipproc.h>
+
+#include "ipstdiowin.h"
+#include "ipdir.c"
+#include "ipenv.c"
+#include "ipsock.c"
+#include "iplio.c"
+#include "ipmem.c"
+#include "ipproc.c"
+#include "ipstdio.c"
+
+static void xs_init _((CPERLarg));
+#define stderr (&_iob[2])
+#undef fprintf
+#undef environ
+
+class CPerlHost
+{
+public:
+ CPerlHost() { pPerl = NULL; };
+ inline BOOL PerlCreate(void)
+ {
+ try
+ {
+ pPerl = perl_alloc(&perlMem,
+ &perlEnv,
+ &perlStdIO,
+ &perlLIO,
+ &perlDir,
+ &perlSock,
+ &perlProc);
+ if(pPerl != NULL)
+ {
+ perlDir.SetPerlObj(pPerl);
+ perlEnv.SetPerlObj(pPerl);
+ perlLIO.SetPerlObj(pPerl);
+ perlLIO.SetSockCtl(&perlSock);
+ perlLIO.SetStdObj(&perlStdIO);
+ perlMem.SetPerlObj(pPerl);
+ perlProc.SetPerlObj(pPerl);
+ perlSock.SetPerlObj(pPerl);
+ perlSock.SetStdObj(&perlStdIO);
+ perlStdIO.SetPerlObj(pPerl);
+ perlStdIO.SetSockCtl(&perlSock);
+ try
+ {
+ pPerl->perl_construct();
+ }
+ catch(...)
+ {
+ fprintf(stderr, "%s\n", "Error: Unable to construct data structures");
+ pPerl->perl_free();
+ pPerl = NULL;
+ }
+ }
+ }
+ catch(...)
+ {
+ fprintf(stderr, "%s\n", "Error: Unable to allocate memory");
+ pPerl = NULL;
+ }
+ return (pPerl != NULL);
+ };
+ inline int PerlParse(int argc, char** argv, char** env)
+ {
+ char* environ = NULL;
+ int retVal;
+ try
+ {
+ retVal = pPerl->perl_parse(xs_init, argc, argv, (env == NULL || *env == NULL ? &environ : env));
+ }
+ catch(int x)
+ {
+ // this is where exit() should arrive
+ retVal = x;
+ }
+ catch(...)
+ {
+ fprintf(stderr, "Error: Parse exception\n");
+ retVal = -1;
+ }
+ return retVal;
+ };
+ inline int PerlRun(void)
+ {
+ int retVal;
+ try
+ {
+ retVal = pPerl->perl_run();
+ }
+ catch(int x)
+ {
+ // this is where exit() should arrive
+ retVal = x;
+ }
+ catch(...)
+ {
+ fprintf(stderr, "Error: Runtime exception\n");
+ retVal = -1;
+ }
+ return retVal;
+ };
+ inline void PerlDestroy(void)
+ {
+ try
+ {
+ pPerl->perl_destruct();
+ pPerl->perl_free();
+ }
+ catch(...)
+ {
+ }
+ };
+
+protected:
+ CPerlObj *pPerl;
+ CPerlDir perlDir;
+ CPerlEnv perlEnv;
+ CPerlLIO perlLIO;
+ CPerlMem perlMem;
+ CPerlProc perlProc;
+ CPerlSock perlSock;
+ CPerlStdIO perlStdIO;
+};
+
+#undef PERL_SYS_INIT
+#define PERL_SYS_INIT(a, c)
+
+int
+main(int argc, char **argv, char **env)
+{
+ CPerlHost host;
+ int exitstatus = 1;
+
+ if(!host.PerlCreate())
+ exit(exitstatus);
+
+
+ exitstatus = host.PerlParse(argc, argv, env);
+
+ if (!exitstatus)
+ {
+ exitstatus = host.PerlRun();
+ }
+
+ host.PerlDestroy();
+
+ return exitstatus;
+}
+
+
+static void xs_init(CPERLarg)
+{
+}
+
+#else /* PERL_OBJECT */
+
/* Say NO to CPP! Hallelujah! */
#ifdef __GNUC__
/*
@@ -22,3 +192,5 @@ main(int argc, char **argv, char **env)
{
return RunPerl(argc, argv, env, (void*)0);
}
+
+#endif /* PERL_OBJECT */
diff --git a/win32/win32iop.h b/win32/win32iop.h
index e71bf3865e..98627e4c6b 100644
--- a/win32/win32iop.h
+++ b/win32/win32iop.h
@@ -151,6 +151,7 @@ END_EXTERN_C
#undef fileno
#endif
+#ifndef PERL_OBJECT
#define stderr win32_stderr()
#define stdout win32_stdout()
#define stdin win32_stdin()
@@ -163,6 +164,7 @@ END_EXTERN_C
/*
* redirect to our own version
*/
+#undef fprintf
#define fprintf win32_fprintf
#define vfprintf win32_vfprintf
#define printf win32_printf
@@ -177,6 +179,7 @@ END_EXTERN_C
#define fputs(s,f) win32_fputs(s,f)
#define fputc(c,f) win32_fputc(c,f)
#define ungetc(c,f) win32_ungetc(c,f)
+#undef getc
#define getc(f) win32_getc(f)
#define fileno(f) win32_fileno(f)
#define clearerr(f) win32_clearerr(f)
@@ -218,9 +221,12 @@ END_EXTERN_C
#define fgets win32_fgets
#define gets win32_gets
#define fgetc win32_fgetc
+#undef putc
#define putc win32_putc
#define puts win32_puts
+#undef getchar
#define getchar win32_getchar
+#undef putchar
#define putchar win32_putchar
#if !defined(MYMALLOC) || !defined(PERL_CORE)
@@ -241,6 +247,7 @@ END_EXTERN_C
#define alarm win32_alarm
#define ioctl win32_ioctl
#define wait win32_wait
+#endif /* PERL_OBJECT */
#ifdef HAVE_DES_FCRYPT
#undef crypt
@@ -248,8 +255,10 @@ END_EXTERN_C
#endif
#ifndef USE_WIN32_RTL_ENV
+#ifndef PERL_OBJECT
#undef getenv
#define getenv win32_getenv
+#endif /* PERL_OBJECT */
#endif
#endif /* WIN32IO_IS_STDIO */