perl 5.0 alpha 2
[p5sagit/p5-mst-13.2.git] / msdos / msdos.c
CommitLineData
79072805 1/* $RCSfile: msdos.c,v $$Revision: 4.1 $$Date: 92/08/07 18:24:49 $
b1248f16 2 *
3 * (C) Copyright 1989, 1990 Diomidis Spinellis.
4 *
352d5a3a 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.
b1248f16 7 *
8 * $Log: msdos.c,v $
79072805 9 * Revision 4.1 92/08/07 18:24:49 lwall
10 *
352d5a3a 11 * Revision 4.0.1.1 91/06/07 11:22:37 lwall
12 * patch4: new copyright notice
13 *
fe14fcc3 14 * Revision 4.0 91/03/20 01:34:46 lwall
15 * 4.0 baseline.
16 *
b1248f16 17 * Revision 3.0.1.1 90/03/27 16:10:41 lwall
18 * patch16: MSDOS support
19 *
20 * Revision 1.1 90/03/18 20:32:01 dds
21 * Initial revision
22 *
23 */
24
25/*
26 * Various Unix compatibility functions for MS-DOS.
27 */
28
b1248f16 29#include "EXTERN.h"
30#include "perl.h"
31
fe14fcc3 32#include <dos.h>
33#include <process.h>
34
b1248f16 35/*
36 * Interface to the MS-DOS ioctl system call.
37 * The function is encoded as follows:
38 * The lowest nibble of the function code goes to AL
39 * The two middle nibbles go to CL
40 * The high nibble goes to CH
41 *
42 * The return code is -1 in the case of an error and if successful
43 * for functions AL = 00, 09, 0a the value of the register DX
44 * for functions AL = 02 - 08, 0e the value of the register AX
45 * for functions AL = 01, 0b - 0f the number 0
46 *
47 * Notice that this restricts the ioctl subcodes stored in AL to 00-0f
48 * In the Ralf Borwn interrupt list 90.1 there are no subcodes above AL=0f
49 * so we are ok.
50 * Furthermore CH is also restriced in the same area. Where CH is used as a
51 * code it always is between 00-0f. In the case where it forms a count
52 * together with CL we arbitrarily set the highest count limit to 4095. It
53 * sounds reasonable for an ioctl.
54 * The other alternative would have been to use the pointer argument to
55 * point the the values of CX. The problem with this approach is that
56 * of accessing wild regions when DX is used as a number and not as a
57 * pointer.
58 */
59int
60ioctl(int handle, unsigned int function, char *data)
61{
62 union REGS srv;
63 struct SREGS segregs;
64
65 srv.h.ah = 0x44;
fe14fcc3 66 srv.h.al = (unsigned char)(function & 0x0F);
b1248f16 67 srv.x.bx = handle;
68 srv.x.cx = function >> 4;
69 segread(&segregs);
70#if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
71 segregs.ds = FP_SEG(data);
72 srv.x.dx = FP_OFF(data);
73#else
74 srv.x.dx = (unsigned int) data;
75#endif
76 intdosx(&srv, &srv, &segregs);
77 if (srv.x.cflag & 1) {
78 switch(srv.x.ax ){
79 case 1:
80 errno = EINVAL;
81 break;
82 case 2:
83 case 3:
84 errno = ENOENT;
85 break;
86 case 4:
87 errno = EMFILE;
88 break;
89 case 5:
90 errno = EPERM;
91 break;
92 case 6:
93 errno = EBADF;
94 break;
95 case 8:
96 errno = ENOMEM;
97 break;
98 case 0xc:
99 case 0xd:
100 case 0xf:
101 errno = EINVAL;
102 break;
103 case 0x11:
104 errno = EXDEV;
105 break;
106 case 0x12:
107 errno = ENFILE;
108 break;
109 default:
110 errno = EZERO;
111 break;
112 }
113 return -1;
114 } else {
115 switch (function & 0xf) {
116 case 0: case 9: case 0xa:
117 return srv.x.dx;
118 case 2: case 3: case 4: case 5:
119 case 6: case 7: case 8: case 0xe:
120 return srv.x.ax;
121 case 1: case 0xb: case 0xc: case 0xd:
122 case 0xf:
123 default:
124 return 0;
125 }
126 }
127}
128
129
130/*
131 * Sleep function.
132 */
133void
134sleep(unsigned len)
135{
136 time_t end;
137
138 end = time((time_t *)0) + len;
139 while (time((time_t *)0) < end)
140 ;
141}
142
143/*
144 * Just pretend that everyone is a superuser
145 */
fe14fcc3 146#define ROOT_UID 0
147#define ROOT_GID 0
b1248f16 148int
149getuid(void)
150{
fe14fcc3 151 return ROOT_UID;
b1248f16 152}
153
154int
155geteuid(void)
156{
fe14fcc3 157 return ROOT_UID;
b1248f16 158}
159
160int
161getgid(void)
162{
fe14fcc3 163 return ROOT_GID;
b1248f16 164}
165
166int
167getegid(void)
168{
fe14fcc3 169 return ROOT_GID;
b1248f16 170}
171
fe14fcc3 172int
173setuid(int uid)
174{ return (uid==ROOT_UID?0:-1); }
175
176int
177setgid(int gid)
178{ return (gid==ROOT_GID?0:-1); }
179
b1248f16 180/*
181 * The following code is based on the do_exec and do_aexec functions
182 * in file doio.c
183 */
184int
185do_aspawn(really,arglast)
186STR *really;
187int *arglast;
188{
189 register STR **st = stack->ary_array;
190 register int sp = arglast[1];
191 register int items = arglast[2] - sp;
192 register char **a;
193 char **argv;
194 char *tmps;
195 int status;
196
197 if (items) {
198 New(1101,argv, items+1, char*);
199 a = argv;
200 for (st += ++sp; items > 0; items--,st++) {
201 if (*st)
202 *a++ = str_get(*st);
203 else
204 *a++ = "";
205 }
206 *a = Nullch;
207 if (really && *(tmps = str_get(really)))
208 status = spawnvp(P_WAIT,tmps,argv);
209 else
210 status = spawnvp(P_WAIT,argv[0],argv);
211 Safefree(argv);
212 }
213 return status;
214}
215
b1248f16 216
217int
218do_spawn(cmd)
219char *cmd;
220{
221 register char **a;
222 register char *s;
223 char **argv;
224 char flags[10];
225 int status;
226 char *shell, *cmd2;
227
228 /* save an extra exec if possible */
229 if ((shell = getenv("COMSPEC")) == 0)
230 shell = "\\command.com";
231
232 /* see if there are shell metacharacters in it */
233 if (strchr(cmd, '>') || strchr(cmd, '<') || strchr(cmd, '|'))
234 doshell:
235 return spawnl(P_WAIT,shell,shell,"/c",cmd,(char*)0);
236
237 New(1102,argv, strlen(cmd) / 2 + 2, char*);
238
239 New(1103,cmd2, strlen(cmd) + 1, char);
240 strcpy(cmd2, cmd);
241 a = argv;
242 for (s = cmd2; *s;) {
243 while (*s && isspace(*s)) s++;
244 if (*s)
245 *(a++) = s;
246 while (*s && !isspace(*s)) s++;
247 if (*s)
248 *s++ = '\0';
249 }
250 *a = Nullch;
251 if (argv[0])
252 if ((status = spawnvp(P_WAIT,argv[0],argv)) == -1) {
253 Safefree(argv);
254 Safefree(cmd2);
255 goto doshell;
256 }
257 Safefree(cmd2);
258 Safefree(argv);
259 return status;
260}