home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / perl / msdos / msdos.c < prev    next >
C/C++ Source or Header  |  1992-04-11  |  5KB  |  259 lines

  1. /* $RCSfile: msdos.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:37 $
  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:    msdos.c,v $
  9.  * Revision 4.0.1.1  91/06/07  11:22:37  lwall
  10.  * patch4: new copyright notice
  11.  * 
  12.  * Revision 4.0  91/03/20  01:34:46  lwall
  13.  * 4.0 baseline.
  14.  * 
  15.  * Revision 3.0.1.1  90/03/27  16:10:41  lwall
  16.  * patch16: MSDOS support
  17.  * 
  18.  * Revision 1.1  90/03/18  20:32:01  dds
  19.  * Initial revision
  20.  *
  21.  */
  22.  
  23. /*
  24.  * Various Unix compatibility functions for MS-DOS.
  25.  */
  26.  
  27. #include "EXTERN.h"
  28. #include "perl.h"
  29.  
  30. #include <dos.h>
  31. #include <process.h>
  32.  
  33. /*
  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
  39.  *
  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
  44.  *
  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
  47.  * so we are ok.
  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
  55.  * pointer.
  56.  */
  57. int
  58. ioctl(int handle, unsigned int function, char *data)
  59. {
  60.     union REGS      srv;
  61.     struct SREGS    segregs;
  62.  
  63.     srv.h.ah = 0x44;
  64.     srv.h.al = (unsigned char)(function & 0x0F);
  65.     srv.x.bx = handle;
  66.     srv.x.cx = function >> 4;
  67.     segread(&segregs);
  68. #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  69.     segregs.ds = FP_SEG(data);
  70.     srv.x.dx = FP_OFF(data);
  71. #else
  72.     srv.x.dx = (unsigned int) data;
  73. #endif
  74.     intdosx(&srv, &srv, &segregs);
  75.     if (srv.x.cflag & 1) {
  76.         switch(srv.x.ax ){
  77.         case 1:
  78.             errno = EINVAL;
  79.             break;
  80.         case 2:
  81.         case 3:
  82.             errno = ENOENT;
  83.             break;
  84.         case 4:
  85.             errno = EMFILE;
  86.             break;
  87.         case 5:
  88.             errno = EPERM;
  89.             break;
  90.         case 6:
  91.             errno = EBADF;
  92.             break;
  93.         case 8:
  94.             errno = ENOMEM;
  95.             break;
  96.         case 0xc:
  97.         case 0xd:
  98.         case 0xf:
  99.             errno = EINVAL;
  100.             break;
  101.         case 0x11:
  102.             errno = EXDEV;
  103.             break;
  104.         case 0x12:
  105.             errno = ENFILE;
  106.             break;
  107.         default:
  108.             errno = EZERO;
  109.             break;
  110.         }
  111.         return -1;
  112.     } else {
  113.         switch (function & 0xf) {
  114.         case 0: case 9: case 0xa:
  115.             return srv.x.dx;
  116.         case 2: case 3: case 4: case 5:
  117.         case 6: case 7: case 8: case 0xe:
  118.             return srv.x.ax;
  119.         case 1: case 0xb: case 0xc: case 0xd:
  120.         case 0xf:
  121.         default:
  122.             return 0;
  123.         }
  124.     }
  125. }
  126.  
  127.  
  128. /*
  129.  * Sleep function.
  130.  */
  131. void
  132. sleep(unsigned len)
  133. {
  134.     time_t end;
  135.  
  136.     end = time((time_t *)0) + len;
  137.     while (time((time_t *)0) < end)
  138.         ;
  139. }
  140.  
  141. /*
  142.  * Just pretend that everyone is a superuser
  143.  */
  144. #define ROOT_UID    0
  145. #define ROOT_GID    0
  146. int
  147. getuid(void)
  148. {
  149.     return ROOT_UID;
  150. }
  151.  
  152. int
  153. geteuid(void)
  154. {
  155.     return ROOT_UID;
  156. }
  157.  
  158. int
  159. getgid(void)
  160. {
  161.     return ROOT_GID;
  162. }
  163.  
  164. int
  165. getegid(void)
  166. {
  167.     return ROOT_GID;
  168. }
  169.  
  170. int
  171. setuid(int uid)
  172. { return (uid==ROOT_UID?0:-1); }
  173.  
  174. int
  175. setgid(int gid)
  176. { return (gid==ROOT_GID?0:-1); }
  177.  
  178. /*
  179.  * The following code is based on the do_exec and do_aexec functions
  180.  * in file doio.c
  181.  */
  182. int
  183. do_aspawn(really,arglast)
  184. STR *really;
  185. int *arglast;
  186. {
  187.     register STR **st = stack->ary_array;
  188.     register int sp = arglast[1];
  189.     register int items = arglast[2] - sp;
  190.     register char **a;
  191.     char **argv;
  192.     char *tmps;
  193.     int status;
  194.  
  195.     if (items) {
  196.     New(1101,argv, items+1, char*);
  197.     a = argv;
  198.     for (st += ++sp; items > 0; items--,st++) {
  199.         if (*st)
  200.         *a++ = str_get(*st);
  201.         else
  202.         *a++ = "";
  203.     }
  204.     *a = Nullch;
  205.     if (really && *(tmps = str_get(really)))
  206.         status = spawnvp(P_WAIT,tmps,argv);
  207.     else
  208.         status = spawnvp(P_WAIT,argv[0],argv);
  209.     Safefree(argv);
  210.     }
  211.     return status;
  212. }
  213.  
  214.  
  215. int
  216. do_spawn(cmd)
  217. char *cmd;
  218. {
  219.     register char **a;
  220.     register char *s;
  221.     char **argv;
  222.     char flags[10];
  223.     int status;
  224.     char *shell, *cmd2;
  225.  
  226.     /* save an extra exec if possible */
  227.     if ((shell = getenv("COMSPEC")) == 0)
  228.     shell = "\\command.com";
  229.  
  230.     /* see if there are shell metacharacters in it */
  231.     if (strchr(cmd, '>') || strchr(cmd, '<') || strchr(cmd, '|'))
  232.       doshell:
  233.         return spawnl(P_WAIT,shell,shell,"/c",cmd,(char*)0);
  234.  
  235.     New(1102,argv, strlen(cmd) / 2 + 2, char*);
  236.  
  237.     New(1103,cmd2, strlen(cmd) + 1, char);
  238.     strcpy(cmd2, cmd);
  239.     a = argv;
  240.     for (s = cmd2; *s;) {
  241.     while (*s && isspace(*s)) s++;
  242.     if (*s)
  243.         *(a++) = s;
  244.     while (*s && !isspace(*s)) s++;
  245.     if (*s)
  246.         *s++ = '\0';
  247.     }
  248.     *a = Nullch;
  249.     if (argv[0])
  250.     if ((status = spawnvp(P_WAIT,argv[0],argv)) == -1) {
  251.         Safefree(argv);
  252.         Safefree(cmd2);
  253.         goto doshell;
  254.     }
  255.     Safefree(cmd2);
  256.     Safefree(argv);
  257.     return status;
  258. }
  259.