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