stdio.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897
  1. /* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk>
  2. * This file is part of the Linux-8086 C library and is distributed
  3. * under the GNU Library General Public License.
  4. */
  5. /* This is an implementation of the C standard IO package.
  6. */
  7. #include <stdio.h>
  8. #include <fcntl.h>
  9. #include <sys/types.h>
  10. #include <malloc.h>
  11. #include <errno.h>
  12. #ifndef O_BINARY
  13. #define O_BINARY 0
  14. #endif
  15. extern FILE *__IO_list; /* For fflush at exit */
  16. #ifdef __AS386_16__
  17. #define Inline_init
  18. #endif
  19. #ifdef __AS386_32__
  20. #define Inline_init
  21. #endif
  22. #ifndef Inline_init
  23. #define Inline_init __io_init_vars()
  24. #endif
  25. #ifdef L__stdio_init
  26. #define buferr (stderr->unbuf) /* Stderr is unbuffered */
  27. FILE *__IO_list = 0; /* For fflush at exit */
  28. static char bufin[BUFSIZ];
  29. static char bufout[BUFSIZ];
  30. #ifndef buferr
  31. static char buferr[BUFSIZ];
  32. #endif
  33. FILE stdin[1] =
  34. {
  35. {bufin, bufin, bufin, bufin, bufin + sizeof(bufin),
  36. 0, _IOFBF | __MODE_READ | __MODE_IOTRAN}
  37. };
  38. FILE stdout[1] =
  39. {
  40. {bufout, bufout, bufout, bufout, bufout + sizeof(bufout),
  41. 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN}
  42. };
  43. FILE stderr[1] =
  44. {
  45. {buferr, buferr, buferr, buferr, buferr + sizeof(buferr),
  46. 2, _IONBF | __MODE_WRITE | __MODE_IOTRAN}
  47. };
  48. /* Call the stdio initiliser; it's main job it to call atexit */
  49. #ifdef __AS386_16__
  50. #define STATIC static
  51. #asm
  52. loc 1 ! Make sure the pointer is in the correct segment
  53. auto_func: ! Label for bcc -M to work.
  54. .word ___io_init_vars ! Pointer to the autorun function
  55. .text ! So the function after is also in the correct seg.
  56. #endasm
  57. #endif
  58. #ifdef __AS386_32__
  59. #define STATIC static
  60. #asm
  61. loc 1 ! Make sure the pointer is in the correct segment
  62. auto_func: ! Label for bcc -M to work.
  63. .long ___io_init_vars ! Pointer to the autorun function
  64. .text ! So the function after is also in the correct seg.
  65. #endasm
  66. #endif
  67. #ifndef STATIC
  68. #define STATIC
  69. #endif
  70. STATIC int
  71. __stdio_close_all()
  72. {
  73. FILE *fp;
  74. fflush(stdout);
  75. fflush(stderr);
  76. for (fp = __IO_list; fp; fp = fp->next)
  77. {
  78. fflush(fp);
  79. close(fp->fd);
  80. /* Note we're not de-allocating the memory */
  81. /* There doesn't seem to be much point :-) */
  82. fp->fd = -1;
  83. }
  84. }
  85. STATIC void
  86. __io_init_vars()
  87. {
  88. #ifndef __AS386_16__
  89. #ifndef __AS386_32__
  90. static int first_time = 1;
  91. if( !first_time ) return ;
  92. first_time = 0;
  93. #endif
  94. #endif
  95. if (isatty(1))
  96. stdout->mode |= _IOLBF;
  97. atexit(__stdio_close_all);
  98. }
  99. #endif
  100. #ifdef L_fputc
  101. int
  102. fputc(ch, fp)
  103. int ch;
  104. FILE *fp;
  105. {
  106. register int v;
  107. Inline_init;
  108. /* If last op was a read ... note fflush may change fp->mode and ret OK */
  109. if ((fp->mode & __MODE_READING) && fflush(fp))
  110. return EOF;
  111. v = fp->mode;
  112. /* Can't write if there's been an EOF or error then return EOF */
  113. if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE)
  114. return EOF;
  115. /* In MSDOS translation mode */
  116. #if __MODE_IOTRAN && !O_BINARY
  117. if (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF)
  118. return EOF;
  119. #endif
  120. /* Buffer is full */
  121. if (fp->bufpos >= fp->bufend && fflush(fp))
  122. return EOF;
  123. /* Right! Do it! */
  124. *(fp->bufpos++) = ch;
  125. fp->mode |= __MODE_WRITING;
  126. /* Unbuffered or Line buffered and end of line */
  127. if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF))
  128. && fflush(fp))
  129. return EOF;
  130. /* Can the macro handle this by itself ? */
  131. if (v & (__MODE_IOTRAN | _IOLBF | _IONBF))
  132. fp->bufwrite = fp->bufstart; /* Nope */
  133. else
  134. fp->bufwrite = fp->bufend; /* Yup */
  135. /* Correct return val */
  136. return (unsigned char) ch;
  137. }
  138. #endif
  139. #ifdef L_fgetc
  140. int
  141. fgetc(fp)
  142. FILE *fp;
  143. {
  144. int ch;
  145. if (fp->mode & __MODE_WRITING)
  146. fflush(fp);
  147. try_again:
  148. /* Can't read or there's been an EOF or error then return EOF */
  149. if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ)
  150. return EOF;
  151. /* Nothing in the buffer - fill it up */
  152. if (fp->bufpos >= fp->bufread)
  153. {
  154. /* Bind stdin to stdout if it's open and line buffered */
  155. if( fp == stdin && stdout->fd >= 0 && (stdout->mode & _IOLBF ))
  156. fflush(stdout);
  157. fp->bufpos = fp->bufread = fp->bufstart;
  158. ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp);
  159. if (ch == 0)
  160. return EOF;
  161. fp->bufread += ch;
  162. fp->mode |= __MODE_READING;
  163. fp->mode &= ~__MODE_UNGOT;
  164. }
  165. ch = *(fp->bufpos++);
  166. #if __MODE_IOTRAN && !O_BINARY
  167. /* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */
  168. if (ch == '\r' && (fp->mode & __MODE_IOTRAN))
  169. goto try_again;
  170. #endif
  171. return ch;
  172. }
  173. #endif
  174. #ifdef L_fflush
  175. int
  176. fflush(fp)
  177. FILE *fp;
  178. {
  179. int len, cc, rv=0;
  180. char * bstart;
  181. if (fp == NULL) /* On NULL flush the lot. */
  182. {
  183. if (fflush(stdin))
  184. return EOF;
  185. if (fflush(stdout))
  186. return EOF;
  187. if (fflush(stderr))
  188. return EOF;
  189. for (fp = __IO_list; fp; fp = fp->next)
  190. if (fflush(fp))
  191. return EOF;
  192. return 0;
  193. }
  194. /* If there's output data pending */
  195. if (fp->mode & __MODE_WRITING)
  196. {
  197. len = fp->bufpos - fp->bufstart;
  198. if (len)
  199. {
  200. bstart = fp->bufstart;
  201. /*
  202. * The loop is so we don't get upset by signals or partial writes.
  203. */
  204. do
  205. {
  206. cc = write(fp->fd, bstart, len);
  207. if( cc > 0 )
  208. {
  209. bstart+=cc; len-=cc;
  210. }
  211. }
  212. while ( len>0 && (cc>0 || (cc == -1 && errno == EINTR)));
  213. /*
  214. * If we get here with len!=0 there was an error, exactly what to
  215. * do about it is another matter ...
  216. *
  217. * I'll just clear the buffer.
  218. */
  219. if (len)
  220. {
  221. fp->mode |= __MODE_ERR;
  222. rv = EOF;
  223. }
  224. }
  225. }
  226. /* If there's data in the buffer sychronise the file positions */
  227. else if (fp->mode & __MODE_READING)
  228. {
  229. /* Humm, I think this means sync the file like fpurge() ... */
  230. /* Anyway the user isn't supposed to call this function when reading */
  231. len = fp->bufread - fp->bufpos; /* Bytes buffered but unread */
  232. /* If it's a file, make it good */
  233. if (len > 0 && lseek(fp->fd, (long)-len, 1) < 0)
  234. {
  235. /* Hummm - Not certain here, I don't think this is reported */
  236. /*
  237. * fp->mode |= __MODE_ERR; return EOF;
  238. */
  239. }
  240. }
  241. /* All done, no problem */
  242. fp->mode &= (~(__MODE_READING|__MODE_WRITING|__MODE_EOF|__MODE_UNGOT));
  243. fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart;
  244. return rv;
  245. }
  246. #endif
  247. #ifdef L_fgets
  248. /* Nothing special here ... */
  249. char *
  250. fgets(s, count, f)
  251. char *s;
  252. size_t count;
  253. FILE *f;
  254. {
  255. char *ret;
  256. register size_t i;
  257. register int ch;
  258. ret = s;
  259. for (i = count-1; i > 0; i--)
  260. {
  261. ch = getc(f);
  262. if (ch == EOF)
  263. {
  264. if (s == ret)
  265. return 0;
  266. break;
  267. }
  268. *s++ = (char) ch;
  269. if (ch == '\n')
  270. break;
  271. }
  272. *s = 0;
  273. if (ferror(f))
  274. return 0;
  275. return ret;
  276. }
  277. #endif
  278. #ifdef L_gets
  279. char *
  280. gets(str) /* BAD function; DON'T use it! */
  281. char *str;
  282. {
  283. /* Auwlright it will work but of course _your_ program will crash */
  284. /* if it's given a too long line */
  285. register char *p = str;
  286. register int c;
  287. while (((c = getc(stdin)) != EOF) && (c != '\n'))
  288. *p++ = c;
  289. *p = '\0';
  290. return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */
  291. }
  292. #endif
  293. #ifdef L_fputs
  294. int
  295. fputs(str, fp)
  296. char *str;
  297. FILE *fp;
  298. {
  299. register int n = 0;
  300. while (*str)
  301. {
  302. if (putc(*str++, fp) == EOF)
  303. return (EOF);
  304. ++n;
  305. }
  306. return (n);
  307. }
  308. #endif
  309. #ifdef L_puts
  310. int
  311. puts(str)
  312. char *str;
  313. {
  314. register int n;
  315. if (((n = fputs(str, stdout)) == EOF)
  316. || (putc('\n', stdout) == EOF))
  317. return (EOF);
  318. return (++n);
  319. }
  320. #endif
  321. #ifdef L_fread
  322. /*
  323. * fread will often be used to read in large chunks of data calling read()
  324. * directly can be a big win in this case. Beware also fgetc calls this
  325. * function to fill the buffer.
  326. *
  327. * This ignores __MODE__IOTRAN; probably exactly what you want. (It _is_ what
  328. * fgetc wants)
  329. */
  330. int
  331. fread(buf, size, nelm, fp)
  332. char *buf;
  333. int size;
  334. int nelm;
  335. FILE *fp;
  336. {
  337. int len, v;
  338. unsigned bytes, got = 0;
  339. Inline_init;
  340. v = fp->mode;
  341. /* Want to do this to bring the file pointer up to date */
  342. if (v & __MODE_WRITING)
  343. fflush(fp);
  344. /* Can't read or there's been an EOF or error then return zero */
  345. if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ)
  346. return 0;
  347. /* This could be long, doesn't seem much point tho */
  348. bytes = size * nelm;
  349. len = fp->bufread - fp->bufpos;
  350. if (len >= bytes) /* Enough buffered */
  351. {
  352. memcpy(buf, fp->bufpos, (unsigned) bytes);
  353. fp->bufpos += bytes;
  354. return nelm;
  355. }
  356. else if (len > 0) /* Some buffered */
  357. {
  358. memcpy(buf, fp->bufpos, len);
  359. fp->bufpos += len;
  360. got = len;
  361. }
  362. /* Need more; do it with a direct read */
  363. len = read(fp->fd, buf + got, (unsigned) (bytes - got));
  364. /* Possibly for now _or_ later */
  365. if (len < 0)
  366. {
  367. fp->mode |= __MODE_ERR;
  368. len = 0;
  369. }
  370. else if (len == 0)
  371. fp->mode |= __MODE_EOF;
  372. return (got + len) / size;
  373. }
  374. #endif
  375. #ifdef L_fwrite
  376. /*
  377. * Like fread, fwrite will often be used to write out large chunks of
  378. * data; calling write() directly can be a big win in this case.
  379. *
  380. * But first we check to see if there's space in the buffer.
  381. *
  382. * Again this ignores __MODE__IOTRAN.
  383. */
  384. int
  385. fwrite(buf, size, nelm, fp)
  386. char *buf;
  387. int size;
  388. int nelm;
  389. FILE *fp;
  390. {
  391. register int v;
  392. int len;
  393. unsigned bytes, put;
  394. /* If last op was a read ... note fflush may change fp->mode and ret OK */
  395. if ((fp->mode & __MODE_READING) && fflush(fp))
  396. return 0;
  397. v = fp->mode;
  398. /* Can't write or there's been an EOF or error then return 0 */
  399. if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE)
  400. return 0;
  401. /* This could be long, doesn't seem much point tho */
  402. bytes = size * nelm;
  403. len = fp->bufend - fp->bufpos;
  404. /* Flush the buffer if not enough room */
  405. if (bytes > len)
  406. if (fflush(fp))
  407. return 0;
  408. len = fp->bufend - fp->bufpos;
  409. if (bytes <= len) /* It'll fit in the buffer ? */
  410. {
  411. register int do_flush=0;
  412. fp->mode |= __MODE_WRITING;
  413. memcpy(fp->bufpos, buf, bytes);
  414. if (v & _IOLBF)
  415. {
  416. if(memchr(fp->bufpos, '\n', bytes))
  417. do_flush=1;
  418. }
  419. fp->bufpos += bytes;
  420. /* If we're unbuffered or line buffered and have seen nl */
  421. if (do_flush || (v & _IONBF) != 0)
  422. fflush(fp);
  423. return nelm;
  424. }
  425. else
  426. /* Too big for the buffer */
  427. {
  428. put = bytes;
  429. do
  430. {
  431. len = write(fp->fd, buf, bytes);
  432. if( len > 0 )
  433. {
  434. buf+=len; bytes-=len;
  435. }
  436. }
  437. while (len > 0 || (len == -1 && errno == EINTR));
  438. if (len < 0)
  439. fp->mode |= __MODE_ERR;
  440. put -= bytes;
  441. }
  442. return put / size;
  443. }
  444. #endif
  445. #ifdef L_rewind
  446. void
  447. rewind(fp)
  448. FILE * fp;
  449. {
  450. fseek(fp, (long)0, 0);
  451. clearerr(fp);
  452. }
  453. #endif
  454. #ifdef L_fseek
  455. int
  456. fseek(fp, offset, ref)
  457. FILE *fp;
  458. long offset;
  459. int ref;
  460. {
  461. #if 1
  462. /* if __MODE_READING and no ungetc ever done can just move pointer */
  463. if ( (fp->mode &(__MODE_READING | __MODE_UNGOT)) == __MODE_READING &&
  464. ( ref == SEEK_SET || ref == SEEK_CUR ))
  465. {
  466. long fpos = lseek(fp->fd, 0L, SEEK_CUR);
  467. if( fpos == -1 ) return EOF;
  468. if( ref == SEEK_CUR )
  469. {
  470. ref = SEEK_SET;
  471. offset = fpos + offset + fp->bufpos - fp->bufread;
  472. }
  473. if( ref == SEEK_SET )
  474. {
  475. if ( offset < fpos && offset >= fpos + fp->bufstart - fp->bufread )
  476. {
  477. fp->bufpos = offset - fpos + fp->bufread;
  478. return 0;
  479. }
  480. }
  481. }
  482. #endif
  483. /* Use fflush to sync the pointers */
  484. if (fflush(fp) == EOF)
  485. return EOF;
  486. if (lseek(fp->fd, offset, ref) < 0)
  487. return EOF;
  488. return 0;
  489. }
  490. #endif
  491. #ifdef L_ftell
  492. long ftell(fp)
  493. FILE * fp;
  494. {
  495. long rv;
  496. if (fflush(fp) == EOF)
  497. return EOF;
  498. return lseek(fp->fd, 0L, SEEK_CUR);
  499. }
  500. #endif
  501. #ifdef L_fopen
  502. FILE *
  503. fopen(file, mode)
  504. char * file;
  505. char * mode;
  506. {
  507. return __fopen(file, -1, (FILE*)0, mode);
  508. }
  509. #endif
  510. #ifdef L_freopen
  511. FILE *
  512. freopen(file, mode, fp)
  513. char * file;
  514. char * mode;
  515. FILE * fp;
  516. {
  517. return __fopen(file, -1, fp, mode);
  518. }
  519. #endif
  520. #ifdef L_fdopen
  521. FILE *
  522. fdopen(file, mode)
  523. int file;
  524. char * mode;
  525. {
  526. return __fopen((char*)0, file, (FILE*)0, mode);
  527. }
  528. #endif
  529. #ifdef L___fopen
  530. /*
  531. * This is the common code for all three of fopen, fdopen and freopen.
  532. */
  533. FILE *
  534. __fopen(fname, fd, fp, mode)
  535. char *fname;
  536. int fd;
  537. FILE *fp;
  538. char *mode;
  539. {
  540. int open_mode = 0;
  541. #if __MODE_IOTRAN && !O_BINARY
  542. int do_iosense = 1;
  543. #endif
  544. int fopen_mode = 0;
  545. FILE *nfp = 0;
  546. /* If we've got an fp close the old one (freopen) */
  547. if (fp)
  548. {
  549. /* Careful, don't de-allocate it */
  550. fopen_mode |= (fp->mode & (__MODE_BUF | __MODE_FREEFIL | __MODE_FREEBUF));
  551. fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF);
  552. fclose(fp);
  553. }
  554. /* decode the new open mode */
  555. while (*mode)
  556. switch (*mode++)
  557. {
  558. case 'r':
  559. fopen_mode |= __MODE_READ;
  560. break;
  561. case 'w':
  562. fopen_mode |= __MODE_WRITE;
  563. open_mode = (O_CREAT | O_TRUNC);
  564. break;
  565. case 'a':
  566. fopen_mode |= __MODE_WRITE;
  567. open_mode = (O_CREAT | O_APPEND);
  568. break;
  569. case '+':
  570. fopen_mode |= __MODE_RDWR;
  571. break;
  572. #if __MODE_IOTRAN || O_BINARY
  573. case 'b': /* Binary */
  574. fopen_mode &= ~__MODE_IOTRAN;
  575. open_mode |= O_BINARY;
  576. #if __MODE_IOTRAN && !O_BINARY
  577. do_iosense=0;
  578. #endif
  579. break;
  580. case 't': /* Text */
  581. fopen_mode |= __MODE_IOTRAN;
  582. #if __MODE_IOTRAN && !O_BINARY
  583. do_iosense=0;
  584. #endif
  585. break;
  586. #endif
  587. }
  588. /* Add in the read/write options to mode for open() */
  589. switch (fopen_mode & (__MODE_READ | __MODE_WRITE))
  590. {
  591. case 0:
  592. return 0;
  593. case __MODE_READ:
  594. open_mode |= O_RDONLY;
  595. break;
  596. case __MODE_WRITE:
  597. open_mode |= O_WRONLY;
  598. break;
  599. default:
  600. open_mode |= O_RDWR;
  601. break;
  602. }
  603. /* Allocate the (FILE) before we do anything irreversable */
  604. if (fp == 0)
  605. {
  606. nfp = malloc(sizeof(FILE));
  607. if (nfp == 0)
  608. return 0;
  609. }
  610. /* Open the file itself */
  611. if (fname)
  612. fd = open(fname, open_mode, 0666);
  613. if (fd < 0) /* Grrrr */
  614. {
  615. if (nfp)
  616. free(nfp);
  617. if (fp)
  618. {
  619. fp->mode |= fopen_mode;
  620. fclose(fp); /* Deallocate if required */
  621. }
  622. return 0;
  623. }
  624. /* If this isn't freopen create a (FILE) and buffer for it */
  625. if (fp == 0)
  626. {
  627. fp = nfp;
  628. fp->next = __IO_list;
  629. __IO_list = fp;
  630. fp->mode = __MODE_FREEFIL;
  631. if( isatty(fd) )
  632. {
  633. fp->mode |= _IOLBF;
  634. #if __MODE_IOTRAN && !O_BINARY
  635. if( do_iosense ) fopen_mode |= __MODE_IOTRAN;
  636. #endif
  637. }
  638. else
  639. fp->mode |= _IOFBF;
  640. fp->bufstart = malloc(BUFSIZ);
  641. if (fp->bufstart == 0) /* Oops, no mem */
  642. { /* Humm, full buffering with a two(!) byte
  643. * buffer. */
  644. fp->bufstart = fp->unbuf;
  645. fp->bufend = fp->unbuf + sizeof(fp->unbuf);
  646. }
  647. else
  648. {
  649. fp->bufend = fp->bufstart + BUFSIZ;
  650. fp->mode |= __MODE_FREEBUF;
  651. }
  652. }
  653. /* Ok, file's ready clear the buffer and save important bits */
  654. fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart;
  655. fp->mode |= fopen_mode;
  656. fp->fd = fd;
  657. return fp;
  658. }
  659. #endif
  660. #ifdef L_fclose
  661. int
  662. fclose(fp)
  663. FILE *fp;
  664. {
  665. int rv = 0;
  666. if (fp == 0)
  667. {
  668. errno = EINVAL;
  669. return EOF;
  670. }
  671. if (fp->fd != -1)
  672. {
  673. if (fflush(fp))
  674. return EOF;
  675. if (close(fp->fd))
  676. rv = EOF;
  677. fp->fd = -1;
  678. }
  679. if (fp->mode & __MODE_FREEBUF)
  680. {
  681. free(fp->bufstart);
  682. fp->mode &= ~__MODE_FREEBUF;
  683. fp->bufstart = fp->bufend = 0;
  684. }
  685. if (fp->mode & __MODE_FREEFIL)
  686. {
  687. FILE *prev = 0, *ptr;
  688. fp->mode = 0;
  689. for (ptr = __IO_list; ptr && ptr != fp; ptr = ptr->next)
  690. ;
  691. if (ptr == fp)
  692. {
  693. if (prev == 0)
  694. __IO_list = fp->next;
  695. else
  696. prev->next = fp->next;
  697. }
  698. free(fp);
  699. }
  700. else
  701. fp->mode = 0;
  702. return rv;
  703. }
  704. #endif
  705. #ifdef L_setbuffer
  706. void
  707. setbuffer(fp, buf, size)
  708. FILE * fp;
  709. char * buf;
  710. int size;
  711. {
  712. fflush(fp);
  713. if( fp->mode & __MODE_FREEBUF ) free(fp->bufstart);
  714. fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF);
  715. if( buf == 0 )
  716. {
  717. fp->bufstart = fp->unbuf;
  718. fp->bufend = fp->unbuf + sizeof(fp->unbuf);
  719. fp->mode |= _IONBF;
  720. }
  721. else
  722. {
  723. fp->bufstart = buf;
  724. fp->bufend = buf+size;
  725. fp->mode |= _IOFBF;
  726. }
  727. fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart;
  728. }
  729. #endif
  730. #ifdef L_setvbuf
  731. int setvbuf(fp, buf, mode, size)
  732. FILE * fp;
  733. char * buf;
  734. int mode;
  735. size_t size;
  736. {
  737. int rv = 0;
  738. fflush(fp);
  739. if( fp->mode & __MODE_FREEBUF ) free(fp->bufstart);
  740. fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF);
  741. fp->bufstart = fp->unbuf;
  742. fp->bufend = fp->unbuf + sizeof(fp->unbuf);
  743. fp->mode |= _IONBF;
  744. if( mode == _IOFBF || mode == _IOLBF )
  745. {
  746. if( size <= 0 ) size = BUFSIZ;
  747. if( buf == 0 )
  748. {
  749. if( (buf = malloc(size)) != 0 )
  750. fp->mode |= __MODE_FREEBUF;
  751. else rv = EOF;
  752. }
  753. if( buf )
  754. {
  755. fp->bufstart = buf;
  756. fp->bufend = buf+size;
  757. fp->mode &= ~__MODE_BUF;
  758. fp->mode |= mode;
  759. }
  760. }
  761. fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart;
  762. return rv;
  763. }
  764. #endif
  765. #ifdef L_ungetc
  766. int
  767. ungetc(c, fp)
  768. int c;
  769. FILE *fp;
  770. {
  771. if (fp->mode & __MODE_WRITING)
  772. fflush(fp);
  773. /* Can't read or there's been an error then return EOF */
  774. if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ)
  775. return EOF;
  776. /* Can't do fast fseeks */
  777. fp->mode |= __MODE_UNGOT;
  778. if( fp->bufpos > fp->bufstart )
  779. return *--fp->bufpos = (unsigned char) c;
  780. else if( fp->bufread == fp->bufstart )
  781. return *fp->bufread++ = (unsigned char) c;
  782. else
  783. return EOF;
  784. }
  785. #endif