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(1322, 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(flags, 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 result(int flag, int pid)
165 Signal_t (*ihand)(); /* place to save signal during system() */
166 Signal_t (*qhand)(); /* place to save signal during system() */
172 if (pid < 0 || flag != 0)
176 ihand = rsignal(SIGINT, SIG_IGN);
177 qhand = rsignal(SIGQUIT, SIG_IGN);
179 r = wait4pid(pid, &status, 0);
180 } while (r == -1 && errno == EINTR);
181 rsignal(SIGINT, ihand);
182 rsignal(SIGQUIT, qhand);
184 statusvalue = (U16)status;
187 return status & 0xFFFF;
189 ihand = rsignal(SIGINT, SIG_IGN);
190 r = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, &res, &rpid, pid);
191 rsignal(SIGINT, ihand);
192 statusvalue = res.codeResult << 8 | res.codeTerminate;
200 do_aspawn(really,mark,sp)
208 int flag = P_WAIT, trueflag, err, secondtry = 0;
211 New(1301,Argv, sp - mark + 3, char*);
214 if (mark < sp && SvNIOKp(*(mark+1)) && !SvPOKp(*(mark+1))) {
219 while (++mark <= sp) {
221 *a++ = SvPVx(*mark, na);
231 if (strEQ(Argv[0],"/bin/sh")) Argv[0] = sh_path;
233 if (Argv[0][0] != '/' && Argv[0][0] != '\\'
234 && !(Argv[0][0] && Argv[0][1] == ':'
235 && (Argv[0][2] == '/' || Argv[0][2] != '\\'))
236 ) /* will swawnvp use PATH? */
237 TAINT_ENV(); /* testing IFS here is overkill, probably */
238 /* We should check PERL_SH* and PERLLIB_* as well? */
240 if (really && *(tmps = SvPV(really, na)))
241 rc = result(trueflag, spawnvp(flag,tmps,Argv));
243 rc = result(trueflag, spawnvp(flag,Argv[0],Argv));
245 if (rc < 0 && secondtry == 0
246 && (!tmps || !*tmps)) { /* Cannot transfer `really' via shell. */
248 if (err == ENOENT) { /* No such file. */
249 /* One reason may be that EMX added .exe. We suppose
250 that .exe-less files are automatically shellable. */
252 (no_dir = strrchr(Argv[0], '/'))
253 || (no_dir = strrchr(Argv[0], '\\'))
254 || (no_dir = Argv[0]);
255 if (!strchr(no_dir, '.')) {
257 if (stat(Argv[0], &buffer) != -1) { /* File exists. */
258 /* Maybe we need to specify the full name here? */
262 } else if (err == ENOEXEC) { /* Need to send to shell. */
274 if (rc < 0 && dowarn)
275 warn("Can't spawn \"%s\": %s", Argv[0], Strerror(errno));
276 if (rc < 0) rc = 255 << 8; /* Emulate the fork(). */
283 #define EXECF_SPAWN 0
285 #define EXECF_TRUEEXEC 2
286 #define EXECF_SPAWN_NOWAIT 3
289 do_spawn2(cmd, execf)
296 char *shell, *copt, *news = NULL;
297 int rc, added_shell = 0, err;
298 char fullcmd[MAXNAMLEN + 1];
301 if ((shell = getenv("EMXSHELL")) != NULL)
303 else if ((shell = getenv("SHELL")) != NULL)
305 else if ((shell = getenv("COMSPEC")) != NULL)
310 /* Consensus on perl5-porters is that it is _very_ important to
311 have a shell which will not change between computers with the
312 same architecture, to avoid "action on a distance".
313 And to have simple build, this shell should be sh. */
318 while (*cmd && isSPACE(*cmd))
321 if (strnEQ(cmd,"/bin/sh",7) && isSPACE(cmd[7])) {
322 STRLEN l = strlen(sh_path);
324 New(1302, news, strlen(cmd) - 7 + l + 1, char);
325 strcpy(news, sh_path);
326 strcpy(news + l, cmd + 7);
331 /* save an extra exec if possible */
332 /* see if there are shell metacharacters in it */
334 if (*cmd == '.' && isSPACE(cmd[1]))
337 if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
340 for (s = cmd; *s && isALPHA(*s); s++) ; /* catch VAR=val gizmo */
344 for (s = cmd; *s; s++) {
345 if (*s != ' ' && !isALPHA(*s) && strchr("$&*(){}[]'\";\\|?<>~`\n",*s)) {
346 if (*s == '\n' && s[1] == '\0') {
351 if (execf == EXECF_TRUEEXEC)
352 return execl(shell,shell,copt,cmd,(char*)0);
353 else if (execf == EXECF_EXEC)
354 return spawnl(P_OVERLAY,shell,shell,copt,cmd,(char*)0);
355 else if (execf == EXECF_SPAWN_NOWAIT)
356 return spawnl(P_NOWAIT,shell,shell,copt,cmd,(char*)0);
357 /* In the ak code internal P_NOWAIT is P_WAIT ??? */
359 spawnl(P_NOWAIT,shell,shell,copt,cmd,(char*)0));
360 if (rc < 0 && dowarn)
361 warn("Can't %s \"%s\": %s",
362 (execf == EXECF_SPAWN ? "spawn" : "exec"),
363 shell, Strerror(errno));
364 if (rc < 0) rc = 255 << 8; /* Emulate the fork(). */
365 if (news) Safefree(news);
370 New(1303,Argv, (s - cmd) / 2 + 2, char*);
371 Cmd = savepvn(cmd, s-cmd);
374 while (*s && isSPACE(*s)) s++;
377 while (*s && !isSPACE(*s)) s++;
385 if (execf == EXECF_TRUEEXEC)
386 rc = execvp(Argv[0],Argv);
387 else if (execf == EXECF_EXEC)
388 rc = spawnvp(P_OVERLAY,Argv[0],Argv);
389 else if (execf == EXECF_SPAWN_NOWAIT)
390 rc = spawnvp(P_NOWAIT,Argv[0],Argv);
392 rc = result(P_WAIT, spawnvp(P_NOWAIT,Argv[0],Argv));
395 if (err == ENOENT) { /* No such file. */
396 /* One reason may be that EMX added .exe. We suppose
397 that .exe-less files are automatically shellable. */
399 (no_dir = strrchr(Argv[0], '/'))
400 || (no_dir = strrchr(Argv[0], '\\'))
401 || (no_dir = Argv[0]);
402 if (!strchr(no_dir, '.')) {
404 if (stat(Argv[0], &buffer) != -1) { /* File exists. */
405 /* Maybe we need to specify the full name here? */
409 } else if (err == ENOEXEC) { /* Need to send to shell. */
413 if (rc < 0 && dowarn)
414 warn("Can't %s \"%s\": %s",
415 ((execf != EXECF_EXEC && execf != EXECF_TRUEEXEC)
417 Argv[0], Strerror(err));
418 if (rc < 0) rc = 255 << 8; /* Emulate the fork(). */
421 if (news) Safefree(news);
430 return do_spawn2(cmd, EXECF_SPAWN);
437 return do_spawn2(cmd, EXECF_SPAWN_NOWAIT);
444 return do_spawn2(cmd, EXECF_EXEC);
451 return do_spawn2(cmd, EXECF_TRUEEXEC);
455 my_syspopen(cmd,mode)
462 register I32 this, that, newfd;
463 register I32 pid, rc;
469 /* `this' is what we use in the parent, `that' in the child. */
470 this = (*mode == 'w');
474 taint_proper("Insecure %s%s", "EXEC");
476 /* Now we need to spawn the child. */
477 newfd = dup(*mode == 'r'); /* Preserve std* */
478 if (p[that] != (*mode == 'r')) {
479 dup2(p[that], *mode == 'r');
482 /* Where is `this' and newfd now? */
483 fcntl(p[this], F_SETFD, FD_CLOEXEC);
484 fcntl(newfd, F_SETFD, FD_CLOEXEC);
485 pid = do_spawn_nowait(cmd);
486 if (newfd != (*mode == 'r')) {
487 dup2(newfd, *mode == 'r'); /* Return std* back. */
495 if (p[that] < p[this]) {
496 dup2(p[this], p[that]);
500 sv = *av_fetch(fdpid,p[this],TRUE);
501 (void)SvUPGRADE(sv,SVt_IV);
504 return PerlIO_fdopen(p[this], mode);
506 #else /* USE_POPEN */
512 res = popen(cmd, mode);
514 char *shell = getenv("EMXSHELL");
516 my_setenv("EMXSHELL", sh_path);
517 res = popen(cmd, mode);
518 my_setenv("EMXSHELL", shell);
520 sv = *av_fetch(fdpid, PerlIO_fileno(res), TRUE);
521 (void)SvUPGRADE(sv,SVt_IV);
522 SvIVX(sv) = -1; /* A cooky. */
525 #endif /* USE_POPEN */
529 /******************************************************************/
535 die(no_func, "Unsupported function fork");
541 /*******************************************************************/
542 /* not implemented in EMX 0.9a */
544 void * ctermid(x) { return 0; }
546 #ifdef MYTTYNAME /* was not in emx0.9a */
547 void * ttyname(x) { return 0; }
550 /******************************************************************/
551 /* my socket forwarders - EMX lib only provides static forwarders */
553 static HMODULE htcp = 0;
561 if (!(_emx_env & 0x200)) croak("%s requires OS/2", name); /* Die if not OS/2. */
563 DosLoadModule(buf, sizeof buf, "tcp32dll", &htcp);
564 if (htcp && DosQueryProcAddr(htcp, 0, name, &fcn) == 0)
565 return (void *) ((void * (*)(void)) fcn) ();
570 tcp1(char *name, int arg)
575 if (!(_emx_env & 0x200)) croak("%s requires OS/2", name); /* Die if not OS/2. */
577 DosLoadModule(buf, sizeof buf, "tcp32dll", &htcp);
578 if (htcp && DosQueryProcAddr(htcp, 0, name, &fcn) == 0)
579 ((void (*)(int)) fcn) (arg);
582 void * gethostent() { return tcp0("GETHOSTENT"); }
583 void * getnetent() { return tcp0("GETNETENT"); }
584 void * getprotoent() { return tcp0("GETPROTOENT"); }
585 void * getservent() { return tcp0("GETSERVENT"); }
586 void sethostent(x) { tcp1("SETHOSTENT", x); }
587 void setnetent(x) { tcp1("SETNETENT", x); }
588 void setprotoent(x) { tcp1("SETPROTOENT", x); }
589 void setservent(x) { tcp1("SETSERVENT", x); }
590 void endhostent() { tcp0("ENDHOSTENT"); }
591 void endnetent() { tcp0("ENDNETENT"); }
592 void endprotoent() { tcp0("ENDPROTOENT"); }
593 void endservent() { tcp0("ENDSERVENT"); }
595 /*****************************************************************************/
596 /* not implemented in C Set++ */
599 int setuid(x) { errno = EINVAL; return -1; }
600 int setgid(x) { errno = EINVAL; return -1; }
603 /*****************************************************************************/
604 /* stat() hack for char/block device */
608 /* First attempt used DosQueryFSAttach which crashed the system when
609 used with 5.001. Now just look for /dev/. */
612 os2_stat(char *name, struct stat *st)
614 static int ino = SHRT_MAX;
616 if (stricmp(name, "/dev/con") != 0
617 && stricmp(name, "/dev/tty") != 0)
618 return stat(name, st);
620 memset(st, 0, sizeof *st);
621 st->st_mode = S_IFCHR|0666;
622 st->st_ino = (ino-- & 0x7FFF);
631 /* SBRK() emulation, mostly moved to malloc.c. */
634 sys_alloc(int size) {
636 APIRET rc = DosAllocMem(&got, size, PAG_COMMIT | PAG_WRITE);
638 if (rc == ERROR_NOT_ENOUGH_MEMORY) {
640 } else if ( rc ) die("Got an error from DosAllocMem: %li", (long)rc);
644 #endif /* USE_PERL_SBRK */
648 char *tmppath = TMPPATH1;
653 char *p = getenv("TMP"), *tpath;
656 if (!p) p = getenv("TEMP");
659 tpath = (char *)malloc(len + strlen(TMPPATH1) + 2);
662 strcpy(tpath + len + 1, TMPPATH1);
668 XS(XS_File__Copy_syscopy)
671 if (items < 2 || items > 3)
672 croak("Usage: File::Copy::syscopy(src,dst,flag=0)");
674 char * src = (char *)SvPV(ST(0),na);
675 char * dst = (char *)SvPV(ST(1),na);
682 flag = (unsigned long)SvIV(ST(2));
685 RETVAL = !CheckOSError(DosCopy(src, dst, flag));
686 ST(0) = sv_newmortal();
687 sv_setiv(ST(0), (IV)RETVAL);
696 static char fname[9];
697 int pos = 6, len, avlen;
698 unsigned int sum = 0;
703 if (!SvROK(sv)) croak("Not a reference given to mod2fname");
705 if (SvTYPE(sv) != SVt_PVAV)
706 croak("Not array reference given to mod2fname");
708 avlen = av_len((AV*)sv);
710 croak("Empty array reference given to mod2fname");
712 s = SvPV(*av_fetch((AV*)sv, avlen, FALSE), na);
713 strncpy(fname, s, 8);
715 if (len < 6) pos = len;
717 sum = 33 * sum + *(s++); /* Checksumming first chars to
718 * get the capitalization into c.s. */
722 s = SvPV(*av_fetch((AV*)sv, avlen, FALSE), na);
724 sum = 33 * sum + *(s++); /* 7 is primitive mod 13. */
728 fname[pos] = 'A' + (sum % 26);
729 fname[pos + 1] = 'A' + (sum / 26 % 26);
730 fname[pos + 2] = '\0';
731 return (char *)fname;
734 XS(XS_DynaLoader_mod2fname)
738 croak("Usage: DynaLoader::mod2fname(sv)");
743 RETVAL = mod2fname(sv);
744 ST(0) = sv_newmortal();
745 sv_setpv((SV*)ST(0), RETVAL);
753 static char buf[300];
756 if (!(_emx_env & 0x200)) return ""; /* Nop if not OS/2. */
759 if (DosGetMessage(NULL, 0, buf, sizeof buf - 1, rc, "OSO001.MSG", &len))
760 sprintf(buf, "OS/2 system error code %d=0x%x", rc, rc);
767 perllib_mangle(char *s, unsigned int l)
769 static char *newp, *oldp;
770 static int newl, oldl, notfound;
771 static char ret[STATIC_FILE_LENGTH+1];
773 if (!newp && !notfound) {
774 newp = getenv("PERLLIB_PREFIX");
779 while (*newp && !isSPACE(*newp) && *newp != ';') {
780 newp++; oldl++; /* Skip digits. */
782 while (*newp && (isSPACE(*newp) || *newp == ';')) {
783 newp++; /* Skip whitespace. */
786 if (newl == 0 || oldl == 0) {
787 die("Malformed PERLLIB_PREFIX");
792 if (*s == '\\') *s = '/';
805 if (l < oldl || strnicmp(oldp, s, oldl) != 0) {
808 if (l + newl - oldl > STATIC_FILE_LENGTH || newl > STATIC_FILE_LENGTH) {
809 die("Malformed PERLLIB_PREFIX");
811 strcpy(ret + newl, s + oldl);
815 extern void dlopen();
816 void *fakedl = &dlopen; /* Pull in dynaloading part. */
818 #define sys_is_absolute(path) ( isALPHA((path)[0]) && (path)[1] == ':' \
819 && ((path)[2] == '/' || (path)[2] == '\\'))
820 #define sys_is_rooted _fnisabs
821 #define sys_is_relative _fnisrel
822 #define current_drive _getdrive
824 #undef chdir /* Was _chdir2. */
825 #define sys_chdir(p) (chdir(p) == 0)
826 #define change_drive(d) (_chdrive(d), (current_drive() == toupper(d)))
828 XS(XS_Cwd_current_drive)
832 croak("Usage: Cwd::current_drive()");
836 RETVAL = current_drive();
837 ST(0) = sv_newmortal();
838 sv_setpvn(ST(0), (char *)&RETVAL, 1);
847 croak("Usage: Cwd::sys_chdir(path)");
849 char * path = (char *)SvPV(ST(0),na);
852 RETVAL = sys_chdir(path);
853 ST(0) = boolSV(RETVAL);
854 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
859 XS(XS_Cwd_change_drive)
863 croak("Usage: Cwd::change_drive(d)");
865 char d = (char)*SvPV(ST(0),na);
868 RETVAL = change_drive(d);
869 ST(0) = boolSV(RETVAL);
870 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
875 XS(XS_Cwd_sys_is_absolute)
879 croak("Usage: Cwd::sys_is_absolute(path)");
881 char * path = (char *)SvPV(ST(0),na);
884 RETVAL = sys_is_absolute(path);
885 ST(0) = boolSV(RETVAL);
886 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
891 XS(XS_Cwd_sys_is_rooted)
895 croak("Usage: Cwd::sys_is_rooted(path)");
897 char * path = (char *)SvPV(ST(0),na);
900 RETVAL = sys_is_rooted(path);
901 ST(0) = boolSV(RETVAL);
902 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
907 XS(XS_Cwd_sys_is_relative)
911 croak("Usage: Cwd::sys_is_relative(path)");
913 char * path = (char *)SvPV(ST(0),na);
916 RETVAL = sys_is_relative(path);
917 ST(0) = boolSV(RETVAL);
918 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
927 croak("Usage: Cwd::sys_cwd()");
931 RETVAL = _getcwd2(p, MAXPATHLEN);
932 ST(0) = sv_newmortal();
933 sv_setpv((SV*)ST(0), RETVAL);
938 XS(XS_Cwd_sys_abspath)
941 if (items < 1 || items > 2)
942 croak("Usage: Cwd::sys_abspath(path, dir = NULL)");
944 char * path = (char *)SvPV(ST(0),na);
952 dir = (char *)SvPV(ST(1),na);
954 if (path[0] == '.' && (path[1] == '/' || path[1] == '\\')) {
958 if (_abspath(p, path, MAXPATHLEN) == 0) {
964 /* Absolute with drive: */
965 if ( sys_is_absolute(path) ) {
966 if (_abspath(p, path, MAXPATHLEN) == 0) {
971 } else if (path[0] == '/' || path[0] == '\\') {
972 /* Rooted, but maybe on different drive. */
973 if (isALPHA(dir[0]) && dir[1] == ':' ) {
976 /* Need to prepend the drive. */
979 Copy(path, p1 + 2, strlen(path) + 1, char);
981 if (_abspath(p, p1, MAXPATHLEN) == 0) {
986 } else if (_abspath(p, path, MAXPATHLEN) == 0) {
992 /* Either path is relative, or starts with a drive letter. */
993 /* If the path starts with a drive letter, then dir is
995 a/b) it is absolute/x:relative on the same drive.
996 c) path is on current drive, and dir is rooted
997 In all the cases it is safe to drop the drive part
999 if ( !sys_is_relative(path) ) {
1002 if ( ( ( sys_is_absolute(dir)
1003 || (isALPHA(dir[0]) && dir[1] == ':'
1004 && strnicmp(dir, path,1) == 0))
1005 && strnicmp(dir, path,1) == 0)
1006 || ( !(isALPHA(dir[0]) && dir[1] == ':')
1007 && toupper(path[0]) == current_drive())) {
1009 } else if (_abspath(p, path, MAXPATHLEN) == 0) {
1010 RETVAL = p; goto done;
1012 RETVAL = NULL; goto done;
1016 /* Need to prepend the absolute path of dir. */
1017 char p1[MAXPATHLEN];
1019 if (_abspath(p1, dir, MAXPATHLEN) == 0) {
1022 if (p1[ l - 1 ] != '/') {
1026 Copy(path, p1 + l, strlen(path) + 1, char);
1027 if (_abspath(p, p1, MAXPATHLEN) == 0) {
1039 ST(0) = sv_newmortal();
1040 sv_setpv((SV*)ST(0), RETVAL);
1044 typedef APIRET (*PELP)(PSZ path, ULONG type);
1047 ExtLIBPATH(ULONG ord, PSZ path, ULONG type)
1049 loadByOrd(ord); /* Guarantied to load or die! */
1050 return (*(PELP)ExtFCN[ord])(path, type);
1053 #define extLibpath(type) \
1054 (CheckOSError(ExtLIBPATH(ORD_QUERY_ELP, to, ((type) ? END_LIBPATH \
1055 : BEGIN_LIBPATH))) \
1058 #define extLibpath_set(p,type) \
1059 (!CheckOSError(ExtLIBPATH(ORD_SET_ELP, (p), ((type) ? END_LIBPATH \
1062 XS(XS_Cwd_extLibpath)
1065 if (items < 0 || items > 1)
1066 croak("Usage: Cwd::extLibpath(type = 0)");
1076 type = (int)SvIV(ST(0));
1079 RETVAL = extLibpath(type);
1080 ST(0) = sv_newmortal();
1081 sv_setpv((SV*)ST(0), RETVAL);
1086 XS(XS_Cwd_extLibpath_set)
1089 if (items < 1 || items > 2)
1090 croak("Usage: Cwd::extLibpath_set(s, type = 0)");
1092 char * s = (char *)SvPV(ST(0),na);
1100 type = (int)SvIV(ST(1));
1103 RETVAL = extLibpath_set(s, type);
1104 ST(0) = boolSV(RETVAL);
1105 if (SvREFCNT(ST(0))) sv_2mortal(ST(0));
1113 char *file = __FILE__;
1117 if (_emx_env & 0x200) { /* OS/2 */
1118 newXS("File::Copy::syscopy", XS_File__Copy_syscopy, file);
1119 newXS("Cwd::extLibpath", XS_Cwd_extLibpath, file);
1120 newXS("Cwd::extLibpath_set", XS_Cwd_extLibpath_set, file);
1122 newXS("DynaLoader::mod2fname", XS_DynaLoader_mod2fname, file);
1123 newXS("Cwd::current_drive", XS_Cwd_current_drive, file);
1124 newXS("Cwd::sys_chdir", XS_Cwd_sys_chdir, file);
1125 newXS("Cwd::change_drive", XS_Cwd_change_drive, file);
1126 newXS("Cwd::sys_is_absolute", XS_Cwd_sys_is_absolute, file);
1127 newXS("Cwd::sys_is_rooted", XS_Cwd_sys_is_rooted, file);
1128 newXS("Cwd::sys_is_relative", XS_Cwd_sys_is_relative, file);
1129 newXS("Cwd::sys_cwd", XS_Cwd_sys_cwd, file);
1130 newXS("Cwd::sys_abspath", XS_Cwd_sys_abspath, file);
1131 gv = gv_fetchpv("OS2::is_aout", TRUE, SVt_PV);
1134 sv_setiv(GvSV(gv), 1);
1139 OS2_Perl_data_t OS2_Perl_data;
1142 Perl_OS2_init(char **env)
1147 OS2_Perl_data.xs_init = &Xs_OS2_init;
1148 if (environ == NULL) {
1151 if ( (shell = getenv("PERL_SH_DRIVE")) ) {
1152 New(1304, sh_path, strlen(SH_PATH) + 1, char);
1153 strcpy(sh_path, SH_PATH);
1154 sh_path[0] = shell[0];
1155 } else if ( (shell = getenv("PERL_SH_DIR")) ) {
1156 int l = strlen(shell), i;
1157 if (shell[l-1] == '/' || shell[l-1] == '\\') {
1160 New(1304, sh_path, l + 8, char);
1161 strncpy(sh_path, shell, l);
1162 strcpy(sh_path + l, "/sh.exe");
1163 for (i = 0; i < l; i++) {
1164 if (sh_path[i] == '\\') sh_path[i] = '/';
1173 my_tmpnam (char *str)
1175 char *p = getenv("TMP"), *tpath;
1178 if (!p) p = getenv("TEMP");
1179 tpath = tempnam(p, "pltmp");
1193 if (s.st_mode & S_IWOTH) {
1196 return fopen(my_tmpnam(NULL), "w+b"); /* Race condition, but
1202 /* This code was contributed by Rocco Caputo. */
1204 my_flock(int handle, int op)
1206 FILELOCK rNull, rFull;
1207 ULONG timeout, handle_type, flag_word;
1209 int blocking, shared;
1210 static int use_my = -1;
1213 char *s = getenv("USE_PERL_FLOCK");
1219 if (!(_emx_env & 0x200) || !use_my)
1220 return flock(handle, op); /* Delegate to EMX. */
1223 if ((DosQueryHType(handle, &handle_type, &flag_word) != 0) ||
1224 (handle_type & 0xFF))
1229 // set lock/unlock ranges
1230 rNull.lOffset = rNull.lRange = rFull.lOffset = 0;
1231 rFull.lRange = 0x7FFFFFFF;
1232 // set timeout for blocking
1233 timeout = ((blocking = !(op & LOCK_NB))) ? 100 : 1;
1234 // shared or exclusive?
1235 shared = (op & LOCK_SH) ? 1 : 0;
1236 // do not block the unlock
1237 if (op & (LOCK_UN | LOCK_SH | LOCK_EX)) {
1238 rc = DosSetFileLocks(handle, &rFull, &rNull, timeout, shared);
1243 case ERROR_INVALID_HANDLE:
1246 case ERROR_SHARING_BUFFER_EXCEEDED:
1249 case ERROR_LOCK_VIOLATION:
1250 break; // not an error
1251 case ERROR_INVALID_PARAMETER:
1252 case ERROR_ATOMIC_LOCK_NOT_SUPPORTED:
1253 case ERROR_READ_LOCKS_NOT_SUPPORTED:
1256 case ERROR_INTERRUPT:
1265 if (op & (LOCK_SH | LOCK_EX)) {
1266 // for blocking operations
1280 case ERROR_INVALID_HANDLE:
1283 case ERROR_SHARING_BUFFER_EXCEEDED:
1286 case ERROR_LOCK_VIOLATION:
1288 errno = EWOULDBLOCK;
1292 case ERROR_INVALID_PARAMETER:
1293 case ERROR_ATOMIC_LOCK_NOT_SUPPORTED:
1294 case ERROR_READ_LOCKS_NOT_SUPPORTED:
1297 case ERROR_INTERRUPT:
1304 // give away timeslice