home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / s920603.zip / DOS.C < prev    next >
C/C++ Source or Header  |  1992-05-30  |  7KB  |  303 lines

  1. /* This file provides direct calls to the MS-DOS file system primitives
  2.  * _creat(), _open(), _close(), _read(), _write(), _lseek() and dup()
  3.  *
  4.  * These are necessary to allow more open file handles than permitted
  5.  * by the compiled-in table sizes in the Borland C library
  6.  */
  7.  
  8. #include <io.h>
  9. #include <dos.h>
  10. #include <errno.h>
  11. #include <fcntl.h>
  12. #include "global.h"
  13.  
  14. /* Table for mapping MS-DOS errors to UNIX errno values */
  15. static int _ioerr[] = {
  16.     0,            /*  0 - OK             */
  17.     EINVAL,        /*  1 - e_badFunction         */
  18.     ENOENT,        /*  2 - e_fileNotFound         */
  19.     ENOENT,        /*  3 - e_pathNotFound         */
  20.     EMFILE,        /*  4 - e_tooManyOpen         */
  21.     EACCES,        /*  5 - e_accessDenied         */
  22.     EBADF,        /*  6 - e_badHandle         */
  23.     ENOMEM,        /*  7 - e_mcbDestroyed         */
  24.     ENOMEM,        /*  8 - e_outOfMemory         */
  25.     ENOMEM,        /*  9 - e_badBlock         */
  26.     E2BIG,        /* 10  e_badEnviron        */
  27.     ENOEXEC,        /* 11  e_badFormat        */
  28.     EACCES,        /* 12  e_badAccess        */
  29.     EINVAL,        /* 13  e_badData        */
  30.     EFAULT,        /* 14  reserved            */
  31.     EXDEV,        /* 15  e_badDrive        */
  32.     EACCES,        /* 16  e_isCurrentDir        */
  33.     ENOTSAM,        /* 17  e_notSameDevice        */
  34.     ENOENT,        /* 18  e_noMoreFiles        */
  35.     EROFS,        /* 19  e_readOnly        */
  36.     ENXIO,        /* 20  e_unknownUnit        */
  37.     EBUSY,        /* 21  e_notReady        */
  38.     EIO,        /* 22  e_unknownCommand     */
  39.     EIO,        /* 23  e_dataError        */
  40.     EIO,        /* 24  e_badRequestLength   */
  41.     EIO,        /* 25  e_seekError        */
  42.     EIO,        /* 26  e_unknownMedia        */
  43.     ENXIO,        /* 27  e_sectorNotFound     */
  44.     EBUSY,        /* 28  e_outOfPaper        */
  45.     EIO,        /* 29  e_writeFault        */
  46.     EIO,        /* 30  e_readFault        */
  47.     EIO,        /* 31  e_generalFault        */
  48.     EACCES,        /* 32  e_sharing        */
  49.     EACCES,        /* 33  e_lock            */
  50.     ENXIO,        /* 34  e_diskChange        */
  51.     ENFILE,        /* 35  e_FCBunavailable     */
  52.     ENFILE,        /* 36  e_sharingOverflow    */
  53.     EFAULT, EFAULT,
  54.     EFAULT, EFAULT,
  55.     EFAULT, EFAULT,
  56.     EFAULT, EFAULT,
  57.     EFAULT, EFAULT,
  58.     EFAULT, EFAULT,
  59.     EFAULT,        /* 37-49  reserved        */
  60.     ENODEV,        /* 50  e_networkUnsupported */
  61.     EBUSY,        /* 51  e_notListening        */
  62.     EEXIST,        /* 52  e_dupNameOnNet        */
  63.     ENOENT,        /* 53  e_nameNotOnNet        */
  64.     EBUSY,        /* 54  e_netBusy        */
  65.     ENODEV,        /* 55  e_netDeviceGone        */
  66.     EAGAIN,        /* 56  e_netCommandLimit    */
  67.     EIO,        /* 57  e_netHardError        */
  68.     EIO,        /* 58  e_wrongNetResponse   */
  69.     EIO,        /* 59  e_netError        */
  70.     EINVAL,        /* 60  e_remoteIncompatible */
  71.     EFBIG,        /* 61  e_printQueueFull     */
  72.     ENOSPC,        /* 62  e_printFileSpace     */
  73.     ENOENT,        /* 63  e_printFileDeleted   */
  74.     ENOENT,        /* 64  e_netNameDeleted     */
  75.     EACCES,        /* 65  e_netAccessDenied    */
  76.     ENODEV,        /* 66  e_netDeviceWrong     */
  77.     ENOENT,        /* 67  e_netNameNotFound    */
  78.     ENFILE,        /* 68  e_netNameLimit        */
  79.     EIO,        /* 69  e_netBIOSlimit        */
  80.     EAGAIN,        /* 70  e_paused            */
  81.     EINVAL,        /* 71  e_netRequestRefused  */
  82.     EAGAIN,        /* 72  e_redirectionPaused  */
  83.     EFAULT, EFAULT,
  84.     EFAULT, EFAULT,
  85.     EFAULT, EFAULT,
  86.     EFAULT,        /* 73- 79  reserved        */
  87.     EEXIST,        /* 80  e_fileExists        */
  88.     EFAULT,        /* 81  reserved            */
  89.     ENOSPC,        /* 82  e_cannotMake        */
  90.     EIO,        /* 83  e_failInt24        */
  91.     ENFILE,        /* 84  e_redirectionLimit   */
  92.     EEXIST,        /* 85  e_dupRedirection     */
  93.     EPERM,        /* 86  e_password        */
  94.     EINVAL,        /* 87  e_parameter        */
  95.     EIO,        /* 88  e_netDevice        */
  96. };
  97. #define    NERROR    89
  98.  
  99. /* Reference count table for open file descriptors */
  100. unsigned *Refcnt;
  101.  
  102. int
  103. _creat(file,mode)
  104. const char *file;    /* File name to create */
  105. int mode;        /* Ignored */
  106. {
  107.     union REGS regs;
  108.     struct SREGS segregs;
  109.     int fd;
  110.  
  111.     segregs.ds = FP_SEG(file);
  112.     regs.x.dx = FP_OFF(file);
  113.     regs.x.cx = 0;    /* Normal attributes */
  114.     regs.h.ah = 0x3c;
  115.     intdosx(®s,®s,&segregs);
  116.     fd = regs.x.ax;
  117.     if(regs.x.cflag){
  118.         if(fd < NERROR)
  119.             errno = _ioerr[fd];
  120.         return -1;
  121.     }
  122.     Refcnt[fd] = 1;
  123.     return fd;    /* Return handle */
  124. }
  125. int
  126. _open(file,mode)
  127. const char *file;
  128. int mode;
  129. {
  130.     union REGS regs;
  131.     struct SREGS segregs;
  132.     int dosmode,fd;
  133.  
  134.     if(mode & O_TRUNC){
  135.         remove(file);
  136.         mode |= O_CREAT;
  137.     }
  138.     /* Translate unix to MS-DOS open modes */
  139.     switch(mode & (O_RDONLY|O_WRONLY|O_RDWR)){
  140.     case O_RDONLY:
  141.         dosmode = 0;
  142.         break;
  143.     case O_WRONLY:
  144.         dosmode = 1;
  145.         break;
  146.     case O_RDWR:
  147.         dosmode = 2;
  148.         break;
  149.     default:
  150.         errno = EINVAL;
  151.         return -1;
  152.     }
  153.     if(mode & O_EXCL)
  154.         dosmode |= 0x10;
  155.     
  156.     segregs.ds = FP_SEG(file);
  157.     regs.x.dx = FP_OFF(file);
  158.     regs.h.al = dosmode;
  159.     regs.h.ah = 0x3d;
  160.     intdosx(®s,®s,&segregs);
  161.     fd = regs.x.ax;
  162.     if(regs.x.cflag){
  163.         if(fd < NERROR){
  164.             errno = _ioerr[fd];
  165.             if(errno == ENOENT && (mode & O_CREAT))
  166.                 return _creat(file,0);
  167.         }
  168.         return -1;
  169.     }
  170.     Refcnt[fd] = 1;
  171.     return fd;    /* Return handle */
  172. }
  173. /* Dup a file descriptor. Rather than allocating a new descriptor,
  174.  * as in UNIX or MS-DOS, we maintain a reference count table so we
  175.  * can return the same descriptor that is passed. This saves precious
  176.  * file descriptor space.
  177.  */
  178. int
  179. dup(fd)
  180. int fd;
  181. {
  182.     if(fd < 0 || fd >= Nfiles || Refcnt[fd] == 0){
  183.         errno = EINVAL;
  184.         return -1;
  185.     }
  186.     Refcnt[fd]++;
  187.     return fd;
  188. }
  189.  
  190. int
  191. _close(fd)
  192. int fd;
  193. {
  194.     union REGS regs;
  195.  
  196.     if(fd < 0 || fd >= Nfiles){
  197.         errno = EINVAL;
  198.         return -1;
  199.     }
  200.     if(--Refcnt[fd] != 0)
  201.         return 0;    /* Somebody else is still using it */
  202.     regs.x.bx = fd;
  203.     regs.h.ah = 0x3e;
  204.     intdos(®s,®s);
  205.     if(regs.x.cflag){
  206.         if(regs.x.ax < NERROR)
  207.             errno = _ioerr[regs.x.ax];
  208.         return -1;
  209.     }
  210.     return 0;
  211. }
  212. int
  213. _read(fd,buf,cnt)
  214. int fd;
  215. void *buf;
  216. unsigned cnt;
  217. {
  218.     union REGS regs;
  219.     struct SREGS segregs;
  220.  
  221.     if(fd < 0 || fd >= Nfiles){
  222.         errno = EINVAL;
  223.         return -1;
  224.     }
  225.     regs.x.bx = fd;
  226.     regs.x.cx = cnt;
  227.     segregs.ds = FP_SEG(buf);
  228.     regs.x.dx = FP_OFF(buf);
  229.     regs.h.ah = 0x3f;
  230.     intdosx(®s,®s,&segregs);
  231.     if(regs.x.cflag){
  232.         if(regs.x.ax < NERROR)
  233.             errno = _ioerr[regs.x.ax];
  234.         return -1;
  235.     }
  236.     return regs.x.ax;    /* Return count */
  237. }
  238. int
  239. _write(fd,buf,cnt)
  240. int fd;
  241. void *buf;
  242. unsigned cnt;
  243. {
  244.     union REGS regs;
  245.     struct SREGS segregs;
  246.  
  247.     if(fd < 0 || fd >= Nfiles){
  248.         errno = EINVAL;
  249.         return -1;
  250.     }
  251.     regs.x.bx = fd;
  252.     regs.x.cx = cnt;
  253.     segregs.ds = FP_SEG(buf);
  254.     regs.x.dx = FP_OFF(buf);
  255.     regs.h.ah = 0x40;
  256.     intdosx(®s,®s,&segregs);
  257.     if(regs.x.cflag){
  258.         if(regs.x.ax < NERROR)
  259.             errno = _ioerr[regs.x.ax];
  260.         return -1;
  261.     }
  262.     cnt = regs.x.ax;    /* Return count */
  263.  
  264. /* Not really necessary when share.exe is loaded, and it really slows down
  265.  * machines without disk write caches
  266.  */
  267. #ifdef    notdef
  268.     /* Call the "commit file" command to flush it out (will fail for
  269.      * MS-DOS before 3.3)
  270.      */
  271.     regs.x.bx = fd;
  272.     regs.h.ah = 0x68;
  273.     intdos(®s,®s);
  274. #endif
  275.     return cnt;
  276. }
  277. long
  278. _lseek(fd,offset,whence)
  279. int fd;
  280. long offset;
  281. int whence;
  282. {
  283.     union REGS regs;
  284.  
  285.     if(fd < 0 || fd >= Nfiles){
  286.         errno = EINVAL;
  287.         return -1;
  288.     }
  289.     regs.x.bx = fd;
  290.     regs.x.cx = offset >> 16;
  291.     regs.x.dx = offset;
  292.     regs.h.al = whence;
  293.     regs.h.ah = 0x42;
  294.     intdos(®s,®s);
  295.     if(regs.x.cflag){
  296.         if(regs.x.ax < NERROR)
  297.             errno = _ioerr[regs.x.ax];
  298.         return -1;
  299.     }
  300.     /* Return new offset */
  301.     return ((long)regs.x.dx << 16) | regs.x.ax;
  302. }
  303.