1 /* $RCSfile: msdos.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:37 $
3 * (C) Copyright 1989, 1990 Diomidis Spinellis.
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.
9 * Revision 4.0.1.1 91/06/07 11:22:37 lwall
10 * patch4: new copyright notice
12 * Revision 4.0 91/03/20 01:34:46 lwall
15 * Revision 3.0.1.1 90/03/27 16:10:41 lwall
16 * patch16: MSDOS support
18 * Revision 1.1 90/03/18 20:32:01 dds
24 * Various Unix compatibility functions for MS-DOS.
34 * Interface to the MS-DOS ioctl system call.
35 * The function is encoded as follows:
36 * The lowest nibble of the function code goes to AL
37 * The two middle nibbles go to CL
38 * The high nibble goes to CH
40 * The return code is -1 in the case of an error and if successful
41 * for functions AL = 00, 09, 0a the value of the register DX
42 * for functions AL = 02 - 08, 0e the value of the register AX
43 * for functions AL = 01, 0b - 0f the number 0
45 * Notice that this restricts the ioctl subcodes stored in AL to 00-0f
46 * In the Ralf Borwn interrupt list 90.1 there are no subcodes above AL=0f
48 * Furthermore CH is also restriced in the same area. Where CH is used as a
49 * code it always is between 00-0f. In the case where it forms a count
50 * together with CL we arbitrarily set the highest count limit to 4095. It
51 * sounds reasonable for an ioctl.
52 * The other alternative would have been to use the pointer argument to
53 * point the the values of CX. The problem with this approach is that
54 * of accessing wild regions when DX is used as a number and not as a
58 ioctl(int handle, unsigned int function, char *data)
64 srv.h.al = (unsigned char)(function & 0x0F);
66 srv.x.cx = function >> 4;
68 #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
69 segregs.ds = FP_SEG(data);
70 srv.x.dx = FP_OFF(data);
72 srv.x.dx = (unsigned int) data;
74 intdosx(&srv, &srv, &segregs);
75 if (srv.x.cflag & 1) {
113 switch (function & 0xf) {
114 case 0: case 9: case 0xa:
116 case 2: case 3: case 4: case 5:
117 case 6: case 7: case 8: case 0xe:
119 case 1: case 0xb: case 0xc: case 0xd:
136 end = time((time_t *)0) + len;
137 while (time((time_t *)0) < end)
142 * Just pretend that everyone is a superuser
172 { return (uid==ROOT_UID?0:-1); }
176 { return (gid==ROOT_GID?0:-1); }
179 * The following code is based on the do_exec and do_aexec functions
183 do_aspawn(really,arglast)
187 register STR **st = stack->ary_array;
188 register int sp = arglast[1];
189 register int items = arglast[2] - sp;
196 New(1101,argv, items+1, char*);
198 for (st += ++sp; items > 0; items--,st++) {
205 if (really && *(tmps = str_get(really)))
206 status = spawnvp(P_WAIT,tmps,argv);
208 status = spawnvp(P_WAIT,argv[0],argv);
226 /* save an extra exec if possible */
227 if ((shell = getenv("COMSPEC")) == 0)
228 shell = "\\command.com";
230 /* see if there are shell metacharacters in it */
231 if (strchr(cmd, '>') || strchr(cmd, '<') || strchr(cmd, '|'))
233 return spawnl(P_WAIT,shell,shell,"/c",cmd,(char*)0);
235 New(1102,argv, strlen(cmd) / 2 + 2, char*);
237 New(1103,cmd2, strlen(cmd) + 1, char);
240 for (s = cmd2; *s;) {
241 while (*s && isspace(*s)) s++;
244 while (*s && !isspace(*s)) s++;
250 if ((status = spawnvp(P_WAIT,argv[0],argv)) == -1) {