applied patch, with indentation tweaks
[p5sagit/p5-mst-13.2.git] / win32 / runperl.c
index b7f61a2..17d2ac2 100644 (file)
 
 #define NO_XSLOCKS
 #include "XSUB.H"
-#undef errno
-#if defined(_MT)
-_CRTIMP int * __cdecl _errno(void);
-#define errno (*_errno())
-#else
-_CRTIMP extern int errno;
-#endif
+#include "Win32iop.h"
+
+#define errno (*win32_errno())
+#define stdout (win32_stdout())
+#define stderr (win32_stderr())
+
+CPerlObj *pPerl;
 
+#include <fcntl.h>
 #include <ipdir.h>
 #include <ipenv.h>
 #include <ipsock.h>
 #include <iplio.h>
 #include <ipmem.h>
 #include <ipproc.h>
+#include <ipstdio.h>
+
+#define CALLFUNC0RET(x)\
+    int ret = x;\
+    if(ret < 0)\
+       err = errno;\
+    return ret;
+
+extern int g_closedir(DIR *dirp);
+extern DIR *g_opendir(char *filename);
+extern struct direct *g_readdir(DIR *dirp);
+extern void g_rewinddir(DIR *dirp);
+extern void g_seekdir(DIR *dirp, long loc);
+extern long g_telldir(DIR *dirp);
+class CPerlDir : public IPerlDir
+{
+public:
+    CPerlDir() {};
+    virtual int Makedir(const char *dirname, int mode, int &err)
+    {
+       CALLFUNC0RET(win32_mkdir(dirname, mode));
+    };
+    virtual int Chdir(const char *dirname, int &err)
+    {
+       CALLFUNC0RET(win32_chdir(dirname));
+    };
+    virtual int Rmdir(const char *dirname, int &err)
+    {
+       CALLFUNC0RET(win32_rmdir(dirname));
+    };
+    virtual int Close(DIR *dirp, int &err)
+    {
+       return g_closedir(dirp);
+    };
+    virtual DIR *Open(char *filename, int &err)
+    {
+       return g_opendir(filename);
+    };
+    virtual struct direct *Read(DIR *dirp, int &err)
+    {
+       return g_readdir(dirp);
+    };
+    virtual void Rewind(DIR *dirp, int &err)
+    {
+       g_rewinddir(dirp);
+    };
+    virtual void Seek(DIR *dirp, long loc, int &err)
+    {
+       g_seekdir(dirp, loc);
+    };
+    virtual long Tell(DIR *dirp, int &err)
+    {
+       return g_telldir(dirp);
+    };
+};
+
+
+extern char * g_win32_get_privlib(char *pl);
+extern char * g_win32_get_sitelib(char *pl);
+class CPerlEnv : public IPerlEnv
+{
+public:
+    CPerlEnv() {};
+    virtual char *Getenv(const char *varname, int &err)
+    {
+       return win32_getenv(varname);
+    };
+    virtual int Putenv(const char *envstring, int &err)
+    {
+       return putenv(envstring);
+    };
+    virtual char* LibPath(char *pl)
+    {
+       return g_win32_get_privlib(pl);
+    };
+    virtual char* SiteLibPath(char *pl)
+    {
+       return g_win32_get_sitelib(pl);
+    };
+};
+
+#define PROCESS_AND_RETURN  \
+    if(errno)              \
+       err = errno;        \
+    return r
+
+class CPerlSock : public IPerlSock
+{
+public:
+    CPerlSock() {};
+    virtual u_long Htonl(u_long hostlong)
+    {
+       return win32_htonl(hostlong);
+    };
+    virtual u_short Htons(u_short hostshort)
+    {
+       return win32_htons(hostshort);
+    };
+    virtual u_long Ntohl(u_long netlong)
+    {
+       return win32_ntohl(netlong);
+    };
+    virtual u_short Ntohs(u_short netshort)
+    {
+       return win32_ntohs(netshort);
+    }
+
+    virtual SOCKET Accept(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
+    {
+       SOCKET r = win32_accept(s, addr, addrlen);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Bind(SOCKET s, const struct sockaddr* name, int namelen, int &err)
+    {
+       int r = win32_bind(s, name, namelen);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Connect(SOCKET s, const struct sockaddr* name, int namelen, int &err)
+    {
+       int r = win32_connect(s, name, namelen);
+       PROCESS_AND_RETURN;
+    };
+    virtual void Endhostent(int &err)
+    {
+       win32_endhostent();
+    };
+    virtual void Endnetent(int &err)
+    {
+       win32_endnetent();
+    };
+    virtual void Endprotoent(int &err)
+    {
+       win32_endprotoent();
+    };
+    virtual void Endservent(int &err)
+    {
+       win32_endservent();
+    };
+    virtual struct hostent* Gethostbyaddr(const char* addr, int len, int type, int &err)
+    {
+       struct hostent *r = win32_gethostbyaddr(addr, len, type);
+       PROCESS_AND_RETURN;
+    };
+    virtual struct hostent* Gethostbyname(const char* name, int &err)
+    {
+       struct hostent *r = win32_gethostbyname(name);
+       PROCESS_AND_RETURN;
+    };
+    virtual struct hostent* Gethostent(int &err)
+    {
+        croak("gethostent not implemented!\n");
+       return NULL;
+    };
+    virtual int Gethostname(char* name, int namelen, int &err)
+    {
+       int r = win32_gethostname(name, namelen);
+       PROCESS_AND_RETURN;
+    };
+    virtual struct netent *Getnetbyaddr(long net, int type, int &err)
+    {
+       struct netent *r = win32_getnetbyaddr(net, type);
+       PROCESS_AND_RETURN;
+    };
+    virtual struct netent *Getnetbyname(const char *name, int &err)
+    {
+       struct netent *r = win32_getnetbyname((char*)name);
+       PROCESS_AND_RETURN;
+    };
+    virtual struct netent *Getnetent(int &err)
+    {
+       struct netent *r = win32_getnetent();
+       PROCESS_AND_RETURN;
+    };
+    virtual int Getpeername(SOCKET s, struct sockaddr* name, int* namelen, int &err)
+    {
+       int r = win32_getpeername(s, name, namelen);
+       PROCESS_AND_RETURN;
+    };
+    virtual struct protoent* Getprotobyname(const char* name, int &err)
+    {
+       struct protoent *r = win32_getprotobyname(name);
+       PROCESS_AND_RETURN;
+    };
+    virtual struct protoent* Getprotobynumber(int number, int &err)
+    {
+       struct protoent *r = win32_getprotobynumber(number);
+       PROCESS_AND_RETURN;
+    };
+    virtual struct protoent* Getprotoent(int &err)
+    {
+       struct protoent *r = win32_getprotoent();
+       PROCESS_AND_RETURN;
+    };
+    virtual struct servent* Getservbyname(const char* name, const char* proto, int &err)
+    {
+       struct servent *r = win32_getservbyname(name, proto);
+       PROCESS_AND_RETURN;
+    };
+    virtual struct servent* Getservbyport(int port, const char* proto, int &err)
+    {
+       struct servent *r = win32_getservbyport(port, proto);
+       PROCESS_AND_RETURN;
+    };
+    virtual struct servent* Getservent(int &err)
+    {
+       struct servent *r = win32_getservent();
+       PROCESS_AND_RETURN;
+    };
+    virtual int Getsockname(SOCKET s, struct sockaddr* name, int* namelen, int &err)
+    {
+       int r = win32_getsockname(s, name, namelen);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen, int &err)
+    {
+       int r = win32_getsockopt(s, level, optname, optval, optlen);
+       PROCESS_AND_RETURN;
+    };
+    virtual unsigned long InetAddr(const char* cp, int &err)
+    {
+       unsigned long r = win32_inet_addr(cp);
+       PROCESS_AND_RETURN;
+    };
+    virtual char* InetNtoa(struct in_addr in, int &err)
+    {
+       char *r = win32_inet_ntoa(in);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Listen(SOCKET s, int backlog, int &err)
+    {
+       int r = win32_listen(s, backlog);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Recv(SOCKET s, char* buffer, int len, int flags, int &err)
+    {
+       int r = win32_recv(s, buffer, len, flags);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Recvfrom(SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen, int &err)
+    {
+       int r = win32_recvfrom(s, buffer, len, flags, from, fromlen);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Select(int nfds, char* readfds, char* writefds, char* exceptfds, const struct timeval* timeout, int &err)
+    {
+       int r = win32_select(nfds, (Perl_fd_set*)readfds, (Perl_fd_set*)writefds, (Perl_fd_set*)exceptfds, timeout);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Send(SOCKET s, const char* buffer, int len, int flags, int &err)
+    {
+       int r = win32_send(s, buffer, len, flags);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Sendto(SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen, int &err)
+    {
+       int r = win32_sendto(s, buffer, len, flags, to, tolen);
+       PROCESS_AND_RETURN;
+    };
+    virtual void Sethostent(int stayopen, int &err)
+    {
+       win32_sethostent(stayopen);
+    };
+    virtual void Setnetent(int stayopen, int &err)
+    {
+       win32_setnetent(stayopen);
+    };
+    virtual void Setprotoent(int stayopen, int &err)
+    {
+       win32_setprotoent(stayopen);
+    };
+    virtual void Setservent(int stayopen, int &err)
+    {
+       win32_setservent(stayopen);
+    };
+    virtual int Setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen, int &err)
+    {
+       int r = win32_setsockopt(s, level, optname, optval, optlen);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Shutdown(SOCKET s, int how, int &err)
+    {
+       int r = win32_shutdown(s, how);
+       PROCESS_AND_RETURN;
+    };
+    virtual SOCKET Socket(int af, int type, int protocol, int &err)
+    {
+       SOCKET r = win32_socket(af, type, protocol);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Socketpair(int domain, int type, int protocol, int* fds, int &err)
+    {
+        croak("socketpair not implemented!\n");
+       return 0;
+    };
+    virtual int Closesocket(SOCKET s, int& err)
+    {
+       int r = win32_closesocket(s);
+       PROCESS_AND_RETURN;
+    };
+    virtual int Ioctlsocket(SOCKET s, long cmd, u_long *argp, int& err)
+    {
+       int r = win32_ioctlsocket(s, cmd, argp);
+       PROCESS_AND_RETURN;
+    };
+};
+
+
+#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;
+
+class CPerlLIO : public IPerlLIO
+{
+public:
+    CPerlLIO() {};
+    virtual int Access(const char *path, int mode, int &err)
+    {
+       CALLFUNCRET(access(path, mode))
+    };
+    virtual int Chmod(const char *filename, int pmode, int &err)
+    {
+       CALLFUNCRET(chmod(filename, pmode))
+    };
+    virtual int Chown(const char *filename, uid_t owner, gid_t group, int &err)
+    {
+       CALLFUNCERR(chown(filename, owner, group))
+    };
+    virtual int Chsize(int handle, long size, int &err)
+    {
+       CALLFUNCRET(chsize(handle, size))
+    };
+    virtual int Close(int handle, int &err)
+    {
+       CALLFUNCRET(win32_close(handle))
+    };
+    virtual int Dup(int handle, int &err)
+    {
+       CALLFUNCERR(win32_dup(handle))
+    };
+    virtual int Dup2(int handle1, int handle2, int &err)
+    {
+       CALLFUNCERR(win32_dup2(handle1, handle2))
+    };
+    virtual int Flock(int fd, int oper, int &err)
+    {
+       CALLFUNCERR(win32_flock(fd, oper))
+    };
+    virtual int FileStat(int handle, struct stat *buffer, int &err)
+    {
+       CALLFUNCERR(fstat(handle, buffer))
+    };
+    virtual int IOCtl(int i, unsigned int u, char *data, int &err)
+    {
+       CALLFUNCERR(win32_ioctlsocket((SOCKET)i, (long)u, (u_long*)data))
+    };
+    virtual int Isatty(int fd, int &err)
+    {
+       return isatty(fd);
+    };
+    virtual long Lseek(int handle, long offset, int origin, int &err)
+    {
+       LCALLFUNCERR(win32_lseek(handle, offset, origin))
+    };
+    virtual int Lstat(const char *path, struct stat *buffer, int &err)
+    {
+       return NameStat(path, buffer, err);
+    };
+    virtual char *Mktemp(char *Template, int &err)
+    {
+       return mktemp(Template);
+    };
+    virtual int Open(const char *filename, int oflag, int &err)
+    {
+       CALLFUNCERR(win32_open(filename, oflag))
+    };
+    virtual int Open(const char *filename, int oflag, int pmode, int &err)
+    {
+       int ret;
+       if(stricmp(filename, "/dev/null") == 0)
+           ret = open("NUL", oflag, pmode);
+       else
+           ret = open(filename, oflag, pmode);
+
+       if(errno)
+           err = errno;
+       return ret;
+    };
+    virtual int Read(int handle, void *buffer, unsigned int count, int &err)
+    {
+       CALLFUNCERR(win32_read(handle, buffer, count))
+    };
+    virtual int 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;
+    };
+    virtual int Setmode(int handle, int mode, int &err)
+    {
+       CALLFUNCRET(win32_setmode(handle, mode))
+    };
+    virtual int NameStat(const char *path, struct stat *buffer, int &err)
+    {
+       return win32_stat(path, buffer);
+    };
+    virtual char *Tmpnam(char *string, int &err)
+    {
+       return tmpnam(string);
+    };
+    virtual int Umask(int pmode, int &err)
+    {
+       return umask(pmode);
+    };
+    virtual int Unlink(const char *filename, int &err)
+    {
+       chmod(filename, S_IREAD | S_IWRITE);
+       CALLFUNCRET(unlink(filename))
+    };
+    virtual int Utime(char *filename, struct utimbuf *times, int &err)
+    {
+       CALLFUNCRET(win32_utime(filename, times))
+    };
+    virtual int Write(int handle, const void *buffer, unsigned int count, int &err)
+    {
+       CALLFUNCERR(win32_write(handle, buffer, count))
+    };
+};
+
+class CPerlMem : public IPerlMem
+{
+public:
+    CPerlMem() {};
+    virtual void* Malloc(size_t size)
+    {
+       return win32_malloc(size);
+    };
+    virtual void* Realloc(void* ptr, size_t size)
+    {
+       return win32_realloc(ptr, size);
+    };
+    virtual void Free(void* ptr)
+    {
+       win32_free(ptr);
+    };
+};
+
+#define EXECF_EXEC 1
+#define EXECF_SPAWN 2
+
+extern char *g_getlogin(void);
+extern int do_spawn2(char *cmd, int exectype);
+extern int g_do_aspawn(void *vreally, void **vmark, void **vsp);
+class CPerlProc : public IPerlProc
+{
+public:
+    CPerlProc() {};
+    virtual void Abort(void)
+    {
+       win32_abort();
+    };
+    virtual void Exit(int status)
+    {
+       exit(status);
+    };
+    virtual void _Exit(int status)
+    {
+       _exit(status);
+    };
+    virtual int Execl(const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3)
+    {
+       return execl(cmdname, arg0, arg1, arg2, arg3);
+    };
+    virtual int Execv(const char *cmdname, const char *const *argv)
+    {
+       return win32_execvp(cmdname, argv);
+    };
+    virtual int Execvp(const char *cmdname, const char *const *argv)
+    {
+       return win32_execvp(cmdname, argv);
+    };
+    virtual uid_t Getuid(void)
+    {
+       return getuid();
+    };
+    virtual uid_t Geteuid(void)
+    {
+       return geteuid();
+    };
+    virtual gid_t Getgid(void)
+    {
+       return getgid();
+    };
+    virtual gid_t Getegid(void)
+    {
+       return getegid();
+    };
+    virtual char *Getlogin(void)
+    {
+       return g_getlogin();
+    };
+    virtual int Kill(int pid, int sig)
+    {
+       return kill(pid, sig);
+    };
+    virtual int Killpg(int pid, int sig)
+    {
+       croak("killpg not implemented!\n");
+       return 0;
+    };
+    virtual int PauseProc(void)
+    {
+       return win32_sleep((32767L << 16) + 32767);
+    };
+    virtual PerlIO* Popen(const char *command, const char *mode)
+    {
+       win32_fflush(stdout);
+       win32_fflush(stderr);
+       return (PerlIO*)win32_popen(command, mode);
+    };
+    virtual int Pclose(PerlIO *stream)
+    {
+       return win32_pclose((FILE*)stream);
+    };
+    virtual int Pipe(int *phandles)
+    {
+       return win32_pipe(phandles, 512, O_BINARY);
+    };
+    virtual int Setuid(uid_t u)
+    {
+       return setuid(u);
+    };
+    virtual int Setgid(gid_t g)
+    {
+       return setgid(g);
+    };
+    virtual int Sleep(unsigned int s)
+    {
+       return win32_sleep(s);
+    };
+    virtual int Times(struct tms *timebuf)
+    {
+       return win32_times(timebuf);
+    };
+    virtual int Wait(int *status)
+    {
+       return win32_wait(status);
+    };
+    virtual Sighandler_t Signal(int sig, Sighandler_t subcode)
+    {
+       return 0;
+    };
+    virtual void 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());
+       }
+    };
+    virtual void FreeBuf(char* sMsg)
+    {
+       LocalFree(sMsg);
+    };
+    virtual BOOL DoCmd(char *cmd)
+    {
+       do_spawn2(cmd, EXECF_EXEC);
+        return FALSE;
+    };
+    virtual int Spawn(char* cmds)
+    {
+       return do_spawn2(cmds, EXECF_SPAWN);
+    };
+    virtual int Spawnvp(int mode, const char *cmdname, const char *const *argv)
+    {
+       return win32_spawnvp(mode, cmdname, argv);
+    };
+    virtual int ASpawn(void *vreally, void **vmark, void **vsp)
+    {
+       return g_do_aspawn(vreally, vmark, vsp);
+    };
+};
+
+
+class CPerlStdIO : public IPerlStdIO
+{
+public:
+    CPerlStdIO() {};
+    virtual PerlIO* Stdin(void)
+    {
+       return (PerlIO*)win32_stdin();
+    };
+    virtual PerlIO* Stdout(void)
+    {
+       return (PerlIO*)win32_stdout();
+    };
+    virtual PerlIO* Stderr(void)
+    {
+       return (PerlIO*)win32_stderr();
+    };
+    virtual PerlIO* Open(const char *path, const char *mode, int &err)
+    {
+       PerlIO*pf = (PerlIO*)win32_fopen(path, mode);
+       if(errno)
+           err = errno;
+       return pf;
+    };
+    virtual int Close(PerlIO* pf, int &err)
+    {
+       CALLFUNCERR(win32_fclose(((FILE*)pf)))
+    };
+    virtual int Eof(PerlIO* pf, int &err)
+    {
+       CALLFUNCERR(win32_feof((FILE*)pf))
+    };
+    virtual int Error(PerlIO* pf, int &err)
+    {
+       CALLFUNCERR(win32_ferror((FILE*)pf))
+    };
+    virtual void Clearerr(PerlIO* pf, int &err)
+    {
+       win32_clearerr((FILE*)pf);
+    };
+    virtual int Getc(PerlIO* pf, int &err)
+    {
+       CALLFUNCERR(win32_getc((FILE*)pf))
+    };
+    virtual char* GetBase(PerlIO* pf, int &err)
+    {
+       FILE *f = (FILE*)pf;
+       return FILE_base(f);
+    };
+    virtual int GetBufsiz(PerlIO* pf, int &err)
+    {
+       FILE *f = (FILE*)pf;
+       return FILE_bufsiz(f);
+    };
+    virtual int GetCnt(PerlIO* pf, int &err)
+    {
+       FILE *f = (FILE*)pf;
+       return FILE_cnt(f);
+    };
+    virtual char* GetPtr(PerlIO* pf, int &err)
+    {
+       FILE *f = (FILE*)pf;
+       return FILE_ptr(f);
+    };
+    virtual char* Gets(PerlIO* pf, char* s, int n, int& err)
+    {
+       char* ret = win32_fgets(s, n, (FILE*)pf);
+       if(errno)
+           err = errno;
+       return ret;
+    };
+    virtual int Putc(PerlIO* pf, int c, int &err)
+    {
+       CALLFUNCERR(win32_fputc(c, (FILE*)pf))
+    };
+    virtual int Puts(PerlIO* pf, const char *s, int &err)
+    {
+       CALLFUNCERR(win32_fputs(s, (FILE*)pf))
+    };
+    virtual int Flush(PerlIO* pf, int &err)
+    {
+       CALLFUNCERR(win32_fflush((FILE*)pf))
+    };
+    virtual int Ungetc(PerlIO* pf,int c, int &err)
+    {
+       CALLFUNCERR(win32_ungetc(c, (FILE*)pf))
+    };
+    virtual int Fileno(PerlIO* pf, int &err)
+    {
+       CALLFUNCERR(win32_fileno((FILE*)pf))
+    };
+    virtual PerlIO* Fdopen(int fd, const char *mode, int &err)
+    {
+       PerlIO* pf = (PerlIO*)win32_fdopen(fd, mode);
+       if(errno)
+           err = errno;
+       return pf;
+    };
+    virtual PerlIO* Reopen(const char*path, const char*mode, PerlIO* pf, int &err)
+    {
+       PerlIO* newPf = (PerlIO*)win32_freopen(path, mode, (FILE*)pf);
+       if(errno)
+           err = errno;
+       return newPf;
+    };
+    virtual SSize_t Read(PerlIO* pf, void *buffer, Size_t size, int &err)
+    {
+       SSize_t i = win32_fread(buffer, 1, size, (FILE*)pf);
+       if(errno)
+           err = errno;
+       return i;
+    };
+    virtual SSize_t Write(PerlIO* pf, const void *buffer, Size_t size, int &err)
+    {
+       SSize_t i = win32_fwrite(buffer, 1, size, (FILE*)pf);
+       if(errno)
+           err = errno;
+       return i;
+    };
+    virtual void SetBuf(PerlIO* pf, char* buffer, int &err)
+    {
+       win32_setbuf((FILE*)pf, buffer);
+    };
+    virtual int SetVBuf(PerlIO* pf, char* buffer, int type, Size_t size, int &err)
+    {
+       int i = win32_setvbuf((FILE*)pf, buffer, type, size);
+       if(errno)
+           err = errno;
+       return i;
+    };
+    virtual void SetCnt(PerlIO* pf, int n, int &err)
+    {
+       FILE *f = (FILE*)pf;
+       FILE_cnt(f) = n;
+    };
+    virtual void SetPtrCnt(PerlIO* pf, char * ptr, int n, int& err)
+    {
+       FILE *f = (FILE*)pf;
+       FILE_ptr(f) = ptr;
+       FILE_cnt(f) = n;
+    };
+    virtual void Setlinebuf(PerlIO* pf, int &err)
+    {
+       win32_setvbuf((FILE*)pf, NULL, _IOLBF, 0);
+    };
+    virtual int Printf(PerlIO* pf, int &err, const char *format,...)
+    {
+       va_list(arglist);
+       va_start(arglist, format);
+       int i = win32_vfprintf((FILE*)pf, format, arglist);
+       if(errno)
+           err = errno;
+       return i;
+    };
+    virtual int Vprintf(PerlIO* pf, int &err, const char *format, va_list arglist)
+    {
+       int i = win32_vfprintf((FILE*)pf, format, arglist);
+       if(errno)
+           err = errno;
+       return i;
+    };
+    virtual long Tell(PerlIO* pf, int &err)
+    {
+       long l = win32_ftell((FILE*)pf);
+       if(errno)
+           err = errno;
+       return l;
+    };
+    virtual int Seek(PerlIO* pf, off_t offset, int origin, int &err)
+    {
+       int i = win32_fseek((FILE*)pf, offset, origin);
+       if(errno)
+           err = errno;
+       return i;
+    };
+    virtual void Rewind(PerlIO* pf, int &err)
+    {
+       win32_rewind((FILE*)pf);
+    };
+    virtual PerlIO* Tmpfile(int &err)
+    {
+       PerlIO* pf = (PerlIO*)win32_tmpfile();
+       if(errno)
+           err = errno;
+       return pf;
+    };
+    virtual int Getpos(PerlIO* pf, Fpos_t *p, int &err)
+    {
+       int i = win32_fgetpos((FILE*)pf, p);
+       if(errno)
+           err = errno;
+       return i;
+    };
+    virtual int Setpos(PerlIO* pf, const Fpos_t *p, int &err)
+    {
+       int i = win32_fsetpos((FILE*)pf, p);
+       if(errno)
+           err = errno;
+       return i;
+    };
+    virtual void Init(int &err)
+    {
+    };
+    virtual void InitOSExtras(void* p)
+    {
+       Perl_init_os_extras();
+    };
+    virtual int OpenOSfhandle(long osfhandle, int flags)
+    {
+       return win32_open_osfhandle(osfhandle, flags);
+    }
+    virtual int GetOSfhandle(int filenum)
+    {
+       return win32_get_osfhandle(filenum);
+    }
+};
 
-#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)
+    CPerlHost() { pPerl = NULL; };
+    inline BOOL PerlCreate(void)
+    {
+       try
        {
+           pPerl = perl_alloc(&perlMem, &perlEnv, &perlStdIO, &perlLIO, &perlDir, &perlSock, &perlProc);
+           if(pPerl != NULL)
+           {
                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;
-                               }
-                       }
+                   pPerl->perl_construct();
                }
                catch(...)
                {
-                       fprintf(stderr, "%s\n", "Error: Unable to allocate memory");
-                       pPerl = NULL;
+                   win32_fprintf(stderr, "%s\n", "Error: Unable to construct data structures");
+                   pPerl->perl_free();
+                   pPerl = NULL;
                }
-               return (pPerl != NULL);
-       };
-       inline int PerlParse(int argc, char** argv, char** env)
+           }
+       }
+       catch(...)
        {
-               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)
+           win32_fprintf(stderr, "%s\n", "Error: Unable to allocate memory");
+           pPerl = NULL;
+       }
+       return (pPerl != NULL);
+    };
+    inline int PerlParse(int argc, char** argv, char** env)
+    {
+       int retVal;
+       try
        {
-               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)
+           retVal = pPerl->perl_parse(xs_init, argc, argv, env);
+       }
+       catch(int x)
        {
-               try
-               {
-                       pPerl->perl_destruct();
-                       pPerl->perl_free();
-               }
-               catch(...)
-               {
-               }
-       };
+           // this is where exit() should arrive
+           retVal = x;
+       }
+       catch(...)
+       {
+           win32_fprintf(stderr, "Error: Parse exception\n");
+           retVal = -1;
+       }
+       *win32_errno() = 0;
+       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(...)
+       {
+           win32_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;
+    CPerlDir   perlDir;
+    CPerlEnv   perlEnv;
+    CPerlLIO   perlLIO;
+    CPerlMem   perlMem;
+    CPerlProc  perlProc;
+    CPerlSock  perlSock;
+    CPerlStdIO perlStdIO;
 };
 
 #undef PERL_SYS_INIT
@@ -150,37 +991,42 @@ protected:
 int
 main(int argc, char **argv, char **env)
 {
-       CPerlHost host;
-       int exitstatus = 1;
+    CPerlHost host;
+    int exitstatus = 1;
 
-       if(!host.PerlCreate())
-               exit(exitstatus);
+    if(!host.PerlCreate())
+       exit(exitstatus);
 
 
-       exitstatus = host.PerlParse(argc, argv, env);
+    exitstatus = host.PerlParse(argc, argv, NULL);
 
-       if (!exitstatus)
-       {
-               exitstatus = host.PerlRun();
+    if (!exitstatus)
+    {
+       exitstatus = host.PerlRun();
     }
 
-       host.PerlDestroy();
+    host.PerlDestroy();
 
     return exitstatus;
 }
 
+char *staticlinkmodules[] = {
+    "DynaLoader",
+    NULL,
+};
 
-static void xs_init(CPERLarg)
-{
-}
+EXTERN_C void boot_DynaLoader _((CV* cv _CPERLarg));
 
-EXTERN_C void boot_DynaLoader _((CPERLarg_ CV* cv))
+static void
+xs_init(CPERLarg)
 {
+    char *file = __FILE__;
+    dXSUB_SYS;
+    newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
 }
 
 #else  /* PERL_OBJECT */
 
-/* Say NO to CPP! Hallelujah! */
 #ifdef __GNUC__
 /*
  * GNU C does not do __declspec()