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
PP
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
PP
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
PP
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
PP
37
38BOOL ProbeEnv = FALSE;
39DWORD Win32System;
40char szShellPath[MAX_PATH+1];
41char szPerlLibRoot[MAX_PATH+1];
42HANDLE PerlDllHandle = INVALID_HANDLE_VALUE;
43
3fe9a6f1
PP
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
PP
54void *
55SetIOSubSystem(void *p)
0a753a76 56{
137443ea 57 PWIN32_IOSUBSYSTEM old = pIOSubSystem;
68dc0745
PP
58 if (p) {
59 PWIN32_IOSUBSYSTEM pio = (PWIN32_IOSUBSYSTEM)p;
68dc0745
PP
60 if (pio->signature_begin == 12345678L
61 && pio->signature_end == 87654321L) {
68dc0745 62 pIOSubSystem = pio;
68dc0745
PP
63 }
64 }
65 else {
137443ea 66 pIOSubSystem = &win32stdio;
68dc0745 67 }
137443ea 68 return old;
68dc0745
PP
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
PP
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
PP
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
PP
121 ++ptr;
122 }
123 return FALSE;
0a753a76
PP
124}
125
68dc0745
PP
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
PP
131{
132#ifdef FIXCMD
68dc0745
PP
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
PP
144#else
145#define fixcmd(x)
146#endif
68dc0745
PP
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
PP
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
PP
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
PP
182 /* first check for errors in the arguments */
183 if ( (cmd == NULL) || (mode == NULL)
184 || ((*mode != 'w') && (*mode != _T('r'))) )
185 goto error1;
0a753a76
PP
186
187 if ( *(mode + 1) == _T('t') )
68dc0745 188 tm = _O_TEXT;
0a753a76 189 else if ( *(mode + 1) == _T('b') )
68dc0745
PP
190 tm = _O_BINARY;
191 else
192 tm = (*mode == 'w' ? _O_BINARY : _O_TEXT);
0a753a76
PP
193
194
68dc0745
PP
195 fixcmd(cmd);
196 if (&win32stdio != pIOSubSystem)
197 return win32_popen(cmd, mode);
0a753a76
PP
198
199#ifdef EFG
200 if ( _pipe( phdls, 1024, tm ) == -1 )
201#else
202 if ( win32_pipe( phdls, 1024, tm ) == -1 )
203#endif
68dc0745
PP
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
PP
239
240#ifdef AAA
68dc0745
PP
241 /* Close the Out pipe, child won't need it */
242 hPDuped = (HANDLE) stolen_get_osfhandle(fhNeeded);
0a753a76 243
68dc0745
PP
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
PP
249#endif
250
68dc0745
PP
251 if (!SetStdHandle(dwDup, (HANDLE) stolen_get_osfhandle(fhInherited)))
252 goto error2;
0a753a76 253
68dc0745
PP
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
PP
264 SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
265 SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
266 SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
267
68dc0745
PP
268 /* we don't need it any more, that's for the child */
269 win32_close(fhInherited);
0a753a76 270
68dc0745
PP
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
PP
284
285error2:
68dc0745
PP
286 win32_close(fhNeeded);
287 win32_close(fhInherited);
0a753a76
PP
288
289error1:
68dc0745 290 return (NULL);
0a753a76
PP
291
292#endif
293}
294
68dc0745
PP
295long
296my_pclose(PerlIO *fp)
0a753a76
PP
297{
298 return win32_pclose(fp);
299}
300
68dc0745
PP
301static void
302IdOS(void)
0a753a76 303{
68dc0745 304 OSVERSIONINFO osver;
0a753a76 305
68dc0745
PP
306 memset(&osver, 0, sizeof(OSVERSIONINFO));
307 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
308 GetVersionEx(&osver);
309 Win32System = osver.dwPlatformId;
310 return;
0a753a76
PP
311}
312
68dc0745
PP
313static char *
314GetShell(void)
0a753a76 315{
68dc0745
PP
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
PP
330}
331
68dc0745
PP
332int
333do_aspawn(void* really, void** mark, void** arglast)
0a753a76 334{
68dc0745
PP
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
PP
342 SV** pSv = (SV**)mark;
343
fc36a67e 344 New(1310, argv, (arglast - mark) + 4, char*);
68dc0745
PP
345
346 if(sv != Nullsv) {
347 cmd = SvPV(sv, length);
348 }
349 else {
3fe9a6f1
PP
350 argv[index++] = cmd = GetShell();
351 argv[index++] = "/x"; /* always enable command extensions */
68dc0745
PP
352 argv[index++] = "/c";
353 }
354
5aabfad6
PP
355 while(++pSv <= (SV**)arglast) {
356 sv = *pSv;
68dc0745
PP
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
PP
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
PP
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
PP
391 New(1301,argv, strlen(cmd) / 2 + 2, char*);
392 New(1302,cmd2, strlen(cmd) + 1, char);
68dc0745
PP
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
PP
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
PP
415 Safefree(cmd2);
416 }
417 if(needToTry) {
418 status = win32_spawnle(P_WAIT,
419 shell,
420 shell,
3fe9a6f1 421 "/x",
68dc0745
PP
422 "/c", cmd, (char*)0, environ);
423 }
5aabfad6
PP
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
PP
431}
432
433
434#define PATHLEN 1024
435
68dc0745
PP
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
PP
442{
443 DIR *p;
68dc0745
PP
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
PP
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
PP
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
PP
522 strcpy(&p->start[idx], FindData.cFileName);
523/* if (downcase)
524 * strlwr(&p->start[idx]);
525 */
0a753a76
PP
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
PP
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
PP
542 int len;
543 static int dummy = 0;
0a753a76 544
68dc0745
PP
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
PP
551 /* Fake an inode */
552 dirp->dirstr.d_ino = dummy++;
0a753a76 553
68dc0745
PP
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
PP
560 return &(dirp->dirstr);
561 }
562 else
563 return NULL;
0a753a76
PP
564}
565
68dc0745
PP
566/* Telldir returns the current string pointer position */
567long
568telldir(DIR *dirp)
0a753a76
PP
569{
570 return (long) dirp->curr;
571}
572
573
68dc0745
PP
574/* Seekdir moves the string pointer to a previously saved position
575 *(Saved by telldir).
576 */
577void
578seekdir(DIR *dirp, long loc)
0a753a76
PP
579{
580 dirp->curr = (char *)loc;
581}
582
68dc0745
PP
583/* Rewinddir resets the string pointer to the start */
584void
585rewinddir(DIR *dirp)
0a753a76
PP
586{
587 dirp->curr = dirp->start;
588}
589
68dc0745
PP
590/* free the memory allocated by opendir */
591int
592closedir(DIR *dirp)
0a753a76
PP
593{
594 Safefree(dirp->start);
595 Safefree(dirp);
68dc0745 596 return 1;
0a753a76
PP
597}
598
599
68dc0745
PP
600/*
601 * various stubs
602 */
0a753a76
PP
603
604
68dc0745
PP
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
PP
610
611#define ROOT_UID ((uid_t)0)
612#define ROOT_GID ((gid_t)0)
613
68dc0745
PP
614uid_t
615getuid(void)
0a753a76 616{
68dc0745 617 return ROOT_UID;
0a753a76
PP
618}
619
68dc0745
PP
620uid_t
621geteuid(void)
0a753a76 622{
68dc0745 623 return ROOT_UID;
0a753a76
PP
624}
625
68dc0745
PP
626gid_t
627getgid(void)
0a753a76 628{
68dc0745 629 return ROOT_GID;
0a753a76
PP
630}
631
68dc0745
PP
632gid_t
633getegid(void)
0a753a76 634{
68dc0745 635 return ROOT_GID;
0a753a76
PP
636}
637
68dc0745
PP
638int
639setuid(uid_t uid)
0a753a76 640{
68dc0745 641 return (uid == ROOT_UID ? 0 : -1);
0a753a76
PP
642}
643
68dc0745
PP
644int
645setgid(gid_t gid)
0a753a76 646{
68dc0745 647 return (gid == ROOT_GID ? 0 : -1);
0a753a76
PP
648}
649
68dc0745
PP
650/*
651 * pretended kill
652 */
653int
654kill(int pid, int sig)
0a753a76 655{
68dc0745 656 HANDLE hProcess= OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
0a753a76
PP
657
658 if (hProcess == NULL) {
68dc0745
PP
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
PP
667}
668
68dc0745
PP
669/*
670 * File system stuff
671 */
0a753a76 672
68dc0745
PP
673int
674ioctl(int i, unsigned int u, char *data)
0a753a76 675{
68dc0745
PP
676 CROAK("ioctl not implemented!\n");
677 return -1;
0a753a76
PP
678}
679
68dc0745
PP
680unsigned int
681sleep(unsigned int t)
0a753a76 682{
68dc0745
PP
683 Sleep(t*1000);
684 return 0;
0a753a76
PP
685}
686
687
688#undef rename
689
68dc0745
PP
690int
691myrename(char *OldFileName, char *newname)
0a753a76 692{
68dc0745
PP
693 if(_access(newname, 0) != -1) { /* file exists */
694 _unlink(newname);
695 }
696 return rename(OldFileName, newname);
0a753a76
PP
697}
698
699
68dc0745
PP
700DllExport int
701win32_stat(const char *path, struct stat *buffer)
0a753a76 702{
68dc0745
PP
703 char t[MAX_PATH];
704 const char *p = path;
705 int l = strlen(path);
0a753a76 706
68dc0745
PP
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
PP
719}
720
721#undef times
68dc0745
PP
722int
723mytimes(struct tms *timebuf)
0a753a76 724{
68dc0745
PP
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
PP
732}
733
734#undef alarm
68dc0745
PP
735unsigned int
736myalarm(unsigned int sec)
0a753a76 737{
68dc0745
PP
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
PP
742}
743
68dc0745
PP
744/*
745 * redirected io subsystem for all XS modules
746 *
747 */
0a753a76 748
68dc0745
PP
749DllExport int *
750win32_errno(void)
0a753a76 751{
68dc0745 752 return (pIOSubSystem->pfnerrno());
0a753a76
PP
753}
754
dcb2879a
GS
755DllExport char ***
756win32_environ(void)
757{
758 return (pIOSubSystem->pfnenviron());
759}
760
68dc0745
PP
761/* the rest are the remapped stdio routines */
762DllExport FILE *
763win32_stderr(void)
0a753a76 764{
68dc0745 765 return (pIOSubSystem->pfnstderr());
0a753a76
PP
766}
767
68dc0745
PP
768DllExport FILE *
769win32_stdin(void)
0a753a76 770{
68dc0745 771 return (pIOSubSystem->pfnstdin());
0a753a76
PP
772}
773
68dc0745
PP
774DllExport FILE *
775win32_stdout()
0a753a76 776{
68dc0745 777 return (pIOSubSystem->pfnstdout());
0a753a76
PP
778}
779
68dc0745
PP
780DllExport int
781win32_ferror(FILE *fp)
0a753a76 782{
68dc0745 783 return (pIOSubSystem->pfnferror(fp));
0a753a76
PP
784}
785
786
68dc0745
PP
787DllExport int
788win32_feof(FILE *fp)
0a753a76 789{
68dc0745 790 return (pIOSubSystem->pfnfeof(fp));
0a753a76
PP
791}
792
68dc0745
PP
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
PP
798
799__declspec(thread) char strerror_buffer[512];
800
68dc0745
PP
801DllExport char *
802win32_strerror(int e)
0a753a76 803{
68dc0745
PP
804 extern int sys_nerr;
805 DWORD source = 0;
0a753a76 806
68dc0745
PP
807 if(e < 0 || e > sys_nerr) {
808 if(e < 0)
809 e = GetLastError();
0a753a76 810
68dc0745
PP
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
PP
815 return strerror_buffer;
816 }
817 return pIOSubSystem->pfnstrerror(e);
0a753a76
PP
818}
819
68dc0745
PP
820DllExport int
821win32_fprintf(FILE *fp, const char *format, ...)
0a753a76 822{
68dc0745
PP
823 va_list marker;
824 va_start(marker, format); /* Initialize variable arguments. */
0a753a76 825
68dc0745 826 return (pIOSubSystem->pfnvfprintf(fp, format, marker));
0a753a76
PP
827}
828
68dc0745
PP
829DllExport int
830win32_printf(const char *format, ...)
0a753a76 831{
68dc0745
PP
832 va_list marker;
833 va_start(marker, format); /* Initialize variable arguments. */
0a753a76 834
68dc0745 835 return (pIOSubSystem->pfnvprintf(format, marker));
0a753a76
PP
836}
837
68dc0745
PP
838DllExport int
839win32_vfprintf(FILE *fp, const char *format, va_list args)
0a753a76 840{
68dc0745 841 return (pIOSubSystem->pfnvfprintf(fp, format, args));
0a753a76
PP
842}
843
96e4d5b1
PP
844DllExport int
845win32_vprintf(const char *format, va_list args)
846{
847 return (pIOSubSystem->pfnvprintf(format, args));
848}
849
68dc0745
PP
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
PP
854}
855
68dc0745
PP
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
PP
860}
861
68dc0745
PP
862DllExport FILE *
863win32_fopen(const char *filename, const char *mode)
0a753a76 864{
68dc0745
PP
865 if (stricmp(filename, "/dev/null")==0)
866 return pIOSubSystem->pfnfopen("NUL", mode);
867 return pIOSubSystem->pfnfopen(filename, mode);
0a753a76
PP
868}
869
68dc0745
PP
870DllExport FILE *
871win32_fdopen( int handle, const char *mode)
0a753a76 872{
68dc0745 873 return pIOSubSystem->pfnfdopen(handle, mode);
0a753a76
PP
874}
875
68dc0745
PP
876DllExport FILE *
877win32_freopen( const char *path, const char *mode, FILE *stream)
0a753a76 878{
68dc0745
PP
879 if (stricmp(path, "/dev/null")==0)
880 return pIOSubSystem->pfnfreopen("NUL", mode, stream);
881 return pIOSubSystem->pfnfreopen(path, mode, stream);
0a753a76
PP
882}
883
68dc0745
PP
884DllExport int
885win32_fclose(FILE *pf)
0a753a76 886{
68dc0745 887 return pIOSubSystem->pfnfclose(pf);
0a753a76
PP
888}
889
68dc0745
PP
890DllExport int
891win32_fputs(const char *s,FILE *pf)
0a753a76 892{
68dc0745 893 return pIOSubSystem->pfnfputs(s, pf);
0a753a76
PP
894}
895
68dc0745
PP
896DllExport int
897win32_fputc(int c,FILE *pf)
0a753a76 898{
68dc0745 899 return pIOSubSystem->pfnfputc(c,pf);
0a753a76
PP
900}
901
68dc0745
PP
902DllExport int
903win32_ungetc(int c,FILE *pf)
0a753a76 904{
68dc0745 905 return pIOSubSystem->pfnungetc(c,pf);
0a753a76
PP
906}
907
68dc0745
PP
908DllExport int
909win32_getc(FILE *pf)
0a753a76 910{
68dc0745 911 return pIOSubSystem->pfngetc(pf);
0a753a76
PP
912}
913
68dc0745
PP
914DllExport int
915win32_fileno(FILE *pf)
0a753a76 916{
68dc0745 917 return pIOSubSystem->pfnfileno(pf);
0a753a76
PP
918}
919
68dc0745
PP
920DllExport void
921win32_clearerr(FILE *pf)
0a753a76 922{
68dc0745
PP
923 pIOSubSystem->pfnclearerr(pf);
924 return;
0a753a76
PP
925}
926
68dc0745
PP
927DllExport int
928win32_fflush(FILE *pf)
0a753a76 929{
68dc0745 930 return pIOSubSystem->pfnfflush(pf);
0a753a76
PP
931}
932
68dc0745
PP
933DllExport long
934win32_ftell(FILE *pf)
0a753a76 935{
68dc0745 936 return pIOSubSystem->pfnftell(pf);
0a753a76
PP
937}
938
68dc0745
PP
939DllExport int
940win32_fseek(FILE *pf,long offset,int origin)
0a753a76 941{
68dc0745 942 return pIOSubSystem->pfnfseek(pf, offset, origin);
0a753a76
PP
943}
944
68dc0745
PP
945DllExport int
946win32_fgetpos(FILE *pf,fpos_t *p)
0a753a76 947{
68dc0745 948 return pIOSubSystem->pfnfgetpos(pf, p);
0a753a76
PP
949}
950
68dc0745
PP
951DllExport int
952win32_fsetpos(FILE *pf,const fpos_t *p)
0a753a76 953{
68dc0745 954 return pIOSubSystem->pfnfsetpos(pf, p);
0a753a76
PP
955}
956
68dc0745
PP
957DllExport void
958win32_rewind(FILE *pf)
0a753a76 959{
68dc0745
PP
960 pIOSubSystem->pfnrewind(pf);
961 return;
0a753a76
PP
962}
963
68dc0745
PP
964DllExport FILE*
965win32_tmpfile(void)
0a753a76 966{
68dc0745 967 return pIOSubSystem->pfntmpfile();
0a753a76
PP
968}
969
68dc0745
PP
970DllExport void
971win32_abort(void)
0a753a76 972{
68dc0745
PP
973 pIOSubSystem->pfnabort();
974 return;
0a753a76
PP
975}
976
68dc0745
PP
977DllExport int
978win32_fstat(int fd,struct stat *bufptr)
0a753a76 979{
68dc0745 980 return pIOSubSystem->pfnfstat(fd,bufptr);
0a753a76
PP
981}
982
68dc0745
PP
983DllExport int
984win32_pipe(int *pfd, unsigned int size, int mode)
0a753a76 985{
68dc0745 986 return pIOSubSystem->pfnpipe(pfd, size, mode);
0a753a76
PP
987}
988
68dc0745
PP
989DllExport FILE*
990win32_popen(const char *command, const char *mode)
0a753a76 991{
68dc0745 992 return pIOSubSystem->pfnpopen(command, mode);
0a753a76
PP
993}
994
68dc0745
PP
995DllExport int
996win32_pclose(FILE *pf)
0a753a76 997{
68dc0745 998 return pIOSubSystem->pfnpclose(pf);
0a753a76
PP
999}
1000
68dc0745
PP
1001DllExport int
1002win32_setmode(int fd, int mode)
0a753a76 1003{
68dc0745 1004 return pIOSubSystem->pfnsetmode(fd, mode);
0a753a76
PP
1005}
1006
96e4d5b1
PP
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
PP
1019DllExport int
1020win32_open(const char *path, int flag, ...)
0a753a76 1021{
68dc0745
PP
1022 va_list ap;
1023 int pmode;
0a753a76
PP
1024
1025 va_start(ap, flag);
1026 pmode = va_arg(ap, int);
1027 va_end(ap);
1028
68dc0745
PP
1029 if (stricmp(path, "/dev/null")==0)
1030 return pIOSubSystem->pfnopen("NUL", flag, pmode);
1031 return pIOSubSystem->pfnopen(path,flag,pmode);
0a753a76
PP
1032}
1033
68dc0745
PP
1034DllExport int
1035win32_close(int fd)
0a753a76 1036{
68dc0745 1037 return pIOSubSystem->pfnclose(fd);
0a753a76
PP
1038}
1039
68dc0745 1040DllExport int
96e4d5b1
PP
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
PP
1050}
1051
68dc0745
PP
1052DllExport int
1053win32_dup2(int fd1,int fd2)
0a753a76 1054{
68dc0745 1055 return pIOSubSystem->pfndup2(fd1,fd2);
0a753a76
PP
1056}
1057
68dc0745
PP
1058DllExport int
1059win32_read(int fd, char *buf, unsigned int cnt)
0a753a76 1060{
68dc0745 1061 return pIOSubSystem->pfnread(fd, buf, cnt);
0a753a76
PP
1062}
1063
68dc0745
PP
1064DllExport int
1065win32_write(int fd, const char *buf, unsigned int cnt)
0a753a76 1066{
68dc0745 1067 return pIOSubSystem->pfnwrite(fd, buf, cnt);
0a753a76
PP
1068}
1069
68dc0745 1070DllExport int
5aabfad6
PP
1071win32_mkdir(const char *dir, int mode)
1072{
1073 return pIOSubSystem->pfnmkdir(dir); /* just ignore mode */
1074}
96e4d5b1 1075
5aabfad6
PP
1076DllExport int
1077win32_rmdir(const char *dir)
1078{
1079 return pIOSubSystem->pfnrmdir(dir);
1080}
96e4d5b1 1081
5aabfad6
PP
1082DllExport int
1083win32_chdir(const char *dir)
1084{
1085 return pIOSubSystem->pfnchdir(dir);
1086}
96e4d5b1 1087
5aabfad6 1088DllExport int
68dc0745
PP
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
PP
1093}
1094
68dc0745
PP
1095DllExport int
1096win32_spawnle(int mode, const char *cmdname, const char *arglist,...)
0a753a76 1097{
68dc0745
PP
1098 const char* const* envp;
1099 const char* const* argp;
0a753a76 1100
68dc0745
PP
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
PP
1106}
1107
68dc0745
PP
1108int
1109stolen_open_osfhandle(long handle, int flags)
0a753a76 1110{
68dc0745 1111 return pIOSubSystem->pfn_open_osfhandle(handle, flags);
0a753a76
PP
1112}
1113
68dc0745
PP
1114long
1115stolen_get_osfhandle(int fd)
0a753a76 1116{
68dc0745 1117 return pIOSubSystem->pfn_get_osfhandle(fd);
0a753a76 1118}