perl 4.0 patch 28: patch #20, continued
[p5sagit/p5-mst-13.2.git] / os2 / os2.c
1 /* $RCSfile: os2.c,v $$Revision: 4.0.1.2 $$Date: 92/06/08 14:32:30 $
2  *
3  *    (C) Copyright 1989, 1990 Diomidis Spinellis.
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  * $Log:        os2.c,v $
9  * Revision 4.0.1.2  92/06/08  14:32:30  lwall
10  * patch20: new OS/2 support
11  * 
12  * Revision 4.0.1.1  91/06/07  11:23:06  lwall
13  * patch4: new copyright notice
14  * 
15  * Revision 4.0  91/03/20  01:36:21  lwall
16  * 4.0 baseline.
17  * 
18  * Revision 3.0.1.2  90/11/10  01:42:38  lwall
19  * patch38: more msdos/os2 upgrades
20  * 
21  * Revision 3.0.1.1  90/10/15  17:49:55  lwall
22  * patch29: Initial revision
23  * 
24  * Revision 3.0.1.1  90/03/27  16:10:41  lwall
25  * patch16: MSDOS support
26  *
27  * Revision 1.1  90/03/18  20:32:01  dds
28  * Initial revision
29  *
30  */
31
32 #define INCL_DOS
33 #define INCL_NOPM
34 #include <os2.h>
35
36 /*
37  * Various Unix compatibility functions for OS/2
38  */
39
40 #include <stdio.h>
41 #include <errno.h>
42 #include <process.h>
43
44 #include "EXTERN.h"
45 #include "perl.h"
46
47
48 /* dummies */
49
50 int ioctl(int handle, unsigned int function, char *data)
51 { return -1; }
52
53 int userinit()
54 { return -1; }
55
56 int syscall()
57 { return -1; }
58
59
60 /* extended chdir() */
61
62 int chdir(char *path)
63 {
64   if ( path[0] != 0 && path[1] == ':' )
65     if ( DosSelectDisk(toupper(path[0]) - '@') )
66       return -1;
67
68   return DosChDir(path, 0L);
69 }
70
71
72 /* priorities */
73
74 int setpriority(int class, int pid, int val)
75 {
76   int flag = 0;
77
78   if ( pid < 0 )
79   {
80     flag++;
81     pid = -pid;
82   }
83
84   return DosSetPrty(flag ? PRTYS_PROCESSTREE : PRTYS_PROCESS, class, val, pid);
85 }
86
87 int getpriority(int which /* ignored */, int pid)
88 {
89   USHORT val;
90
91   if ( DosGetPrty(PRTYS_PROCESS, &val, pid) )
92     return -1;
93   else
94     return val;
95 }
96
97
98 /* get parent process id */
99
100 int getppid(void)
101 {
102   PIDINFO pi;
103
104   DosGetPID(&pi);
105   return pi.pidParent;
106 }
107
108
109 /* wait for specific pid */
110 int wait4pid(int pid, int *status, int flags)
111 {
112   RESULTCODES res;
113   int endpid, rc;
114   if ( DosCwait(DCWA_PROCESS, flags ? DCWW_NOWAIT : DCWW_WAIT,
115                 &res, &endpid, pid) )
116     return -1;
117   *status = res.codeResult;
118   return endpid;
119 }
120 /* kill */
121
122 int kill(int pid, int sig)
123 {
124   int flag = 0;
125
126   if ( pid < 0 )
127   {
128     flag++;
129     pid = -pid;
130   }
131
132   switch ( sig & 3 )
133   {
134
135   case 0:
136     DosKillProcess(flag ? DKP_PROCESSTREE : DKP_PROCESS, pid);
137     break;
138
139   case 1: /* FLAG A */
140     DosFlagProcess(pid, flag ? FLGP_SUBTREE : FLGP_PID, PFLG_A, 0);
141     break;
142
143   case 2: /* FLAG B */
144     DosFlagProcess(pid, flag ? FLGP_SUBTREE : FLGP_PID, PFLG_B, 0);
145     break;
146
147   case 3: /* FLAG C */
148     DosFlagProcess(pid, flag ? FLGP_SUBTREE : FLGP_PID, PFLG_C, 0);
149     break;
150
151   }
152 }
153
154
155 /* Sleep function. */
156 void
157 sleep(unsigned len)
158 {
159    DosSleep(len * 1000L);
160 }
161
162 /* Just pretend that everyone is a superuser */
163
164 int setuid()
165 { return 0; }
166
167 int setgid()
168 { return 0; }
169
170 int getuid(void)
171 { return 0; }
172
173 int geteuid(void)
174 { return 0; }
175
176 int getgid(void)
177 { return 0; }
178
179 int getegid(void)
180 { return 0; }
181
182 /*
183  * The following code is based on the do_exec and do_aexec functions
184  * in file doio.c
185  */
186 int
187 do_aspawn(really,arglast)
188 STR *really;
189 int *arglast;
190 {
191     register STR **st = stack->ary_array;
192     register int sp = arglast[1];
193     register int items = arglast[2] - sp;
194     register char **a;
195     char **argv;
196     char *tmps;
197     int status;
198
199     if (items) {
200         New(1101,argv, items+1, char*);
201         a = argv;
202         for (st += ++sp; items > 0; items--,st++) {
203             if (*st)
204                 *a++ = str_get(*st);
205             else
206                 *a++ = "";
207         }
208         *a = Nullch;
209         if (really && *(tmps = str_get(really)))
210             status = spawnvp(P_WAIT,tmps,argv);
211         else
212             status = spawnvp(P_WAIT,argv[0],argv);
213         Safefree(argv);
214     }
215     return status;
216 }
217
218 char *getenv(char *name);
219
220 int
221 do_spawn(cmd)
222 char *cmd;
223 {
224     register char **a;
225     register char *s;
226     char **argv;
227     char flags[10];
228     int status;
229     char *shell, *cmd2;
230
231     /* save an extra exec if possible */
232     if ((shell = getenv("COMSPEC")) == 0)
233         shell = "C:\\OS2\\CMD.EXE";
234
235     /* see if there are shell metacharacters in it */
236     if (strchr(cmd, '>') || strchr(cmd, '<') || strchr(cmd, '|')
237         || strchr(cmd, '&') || strchr(cmd, '^'))
238           doshell:
239             return spawnl(P_WAIT,shell,shell,"/C",cmd,(char*)0);
240
241     New(1102,argv, strlen(cmd) / 2 + 2, char*);
242
243     New(1103,cmd2, strlen(cmd) + 1, char);
244     strcpy(cmd2, cmd);
245     a = argv;
246     for (s = cmd2; *s;) {
247         while (*s && isspace(*s)) s++;
248         if (*s)
249             *(a++) = s;
250         while (*s && !isspace(*s)) s++;
251         if (*s)
252             *s++ = '\0';
253     }
254     *a = Nullch;
255     if (argv[0])
256         if ((status = spawnvp(P_WAIT,argv[0],argv)) == -1) {
257             Safefree(argv);
258             Safefree(cmd2);
259             goto doshell;
260         }
261     Safefree(cmd2);
262     Safefree(argv);
263     return status;
264 }
265
266 usage(char *myname)
267 {
268 #ifdef MSDOS
269   printf("\nUsage: %s [-acdnpPsSvw] [-0[octal]] [-Dnumber] [-i[extension]] [-Idirectory]"
270 #else
271   printf("\nUsage: %s [-acdnpPsSuUvw] [-Dnumber] [-i[extension]] [-Idirectory]"
272 #endif
273          "\n            [-e \"command\"] [-x[directory]] [filename] [arguments]\n", myname);
274
275   printf("\n  -a  autosplit mode with -n or -p"
276          "\n  -c  syntaxcheck only"
277          "\n  -d  run scripts under debugger"
278          "\n  -n  assume 'while (<>) { ...script... }' loop arround your script"
279          "\n  -p  assume loop like -n but print line also like sed"
280          "\n  -P  run script through C preprocessor befor compilation"
281          "\n  -s  enable some switch parsing for switches after script name"
282          "\n  -S  look for the script using PATH environment variable");
283 #ifndef MSDOS
284   printf("\n  -u  dump core after compiling the script"
285          "\n  -U  allow unsafe operations");
286 #endif
287   printf("\n  -v  print version number and patchlevel of perl"
288          "\n  -w  turn warnings on for compilation of your script\n"
289          "\n  -0[octal]       specify record separator (0, if no argument)"
290          "\n  -Dnumber        set debugging flags (argument is a bit mask)"
291          "\n  -i[extension]   edit <> files in place (make backup if extension supplied)"
292          "\n  -Idirectory     specify include directory in conjunction with -P"
293          "\n  -e command      one line of script, multiple -e options are allowed"
294          "\n                  [filename] can be ommitted, when -e is used"
295          "\n  -x[directory]   strip off text before #!perl line and perhaps cd to directory\n");
296 }