This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
applied patch, along with many changes:
[perl5.git] / win32 / perlhost.h
1
2 #include "iperlsys.h"
3
4 extern CPerlObj *pPerl;
5
6 #define CALLFUNC0RET(x)\
7     int ret = x;\
8     if (ret < 0)\
9         err = errno;\
10     return ret;
11
12 #define PROCESS_AND_RETURN  \
13     if (errno)              \
14         err = errno;        \
15     return r
16
17 #define CALLFUNCRET(x)\
18     int ret = x;\
19     if (ret)\
20         err = errno;\
21     return ret;
22
23 #define CALLFUNCERR(x)\
24     int ret = x;\
25     if (errno)\
26         err = errno;\
27     return ret;
28
29 #define LCALLFUNCERR(x)\
30     long ret = x;\
31     if (errno)\
32         err = errno;\
33     return ret;
34
35 extern int              g_closedir(DIR *dirp);
36 extern DIR *            g_opendir(char *filename);
37 extern struct direct *  g_readdir(DIR *dirp);
38 extern void             g_rewinddir(DIR *dirp);
39 extern void             g_seekdir(DIR *dirp, long loc);
40 extern long             g_telldir(DIR *dirp);
41
42 class CPerlDir : public IPerlDir
43 {
44 public:
45     CPerlDir() {};
46     virtual int Makedir(const char *dirname, int mode, int &err)
47     {
48         CALLFUNC0RET(win32_mkdir(dirname, mode));
49     };
50     virtual int Chdir(const char *dirname, int &err)
51     {
52         CALLFUNC0RET(win32_chdir(dirname));
53     };
54     virtual int Rmdir(const char *dirname, int &err)
55     {
56         CALLFUNC0RET(win32_rmdir(dirname));
57     };
58     virtual int Close(DIR *dirp, int &err)
59     {
60         return g_closedir(dirp);
61     };
62     virtual DIR *Open(char *filename, int &err)
63     {
64         return g_opendir(filename);
65     };
66     virtual struct direct *Read(DIR *dirp, int &err)
67     {
68         return g_readdir(dirp);
69     };
70     virtual void Rewind(DIR *dirp, int &err)
71     {
72         g_rewinddir(dirp);
73     };
74     virtual void Seek(DIR *dirp, long loc, int &err)
75     {
76         g_seekdir(dirp, loc);
77     };
78     virtual long Tell(DIR *dirp, int &err)
79     {
80         return g_telldir(dirp);
81     };
82 };
83
84
85 extern char *           g_win32_get_privlib(char *pl);
86 extern char *           g_win32_get_sitelib(char *pl);
87
88 class CPerlEnv : public IPerlEnv
89 {
90 public:
91     CPerlEnv() {};
92     virtual char *Getenv(const char *varname, int &err)
93     {
94         return win32_getenv(varname);
95     };
96     virtual int Putenv(const char *envstring, int &err)
97     {
98         return putenv(envstring);
99     };
100     virtual char* LibPath(char *pl)
101     {
102         return g_win32_get_privlib(pl);
103     };
104     virtual char* SiteLibPath(char *pl)
105     {
106         return g_win32_get_sitelib(pl);
107     };
108 };
109
110 class CPerlSock : public IPerlSock
111 {
112 public:
113     CPerlSock() {};
114     virtual u_long Htonl(u_long hostlong)
115     {
116         return win32_htonl(hostlong);
117     };
118     virtual u_short Htons(u_short hostshort)
119     {
120         return win32_htons(hostshort);
121     };
122     virtual u_long Ntohl(u_long netlong)
123     {
124         return win32_ntohl(netlong);
125     };
126     virtual u_short Ntohs(u_short netshort)
127     {
128         return win32_ntohs(netshort);
129     }
130
131     virtual SOCKET Accept(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
132     {
133         SOCKET r = win32_accept(s, addr, addrlen);
134         PROCESS_AND_RETURN;
135     };
136     virtual int Bind(SOCKET s, const struct sockaddr* name, int namelen, int &err)
137     {
138         int r = win32_bind(s, name, namelen);
139         PROCESS_AND_RETURN;
140     };
141     virtual int Connect(SOCKET s, const struct sockaddr* name, int namelen, int &err)
142     {
143         int r = win32_connect(s, name, namelen);
144         PROCESS_AND_RETURN;
145     };
146     virtual void Endhostent(int &err)
147     {
148         win32_endhostent();
149     };
150     virtual void Endnetent(int &err)
151     {
152         win32_endnetent();
153     };
154     virtual void Endprotoent(int &err)
155     {
156         win32_endprotoent();
157     };
158     virtual void Endservent(int &err)
159     {
160         win32_endservent();
161     };
162     virtual struct hostent* Gethostbyaddr(const char* addr, int len, int type, int &err)
163     {
164         struct hostent *r = win32_gethostbyaddr(addr, len, type);
165         PROCESS_AND_RETURN;
166     };
167     virtual struct hostent* Gethostbyname(const char* name, int &err)
168     {
169         struct hostent *r = win32_gethostbyname(name);
170         PROCESS_AND_RETURN;
171     };
172     virtual struct hostent* Gethostent(int &err)
173     {
174         croak("gethostent not implemented!\n");
175         return NULL;
176     };
177     virtual int Gethostname(char* name, int namelen, int &err)
178     {
179         int r = win32_gethostname(name, namelen);
180         PROCESS_AND_RETURN;
181     };
182     virtual struct netent *Getnetbyaddr(long net, int type, int &err)
183     {
184         struct netent *r = win32_getnetbyaddr(net, type);
185         PROCESS_AND_RETURN;
186     };
187     virtual struct netent *Getnetbyname(const char *name, int &err)
188     {
189         struct netent *r = win32_getnetbyname((char*)name);
190         PROCESS_AND_RETURN;
191     };
192     virtual struct netent *Getnetent(int &err)
193     {
194         struct netent *r = win32_getnetent();
195         PROCESS_AND_RETURN;
196     };
197     virtual int Getpeername(SOCKET s, struct sockaddr* name, int* namelen, int &err)
198     {
199         int r = win32_getpeername(s, name, namelen);
200         PROCESS_AND_RETURN;
201     };
202     virtual struct protoent* Getprotobyname(const char* name, int &err)
203     {
204         struct protoent *r = win32_getprotobyname(name);
205         PROCESS_AND_RETURN;
206     };
207     virtual struct protoent* Getprotobynumber(int number, int &err)
208     {
209         struct protoent *r = win32_getprotobynumber(number);
210         PROCESS_AND_RETURN;
211     };
212     virtual struct protoent* Getprotoent(int &err)
213     {
214         struct protoent *r = win32_getprotoent();
215         PROCESS_AND_RETURN;
216     };
217     virtual struct servent* Getservbyname(const char* name, const char* proto, int &err)
218     {
219         struct servent *r = win32_getservbyname(name, proto);
220         PROCESS_AND_RETURN;
221     };
222     virtual struct servent* Getservbyport(int port, const char* proto, int &err)
223     {
224         struct servent *r = win32_getservbyport(port, proto);
225         PROCESS_AND_RETURN;
226     };
227     virtual struct servent* Getservent(int &err)
228     {
229         struct servent *r = win32_getservent();
230         PROCESS_AND_RETURN;
231     };
232     virtual int Getsockname(SOCKET s, struct sockaddr* name, int* namelen, int &err)
233     {
234         int r = win32_getsockname(s, name, namelen);
235         PROCESS_AND_RETURN;
236     };
237     virtual int Getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen, int &err)
238     {
239         int r = win32_getsockopt(s, level, optname, optval, optlen);
240         PROCESS_AND_RETURN;
241     };
242     virtual unsigned long InetAddr(const char* cp, int &err)
243     {
244         unsigned long r = win32_inet_addr(cp);
245         PROCESS_AND_RETURN;
246     };
247     virtual char* InetNtoa(struct in_addr in, int &err)
248     {
249         char *r = win32_inet_ntoa(in);
250         PROCESS_AND_RETURN;
251     };
252     virtual int Listen(SOCKET s, int backlog, int &err)
253     {
254         int r = win32_listen(s, backlog);
255         PROCESS_AND_RETURN;
256     };
257     virtual int Recv(SOCKET s, char* buffer, int len, int flags, int &err)
258     {
259         int r = win32_recv(s, buffer, len, flags);
260         PROCESS_AND_RETURN;
261     };
262     virtual int Recvfrom(SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen, int &err)
263     {
264         int r = win32_recvfrom(s, buffer, len, flags, from, fromlen);
265         PROCESS_AND_RETURN;
266     };
267     virtual int Select(int nfds, char* readfds, char* writefds, char* exceptfds, const struct timeval* timeout, int &err)
268     {
269         int r = win32_select(nfds, (Perl_fd_set*)readfds, (Perl_fd_set*)writefds, (Perl_fd_set*)exceptfds, timeout);
270         PROCESS_AND_RETURN;
271     };
272     virtual int Send(SOCKET s, const char* buffer, int len, int flags, int &err)
273     {
274         int r = win32_send(s, buffer, len, flags);
275         PROCESS_AND_RETURN;
276     };
277     virtual int Sendto(SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen, int &err)
278     {
279         int r = win32_sendto(s, buffer, len, flags, to, tolen);
280         PROCESS_AND_RETURN;
281     };
282     virtual void Sethostent(int stayopen, int &err)
283     {
284         win32_sethostent(stayopen);
285     };
286     virtual void Setnetent(int stayopen, int &err)
287     {
288         win32_setnetent(stayopen);
289     };
290     virtual void Setprotoent(int stayopen, int &err)
291     {
292         win32_setprotoent(stayopen);
293     };
294     virtual void Setservent(int stayopen, int &err)
295     {
296         win32_setservent(stayopen);
297     };
298     virtual int Setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen, int &err)
299     {
300         int r = win32_setsockopt(s, level, optname, optval, optlen);
301         PROCESS_AND_RETURN;
302     };
303     virtual int Shutdown(SOCKET s, int how, int &err)
304     {
305         int r = win32_shutdown(s, how);
306         PROCESS_AND_RETURN;
307     };
308     virtual SOCKET Socket(int af, int type, int protocol, int &err)
309     {
310         SOCKET r = win32_socket(af, type, protocol);
311         PROCESS_AND_RETURN;
312     };
313     virtual int Socketpair(int domain, int type, int protocol, int* fds, int &err)
314     {
315         croak("socketpair not implemented!\n");
316         return 0;
317     };
318     virtual int Closesocket(SOCKET s, int& err)
319     {
320         int r = win32_closesocket(s);
321         PROCESS_AND_RETURN;
322     };
323     virtual int Ioctlsocket(SOCKET s, long cmd, u_long *argp, int& err)
324     {
325         int r = win32_ioctlsocket(s, cmd, argp);
326         PROCESS_AND_RETURN;
327     };
328 };
329
330 class CPerlLIO : public IPerlLIO
331 {
332 public:
333     CPerlLIO() {};
334     virtual int Access(const char *path, int mode, int &err)
335     {
336         CALLFUNCRET(access(path, mode))
337     };
338     virtual int Chmod(const char *filename, int pmode, int &err)
339     {
340         CALLFUNCRET(chmod(filename, pmode))
341     };
342     virtual int Chown(const char *filename, uid_t owner, gid_t group, int &err)
343     {
344         CALLFUNCERR(chown(filename, owner, group))
345     };
346     virtual int Chsize(int handle, long size, int &err)
347     {
348         CALLFUNCRET(chsize(handle, size))
349     };
350     virtual int Close(int handle, int &err)
351     {
352         CALLFUNCRET(win32_close(handle))
353     };
354     virtual int Dup(int handle, int &err)
355     {
356         CALLFUNCERR(win32_dup(handle))
357     };
358     virtual int Dup2(int handle1, int handle2, int &err)
359     {
360         CALLFUNCERR(win32_dup2(handle1, handle2))
361     };
362     virtual int Flock(int fd, int oper, int &err)
363     {
364         CALLFUNCERR(win32_flock(fd, oper))
365     };
366     virtual int FileStat(int handle, struct stat *buffer, int &err)
367     {
368         CALLFUNCERR(fstat(handle, buffer))
369     };
370     virtual int IOCtl(int i, unsigned int u, char *data, int &err)
371     {
372         CALLFUNCERR(win32_ioctlsocket((SOCKET)i, (long)u, (u_long*)data))
373     };
374     virtual int Isatty(int fd, int &err)
375     {
376         return isatty(fd);
377     };
378     virtual long Lseek(int handle, long offset, int origin, int &err)
379     {
380         LCALLFUNCERR(win32_lseek(handle, offset, origin))
381     };
382     virtual int Lstat(const char *path, struct stat *buffer, int &err)
383     {
384         return NameStat(path, buffer, err);
385     };
386     virtual char *Mktemp(char *Template, int &err)
387     {
388         return mktemp(Template);
389     };
390     virtual int Open(const char *filename, int oflag, int &err)
391     {
392         CALLFUNCERR(win32_open(filename, oflag))
393     };
394     virtual int Open(const char *filename, int oflag, int pmode, int &err)
395     {
396         int ret;
397         if(stricmp(filename, "/dev/null") == 0)
398             ret = open("NUL", oflag, pmode);
399         else
400             ret = open(filename, oflag, pmode);
401
402         if(errno)
403             err = errno;
404         return ret;
405     };
406     virtual int Read(int handle, void *buffer, unsigned int count, int &err)
407     {
408         CALLFUNCERR(win32_read(handle, buffer, count))
409     };
410     virtual int Rename(const char *OldFileName, const char *newname, int &err)
411     {
412         char szNewWorkName[MAX_PATH+1];
413         WIN32_FIND_DATA fdOldFile, fdNewFile;
414         HANDLE handle;
415         char *ptr;
416
417         if((strchr(OldFileName, '\\') || strchr(OldFileName, '/'))
418                 && strchr(newname, '\\') == NULL
419                         && strchr(newname, '/') == NULL)
420         {
421             strcpy(szNewWorkName, OldFileName);
422             if((ptr = strrchr(szNewWorkName, '\\')) == NULL)
423                 ptr = strrchr(szNewWorkName, '/');
424             strcpy(++ptr, newname);
425         }
426         else
427             strcpy(szNewWorkName, newname);
428
429         if(stricmp(OldFileName, szNewWorkName) != 0)
430         {   // check that we're not being fooled by relative paths
431             // and only delete the new file
432             //  1) if it exists
433             //  2) it is not the same file as the old file
434             //  3) old file exist
435             // GetFullPathName does not return the long file name on some systems
436             handle = FindFirstFile(OldFileName, &fdOldFile);
437             if(handle != INVALID_HANDLE_VALUE)
438             {
439                 FindClose(handle);
440         
441                 handle = FindFirstFile(szNewWorkName, &fdNewFile);
442         
443                 if(handle != INVALID_HANDLE_VALUE)
444                     FindClose(handle);
445                 else
446                     fdNewFile.cFileName[0] = '\0';
447
448                 if(strcmp(fdOldFile.cAlternateFileName, fdNewFile.cAlternateFileName) != 0
449                         && strcmp(fdOldFile.cFileName, fdNewFile.cFileName) != 0)
450                 {   // file exists and not same file
451                     DeleteFile(szNewWorkName);
452                 }
453             }
454         }
455         int ret = rename(OldFileName, szNewWorkName);
456         if(ret)
457             err = errno;
458
459         return ret;
460     };
461     virtual int Setmode(int handle, int mode, int &err)
462     {
463         CALLFUNCRET(win32_setmode(handle, mode))
464     };
465     virtual int NameStat(const char *path, struct stat *buffer, int &err)
466     {
467         return win32_stat(path, buffer);
468     };
469     virtual char *Tmpnam(char *string, int &err)
470     {
471         return tmpnam(string);
472     };
473     virtual int Umask(int pmode, int &err)
474     {
475         return umask(pmode);
476     };
477     virtual int Unlink(const char *filename, int &err)
478     {
479         chmod(filename, S_IREAD | S_IWRITE);
480         CALLFUNCRET(unlink(filename))
481     };
482     virtual int Utime(char *filename, struct utimbuf *times, int &err)
483     {
484         CALLFUNCRET(win32_utime(filename, times))
485     };
486     virtual int Write(int handle, const void *buffer, unsigned int count, int &err)
487     {
488         CALLFUNCERR(win32_write(handle, buffer, count))
489     };
490 };
491
492 class CPerlMem : public IPerlMem
493 {
494 public:
495     CPerlMem() {};
496     virtual void* Malloc(size_t size)
497     {
498         return win32_malloc(size);
499     };
500     virtual void* Realloc(void* ptr, size_t size)
501     {
502         return win32_realloc(ptr, size);
503     };
504     virtual void Free(void* ptr)
505     {
506         win32_free(ptr);
507     };
508 };
509
510 #define EXECF_EXEC 1
511 #define EXECF_SPAWN 2
512
513 extern char *           g_getlogin(void);
514 extern int              do_spawn2(char *cmd, int exectype);
515 extern int              g_do_aspawn(void *vreally, void **vmark, void **vsp);
516
517 class CPerlProc : public IPerlProc
518 {
519 public:
520     CPerlProc() {};
521     virtual void Abort(void)
522     {
523         win32_abort();
524     };
525     virtual void Exit(int status)
526     {
527         exit(status);
528     };
529     virtual void _Exit(int status)
530     {
531         _exit(status);
532     };
533     virtual int Execl(const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3)
534     {
535         return execl(cmdname, arg0, arg1, arg2, arg3);
536     };
537     virtual int Execv(const char *cmdname, const char *const *argv)
538     {
539         return win32_execvp(cmdname, argv);
540     };
541     virtual int Execvp(const char *cmdname, const char *const *argv)
542     {
543         return win32_execvp(cmdname, argv);
544     };
545     virtual uid_t Getuid(void)
546     {
547         return getuid();
548     };
549     virtual uid_t Geteuid(void)
550     {
551         return geteuid();
552     };
553     virtual gid_t Getgid(void)
554     {
555         return getgid();
556     };
557     virtual gid_t Getegid(void)
558     {
559         return getegid();
560     };
561     virtual char *Getlogin(void)
562     {
563         return g_getlogin();
564     };
565     virtual int Kill(int pid, int sig)
566     {
567         return win32_kill(pid, sig);
568     };
569     virtual int Killpg(int pid, int sig)
570     {
571         croak("killpg not implemented!\n");
572         return 0;
573     };
574     virtual int PauseProc(void)
575     {
576         return win32_sleep((32767L << 16) + 32767);
577     };
578     virtual PerlIO* Popen(const char *command, const char *mode)
579     {
580         win32_fflush(stdout);
581         win32_fflush(stderr);
582         return (PerlIO*)win32_popen(command, mode);
583     };
584     virtual int Pclose(PerlIO *stream)
585     {
586         return win32_pclose((FILE*)stream);
587     };
588     virtual int Pipe(int *phandles)
589     {
590         return win32_pipe(phandles, 512, O_BINARY);
591     };
592     virtual int Setuid(uid_t u)
593     {
594         return setuid(u);
595     };
596     virtual int Setgid(gid_t g)
597     {
598         return setgid(g);
599     };
600     virtual int Sleep(unsigned int s)
601     {
602         return win32_sleep(s);
603     };
604     virtual int Times(struct tms *timebuf)
605     {
606         return win32_times(timebuf);
607     };
608     virtual int Wait(int *status)
609     {
610         return win32_wait(status);
611     };
612     virtual int Waitpid(int pid, int *status, int flags)
613     {
614         return win32_waitpid(pid, status, flags);
615     };
616     virtual Sighandler_t Signal(int sig, Sighandler_t subcode)
617     {
618         return 0;
619     };
620     virtual void GetSysMsg(char*& sMsg, DWORD& dwLen, DWORD dwErr)
621     {
622         dwLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
623                           |FORMAT_MESSAGE_IGNORE_INSERTS
624                           |FORMAT_MESSAGE_FROM_SYSTEM, NULL,
625                            dwErr, 0, (char *)&sMsg, 1, NULL);
626         if (0 < dwLen) {
627             while (0 < dwLen  &&  isspace(sMsg[--dwLen]))
628                 ;
629             if ('.' != sMsg[dwLen])
630                 dwLen++;
631             sMsg[dwLen]= '\0';
632         }
633         if (0 == dwLen) {
634             sMsg = (char*)LocalAlloc(0, 64/**sizeof(TCHAR)*/);
635             dwLen = sprintf(sMsg,
636                         "Unknown error #0x%lX (lookup 0x%lX)",
637                         dwErr, GetLastError());
638         }
639     };
640     virtual void FreeBuf(char* sMsg)
641     {
642         LocalFree(sMsg);
643     };
644     virtual BOOL DoCmd(char *cmd)
645     {
646         do_spawn2(cmd, EXECF_EXEC);
647         return FALSE;
648     };
649     virtual int Spawn(char* cmds)
650     {
651         return do_spawn2(cmds, EXECF_SPAWN);
652     };
653     virtual int Spawnvp(int mode, const char *cmdname, const char *const *argv)
654     {
655         return win32_spawnvp(mode, cmdname, argv);
656     };
657     virtual int ASpawn(void *vreally, void **vmark, void **vsp)
658     {
659         return g_do_aspawn(vreally, vmark, vsp);
660     };
661 };
662
663
664 class CPerlStdIO : public IPerlStdIO
665 {
666 public:
667     CPerlStdIO() {};
668     virtual PerlIO* Stdin(void)
669     {
670         return (PerlIO*)win32_stdin();
671     };
672     virtual PerlIO* Stdout(void)
673     {
674         return (PerlIO*)win32_stdout();
675     };
676     virtual PerlIO* Stderr(void)
677     {
678         return (PerlIO*)win32_stderr();
679     };
680     virtual PerlIO* Open(const char *path, const char *mode, int &err)
681     {
682         PerlIO*pf = (PerlIO*)win32_fopen(path, mode);
683         if(errno)
684             err = errno;
685         return pf;
686     };
687     virtual int Close(PerlIO* pf, int &err)
688     {
689         CALLFUNCERR(win32_fclose(((FILE*)pf)))
690     };
691     virtual int Eof(PerlIO* pf, int &err)
692     {
693         CALLFUNCERR(win32_feof((FILE*)pf))
694     };
695     virtual int Error(PerlIO* pf, int &err)
696     {
697         CALLFUNCERR(win32_ferror((FILE*)pf))
698     };
699     virtual void Clearerr(PerlIO* pf, int &err)
700     {
701         win32_clearerr((FILE*)pf);
702     };
703     virtual int Getc(PerlIO* pf, int &err)
704     {
705         CALLFUNCERR(win32_getc((FILE*)pf))
706     };
707     virtual char* GetBase(PerlIO* pf, int &err)
708     {
709         FILE *f = (FILE*)pf;
710         return FILE_base(f);
711     };
712     virtual int GetBufsiz(PerlIO* pf, int &err)
713     {
714         FILE *f = (FILE*)pf;
715         return FILE_bufsiz(f);
716     };
717     virtual int GetCnt(PerlIO* pf, int &err)
718     {
719         FILE *f = (FILE*)pf;
720         return FILE_cnt(f);
721     };
722     virtual char* GetPtr(PerlIO* pf, int &err)
723     {
724         FILE *f = (FILE*)pf;
725         return FILE_ptr(f);
726     };
727     virtual char* Gets(PerlIO* pf, char* s, int n, int& err)
728     {
729         char* ret = win32_fgets(s, n, (FILE*)pf);
730         if(errno)
731             err = errno;
732         return ret;
733     };
734     virtual int Putc(PerlIO* pf, int c, int &err)
735     {
736         CALLFUNCERR(win32_fputc(c, (FILE*)pf))
737     };
738     virtual int Puts(PerlIO* pf, const char *s, int &err)
739     {
740         CALLFUNCERR(win32_fputs(s, (FILE*)pf))
741     };
742     virtual int Flush(PerlIO* pf, int &err)
743     {
744         CALLFUNCERR(win32_fflush((FILE*)pf))
745     };
746     virtual int Ungetc(PerlIO* pf,int c, int &err)
747     {
748         CALLFUNCERR(win32_ungetc(c, (FILE*)pf))
749     };
750     virtual int Fileno(PerlIO* pf, int &err)
751     {
752         CALLFUNCERR(win32_fileno((FILE*)pf))
753     };
754     virtual PerlIO* Fdopen(int fd, const char *mode, int &err)
755     {
756         PerlIO* pf = (PerlIO*)win32_fdopen(fd, mode);
757         if(errno)
758             err = errno;
759         return pf;
760     };
761     virtual PerlIO* Reopen(const char*path, const char*mode, PerlIO* pf, int &err)
762     {
763         PerlIO* newPf = (PerlIO*)win32_freopen(path, mode, (FILE*)pf);
764         if(errno)
765             err = errno;
766         return newPf;
767     };
768     virtual SSize_t Read(PerlIO* pf, void *buffer, Size_t size, int &err)
769     {
770         SSize_t i = win32_fread(buffer, 1, size, (FILE*)pf);
771         if(errno)
772             err = errno;
773         return i;
774     };
775     virtual SSize_t Write(PerlIO* pf, const void *buffer, Size_t size, int &err)
776     {
777         SSize_t i = win32_fwrite(buffer, 1, size, (FILE*)pf);
778         if(errno)
779             err = errno;
780         return i;
781     };
782     virtual void SetBuf(PerlIO* pf, char* buffer, int &err)
783     {
784         win32_setbuf((FILE*)pf, buffer);
785     };
786     virtual int SetVBuf(PerlIO* pf, char* buffer, int type, Size_t size, int &err)
787     {
788         int i = win32_setvbuf((FILE*)pf, buffer, type, size);
789         if(errno)
790             err = errno;
791         return i;
792     };
793     virtual void SetCnt(PerlIO* pf, int n, int &err)
794     {
795         FILE *f = (FILE*)pf;
796         FILE_cnt(f) = n;
797     };
798     virtual void SetPtrCnt(PerlIO* pf, char * ptr, int n, int& err)
799     {
800         FILE *f = (FILE*)pf;
801         FILE_ptr(f) = ptr;
802         FILE_cnt(f) = n;
803     };
804     virtual void Setlinebuf(PerlIO* pf, int &err)
805     {
806         win32_setvbuf((FILE*)pf, NULL, _IOLBF, 0);
807     };
808     virtual int Printf(PerlIO* pf, int &err, const char *format,...)
809     {
810         va_list(arglist);
811         va_start(arglist, format);
812         int i = win32_vfprintf((FILE*)pf, format, arglist);
813         if(errno)
814             err = errno;
815         return i;
816     };
817     virtual int Vprintf(PerlIO* pf, int &err, const char *format, va_list arglist)
818     {
819         int i = win32_vfprintf((FILE*)pf, format, arglist);
820         if(errno)
821             err = errno;
822         return i;
823     };
824     virtual long Tell(PerlIO* pf, int &err)
825     {
826         long l = win32_ftell((FILE*)pf);
827         if(errno)
828             err = errno;
829         return l;
830     };
831     virtual int Seek(PerlIO* pf, off_t offset, int origin, int &err)
832     {
833         int i = win32_fseek((FILE*)pf, offset, origin);
834         if(errno)
835             err = errno;
836         return i;
837     };
838     virtual void Rewind(PerlIO* pf, int &err)
839     {
840         win32_rewind((FILE*)pf);
841     };
842     virtual PerlIO* Tmpfile(int &err)
843     {
844         PerlIO* pf = (PerlIO*)win32_tmpfile();
845         if(errno)
846             err = errno;
847         return pf;
848     };
849     virtual int Getpos(PerlIO* pf, Fpos_t *p, int &err)
850     {
851         int i = win32_fgetpos((FILE*)pf, p);
852         if(errno)
853             err = errno;
854         return i;
855     };
856     virtual int Setpos(PerlIO* pf, const Fpos_t *p, int &err)
857     {
858         int i = win32_fsetpos((FILE*)pf, p);
859         if(errno)
860             err = errno;
861         return i;
862     };
863     virtual void Init(int &err)
864     {
865     };
866     virtual void InitOSExtras(void* p)
867     {
868         Perl_init_os_extras();
869     };
870     virtual int OpenOSfhandle(long osfhandle, int flags)
871     {
872         return win32_open_osfhandle(osfhandle, flags);
873     }
874     virtual int GetOSfhandle(int filenum)
875     {
876         return win32_get_osfhandle(filenum);
877     }
878 };
879
880 class CPerlHost
881 {
882 public:
883     CPerlHost() { pPerl = NULL; };
884     inline BOOL PerlCreate(void)
885     {
886         try
887         {
888             pPerl = perl_alloc(&perlMem, &perlEnv, &perlStdIO, &perlLIO,
889                                &perlDir, &perlSock, &perlProc);
890             if(pPerl != NULL)
891             {
892                 try
893                 {
894                     pPerl->perl_construct();
895                 }
896                 catch(...)
897                 {
898                     win32_fprintf(stderr, "%s\n",
899                                   "Error: Unable to construct data structures");
900                     pPerl->perl_free();
901                     pPerl = NULL;
902                 }
903             }
904         }
905         catch(...)
906         {
907             win32_fprintf(stderr, "%s\n", "Error: Unable to allocate memory");
908             pPerl = NULL;
909         }
910         return (pPerl != NULL);
911     };
912     inline int PerlParse(void (*xs_init)(CPerlObj*), int argc, char** argv, char** env)
913     {
914         int retVal;
915         try
916         {
917             retVal = pPerl->perl_parse(xs_init, argc, argv, env);
918         }
919         catch(int x)
920         {
921             // this is where exit() should arrive
922             retVal = x;
923         }
924         catch(...)
925         {
926             win32_fprintf(stderr, "Error: Parse exception\n");
927             retVal = -1;
928         }
929         *win32_errno() = 0;
930         return retVal;
931     };
932     inline int PerlRun(void)
933     {
934         int retVal;
935         try
936         {
937             retVal = pPerl->perl_run();
938         }
939         catch(int x)
940         {
941             // this is where exit() should arrive
942             retVal = x;
943         }
944         catch(...)
945         {
946             win32_fprintf(stderr, "Error: Runtime exception\n");
947             retVal = -1;
948         }
949         return retVal;
950     };
951     inline void PerlDestroy(void)
952     {
953         try
954         {
955             pPerl->perl_destruct();
956             pPerl->perl_free();
957         }
958         catch(...)
959         {
960         }
961     };
962
963 protected:
964     CPerlDir    perlDir;
965     CPerlEnv    perlEnv;
966     CPerlLIO    perlLIO;
967     CPerlMem    perlMem;
968     CPerlProc   perlProc;
969     CPerlSock   perlSock;
970     CPerlStdIO  perlStdIO;
971 };