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