Updated.
[p5sagit/p5-mst-13.2.git] / os2 / os2.c
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
44         if (pid < 0 || flag != 0)
45                 return pid;
46
47         ihand = signal(SIGINT, SIG_IGN);
48         qhand = signal(SIGQUIT, SIG_IGN);
49         r = waitpid(pid, &status, 0);
50         signal(SIGINT, ihand);
51         signal(SIGQUIT, qhand);
52
53         statusvalue = (U16)status;
54         if (r < 0)
55                 return -1;
56         return status & 0xFFFF;
57 }
58
59 int
60 do_aspawn(really,mark,sp)
61 SV *really;
62 register SV **mark;
63 register SV **sp;
64 {
65     register char **a;
66     char *tmps;
67     int rc;
68     int flag = P_WAIT, trueflag;
69
70     if (sp > mark) {
71         New(401,Argv, sp - mark + 1, char*);
72         a = Argv;
73
74         if (mark < sp && SvIOKp(*(mark+1))) {
75                 ++mark;
76                 flag = SvIVx(*mark);
77         }
78
79         while (++mark <= sp) {
80             if (*mark)
81                 *a++ = SvPVx(*mark, na);
82             else
83                 *a++ = "";
84         }
85         *a = Nullch;
86
87         trueflag = flag;
88         if (flag == P_WAIT)
89                 flag = P_NOWAIT;
90
91         if (really && *(tmps = SvPV(really, na)))
92             rc = result(trueflag, spawnvp(flag,tmps,Argv));
93         else
94             rc = result(trueflag, spawnvp(flag,Argv[0],Argv));
95
96         if (rc < 0 && dowarn)
97             warn("Can't spawn \"%s\": %s", Argv[0], Strerror(errno));
98     } else
99         rc = -1;
100     do_execfree();
101     return rc;
102 }
103
104 int
105 do_spawn(cmd)
106 char *cmd;
107 {
108     register char **a;
109     register char *s;
110     char flags[10];
111     char *shell, *copt;
112     int rc;
113
114     if ((shell = getenv("SHELL")) != NULL)
115         copt = "-c";
116     else if ((shell = getenv("COMSPEC")) != NULL)
117         copt = "/C";
118     else
119         shell = "cmd.exe";
120
121     /* save an extra exec if possible */
122     /* see if there are shell metacharacters in it */
123
124     /*SUPPRESS 530*/
125     if (*cmd == '@') {
126         ++cmd;
127         goto shell_cmd;
128     }
129     for (s = cmd; *s; s++) {
130         if (*s != ' ' && !isALPHA(*s) && strchr("%&|<>\n",*s)) {
131             if (*s == '\n' && !s[1]) {
132                 *s = '\0';
133                 break;
134             }
135 shell_cmd:  return result(P_WAIT, spawnl(P_NOWAIT,shell,shell,copt,cmd,(char*)0));
136         }
137     }
138     New(402,Argv, (s - cmd) / 2 + 2, char*);
139     Cmd = savepvn(cmd, s-cmd);
140     a = Argv;
141     for (s = Cmd; *s;) {
142         while (*s && isSPACE(*s)) s++;
143         if (*s)
144             *(a++) = s;
145         while (*s && !isSPACE(*s)) s++;
146         if (*s)
147             *s++ = '\0';
148     }
149     *a = Nullch;
150     if (Argv[0]) {
151         rc = result(P_WAIT, spawnvp(P_NOWAIT,Argv[0],Argv));
152         if (rc < 0 && dowarn)
153             warn("Can't spawn \"%s\": %s", Argv[0], Strerror(errno));
154     } else
155         rc = -1;
156     do_execfree();
157     return rc;
158 }
159
160 /*****************************************************************************/
161
162 #ifndef HAS_FORK
163 int
164 fork(void)
165 {
166     die(no_func, "Unsupported function fork");
167     errno = EINVAL;
168     return -1;
169 }
170 #endif
171
172 /*****************************************************************************/
173 /* not implemented in EMX 0.9a */
174
175 void *  ctermid(x)      { return 0; }
176
177 #ifdef MYTTYNAME /* was not in emx0.9a */
178 void *  ttyname(x)      { return 0; }
179 #endif
180
181 void *  gethostent()    { return 0; }
182 void *  getnetent()     { return 0; }
183 void *  getprotoent()   { return 0; }
184 void *  getservent()    { return 0; }
185 void    sethostent(x)   {}
186 void    setnetent(x)    {}
187 void    setprotoent(x)  {}
188 void    setservent(x)   {}
189 void    endhostent(x)   {}
190 void    endnetent(x)    {}
191 void    endprotoent(x)  {}
192 void    endservent(x)   {}
193
194 /*****************************************************************************/
195 /* stat() hack for char/block device */
196
197 #if OS2_STAT_HACK
198
199     /* First attempt used DosQueryFSAttach which crashed the system when
200        used with 5.001. Now just look for /dev/. */
201
202 int
203 os2_stat(char *name, struct stat *st)
204 {
205     static int ino = SHRT_MAX;
206
207     if (stricmp(name, "/dev/con") != 0
208      && stricmp(name, "/dev/tty") != 0)
209         return stat(name, st);
210
211     memset(st, 0, sizeof *st);
212     st->st_mode = S_IFCHR|0666;
213     st->st_ino = (ino-- & 0x7FFF);
214     st->st_nlink = 1;
215     return 0;
216 }
217
218 #endif