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