dos.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:8k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

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