[inseparable changes from match from perl-5.003_93 to perl-5.003_94]
[p5sagit/p5-mst-13.2.git] / win32 / win32.c
CommitLineData
68dc0745 1/* WIN32.C
2 *
3 * (c) 1995 Microsoft Corporation. All rights reserved.
4 * Developed by hip communications inc., http://info.hip.com/info/
5 * Portions (c) 1993 Intergraph Corporation. All rights reserved.
6 *
7 * You may distribute under the terms of either the GNU General Public
8 * License or the Artistic License, as specified in the README file.
9 */
0a753a76 10
11#define WIN32_LEAN_AND_MEAN
12#define WIN32IO_IS_STDIO
13#include <tchar.h>
14#include <windows.h>
15
68dc0745 16/* #include "config.h" */
0a753a76 17
18#define PERLIO_NOT_STDIO 0
19#if !defined(PERLIO_IS_STDIO) && !defined(USE_SFIO)
20#define PerlIO FILE
21#endif
22
23#include "EXTERN.h"
24#include "perl.h"
25#include <fcntl.h>
26#include <sys/stat.h>
27#include <assert.h>
28#include <string.h>
29#include <stdarg.h>
30
31#define CROAK croak
32#define WARN warn
33
34extern WIN32_IOSUBSYSTEM win32stdio;
35__declspec(thread) PWIN32_IOSUBSYSTEM pIOSubSystem = &win32stdio;
68dc0745 36/*__declspec(thread) PWIN32_IOSUBSYSTEM pIOSubSystem = NULL;*/
0a753a76 37
38BOOL ProbeEnv = FALSE;
39DWORD Win32System;
40char szShellPath[MAX_PATH+1];
41char szPerlLibRoot[MAX_PATH+1];
42HANDLE PerlDllHandle = INVALID_HANDLE_VALUE;
43
44#define IsWin95() (Win32System == VER_PLATFORM_WIN32_WINDOWS)
45#define IsWinNT() (Win32System == VER_PLATFORM_WIN32_NT)
46
68dc0745 47void *
48SetIOSubSystem(void *p)
0a753a76 49{
68dc0745 50 if (p) {
51 PWIN32_IOSUBSYSTEM pio = (PWIN32_IOSUBSYSTEM)p;
0a753a76 52
68dc0745 53 if (pio->signature_begin == 12345678L
54 && pio->signature_end == 87654321L) {
55 PWIN32_IOSUBSYSTEM pold = pIOSubSystem;
56 pIOSubSystem = pio;
57 return pold;
58 }
59 }
60 else {
61 /* re-assign our stuff */
62/* pIOSubSystem = &win32stdio; */
63 pIOSubSystem = NULL;
64 }
65 return pIOSubSystem;
66}
67
68char *
69win32PerlLibPath(void)
70{
71 char *end;
72 GetModuleFileName((PerlDllHandle == INVALID_HANDLE_VALUE)
73 ? GetModuleHandle(NULL)
74 : PerlDllHandle,
75 szPerlLibRoot,
76 sizeof(szPerlLibRoot));
77
78 *(end = strrchr(szPerlLibRoot, '\\')) = '\0';
79 if (stricmp(end-4,"\\bin") == 0)
80 end -= 4;
81 strcpy(end,"\\lib");
82 return (szPerlLibRoot);
83}
0a753a76 84
68dc0745 85BOOL
86HasRedirection(char *ptr)
87{
88 int inquote = 0;
89 char quote = '\0';
90
91 /*
92 * Scan string looking for redirection (< or >) or pipe
93 * characters (|) that are not in a quoted string
94 */
95 while(*ptr) {
96 switch(*ptr) {
97 case '\'':
98 case '\"':
99 if(inquote) {
100 if(quote == *ptr) {
101 inquote = 0;
102 quote = '\0';
0a753a76 103 }
68dc0745 104 }
105 else {
106 quote = *ptr;
107 inquote++;
108 }
109 break;
110 case '>':
111 case '<':
112 case '|':
113 if(!inquote)
114 return TRUE;
115 default:
116 break;
0a753a76 117 }
68dc0745 118 ++ptr;
119 }
120 return FALSE;
0a753a76 121}
122
68dc0745 123/* since the current process environment is being updated in util.c
124 * the library functions will get the correct environment
125 */
126PerlIO *
127my_popen(char *cmd, char *mode)
0a753a76 128{
129#ifdef FIXCMD
68dc0745 130#define fixcmd(x) { \
131 char *pspace = strchr((x),' '); \
132 if (pspace) { \
133 char *p = (x); \
134 while (p < pspace) { \
135 if (*p == '/') \
136 *p = '\\'; \
137 p++; \
138 } \
139 } \
140 }
0a753a76 141#else
142#define fixcmd(x)
143#endif
68dc0745 144
145#if 1
146/* was #ifndef PERLDLL, but the #else stuff doesn't work on NT
147 * GSAR 97/03/13
148 */
149 fixcmd(cmd);
0a753a76 150 return win32_popen(cmd, mode);
151#else
152/*
153 * There seems to be some problems for the _popen call in a DLL
154 * this trick at the moment seems to work but it is never test
155 * on NT yet
156 *
157 */
158# ifdef __cplusplus
159#define EXT_C_FUNC extern "C"
160# else
161#define EXT_C_FUNC extern
162# endif
163
68dc0745 164 EXT_C_FUNC int __cdecl _set_osfhnd(int fh, long value);
165 EXT_C_FUNC void __cdecl _lock_fhandle(int);
166 EXT_C_FUNC void __cdecl _unlock_fhandle(int);
167
168 BOOL fSuccess;
169 PerlIO *pf; /* to store the _popen return value */
170 int tm = 0; /* flag indicating tDllExport or binary mode */
171 int fhNeeded, fhInherited, fhDup;
172 int ineeded, iinherited;
173 DWORD dwDup;
174 int phdls[2]; /* I/O handles for pipe */
175 HANDLE hPIn, hPOut, hPErr,
176 hSaveStdin, hSaveStdout, hSaveStderr,
177 hPNeeded, hPInherited, hPDuped;
0a753a76 178
68dc0745 179 /* first check for errors in the arguments */
180 if ( (cmd == NULL) || (mode == NULL)
181 || ((*mode != 'w') && (*mode != _T('r'))) )
182 goto error1;
0a753a76 183
184 if ( *(mode + 1) == _T('t') )
68dc0745 185 tm = _O_TEXT;
0a753a76 186 else if ( *(mode + 1) == _T('b') )
68dc0745 187 tm = _O_BINARY;
188 else
189 tm = (*mode == 'w' ? _O_BINARY : _O_TEXT);
0a753a76 190
191
68dc0745 192 fixcmd(cmd);
193 if (&win32stdio != pIOSubSystem)
194 return win32_popen(cmd, mode);
0a753a76 195
196#ifdef EFG
197 if ( _pipe( phdls, 1024, tm ) == -1 )
198#else
199 if ( win32_pipe( phdls, 1024, tm ) == -1 )
200#endif
68dc0745 201 goto error1;
202
203 /* save the current situation */
204 hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
205 hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
206 hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
207
208 if (*mode == _T('w')) {
209 ineeded = 1;
210 dwDup = STD_INPUT_HANDLE;
211 iinherited = 0;
212 }
213 else {
214 ineeded = 0;
215 dwDup = STD_OUTPUT_HANDLE;
216 iinherited = 1;
217 }
218
219 fhNeeded = phdls[ineeded];
220 fhInherited = phdls[iinherited];
221
222 fSuccess = DuplicateHandle(GetCurrentProcess(),
223 (HANDLE) stolen_get_osfhandle(fhNeeded),
224 GetCurrentProcess(),
225 &hPNeeded,
226 0,
227 FALSE, /* not inherited */
228 DUPLICATE_SAME_ACCESS);
229
230 if (!fSuccess)
231 goto error2;
232
233 fhDup = stolen_open_osfhandle((long) hPNeeded, tm);
234 win32_dup2(fhDup, fhNeeded);
235 win32_close(fhDup);
0a753a76 236
237#ifdef AAA
68dc0745 238 /* Close the Out pipe, child won't need it */
239 hPDuped = (HANDLE) stolen_get_osfhandle(fhNeeded);
0a753a76 240
68dc0745 241 _lock_fhandle(fhNeeded);
242 _set_osfhnd(fhNeeded, (long)hPNeeded); /* put in ours duplicated one */
243 _unlock_fhandle(fhNeeded);
0a753a76 244
68dc0745 245 CloseHandle(hPDuped); /* close the handle first */
0a753a76 246#endif
247
68dc0745 248 if (!SetStdHandle(dwDup, (HANDLE) stolen_get_osfhandle(fhInherited)))
249 goto error2;
0a753a76 250
68dc0745 251 /*
252 * make sure the child see the same stderr as the calling program
253 */
254 if (!SetStdHandle(STD_ERROR_HANDLE,
255 (HANDLE)stolen_get_osfhandle(win32_fileno(win32_stderr()))))
256 goto error2;
0a753a76 257
68dc0745 258 pf = win32_popen(cmd, mode); /* ask _popen to do the job */
0a753a76 259
68dc0745 260 /* restore to where we were */
0a753a76 261 SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
262 SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
263 SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
264
68dc0745 265 /* we don't need it any more, that's for the child */
266 win32_close(fhInherited);
0a753a76 267
68dc0745 268 if (NULL == pf) {
269 /* something wrong */
270 win32_close(fhNeeded);
271 goto error1;
272 }
273 else {
274 /*
275 * here we steal the file handle in pf and stuff ours in
276 */
277 win32_dup2(fhNeeded, win32_fileno(pf));
278 win32_close(fhNeeded);
279 }
280 return (pf);
0a753a76 281
282error2:
68dc0745 283 win32_close(fhNeeded);
284 win32_close(fhInherited);
0a753a76 285
286error1:
68dc0745 287 return (NULL);
0a753a76 288
289#endif
290}
291
68dc0745 292long
293my_pclose(PerlIO *fp)
0a753a76 294{
295 return win32_pclose(fp);
296}
297
68dc0745 298static void
299IdOS(void)
0a753a76 300{
68dc0745 301 OSVERSIONINFO osver;
0a753a76 302
68dc0745 303 memset(&osver, 0, sizeof(OSVERSIONINFO));
304 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
305 GetVersionEx(&osver);
306 Win32System = osver.dwPlatformId;
307 return;
0a753a76 308}
309
68dc0745 310static char *
311GetShell(void)
0a753a76 312{
68dc0745 313 static char* szWin95ShellEntry = "Win95Shell";
314 static char* szWin95DefaultShell = "Cmd32.exe";
315 static char* szWinNTDefaultShell = "cmd.exe";
316
317 if (!ProbeEnv) {
318 IdOS(), ProbeEnv = TRUE;
319 if (IsWin95()) {
320 strcpy(szShellPath, szWin95DefaultShell);
321 }
322 else {
323 strcpy(szShellPath, szWinNTDefaultShell);
324 }
325 }
326 return szShellPath;
0a753a76 327}
328
68dc0745 329int
330do_aspawn(void* really, void** mark, void** arglast)
0a753a76 331{
68dc0745 332 char **argv;
333 char *strPtr;
334 char *cmd;
335 int status;
336 unsigned int length;
337 int index = 0;
0a753a76 338 SV *sv = (SV*)really;
68dc0745 339 SV** pSv = (SV**)mark;
340
341 New(1110, argv, (arglast - mark) + 3, char*);
342
343 if(sv != Nullsv) {
344 cmd = SvPV(sv, length);
345 }
346 else {
347 cmd = GetShell();
348 argv[index++] = "/c";
349 }
350
351 while(pSv <= (SV**)arglast) {
352 sv = *pSv++;
353 strPtr = SvPV(sv, length);
354 if(strPtr != NULL && *strPtr != '\0')
355 argv[index++] = strPtr;
356 }
357 argv[index++] = 0;
358
359 status = win32_spawnvpe(P_WAIT, cmd, (const char* const*)argv,
360 (const char* const*)environ);
361
362 Safefree(argv);
363
364 /* set statusvalue the perl variable $? */
365 return (statusvalue = status*256);
366}
367
368int
369do_spawn(char *cmd)
370{
371 char **a;
372 char *s;
373 char **argv;
374 int status = -1;
375 BOOL needToTry = TRUE;
376 char *shell, *cmd2;
377
378 /* save an extra exec if possible */
379 shell = GetShell();
380
381 /* see if there are shell metacharacters in it */
382 if(!HasRedirection(cmd)) {
383 New(1102,argv, strlen(cmd) / 2 + 2, char*);
384 New(1103,cmd2, strlen(cmd) + 1, char);
385 strcpy(cmd2, cmd);
386 a = argv;
387 for (s = cmd2; *s;) {
388 while (*s && isspace(*s))
389 s++;
390 if (*s)
391 *(a++) = s;
392 while(*s && !isspace(*s))
393 s++;
394 if(*s)
395 *s++ = '\0';
0a753a76 396 }
68dc0745 397 *a = Nullch;
398 if(argv[0]) {
399 status = win32_spawnvpe(P_WAIT,
400 argv[0],
401 (const char* const*)argv,
402 (const char* const*)environ);
403 if(status != -1 || errno == 0)
404 needToTry = FALSE;
0a753a76 405 }
0a753a76 406 Safefree(argv);
68dc0745 407 Safefree(cmd2);
408 }
409 if(needToTry) {
410 status = win32_spawnle(P_WAIT,
411 shell,
412 shell,
413 "/c", cmd, (char*)0, environ);
414 }
0a753a76 415
68dc0745 416 /* set statusvalue the perl variable $? */
417 return (statusvalue = status*256);
0a753a76 418}
419
420
421#define PATHLEN 1024
422
68dc0745 423/* The idea here is to read all the directory names into a string table
424 * (separated by nulls) and when one of the other dir functions is called
425 * return the pointer to the current file name.
426 */
427DIR *
428opendir(char *filename)
0a753a76 429{
430 DIR *p;
68dc0745 431 long len;
432 long idx;
433 char scannamespc[PATHLEN];
434 char *scanname = scannamespc;
435 struct stat sbuf;
436 WIN32_FIND_DATA FindData;
437 HANDLE fh;
438/* char root[_MAX_PATH];*/
439/* char volname[_MAX_PATH];*/
440/* DWORD serial, maxname, flags;*/
441/* BOOL downcase;*/
442/* char *dummy;*/
443
444 /* check to see if filename is a directory */
445 if(stat(filename, &sbuf) < 0 || sbuf.st_mode & _S_IFDIR == 0) {
446 return NULL;
447 }
448
449 /* get the file system characteristics */
450/* if(GetFullPathName(filename, MAX_PATH, root, &dummy)) {
451 * if(dummy = strchr(root, '\\'))
452 * *++dummy = '\0';
453 * if(GetVolumeInformation(root, volname, MAX_PATH, &serial,
454 * &maxname, &flags, 0, 0)) {
455 * downcase = !(flags & FS_CASE_IS_PRESERVED);
456 * }
457 * }
458 * else {
459 * downcase = TRUE;
460 * }
461 */
462 /* Get us a DIR structure */
463 Newz(1501, p, 1, DIR);
464 if(p == NULL)
465 return NULL;
466
467 /* Create the search pattern */
468 strcpy(scanname, filename);
469
470 if(index("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
471 strcat(scanname, "/*");
472 else
473 strcat(scanname, "*");
474
475 /* do the FindFirstFile call */
476 fh = FindFirstFile(scanname, &FindData);
477 if(fh == INVALID_HANDLE_VALUE) {
478 return NULL;
479 }
480
481 /* now allocate the first part of the string table for
482 * the filenames that we find.
483 */
484 idx = strlen(FindData.cFileName)+1;
485 New(1502, p->start, idx, char);
486 if(p->start == NULL) {
487 CROAK("opendir: malloc failed!\n");
488 }
489 strcpy(p->start, FindData.cFileName);
490/* if(downcase)
491 * strlwr(p->start);
492 */
493 p->nfiles++;
494
495 /* loop finding all the files that match the wildcard
496 * (which should be all of them in this directory!).
497 * the variable idx should point one past the null terminator
498 * of the previous string found.
499 */
500 while (FindNextFile(fh, &FindData)) {
501 len = strlen(FindData.cFileName);
502 /* bump the string table size by enough for the
503 * new name and it's null terminator
504 */
505 Renew(p->start, idx+len+1, char);
506 if(p->start == NULL) {
507 CROAK("opendir: malloc failed!\n");
0a753a76 508 }
68dc0745 509 strcpy(&p->start[idx], FindData.cFileName);
510/* if (downcase)
511 * strlwr(&p->start[idx]);
512 */
0a753a76 513 p->nfiles++;
514 idx += len+1;
515 }
516 FindClose(fh);
517 p->size = idx;
518 p->curr = p->start;
519 return p;
520}
521
522
68dc0745 523/* Readdir just returns the current string pointer and bumps the
524 * string pointer to the nDllExport entry.
525 */
526struct direct *
527readdir(DIR *dirp)
0a753a76 528{
68dc0745 529 int len;
530 static int dummy = 0;
0a753a76 531
68dc0745 532 if (dirp->curr) {
533 /* first set up the structure to return */
534 len = strlen(dirp->curr);
535 strcpy(dirp->dirstr.d_name, dirp->curr);
536 dirp->dirstr.d_namlen = len;
0a753a76 537
68dc0745 538 /* Fake an inode */
539 dirp->dirstr.d_ino = dummy++;
0a753a76 540
68dc0745 541 /* Now set up for the nDllExport call to readdir */
542 dirp->curr += len + 1;
543 if (dirp->curr >= (dirp->start + dirp->size)) {
544 dirp->curr = NULL;
545 }
0a753a76 546
68dc0745 547 return &(dirp->dirstr);
548 }
549 else
550 return NULL;
0a753a76 551}
552
68dc0745 553/* Telldir returns the current string pointer position */
554long
555telldir(DIR *dirp)
0a753a76 556{
557 return (long) dirp->curr;
558}
559
560
68dc0745 561/* Seekdir moves the string pointer to a previously saved position
562 *(Saved by telldir).
563 */
564void
565seekdir(DIR *dirp, long loc)
0a753a76 566{
567 dirp->curr = (char *)loc;
568}
569
68dc0745 570/* Rewinddir resets the string pointer to the start */
571void
572rewinddir(DIR *dirp)
0a753a76 573{
574 dirp->curr = dirp->start;
575}
576
68dc0745 577/* free the memory allocated by opendir */
578int
579closedir(DIR *dirp)
0a753a76 580{
581 Safefree(dirp->start);
582 Safefree(dirp);
68dc0745 583 return 1;
0a753a76 584}
585
586
68dc0745 587/*
588 * various stubs
589 */
0a753a76 590
591
68dc0745 592/* Ownership
593 *
594 * Just pretend that everyone is a superuser. NT will let us know if
595 * we don\'t really have permission to do something.
596 */
0a753a76 597
598#define ROOT_UID ((uid_t)0)
599#define ROOT_GID ((gid_t)0)
600
68dc0745 601uid_t
602getuid(void)
0a753a76 603{
68dc0745 604 return ROOT_UID;
0a753a76 605}
606
68dc0745 607uid_t
608geteuid(void)
0a753a76 609{
68dc0745 610 return ROOT_UID;
0a753a76 611}
612
68dc0745 613gid_t
614getgid(void)
0a753a76 615{
68dc0745 616 return ROOT_GID;
0a753a76 617}
618
68dc0745 619gid_t
620getegid(void)
0a753a76 621{
68dc0745 622 return ROOT_GID;
0a753a76 623}
624
68dc0745 625int
626setuid(uid_t uid)
0a753a76 627{
68dc0745 628 return (uid == ROOT_UID ? 0 : -1);
0a753a76 629}
630
68dc0745 631int
632setgid(gid_t gid)
0a753a76 633{
68dc0745 634 return (gid == ROOT_GID ? 0 : -1);
0a753a76 635}
636
68dc0745 637/*
638 * pretended kill
639 */
640int
641kill(int pid, int sig)
0a753a76 642{
68dc0745 643 HANDLE hProcess= OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
0a753a76 644
645 if (hProcess == NULL) {
68dc0745 646 CROAK("kill process failed!\n");
647 }
648 else {
649 if (!TerminateProcess(hProcess, sig))
650 CROAK("kill process failed!\n");
651 CloseHandle(hProcess);
652 }
653 return 0;
0a753a76 654}
655
68dc0745 656/*
657 * File system stuff
658 */
0a753a76 659
68dc0745 660int
661ioctl(int i, unsigned int u, char *data)
0a753a76 662{
68dc0745 663 CROAK("ioctl not implemented!\n");
664 return -1;
0a753a76 665}
666
68dc0745 667unsigned int
668sleep(unsigned int t)
0a753a76 669{
68dc0745 670 Sleep(t*1000);
671 return 0;
0a753a76 672}
673
674
675#undef rename
676
68dc0745 677int
678myrename(char *OldFileName, char *newname)
0a753a76 679{
68dc0745 680 if(_access(newname, 0) != -1) { /* file exists */
681 _unlink(newname);
682 }
683 return rename(OldFileName, newname);
0a753a76 684}
685
686
68dc0745 687DllExport int
688win32_stat(const char *path, struct stat *buffer)
0a753a76 689{
68dc0745 690 char t[MAX_PATH];
691 const char *p = path;
692 int l = strlen(path);
0a753a76 693
68dc0745 694 if (l > 1) {
695 switch(path[l - 1]) {
696 case '\\':
697 case '/':
698 if (path[l - 2] != ':') {
699 strncpy(t, path, l - 1);
700 t[l - 1] = 0;
701 p = t;
702 };
703 }
704 }
705 return stat(p, buffer);
0a753a76 706}
707
708#undef times
68dc0745 709int
710mytimes(struct tms *timebuf)
0a753a76 711{
68dc0745 712 clock_t t = clock();
713 timebuf->tms_utime = t;
714 timebuf->tms_stime = 0;
715 timebuf->tms_cutime = 0;
716 timebuf->tms_cstime = 0;
0a753a76 717
68dc0745 718 return 0;
0a753a76 719}
720
721#undef alarm
68dc0745 722unsigned int
723myalarm(unsigned int sec)
0a753a76 724{
68dc0745 725 /* we warn the usuage of alarm function */
726 if (sec != 0)
727 WARN("dummy function alarm called, program might not function as expected\n");
728 return 0;
0a753a76 729}
730
68dc0745 731/*
732 * redirected io subsystem for all XS modules
733 *
734 */
0a753a76 735
68dc0745 736DllExport int *
737win32_errno(void)
0a753a76 738{
68dc0745 739 return (pIOSubSystem->pfnerrno());
0a753a76 740}
741
68dc0745 742/* the rest are the remapped stdio routines */
743DllExport FILE *
744win32_stderr(void)
0a753a76 745{
68dc0745 746 return (pIOSubSystem->pfnstderr());
0a753a76 747}
748
68dc0745 749DllExport FILE *
750win32_stdin(void)
0a753a76 751{
68dc0745 752 return (pIOSubSystem->pfnstdin());
0a753a76 753}
754
68dc0745 755DllExport FILE *
756win32_stdout()
0a753a76 757{
68dc0745 758 return (pIOSubSystem->pfnstdout());
0a753a76 759}
760
68dc0745 761DllExport int
762win32_ferror(FILE *fp)
0a753a76 763{
68dc0745 764 return (pIOSubSystem->pfnferror(fp));
0a753a76 765}
766
767
68dc0745 768DllExport int
769win32_feof(FILE *fp)
0a753a76 770{
68dc0745 771 return (pIOSubSystem->pfnfeof(fp));
0a753a76 772}
773
68dc0745 774/*
775 * Since the errors returned by the socket error function
776 * WSAGetLastError() are not known by the library routine strerror
777 * we have to roll our own.
778 */
0a753a76 779
780__declspec(thread) char strerror_buffer[512];
781
68dc0745 782DllExport char *
783win32_strerror(int e)
0a753a76 784{
68dc0745 785 extern int sys_nerr;
786 DWORD source = 0;
0a753a76 787
68dc0745 788 if(e < 0 || e > sys_nerr) {
789 if(e < 0)
790 e = GetLastError();
0a753a76 791
68dc0745 792 if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, &source, e, 0,
793 strerror_buffer, sizeof(strerror_buffer), NULL) == 0)
794 strcpy(strerror_buffer, "Unknown Error");
0a753a76 795
68dc0745 796 return strerror_buffer;
797 }
798 return pIOSubSystem->pfnstrerror(e);
0a753a76 799}
800
68dc0745 801DllExport int
802win32_fprintf(FILE *fp, const char *format, ...)
0a753a76 803{
68dc0745 804 va_list marker;
805 va_start(marker, format); /* Initialize variable arguments. */
0a753a76 806
68dc0745 807 return (pIOSubSystem->pfnvfprintf(fp, format, marker));
0a753a76 808}
809
68dc0745 810DllExport int
811win32_printf(const char *format, ...)
0a753a76 812{
68dc0745 813 va_list marker;
814 va_start(marker, format); /* Initialize variable arguments. */
0a753a76 815
68dc0745 816 return (pIOSubSystem->pfnvprintf(format, marker));
0a753a76 817}
818
68dc0745 819DllExport int
820win32_vfprintf(FILE *fp, const char *format, va_list args)
0a753a76 821{
68dc0745 822 return (pIOSubSystem->pfnvfprintf(fp, format, args));
0a753a76 823}
824
68dc0745 825DllExport size_t
826win32_fread(void *buf, size_t size, size_t count, FILE *fp)
0a753a76 827{
68dc0745 828 return pIOSubSystem->pfnfread(buf, size, count, fp);
0a753a76 829}
830
68dc0745 831DllExport size_t
832win32_fwrite(const void *buf, size_t size, size_t count, FILE *fp)
0a753a76 833{
68dc0745 834 return pIOSubSystem->pfnfwrite(buf, size, count, fp);
0a753a76 835}
836
68dc0745 837DllExport FILE *
838win32_fopen(const char *filename, const char *mode)
0a753a76 839{
68dc0745 840 if (stricmp(filename, "/dev/null")==0)
841 return pIOSubSystem->pfnfopen("NUL", mode);
842 return pIOSubSystem->pfnfopen(filename, mode);
0a753a76 843}
844
68dc0745 845DllExport FILE *
846win32_fdopen( int handle, const char *mode)
0a753a76 847{
68dc0745 848 return pIOSubSystem->pfnfdopen(handle, mode);
0a753a76 849}
850
68dc0745 851DllExport FILE *
852win32_freopen( const char *path, const char *mode, FILE *stream)
0a753a76 853{
68dc0745 854 if (stricmp(path, "/dev/null")==0)
855 return pIOSubSystem->pfnfreopen("NUL", mode, stream);
856 return pIOSubSystem->pfnfreopen(path, mode, stream);
0a753a76 857}
858
68dc0745 859DllExport int
860win32_fclose(FILE *pf)
0a753a76 861{
68dc0745 862 return pIOSubSystem->pfnfclose(pf);
0a753a76 863}
864
68dc0745 865DllExport int
866win32_fputs(const char *s,FILE *pf)
0a753a76 867{
68dc0745 868 return pIOSubSystem->pfnfputs(s, pf);
0a753a76 869}
870
68dc0745 871DllExport int
872win32_fputc(int c,FILE *pf)
0a753a76 873{
68dc0745 874 return pIOSubSystem->pfnfputc(c,pf);
0a753a76 875}
876
68dc0745 877DllExport int
878win32_ungetc(int c,FILE *pf)
0a753a76 879{
68dc0745 880 return pIOSubSystem->pfnungetc(c,pf);
0a753a76 881}
882
68dc0745 883DllExport int
884win32_getc(FILE *pf)
0a753a76 885{
68dc0745 886 return pIOSubSystem->pfngetc(pf);
0a753a76 887}
888
68dc0745 889DllExport int
890win32_fileno(FILE *pf)
0a753a76 891{
68dc0745 892 return pIOSubSystem->pfnfileno(pf);
0a753a76 893}
894
68dc0745 895DllExport void
896win32_clearerr(FILE *pf)
0a753a76 897{
68dc0745 898 pIOSubSystem->pfnclearerr(pf);
899 return;
0a753a76 900}
901
68dc0745 902DllExport int
903win32_fflush(FILE *pf)
0a753a76 904{
68dc0745 905 return pIOSubSystem->pfnfflush(pf);
0a753a76 906}
907
68dc0745 908DllExport long
909win32_ftell(FILE *pf)
0a753a76 910{
68dc0745 911 return pIOSubSystem->pfnftell(pf);
0a753a76 912}
913
68dc0745 914DllExport int
915win32_fseek(FILE *pf,long offset,int origin)
0a753a76 916{
68dc0745 917 return pIOSubSystem->pfnfseek(pf, offset, origin);
0a753a76 918}
919
68dc0745 920DllExport int
921win32_fgetpos(FILE *pf,fpos_t *p)
0a753a76 922{
68dc0745 923 return pIOSubSystem->pfnfgetpos(pf, p);
0a753a76 924}
925
68dc0745 926DllExport int
927win32_fsetpos(FILE *pf,const fpos_t *p)
0a753a76 928{
68dc0745 929 return pIOSubSystem->pfnfsetpos(pf, p);
0a753a76 930}
931
68dc0745 932DllExport void
933win32_rewind(FILE *pf)
0a753a76 934{
68dc0745 935 pIOSubSystem->pfnrewind(pf);
936 return;
0a753a76 937}
938
68dc0745 939DllExport FILE*
940win32_tmpfile(void)
0a753a76 941{
68dc0745 942 return pIOSubSystem->pfntmpfile();
0a753a76 943}
944
68dc0745 945DllExport void
946win32_abort(void)
0a753a76 947{
68dc0745 948 pIOSubSystem->pfnabort();
949 return;
0a753a76 950}
951
68dc0745 952DllExport int
953win32_fstat(int fd,struct stat *bufptr)
0a753a76 954{
68dc0745 955 return pIOSubSystem->pfnfstat(fd,bufptr);
0a753a76 956}
957
68dc0745 958DllExport int
959win32_pipe(int *pfd, unsigned int size, int mode)
0a753a76 960{
68dc0745 961 return pIOSubSystem->pfnpipe(pfd, size, mode);
0a753a76 962}
963
68dc0745 964DllExport FILE*
965win32_popen(const char *command, const char *mode)
0a753a76 966{
68dc0745 967 return pIOSubSystem->pfnpopen(command, mode);
0a753a76 968}
969
68dc0745 970DllExport int
971win32_pclose(FILE *pf)
0a753a76 972{
68dc0745 973 return pIOSubSystem->pfnpclose(pf);
0a753a76 974}
975
68dc0745 976DllExport int
977win32_setmode(int fd, int mode)
0a753a76 978{
68dc0745 979 return pIOSubSystem->pfnsetmode(fd, mode);
0a753a76 980}
981
68dc0745 982DllExport int
983win32_open(const char *path, int flag, ...)
0a753a76 984{
68dc0745 985 va_list ap;
986 int pmode;
0a753a76 987
988 va_start(ap, flag);
989 pmode = va_arg(ap, int);
990 va_end(ap);
991
68dc0745 992 if (stricmp(path, "/dev/null")==0)
993 return pIOSubSystem->pfnopen("NUL", flag, pmode);
994 return pIOSubSystem->pfnopen(path,flag,pmode);
0a753a76 995}
996
68dc0745 997DllExport int
998win32_close(int fd)
0a753a76 999{
68dc0745 1000 return pIOSubSystem->pfnclose(fd);
0a753a76 1001}
1002
68dc0745 1003DllExport int
1004win32_dup(int fd)
0a753a76 1005{
68dc0745 1006 return pIOSubSystem->pfndup(fd);
0a753a76 1007}
1008
68dc0745 1009DllExport int
1010win32_dup2(int fd1,int fd2)
0a753a76 1011{
68dc0745 1012 return pIOSubSystem->pfndup2(fd1,fd2);
0a753a76 1013}
1014
68dc0745 1015DllExport int
1016win32_read(int fd, char *buf, unsigned int cnt)
0a753a76 1017{
68dc0745 1018 return pIOSubSystem->pfnread(fd, buf, cnt);
0a753a76 1019}
1020
68dc0745 1021DllExport int
1022win32_write(int fd, const char *buf, unsigned int cnt)
0a753a76 1023{
68dc0745 1024 return pIOSubSystem->pfnwrite(fd, buf, cnt);
0a753a76 1025}
1026
68dc0745 1027DllExport int
1028win32_spawnvpe(int mode, const char *cmdname,
1029 const char *const *argv, const char *const *envp)
0a753a76 1030{
68dc0745 1031 return pIOSubSystem->pfnspawnvpe(mode, cmdname, argv, envp);
0a753a76 1032}
1033
68dc0745 1034DllExport int
1035win32_spawnle(int mode, const char *cmdname, const char *arglist,...)
0a753a76 1036{
68dc0745 1037 const char* const* envp;
1038 const char* const* argp;
0a753a76 1039
68dc0745 1040 argp = &arglist;
1041 while (*argp++) ;
0a753a76 1042
68dc0745 1043 return pIOSubSystem->pfnspawnvpe(mode, cmdname, &arglist, argp);
0a753a76 1044}
1045
68dc0745 1046int
1047stolen_open_osfhandle(long handle, int flags)
0a753a76 1048{
68dc0745 1049 return pIOSubSystem->pfn_open_osfhandle(handle, flags);
0a753a76 1050}
1051
68dc0745 1052long
1053stolen_get_osfhandle(int fd)
0a753a76 1054{
68dc0745 1055 return pIOSubSystem->pfn_get_osfhandle(fd);
0a753a76 1056}