home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / perl501m.zip / OS2 / os2.c < prev    next >
C/C++ Source or Header  |  1995-07-04  |  6KB  |  284 lines

  1. #define INCL_DOS
  2. #define INCL_NOPM
  3. #include <os2.h>
  4.  
  5. /*
  6.  * Various Unix compatibility functions for OS/2
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <errno.h>
  11. #include <limits.h>
  12. #include <process.h>
  13.  
  14. #include "EXTERN.h"
  15. #include "perl.h"
  16.  
  17. /*****************************************************************************/
  18. /* priorities */
  19.  
  20. int setpriority(int which, int pid, int val)
  21. {
  22.   return DosSetPriority((pid < 0) ? PRTYS_PROCESSTREE : PRTYS_PROCESS,
  23.             val >> 8, val & 0xFF, abs(pid));
  24. }
  25.  
  26. int getpriority(int which /* ignored */, int pid)
  27. {
  28.   TIB *tib;
  29.   PIB *pib;
  30.   DosGetInfoBlocks(&tib, &pib);
  31.   return tib->tib_ptib2->tib2_ulpri;
  32. }
  33.  
  34. /*****************************************************************************/
  35. /* spawn */
  36.  
  37. static int
  38. result(int flag, int pid)
  39. {
  40.     int r, status;
  41.     Signal_t (*ihand)();     /* place to save signal during system() */
  42.     Signal_t (*qhand)();     /* place to save signal during system() */
  43. #ifndef __EMX__
  44.     RESULTCODES res;
  45.     int rpid;
  46. #endif
  47.  
  48.     if (pid < 0 || flag != 0)
  49.         return pid;
  50.  
  51. #ifdef __EMX__
  52.     ihand = signal(SIGINT, SIG_IGN);
  53.     qhand = signal(SIGQUIT, SIG_IGN);
  54.     r = waitpid(pid, &status, 0);
  55.     signal(SIGINT, ihand);
  56.     signal(SIGQUIT, qhand);
  57.     statusvalue = (U16)status;
  58.     if (r < 0)
  59.         return -1;
  60.     return status & 0xFFFF;
  61. #else
  62.     ihand = signal(SIGINT, SIG_IGN);
  63.     r = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, &res, &rpid, pid);
  64.     signal(SIGINT, ihand);
  65.     statusvalue = res.codeResult << 8 | res.codeTerminate;
  66.     if (r)
  67.         return -1;
  68.     return statusvalue;
  69. #endif
  70. }
  71.  
  72. int
  73. do_aspawn(really,mark,sp)
  74. SV *really;
  75. register SV **mark;
  76. register SV **sp;
  77. {
  78.     register char **a;
  79.     char *tmps;
  80.     int rc;
  81.     int flag = P_WAIT, trueflag;
  82.  
  83.     if (sp > mark) {
  84.     New(401,Argv, sp - mark + 1, char*);
  85.     a = Argv;
  86.  
  87.     if (mark < sp && SvIOKp(*(mark+1))) {
  88.         ++mark;
  89.         flag = SvIVx(*mark);
  90.     }
  91.  
  92.     while (++mark <= sp) {
  93.         if (*mark)
  94.         *a++ = SvPVx(*mark, na);
  95.         else
  96.         *a++ = "";
  97.     }
  98.     *a = Nullch;
  99.  
  100.     trueflag = flag;
  101.     if (flag == P_WAIT)
  102.         flag = P_NOWAIT;
  103.  
  104.     if (really && *(tmps = SvPV(really, na)))
  105.         rc = result(trueflag, spawnvp(flag,tmps,Argv));
  106.     else
  107.         rc = result(trueflag, spawnvp(flag,Argv[0],Argv));
  108.  
  109.     if (rc < 0 && dowarn)
  110.         warn("Can't spawn \"%s\": %s", Argv[0], Strerror(errno));
  111.     } else
  112.         rc = -1;
  113.     do_execfree();
  114.     return rc;
  115. }
  116.  
  117. int
  118. do_spawn2(cmd, execf)
  119. char *cmd;
  120. {
  121.     register char **a;
  122.     register char *s;
  123.     char flags[10];
  124.     char *shell, *copt;
  125.     int rc;
  126.  
  127.     if ((shell = getenv("SHELL")) != NULL)
  128.         copt = "-c";
  129.     else if ((shell = getenv("COMSPEC")) != NULL)
  130.         copt = "/C";
  131.     else
  132.         shell = "cmd.exe";
  133.  
  134.     /* save an extra exec if possible */
  135.     /* see if there are shell metacharacters in it */
  136.  
  137.     /*SUPPRESS 530*/
  138.     if (*cmd == '@') {
  139.         ++cmd;
  140.         goto shell_cmd;
  141.     }
  142.     for (s = cmd; *s; s++) {
  143.     if (*s != ' ' && !isALPHA(*s) && strchr("%&|<>\n",*s)) {
  144.         if (*s == '\n' && !s[1]) {
  145.         *s = '\0';
  146.         break;
  147.         }
  148. shell_cmd:  if (execf)
  149.                 return spawnl(P_OVERLAY,shell,shell,copt,cmd,(char*)0);
  150.         return result(P_WAIT, spawnl(P_WAIT,shell,shell,copt,cmd,(char*)0));
  151.     }
  152.     }
  153.     New(402,Argv, (s - cmd) / 2 + 2, char*);
  154.     Cmd = savepvn(cmd, s-cmd);
  155.     a = Argv;
  156.     for (s = Cmd; *s;) {
  157.     while (*s && isSPACE(*s)) s++;
  158.     if (*s)
  159.         *(a++) = s;
  160.     while (*s && !isSPACE(*s)) s++;
  161.     if (*s)
  162.         *s++ = '\0';
  163.     }
  164.     *a = Nullch;
  165.     if (Argv[0]) {
  166.     if (execf)
  167.         rc = spawnvp(P_OVERLAY,Argv[0],Argv);
  168.         else
  169.         rc = result(P_WAIT, spawnvp(P_NOWAIT,Argv[0],Argv));
  170.     if (rc < 0 && dowarn)
  171.         warn("Can't spawn \"%s\": %s", Argv[0], Strerror(errno));
  172.     } else
  173.         rc = -1;
  174.     do_execfree();
  175.     return rc;
  176. }
  177.  
  178. int
  179. do_spawn(cmd)
  180. char *cmd;
  181. {
  182.     return do_spawn2(cmd, 0);
  183. }
  184.  
  185. bool
  186. do_exec(cmd)
  187. char *cmd;
  188. {
  189.     return do_spawn2(cmd, 1);
  190. }
  191.  
  192. /*****************************************************************************/
  193.  
  194. #ifndef HAS_FORK
  195. int
  196. fork(void)
  197. {
  198.     die(no_func, "Unsupported function fork");
  199.     errno = EINVAL;
  200.     return -1;
  201. }
  202. #endif
  203.  
  204. /*****************************************************************************/
  205. /* not implemented in EMX 0.9a */
  206.  
  207. void *    ctermid(x)    { return 0; }
  208. void *    ttyname(x)    { return 0; }
  209.  
  210. /*****************************************************************************/
  211. /* my socket forwarders - EMX lib only provides static forwarders */
  212.  
  213. static HMODULE htcp = 0;
  214.  
  215. static void *
  216. tcp0(char *name)
  217. {
  218.     static BYTE buf[20];
  219.     PFN fcn;
  220.     if (!htcp)
  221.     DosLoadModule(buf, sizeof buf, "tcp32dll", &htcp);
  222.     if (htcp && DosQueryProcAddr(htcp, 0, name, &fcn) == 0)
  223.     return (void *) ((void * (*)(void)) fcn) ();
  224.     return 0;
  225. }
  226.  
  227. static void
  228. tcp1(char *name, int arg)
  229. {
  230.     static BYTE buf[20];
  231.     PFN fcn;
  232.     if (!htcp)
  233.     DosLoadModule(buf, sizeof buf, "tcp32dll", &htcp);
  234.     if (htcp && DosQueryProcAddr(htcp, 0, name, &fcn) == 0)
  235.     ((void (*)(int)) fcn) (arg);
  236. }
  237.  
  238. void *    gethostent()    { return tcp0("GETHOSTENT");  }
  239. void *    getnetent()    { return tcp0("GETNETENT");   }
  240. void *    getprotoent()    { return tcp0("GETPROTOENT"); }
  241. void *    getservent()    { return tcp0("GETSERVENT");  }
  242. void    sethostent(x)    { tcp1("SETHOSTENT",  x); }
  243. void    setnetent(x)    { tcp1("SETNETENT",   x); }
  244. void    setprotoent(x)    { tcp1("SETPROTOENT", x); }
  245. void    setservent(x)    { tcp1("SETSERVENT",  x); }
  246. void    endhostent()    { tcp0("ENDHOSTENT");  }
  247. void    endnetent()    { tcp0("ENDNETENT");   }
  248. void    endprotoent()    { tcp0("ENDPROTOENT"); }
  249. void    endservent()    { tcp0("ENDSERVENT");  }
  250.  
  251. /*****************************************************************************/
  252. /* not implemented in C Set++ */
  253.  
  254. #ifndef __EMX__
  255. int    setuid(x)    { errno = EINVAL; return -1; }
  256. int    setgid(x)    { errno = EINVAL; return -1; }
  257. #endif
  258.  
  259. /*****************************************************************************/
  260. /* stat() hack for char/block device */
  261.  
  262. #if OS2_STAT_HACK
  263.  
  264.     /* First attempt used DosQueryFSAttach which crashed the system when
  265.        used with 5.001. Now just look for /dev/. */
  266.  
  267. int
  268. os2_stat(char *name, struct stat *st)
  269. {
  270.     static int ino = SHRT_MAX;
  271.  
  272.     if (stricmp(name, "/dev/con") != 0
  273.      && stricmp(name, "/dev/tty") != 0)
  274.     return stat(name, st);
  275.  
  276.     memset(st, 0, sizeof *st);
  277.     st->st_mode = S_IFCHR|0666;
  278.     st->st_ino = (ino-- & 0x7FFF);
  279.     st->st_nlink = 1;
  280.     return 0;
  281. }
  282.  
  283. #endif
  284.