3 #define INCL_DOSFILEMGR
9 * Various Unix compatibility functions for OS/2
21 /*****************************************************************************/
22 /* 2.1 would not resolve symbols on demand, and has no ExtLIBPATH. */
23 static PFN ExtFCN[2]; /* Labeled by ord below. */
24 static USHORT loadOrd[2] = { 874, 873 }; /* Query=874, Set=873. */
25 #define ORD_QUERY_ELP 0
31 if (ExtFCN[ord] == NULL) {
32 static HMODULE hdosc = 0;
37 if ((!hdosc && CheckOSError(DosLoadModule(buf, sizeof buf,
39 || CheckOSError(DosQueryProcAddr(hdosc, loadOrd[ord], NULL, &fcn)))
40 die("This version of OS/2 does not support doscalls.%i",
44 if ((long)ExtFCN[ord] == -1) die("panic queryaddr");
48 static signed char priors[] = {0, 1, 3, 2}; /* Last two interchanged,
50 #define QSS_INI_BUFFER 1024
53 get_sysinfo(ULONG pid, ULONG flags)
56 ULONG rc, buf_len = QSS_INI_BUFFER;
58 New(1022, pbuffer, buf_len, char);
59 /* QSS_PROCESS | QSS_MODULE | QSS_SEMAPHORES | QSS_SHARED */
60 rc = QuerySysState(flags, pid, pbuffer, buf_len);
61 while (rc == ERROR_BUFFER_OVERFLOW) {
62 Renew(pbuffer, buf_len *= 2, char);
63 rc = QuerySysState(QSS_PROCESS, pid, pbuffer, buf_len);
70 return (PQTOPLEVEL)pbuffer;
73 #define PRIO_ERR 0x1111
81 psi = get_sysinfo(pid, QSS_PROCESS);
85 if (pid != psi->procdata->pid) {
87 croak("panic: wrong pid in sysinfo");
89 prio = psi->procdata->threads->priority;
95 setpriority(int which, int pid, int val)
100 prio = sys_prio(pid);
102 if (!(_emx_env & 0x200)) return 0; /* Nop if not OS/2. */
103 if (priors[(32 - val) >> 5] + 1 == (prio >> 8)) {
104 /* Do not change class. */
105 return CheckOSError(DosSetPriority((pid < 0)
106 ? PRTYS_PROCESSTREE : PRTYS_PROCESS,
108 (32 - val) % 32 - (prio & 0xFF),
111 } else /* if ((32 - val) % 32 == (prio & 0xFF)) */ {
112 /* Documentation claims one can change both class and basevalue,
113 * but I find it wrong. */
114 /* Change class, but since delta == 0 denotes absolute 0, correct. */
115 if (CheckOSError(DosSetPriority((pid < 0)
116 ? PRTYS_PROCESSTREE : PRTYS_PROCESS,
117 priors[(32 - val) >> 5] + 1,
121 if ( ((32 - val) % 32) == 0 ) return 0;
122 return CheckOSError(DosSetPriority((pid < 0)
123 ? PRTYS_PROCESSTREE : PRTYS_PROCESS,
129 /* else return CheckOSError(DosSetPriority((pid < 0) */
130 /* ? PRTYS_PROCESSTREE : PRTYS_PROCESS, */
131 /* priors[(32 - val) >> 5] + 1, */
132 /* (32 - val) % 32 - (prio & 0xFF), */
138 getpriority(int which /* ignored */, int pid)
144 if (!(_emx_env & 0x200)) return 0; /* Nop if not OS/2. */
145 /* DosGetInfoBlocks has old priority! */
146 /* if (CheckOSError(DosGetInfoBlocks(&tib, &pib))) return -1; */
147 /* if (pid != pib->pib_ulpid) { */
149 if (ret == PRIO_ERR) {
153 /* ret = tib->tib_ptib2->tib2_ulpri; */
154 return (1 - priors[((ret >> 8) - 1)])*32 - (ret & 0xFF);
157 /*****************************************************************************/
159 typedef void (*Sigfunc) _((int));
162 Sigfunc rsignal(signo,handler)
166 struct sigaction act,oact;
168 act.sa_handler = handler;
169 sigemptyset(&act.sa_mask);
171 if (sigaction(signo, &act, &oact) < 0)
174 return(oact.sa_handler);
178 result(int flag, int pid)
181 Signal_t (*ihand)(); /* place to save signal during system() */
182 Signal_t (*qhand)(); /* place to save signal during system() */
188 if (pid < 0 || flag != 0)
192 ihand = rsignal(SIGINT, SIG_IGN);
193 qhand = rsignal(SIGQUIT, SIG_IGN);
195 r = wait4pid(pid, &status, 0);
196 } while (r == -1 && errno == EINTR);
197 rsignal(SIGINT, ihand);
198 rsignal(SIGQUIT, qhand);
200 statusvalue = (U16)status;
203 return status & 0xFFFF;
205 ihand = rsignal(SIGINT, SIG_IGN);
206 r = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, &res, &rpid, pid);
207 rsignal(SIGINT, ihand);
208 statusvalue = res.codeResult << 8 | res.codeTerminate;
216 do_aspawn(really,mark,sp)
224 int flag = P_WAIT, trueflag;
227 New(401,Argv, sp - mark + 1, char*);
230 if (mark < sp && SvNIOKp(*(mark+1)) && !SvPOKp(*(mark+1))) {
235 while (++mark <= sp) {
237 *a++ = SvPVx(*mark, na);
247 if (strEQ(Argv[0],"/bin/sh")) Argv[0] = SH_PATH;
249 if (Argv[0][0] != '/' && Argv[0][0] != '\\'
250 && !(Argv[0][0] && Argv[0][1] == ':'
251 && (Argv[0][2] == '/' || Argv[0][2] != '\\'))
252 ) /* will swawnvp use PATH? */
253 TAINT_ENV(); /* testing IFS here is overkill, probably */
254 /* We should check PERL_SH* and PERLLIB_* as well? */
255 if (really && *(tmps = SvPV(really, na)))
256 rc = result(trueflag, spawnvp(flag,tmps,Argv));
258 rc = result(trueflag, spawnvp(flag,Argv[0],Argv));
260 if (rc < 0 && dowarn)
261 warn("Can't spawn \"%s\": %s", Argv[0], Strerror(errno));
262 if (rc < 0) rc = 255 << 8; /* Emulate the fork(). */
269 #define EXECF_SPAWN 0
271 #define EXECF_TRUEEXEC 2
272 #define EXECF_SPAWN_NOWAIT 3
275 do_spawn2(cmd, execf)
282 char *shell, *copt, *news = NULL;
286 if ((shell = getenv("EMXSHELL")) != NULL)
288 else if ((shell = getenv("SHELL")) != NULL)
290 else if ((shell = getenv("COMSPEC")) != NULL)
295 /* Consensus on perl5-porters is that it is _very_ important to
296 have a shell which will not change between computers with the
297 same architecture, to avoid "action on a distance".
298 And to have simple build, this shell should be sh. */
303 while (*cmd && isSPACE(*cmd))
306 if (strnEQ(cmd,"/bin/sh",7) && isSPACE(cmd[7])) {
307 STRLEN l = strlen(SH_PATH);
309 New(4545, news, strlen(cmd) - 7 + l, char);
310 strcpy(news, SH_PATH);
311 strcpy(news + l, cmd + 7);
315 /* save an extra exec if possible */
316 /* see if there are shell metacharacters in it */
318 if (*cmd == '.' && isSPACE(cmd[1]))
321 if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
324 for (s = cmd; *s && isALPHA(*s); s++) ; /* catch VAR=val gizmo */
328 for (s = cmd; *s; s++) {
329 if (*s != ' ' && !isALPHA(*s) && strchr("$&*(){}[]'\";\\|?<>~`\n",*s)) {
330 if (*s == '\n' && s[1] == '\0') {
335 if (execf == EXECF_TRUEEXEC)
336 return execl(shell,shell,copt,cmd,(char*)0);
337 else if (execf == EXECF_EXEC)
338 return spawnl(P_OVERLAY,shell,shell,copt,cmd,(char*)0);
339 else if (execf == EXECF_SPAWN_NOWAIT)
340 return spawnl(P_NOWAIT,shell,shell,copt,cmd,(char*)0);
341 /* In the ak code internal P_NOWAIT is P_WAIT ??? */
343 spawnl(P_NOWAIT,shell,shell,copt,cmd,(char*)0));
344 if (rc < 0 && dowarn)
345 warn("Can't %s \"%s\": %s",
346 (execf == EXECF_SPAWN ? "spawn" : "exec"),
347 shell, Strerror(errno));
348 if (rc < 0) rc = 255 << 8; /* Emulate the fork(). */
349 if (news) Safefree(news);
354 New(402,Argv, (s - cmd) / 2 + 2, char*);
355 Cmd = savepvn(cmd, s-cmd);
358 while (*s && isSPACE(*s)) s++;
361 while (*s && !isSPACE(*s)) s++;
367 if (execf == EXECF_TRUEEXEC)
368 rc = execvp(Argv[0],Argv);
369 else if (execf == EXECF_EXEC)
370 rc = spawnvp(P_OVERLAY,Argv[0],Argv);
371 else if (execf == EXECF_SPAWN_NOWAIT)
372 rc = spawnvp(P_NOWAIT,Argv[0],Argv);
374 rc = result(P_WAIT, spawnvp(P_NOWAIT,Argv[0],Argv));
375 if (rc < 0 && dowarn)
376 warn("Can't %s \"%s\": %s",
377 (execf == EXECF_SPAWN ? "spawn" : "exec"),
378 Argv[0], Strerror(errno));
379 if (rc < 0) rc = 255 << 8; /* Emulate the fork(). */
382 if (news) Safefree(news);
391 return do_spawn2(cmd, EXECF_SPAWN);
398 return do_spawn2(cmd, EXECF_SPAWN_NOWAIT);
405 return do_spawn2(cmd, EXECF_EXEC);
412 return do_spawn2(cmd, EXECF_TRUEEXEC);
416 my_syspopen(cmd,mode)
423 register I32 this, that, newfd;
424 register I32 pid, rc;
430 /* `this' is what we use in the parent, `that' in the child. */
431 this = (*mode == 'w');
435 taint_proper("Insecure %s%s", "EXEC");
437 /* Now we need to spawn the child. */
438 newfd = dup(*mode == 'r'); /* Preserve std* */
439 if (p[that] != (*mode == 'r')) {
440 dup2(p[that], *mode == 'r');
443 /* Where is `this' and newfd now? */
444 fcntl(p[this], F_SETFD, FD_CLOEXEC);
445 fcntl(newfd, F_SETFD, FD_CLOEXEC);
446 pid = do_spawn_nowait(cmd);
447 if (newfd != (*mode == 'r')) {
448 dup2(newfd, *mode == 'r'); /* Return std* back. */
456 if (p[that] < p[this]) {
457 dup2(p[this], p[that]);
461 sv = *av_fetch(fdpid,p[this],TRUE);
462 (void)SvUPGRADE(sv,SVt_IV);
465 return PerlIO_fdopen(p[this], mode);
467 #else /* USE_POPEN */
473 res = popen(cmd, mode);
475 char *shell = getenv("EMXSHELL");
477 my_setenv("EMXSHELL", SH_PATH);
478 res = popen(cmd, mode);
479 my_setenv("EMXSHELL", shell);
481 sv = *av_fetch(fdpid, PerlIO_fileno(res), TRUE);
482 (void)SvUPGRADE(sv,SVt_IV);
483 SvIVX(sv) = -1; /* A cooky. */
486 #endif /* USE_POPEN */
490 /******************************************************************/
496 die(no_func, "Unsupported function fork");
502 /*******************************************************************/
503 /* not implemented in EMX 0.9a */
505 void * ctermid(x) { return 0; }
507 #ifdef MYTTYNAME /* was not in emx0.9a */
508 void * ttyname(x) { return 0; }
511 /******************************************************************/
512 /* my socket forwarders - EMX lib only provides static forwarders */
514 static HMODULE htcp = 0;
522 if (!(_emx_env & 0x200)) croak("%s requires OS/2", name); /* Die if not OS/2. */
524 DosLoadModule(buf, sizeof buf, "tcp32dll", &htcp);
525 if (htcp && DosQueryProcAddr(htcp, 0, name, &fcn) == 0)
526 return (void *) ((void * (*)(void)) fcn) ();
531 tcp1(char *name, int arg)
536 if (!(_emx_env & 0x200)) croak("%s requires OS/2", name); /* Die if not OS/2. */
538 DosLoadModule(buf, sizeof buf, "tcp32dll", &htcp);
539 if (htcp && DosQueryProcAddr(htcp, 0, name, &fcn) == 0)
540 ((void (*)(int)) fcn) (arg);
543 void * gethostent() { return tcp0("GETHOSTENT"); }
544 void * getnetent() { return tcp0("GETNETENT"); }
545 void * getprotoent() { return tcp0("GETPROTOENT"); }
546 void * getservent() { return tcp0("GETSERVENT"); }
547 void sethostent(x) { tcp1("SETHOSTENT", x); }
548 void setnetent(x) { tcp1("SETNETENT", x); }
549 void setprotoent(x) { tcp1("SETPROTOENT", x); }
550 void setservent(x) { tcp1("SETSERVENT", x); }
551 void endhostent() { tcp0("ENDHOSTENT"); }
552 void endnetent() { tcp0("ENDNETENT"); }
553 void endprotoent() { tcp0("ENDPROTOENT"); }
554 void endservent() { tcp0("ENDSERVENT"); }
556 /*****************************************************************************/
557 /* not implemented in C Set++ */
560 int setuid(x) { errno = EINVAL; return -1; }
561 int setgid(x) { errno = EINVAL; return -1; }
564 /*****************************************************************************/
565 /* stat() hack for char/block device */
569 /* First attempt used DosQueryFSAttach which crashed the system when
570 used with 5.001. Now just look for /dev/. */
573 os2_stat(char *name, struct stat *st)
575 static int ino = SHRT_MAX;
577 if (stricmp(name, "/dev/con") != 0
578 && stricmp(name, "/dev/tty") != 0)
579 return stat(name, st);
581 memset(st, 0, sizeof *st);
582 st->st_mode = S_IFCHR|0666;
583 st->st_ino = (ino-- & 0x7FFF);
592 /* SBRK() emulation, mostly moved to malloc.c. */
595 sys_alloc(int size) {
597 APIRET rc = DosAllocMem(&got, size, PAG_COMMIT | PAG_WRITE);
599 if (rc == ERROR_NOT_ENOUGH_MEMORY) {
601 } else if ( rc ) die("Got an error from DosAllocMem: %li", (long)rc);
605 #endif /* USE_PERL_SBRK */
609 char *tmppath = TMPPATH1;
614 char *p = getenv("TMP"), *tpath;
617 if (!p) p = getenv("TEMP");
620 tpath = (char *)malloc(len + strlen(TMPPATH1) + 2);
623 strcpy(tpath + len + 1, TMPPATH1);
629 XS(XS_File__Copy_syscopy)
632 if (items < 2 || items > 3)
633 croak("Usage: File::Copy::syscopy(src,dst,flag=0)");
635 char * src = (char *)SvPV(ST(0),na);
636 char * dst = (char *)SvPV(ST(1),na);
643 flag = (unsigned long)SvIV(ST(2));
646 RETVAL = !CheckOSError(DosCopy(src, dst, flag));
647 ST(0) = sv_newmortal();
648 sv_setiv(ST(0), (IV)RETVAL);
657 static char fname[9];
658 int pos = 6, len, avlen;
659 unsigned int sum = 0;
664 if (!SvROK(sv)) croak("Not a reference given to mod2fname");
666 if (SvTYPE(sv) != SVt_PVAV)
667 croak("Not array reference given to mod2fname");
669 avlen = av_len((AV*)sv);
671 croak("Empty array reference given to mod2fname");
673 s = SvPV(*av_fetch((AV*)sv, avlen, FALSE), na);
674 strncpy(fname, s, 8);
676 if (len < 6) pos = len;
678 sum = 33 * sum + *(s++); /* Checksumming first chars to
679 * get the capitalization into c.s. */
683 s = SvPV(*av_fetch((AV*)sv, avlen, FALSE), na);
685 sum = 33 * sum + *(s++); /* 7 is primitive mod 13. */
689 fname[pos] = 'A' + (sum % 26);
690 fname[pos + 1] = 'A' + (sum / 26 % 26);
691 fname[pos + 2] = '\0';
692 return (char *)fname;
695 XS(XS_DynaLoader_mod2fname)
699 croak("Usage: DynaLoader::mod2fname(sv)");
704 RETVAL = mod2fname(sv);
705 ST(0) = sv_newmortal();
706 sv_setpv((SV*)ST(0), RETVAL);
714 static char buf[300];
717 if (!(_emx_env & 0x200)) return ""; /* Nop if not OS/2. */
720 if (DosGetMessage(NULL, 0, buf, sizeof buf - 1, rc, "OSO001.MSG", &len))
721 sprintf(buf, "OS/2 system error code %d=0x%x", rc, rc);
727 char sh_path[STATIC_FILE_LENGTH+1] = SH_PATH_INI;
730 perllib_mangle(char *s, unsigned int l)
732 static char *newp, *oldp;
733 static int newl, oldl, notfound;
734 static char ret[STATIC_FILE_LENGTH+1];
736 if (!newp && !notfound) {
737 newp = getenv("PERLLIB_PREFIX");
740 while (*newp && !isSPACE(*newp) && *newp != ';') {
741 newp++; oldl++; /* Skip digits. */
743 while (*newp && (isSPACE(*newp) || *newp == ';')) {
744 newp++; /* Skip whitespace. */
747 if (newl == 0 || oldl == 0) {
748 die("Malformed PERLLIB_PREFIX");
760 if (l < oldl || strnicmp(oldp, s, oldl) != 0) {
763 if (l + newl - oldl > STATIC_FILE_LENGTH || newl > STATIC_FILE_LENGTH) {
764 die("Malformed PERLLIB_PREFIX");
766 strncpy(ret, newp, newl);
767 strcpy(ret + newl, s + oldl);
771 extern void dlopen();
772 void *fakedl = &dlopen; /* Pull in dynaloading part. */
774 #define sys_is_absolute(path) ( isALPHA((path)[0]) && (path)[1] == ':' \
775 && ((path)[2] == '/' || (path)[2] == '\\'))
776 #define sys_is_rooted _fnisabs
777 #define sys_is_relative _fnisrel
778 #define current_drive _getdrive
780 #undef chdir /* Was _chdir2. */
781 #define sys_chdir(p) (chdir(p) == 0)
782 #define change_drive(d) (_chdrive(d), (current_drive() == toupper(d)))
784 XS(XS_Cwd_current_drive)
788 croak("Usage: Cwd::current_drive()");
792 RETVAL = current_drive();
793 ST(0) = sv_newmortal();
794 sv_setpvn(ST(0), (char *)&RETVAL, 1);
803 croak("Usage: Cwd::sys_chdir(path)");
805 char * path = (char *)SvPV(ST(0),na);
808 RETVAL = sys_chdir(path);
809 ST(0) = RETVAL ? &sv_yes : &sv_no;
810 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
815 XS(XS_Cwd_change_drive)
819 croak("Usage: Cwd::change_drive(d)");
821 char d = (char)*SvPV(ST(0),na);
824 RETVAL = change_drive(d);
825 ST(0) = RETVAL ? &sv_yes : &sv_no;
826 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
831 XS(XS_Cwd_sys_is_absolute)
835 croak("Usage: Cwd::sys_is_absolute(path)");
837 char * path = (char *)SvPV(ST(0),na);
840 RETVAL = sys_is_absolute(path);
841 ST(0) = RETVAL ? &sv_yes : &sv_no;
842 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
847 XS(XS_Cwd_sys_is_rooted)
851 croak("Usage: Cwd::sys_is_rooted(path)");
853 char * path = (char *)SvPV(ST(0),na);
856 RETVAL = sys_is_rooted(path);
857 ST(0) = RETVAL ? &sv_yes : &sv_no;
858 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
863 XS(XS_Cwd_sys_is_relative)
867 croak("Usage: Cwd::sys_is_relative(path)");
869 char * path = (char *)SvPV(ST(0),na);
872 RETVAL = sys_is_relative(path);
873 ST(0) = RETVAL ? &sv_yes : &sv_no;
874 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
883 croak("Usage: Cwd::sys_cwd()");
887 RETVAL = _getcwd2(p, MAXPATHLEN);
888 ST(0) = sv_newmortal();
889 sv_setpv((SV*)ST(0), RETVAL);
894 XS(XS_Cwd_sys_abspath)
897 if (items < 1 || items > 2)
898 croak("Usage: Cwd::sys_abspath(path, dir = NULL)");
900 char * path = (char *)SvPV(ST(0),na);
908 dir = (char *)SvPV(ST(1),na);
910 if (path[0] == '.' && (path[1] == '/' || path[1] == '\\')) {
914 if (_abspath(p, path, MAXPATHLEN) == 0) {
920 /* Absolute with drive: */
921 if ( sys_is_absolute(path) ) {
922 if (_abspath(p, path, MAXPATHLEN) == 0) {
927 } else if (path[0] == '/' || path[0] == '\\') {
928 /* Rooted, but maybe on different drive. */
929 if (isALPHA(dir[0]) && dir[1] == ':' ) {
932 /* Need to prepend the drive. */
935 Copy(path, p1 + 2, strlen(path) + 1, char);
937 if (_abspath(p, p1, MAXPATHLEN) == 0) {
942 } else if (_abspath(p, path, MAXPATHLEN) == 0) {
948 /* Either path is relative, or starts with a drive letter. */
949 /* If the path starts with a drive letter, then dir is
951 a/b) it is absolute/x:relative on the same drive.
952 c) path is on current drive, and dir is rooted
953 In all the cases it is safe to drop the drive part
955 if ( !sys_is_relative(path) ) {
958 if ( ( ( sys_is_absolute(dir)
959 || (isALPHA(dir[0]) && dir[1] == ':'
960 && strnicmp(dir, path,1) == 0))
961 && strnicmp(dir, path,1) == 0)
962 || ( !(isALPHA(dir[0]) && dir[1] == ':')
963 && toupper(path[0]) == current_drive())) {
965 } else if (_abspath(p, path, MAXPATHLEN) == 0) {
966 RETVAL = p; goto done;
968 RETVAL = NULL; goto done;
972 /* Need to prepend the absolute path of dir. */
975 if (_abspath(p1, dir, MAXPATHLEN) == 0) {
978 if (p1[ l - 1 ] != '/') {
982 Copy(path, p1 + l, strlen(path) + 1, char);
983 if (_abspath(p, p1, MAXPATHLEN) == 0) {
995 ST(0) = sv_newmortal();
996 sv_setpv((SV*)ST(0), RETVAL);
1000 typedef APIRET (*PELP)(PSZ path, ULONG type);
1003 ExtLIBPATH(ULONG ord, PSZ path, ULONG type)
1005 loadByOrd(ord); /* Guarantied to load or die! */
1006 return (*(PELP)ExtFCN[ord])(path, type);
1009 #define extLibpath(type) \
1010 (CheckOSError(ExtLIBPATH(ORD_QUERY_ELP, to, ((type) ? END_LIBPATH \
1011 : BEGIN_LIBPATH))) \
1014 #define extLibpath_set(p,type) \
1015 (!CheckOSError(ExtLIBPATH(ORD_SET_ELP, (p), ((type) ? END_LIBPATH \
1018 XS(XS_Cwd_extLibpath)
1021 if (items < 0 || items > 1)
1022 croak("Usage: Cwd::extLibpath(type = 0)");
1032 type = (int)SvIV(ST(0));
1035 RETVAL = extLibpath(type);
1036 ST(0) = sv_newmortal();
1037 sv_setpv((SV*)ST(0), RETVAL);
1042 XS(XS_Cwd_extLibpath_set)
1045 if (items < 1 || items > 2)
1046 croak("Usage: Cwd::extLibpath_set(s, type = 0)");
1048 char * s = (char *)SvPV(ST(0),na);
1056 type = (int)SvIV(ST(1));
1059 RETVAL = extLibpath_set(s, type);
1060 ST(0) = RETVAL ? &sv_yes : &sv_no;
1061 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
1069 char *file = __FILE__;
1073 if (_emx_env & 0x200) { /* OS/2 */
1074 newXS("File::Copy::syscopy", XS_File__Copy_syscopy, file);
1075 newXS("Cwd::extLibpath", XS_Cwd_extLibpath, file);
1076 newXS("Cwd::extLibpath_set", XS_Cwd_extLibpath_set, file);
1078 newXS("DynaLoader::mod2fname", XS_DynaLoader_mod2fname, file);
1079 newXS("Cwd::current_drive", XS_Cwd_current_drive, file);
1080 newXS("Cwd::sys_chdir", XS_Cwd_sys_chdir, file);
1081 newXS("Cwd::change_drive", XS_Cwd_change_drive, file);
1082 newXS("Cwd::sys_is_absolute", XS_Cwd_sys_is_absolute, file);
1083 newXS("Cwd::sys_is_rooted", XS_Cwd_sys_is_rooted, file);
1084 newXS("Cwd::sys_is_relative", XS_Cwd_sys_is_relative, file);
1085 newXS("Cwd::sys_cwd", XS_Cwd_sys_cwd, file);
1086 newXS("Cwd::sys_abspath", XS_Cwd_sys_abspath, file);
1087 gv = gv_fetchpv("OS2::is_aout", TRUE, SVt_PV);
1090 sv_setiv(GvSV(gv), 1);
1095 OS2_Perl_data_t OS2_Perl_data;
1103 OS2_Perl_data.xs_init = &Xs_OS2_init;
1104 if ( (shell = getenv("PERL_SH_DRIVE")) ) {
1105 sh_path[0] = shell[0];
1106 } else if ( (shell = getenv("PERL_SH_DIR")) ) {
1107 int l = strlen(shell);
1108 if (shell[l-1] == '/' || shell[l-1] == '\\') {
1111 if (l > STATIC_FILE_LENGTH - 7) {
1112 die("PERL_SH_DIR too long");
1114 strncpy(sh_path, shell, l);
1115 strcpy(sh_path + l, "/sh.exe");
1123 my_tmpnam (char *str)
1125 char *p = getenv("TMP"), *tpath;
1128 if (!p) p = getenv("TEMP");
1129 tpath = tempnam(p, "pltmp");
1143 if (s.st_mode & S_IWOTH) {
1146 return fopen(my_tmpnam(NULL), "w+b"); /* Race condition, but