stdio.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  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. * Updates:
  8. * 29-Sep-2000 W. Greathouse 1. fgetc copying beyond end of buffer
  9. * 2. stdout needs flushed when input requested on
  10. * stdin.
  11. * 3. bufend was set incorrectly to 4 bytes beyond
  12. * bufin (sizeof a pointer) instead of BUFSIZ.
  13. * This resulted in 4 byte buffers for full
  14. * buffered stdin and stdout and an 8 byte
  15. * buffer for the unbuffered stderr!
  16. */
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <unistd.h>
  20. #include <fcntl.h>
  21. #include <sys/types.h>
  22. #include <malloc.h>
  23. #include <errno.h>
  24. #include <string.h>
  25. #include <assert.h>
  26. #define FIXED_STREAMS 3
  27. #define FIXED_BUFFERS 2
  28. struct fixed_buffer {
  29. unsigned char data[BUFSIZ];
  30. unsigned char used;
  31. };
  32. extern FILE *__IO_list; /* For fflush at exit */
  33. extern FILE _stdio_streams[FIXED_STREAMS];
  34. extern struct fixed_buffer _fixed_buffers[FIXED_BUFFERS];
  35. #if defined L__fopen || defined L_fclose || defined L_setvbuf
  36. extern unsigned char *_alloc_stdio_buffer(size_t size);
  37. extern void _free_stdio_buffer(unsigned char *buf);
  38. #endif
  39. #if defined L__fopen || defined L_fclose
  40. extern void _free_stdio_stream(FILE *fp);
  41. #endif
  42. #ifdef L__alloc_stdio_buffer
  43. unsigned char *_alloc_stdio_buffer(size_t size)
  44. {
  45. if (size == BUFSIZ) {
  46. int i;
  47. for (i = 0; i < FIXED_BUFFERS; i++)
  48. if (!_fixed_buffers[i].used) {
  49. _fixed_buffers[i].used = 1;
  50. return _fixed_buffers[i].data;
  51. }
  52. }
  53. return malloc(size);
  54. }
  55. #endif
  56. #ifdef L__free_stdio_buffer
  57. void _free_stdio_buffer(unsigned char *buf)
  58. {
  59. int i;
  60. for (i = 0; i < FIXED_BUFFERS; i++) {
  61. if (buf == _fixed_buffers[i].data) {
  62. _fixed_buffers[i].used = 0;
  63. return;
  64. }
  65. }
  66. free(buf);
  67. }
  68. #endif
  69. #ifdef L__stdio_init
  70. #if FIXED_BUFFERS < 2
  71. #error FIXED_BUFFERS must be >= 2
  72. #endif
  73. #define bufin (_fixed_buffers[0].data)
  74. #define bufout (_fixed_buffers[1].data)
  75. #define buferr (_stdio_streams[2].unbuf) /* Stderr is unbuffered */
  76. struct fixed_buffer _fixed_buffers[FIXED_BUFFERS];
  77. #if FIXED_STREAMS < 3
  78. #error FIXED_STREAMS must be >= 3
  79. #endif
  80. FILE _stdio_streams[FIXED_STREAMS] = {
  81. {bufin, bufin, bufin, bufin, bufin + BUFSIZ,
  82. 0, _IOFBF | __MODE_READ | __MODE_FREEBUF,
  83. _stdio_streams + 1},
  84. {bufout, bufout, bufout, bufout, bufout + BUFSIZ,
  85. 1, _IOFBF | __MODE_WRITE | __MODE_FREEBUF,
  86. _stdio_streams + 2},
  87. {buferr, buferr, buferr, buferr, buferr + sizeof(buferr),
  88. 2, _IONBF | __MODE_WRITE,
  89. 0},
  90. };
  91. FILE *_stdin = _stdio_streams + 0;
  92. FILE *_stdout = _stdio_streams + 1;
  93. FILE *_stderr = _stdio_streams + 2;
  94. /*
  95. * Note: the following forces linking of the __init_stdio function if
  96. * any of the stdio functions are used since they all call fflush directly
  97. * or indirectly.
  98. */
  99. FILE *__IO_list = _stdio_streams; /* For fflush at exit */
  100. /*
  101. * __stdio_close_all is automatically when exiting if stdio is used.
  102. * See misc/internals/__uClibc_main.c and and stdlib/atexit.c.
  103. */
  104. void __stdio_close_all(void)
  105. {
  106. FILE *fp;
  107. for (fp = __IO_list; fp; fp = fp->next) {
  108. fflush(fp);
  109. close(fp->fd);
  110. }
  111. }
  112. /*
  113. * __init_stdio is automatically by __uClibc_main if stdio is used.
  114. */
  115. void __init_stdio(void)
  116. {
  117. #if (FIXED_BUFFERS > 2) || (FIXED_STREAMS > 3)
  118. int i;
  119. #endif
  120. #if FIXED_BUFFERS > 2
  121. for ( i = 2 ; i < FIXED_BUFFERS ; i++ ) {
  122. _fixed_buffers[i].used = 0;
  123. }
  124. #endif
  125. #if FIXED_STREAMS > 3
  126. for ( i = 3 ; i < FIXED_STREAMS ; i++ ) {
  127. _stdio_streams[i].fd = -1;
  128. }
  129. #endif
  130. _fixed_buffers[0].used = 1;
  131. _fixed_buffers[1].used = 1;
  132. #if _IOFBF != 0 || _IOLBF != 1
  133. #error Assumption violated -- values of _IOFBF and/or _IOLBF
  134. /* This asssumption is also made in _fopen. */
  135. #endif
  136. /* stdout uses line buffering when connected to a tty. */
  137. _stdio_streams[1].mode |= isatty(1);
  138. }
  139. #endif
  140. #ifdef L_fputc
  141. int fputc(ch, fp)
  142. int ch;
  143. FILE *fp;
  144. {
  145. register int v;
  146. v = fp->mode;
  147. /* If last op was a read ... */
  148. if ((v & __MODE_READING) && fflush(fp))
  149. return EOF;
  150. /* Can't write or there's been an EOF or error then return EOF */
  151. if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE)
  152. return EOF;
  153. /* Buffer is full */
  154. if (fp->bufpos >= fp->bufend && fflush(fp))
  155. return EOF;
  156. /* Right! Do it! */
  157. *(fp->bufpos++) = ch;
  158. fp->mode |= __MODE_WRITING;
  159. /* Unbuffered or Line buffered and end of line */
  160. if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF))
  161. && fflush(fp))
  162. return EOF;
  163. /* Can the macro handle this by itself ? */
  164. if (v & (_IOLBF | _IONBF))
  165. fp->bufwrite = fp->bufstart; /* Nope */
  166. else
  167. fp->bufwrite = fp->bufend; /* Yup */
  168. /* Correct return val */
  169. return (unsigned char) ch;
  170. }
  171. #endif
  172. #ifdef L_fgetc
  173. int fgetc(fp)
  174. FILE *fp;
  175. {
  176. int ch;
  177. if (fp->mode & __MODE_WRITING)
  178. fflush(fp);
  179. #if 1
  180. #warning Need to check out tie between stdin and stdout.
  181. /*
  182. * This bit of code needs checking. The way I read the C89 standard,
  183. * there is no guarantee that stdout is flushed before reading stdin.
  184. * Plus, this is broken if either stdin or stdout has been closed and
  185. * reopend.
  186. */
  187. if ( (fp == stdin) && (stdout->fd != -1)
  188. && (stdout->mode & __MODE_WRITING) )
  189. fflush(stdout);
  190. #endif
  191. /* Can't read or there's been an EOF or error then return EOF */
  192. if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) !=
  193. __MODE_READ) return EOF;
  194. /* Nothing in the buffer - fill it up */
  195. if (fp->bufpos >= fp->bufread) {
  196. fp->bufpos = fp->bufread = fp->bufstart;
  197. ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp);
  198. if (ch == 0)
  199. return EOF;
  200. fp->bufread += ch;
  201. fp->mode |= __MODE_READING;
  202. fp->mode &= ~__MODE_UNGOT;
  203. }
  204. ch = *(fp->bufpos++);
  205. return ch;
  206. }
  207. #endif
  208. #ifdef L_fflush
  209. int fflush(fp)
  210. FILE *fp;
  211. {
  212. int len, cc, rv;
  213. char *bstart;
  214. rv = 0;
  215. if (fp == NULL) { /* On NULL flush the lot. */
  216. for (fp = __IO_list; fp; fp = fp->next) {
  217. if (fflush(fp)) {
  218. rv = EOF;
  219. }
  220. }
  221. return rv;
  222. }
  223. /* If there's output data pending */
  224. if (fp->mode & __MODE_WRITING) {
  225. len = fp->bufpos - fp->bufstart;
  226. if (len) {
  227. bstart = fp->bufstart;
  228. /*
  229. * The loop is so we don't get upset by signals or partial writes.
  230. */
  231. do {
  232. cc = write(fp->fd, bstart, len);
  233. if (cc > 0) {
  234. bstart += cc;
  235. len -= cc;
  236. }
  237. }
  238. while (cc > 0 || (cc == -1 && errno == EINTR));
  239. /*
  240. * If we get here with len!=0 there was an error, exactly what to
  241. * do about it is another matter ...
  242. *
  243. * I'll just clear the buffer.
  244. */
  245. if (len) {
  246. fp->mode |= __MODE_ERR;
  247. rv = EOF;
  248. }
  249. }
  250. }
  251. /* If there's data in the buffer sychronise the file positions */
  252. else if (fp->mode & __MODE_READING) {
  253. /* Humm, I think this means sync the file like fpurge() ... */
  254. /* Anyway the user isn't supposed to call this function when reading */
  255. len = fp->bufread - fp->bufpos; /* Bytes buffered but unread */
  256. /* If it's a file, make it good */
  257. if (len > 0 && lseek(fp->fd, (long) -len, 1) < 0) {
  258. /* Hummm - Not certain here, I don't think this is reported */
  259. /*
  260. * fp->mode |= __MODE_ERR; return EOF;
  261. */
  262. }
  263. }
  264. /* All done, no problem */
  265. fp->mode &=
  266. (~(__MODE_READING | __MODE_WRITING | __MODE_EOF | __MODE_UNGOT));
  267. fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart;
  268. return rv;
  269. }
  270. #endif
  271. #ifdef L_fgets
  272. /* Nothing special here ... */
  273. char *fgets(s, count, f)
  274. char *s;
  275. int count;
  276. FILE *f;
  277. {
  278. char *ret;
  279. register size_t i;
  280. register int ch;
  281. ret = s;
  282. for (i = count-1; i > 0; i--) {
  283. ch = getc(f);
  284. if (ch == EOF) {
  285. if (s == ret)
  286. return 0;
  287. break;
  288. }
  289. *s++ = (char) ch;
  290. if (ch == '\n')
  291. break;
  292. }
  293. *s = 0;
  294. if (ferror(f))
  295. return 0;
  296. return ret;
  297. }
  298. #endif
  299. #ifdef L_gets
  300. char *gets(str) /* BAD function; DON'T use it! */
  301. char *str;
  302. {
  303. /* Auwlright it will work but of course _your_ program will crash */
  304. /* if it's given a too long line */
  305. register char *p = str;
  306. register int c;
  307. while (((c = getc(stdin)) != EOF) && (c != '\n'))
  308. *p++ = c;
  309. *p = '\0';
  310. return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */
  311. }
  312. #endif
  313. #ifdef L_fputs
  314. int fputs(str, fp)
  315. const char *str;
  316. FILE *fp;
  317. {
  318. register int n = 0;
  319. while (*str) {
  320. if (putc(*str++, fp) == EOF)
  321. return (EOF);
  322. ++n;
  323. }
  324. return (n);
  325. }
  326. #endif
  327. #ifdef L_puts
  328. int puts(str)
  329. const char *str;
  330. {
  331. register int n;
  332. if (((n = fputs(str, stdout)) == EOF)
  333. || (putc('\n', stdout) == EOF))
  334. return (EOF);
  335. return (++n);
  336. }
  337. #endif
  338. #ifdef L_fread
  339. /*
  340. * fread will often be used to read in large chunks of data calling read()
  341. * directly can be a big win in this case. Beware also fgetc calls this
  342. * function to fill the buffer.
  343. */
  344. size_t fread(buf, size, nelm, fp)
  345. void *buf;
  346. size_t size;
  347. size_t nelm;
  348. FILE *fp;
  349. {
  350. int len, v;
  351. unsigned bytes, got = 0;
  352. v = fp->mode;
  353. /* Want to do this to bring the file pointer up to date */
  354. if (v & __MODE_WRITING)
  355. fflush(fp);
  356. /* Can't read or there's been an EOF or error then return zero */
  357. if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ)
  358. return 0;
  359. /* This could be long, doesn't seem much point tho */
  360. bytes = size * nelm;
  361. len = fp->bufread - fp->bufpos;
  362. if (len >= bytes) { /* Enough buffered */
  363. memcpy(buf, fp->bufpos, (unsigned) bytes);
  364. fp->bufpos += bytes;
  365. return bytes;
  366. } else if (len > 0) { /* Some buffered */
  367. memcpy(buf, fp->bufpos, len);
  368. got = len;
  369. }
  370. /* Need more; do it with a direct read */
  371. len = read(fp->fd, buf + got, (unsigned) (bytes - got));
  372. /* Possibly for now _or_ later */
  373. if (len < 0) {
  374. fp->mode |= __MODE_ERR;
  375. len = 0;
  376. } else if (len == 0)
  377. fp->mode |= __MODE_EOF;
  378. return (got + len) / size;
  379. }
  380. #endif
  381. #ifdef L_fwrite
  382. /*
  383. * Like fread, fwrite will often be used to write out large chunks of
  384. * data; calling write() directly can be a big win in this case.
  385. *
  386. * But first we check to see if there's space in the buffer.
  387. */
  388. size_t fwrite(buf, size, nelm, fp)
  389. const void *buf;
  390. size_t size;
  391. size_t nelm;
  392. FILE *fp;
  393. {
  394. register int v;
  395. int len;
  396. unsigned bytes, put;
  397. v = fp->mode;
  398. /* If last op was a read ... */
  399. if ((v & __MODE_READING) && fflush(fp))
  400. return 0;
  401. /* Can't write or there's been an EOF or error then return 0 */
  402. if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE)
  403. return 0;
  404. /* This could be long, doesn't seem much point tho */
  405. bytes = size * nelm;
  406. len = fp->bufend - fp->bufpos;
  407. /* Flush the buffer if not enough room */
  408. if (bytes > len)
  409. if (fflush(fp))
  410. return 0;
  411. len = fp->bufend - fp->bufpos;
  412. if (bytes <= len) { /* It'll fit in the buffer ? */
  413. fp->mode |= __MODE_WRITING;
  414. memcpy(fp->bufpos, buf, bytes);
  415. fp->bufpos += bytes;
  416. /* If we're not fully buffered */
  417. if (v & (_IOLBF | _IONBF))
  418. fflush(fp);
  419. return nelm;
  420. } else
  421. /* Too big for the buffer */
  422. {
  423. put = bytes;
  424. do {
  425. len = write(fp->fd, buf, bytes);
  426. if (len > 0) {
  427. buf += len;
  428. bytes -= len;
  429. }
  430. }
  431. while (len > 0 || (len == -1 && errno == EINTR));
  432. if (len < 0)
  433. fp->mode |= __MODE_ERR;
  434. put -= bytes;
  435. }
  436. return put / size;
  437. }
  438. #endif
  439. #ifdef L_rewind
  440. void rewind(fp)
  441. FILE *fp;
  442. {
  443. fseek(fp, (long) 0, 0);
  444. clearerr(fp);
  445. }
  446. #endif
  447. #ifdef L_fseek
  448. int fseek(fp, offset, ref)
  449. FILE *fp;
  450. long offset;
  451. int ref;
  452. {
  453. #if 0
  454. /* FIXME: this is broken! BROKEN!!!! */
  455. /* if __MODE_READING and no ungetc ever done can just move pointer */
  456. /* This needs testing! */
  457. if ((fp->mode & (__MODE_READING | __MODE_UNGOT)) == __MODE_READING &&
  458. (ref == SEEK_SET || ref == SEEK_CUR)) {
  459. long fpos = lseek(fp->fd, 0L, SEEK_CUR);
  460. if (fpos == -1)
  461. return EOF;
  462. if (ref == SEEK_CUR) {
  463. ref = SEEK_SET;
  464. offset = fpos + offset + fp->bufpos - fp->bufread;
  465. }
  466. if (ref == SEEK_SET) {
  467. if (offset < fpos
  468. && offset >= fpos + fp->bufstart - fp->bufread) {
  469. fp->bufpos = offset - fpos + fp->bufread;
  470. return 0;
  471. }
  472. }
  473. }
  474. #endif
  475. /* Use fflush to sync the pointers */
  476. if (fflush(fp) || (lseek(fp->fd, offset, ref) < 0)) {
  477. return EOF;
  478. }
  479. return 0;
  480. }
  481. #endif
  482. #ifdef L_ftell
  483. long ftell(fp)
  484. FILE *fp;
  485. {
  486. if (fflush(fp) == EOF)
  487. return EOF;
  488. return lseek(fp->fd, 0L, SEEK_CUR);
  489. }
  490. #endif
  491. #ifdef L__fopen
  492. /*
  493. * This Fopen is all three of fopen, fdopen and freopen. The macros in
  494. * stdio.h show the other names.
  495. */
  496. FILE *__fopen(fname, fd, fp, mode)
  497. const char *fname;
  498. int fd;
  499. FILE *fp;
  500. const char *mode;
  501. {
  502. FILE *nfp;
  503. int open_mode;
  504. int fopen_mode;
  505. int i;
  506. nfp = fp;
  507. /* If we've got an fp, flush it and close the old fd (freopen) */
  508. if (nfp) { /* We don't want to deallocate fp. */
  509. fflush(nfp);
  510. close(nfp->fd);
  511. nfp->mode &= (__MODE_FREEFIL | __MODE_FREEBUF);
  512. }
  513. /* Parse the mode string arg. */
  514. switch (*mode++) {
  515. case 'r': /* read */
  516. fopen_mode = __MODE_READ;
  517. open_mode = O_RDONLY;
  518. break;
  519. case 'w': /* write (create or truncate)*/
  520. fopen_mode = __MODE_WRITE;
  521. open_mode = (O_WRONLY | O_CREAT | O_TRUNC);
  522. break;
  523. case 'a': /* write (create or append) */
  524. fopen_mode = __MODE_WRITE;
  525. open_mode = (O_WRONLY | O_CREAT | O_APPEND);
  526. break;
  527. default: /* illegal mode */
  528. errno = EINVAL;
  529. goto _fopen_ERROR;
  530. }
  531. if ((*mode == 'b')) { /* binary mode (nop for uClibc) */
  532. ++mode;
  533. }
  534. if (*mode == '+') { /* read-write */
  535. ++mode;
  536. fopen_mode |= __MODE_RDWR;
  537. open_mode &= ~(O_RDONLY | O_WRONLY);
  538. open_mode |= O_RDWR;
  539. }
  540. while (*mode) { /* ignore everything else except ... */
  541. if (*mode == 'x') { /* open exclusive -- GNU extension */
  542. open_mode |= O_EXCL;
  543. }
  544. ++mode;
  545. }
  546. if (fp == 0) { /* We need a FILE so allocate it before */
  547. for (i = 0; i < FIXED_STREAMS; i++) { /* we potentially call open. */
  548. if (_stdio_streams[i].fd == -1) {
  549. nfp = _stdio_streams + i;
  550. break;
  551. }
  552. }
  553. if ((i == FIXED_STREAMS) && (!(nfp = malloc(sizeof(FILE))))) {
  554. return 0;
  555. }
  556. nfp->mode = __MODE_FREEFIL;
  557. /* Initially set to use 8 byte buffer in FILE structure */
  558. nfp->bufstart = nfp->unbuf;
  559. nfp->bufend = nfp->unbuf + sizeof(nfp->unbuf);
  560. }
  561. if (fname) { /* Open the file itself */
  562. fd = open(fname, open_mode, 0666);
  563. }
  564. #warning fdopen should check that modes are compatible with existing fd.
  565. if (fd < 0) { /* Error from open or bad arg passed. */
  566. _fopen_ERROR:
  567. if (nfp) {
  568. if (nfp->mode & __MODE_FREEBUF) {
  569. _free_stdio_buffer(nfp->bufstart);
  570. }
  571. _free_stdio_stream(nfp);
  572. }
  573. return 0;
  574. }
  575. nfp->fd = fd; /* Set FILE's fd before adding to open list. */
  576. if (fp == 0) { /* Not freopen so... */
  577. nfp->next = __IO_list; /* use newly created FILE and */
  578. __IO_list = nfp; /* add it to the list of open files. */
  579. if ((nfp->bufstart = _alloc_stdio_buffer(BUFSIZ)) != 0) {
  580. nfp->bufend = nfp->bufstart + BUFSIZ;
  581. nfp->mode |= __MODE_FREEBUF;
  582. }
  583. }
  584. /* Ok, file's ready clear the buffer and save important bits */
  585. nfp->bufpos = nfp->bufread = nfp->bufwrite = nfp->bufstart;
  586. nfp->mode |= fopen_mode;
  587. nfp->mode |= isatty(fd);
  588. return nfp;
  589. }
  590. #endif
  591. #ifdef L_fclose
  592. int fclose(fp)
  593. FILE *fp;
  594. {
  595. FILE *prev;
  596. FILE *ptr;
  597. int rv;
  598. assert(fp); /* Shouldn't be NULL */
  599. assert(fp->fd >= 0); /* Need file descriptor in valid range. */
  600. rv = fflush(fp);
  601. if (close(fp->fd)) { /* Need to close even if fflush fails. */
  602. rv = EOF;
  603. }
  604. if (fp->mode & __MODE_FREEBUF) { /* Free buffer if necessary. */
  605. _free_stdio_buffer(fp->bufstart);
  606. }
  607. prev = 0; /* Remove file from open list. */
  608. for (ptr = __IO_list; ptr ; ptr = ptr->next) {
  609. if (ptr == fp) {
  610. if (prev == 0) {
  611. __IO_list = fp->next;
  612. } else {
  613. prev->next = fp->next;
  614. }
  615. break;
  616. }
  617. prev = ptr;
  618. }
  619. _free_stdio_stream(fp); /* Finally free the stream if necessary. */
  620. return rv;
  621. }
  622. #endif
  623. #ifdef L__free_stdio_stream
  624. /* The following is only called by fclose and _fopen. */
  625. void _free_stdio_stream(FILE *fp)
  626. {
  627. int i;
  628. if (!(fp->mode & __MODE_FREEFIL)) {
  629. return;
  630. }
  631. for (i = 0; i < FIXED_STREAMS; i++) {
  632. if (fp == _stdio_streams + i) {
  633. fp->fd = -1;
  634. return;
  635. }
  636. }
  637. free(fp);
  638. }
  639. #endif
  640. #ifdef L_setbuffer
  641. /*
  642. * Rewritten Feb 2001 Manuel Novoa III
  643. *
  644. * Just call setvbuf with appropriate args.
  645. */
  646. void setbuffer(FILE *fp, char *buf, size_t size)
  647. {
  648. int mode;
  649. mode = _IOFBF;
  650. if (!buf) {
  651. mode = _IONBF;
  652. }
  653. setvbuf(fp, buf, mode, size);
  654. }
  655. #endif
  656. #ifdef L_setvbuf
  657. /*
  658. * Rewritten Feb 2001 Manuel Novoa III
  659. *
  660. * Bugs in previous version:
  661. * No checking on mode arg.
  662. * If alloc of new buffer failed, some FILE fields not set correctly.
  663. * If requested buf is same size as current and buf is NULL, then
  664. * don't free current buffer; just use it.
  665. */
  666. int setvbuf(FILE *fp, char *buf, int mode, size_t size)
  667. {
  668. int allocated_buf_flag;
  669. if (fflush(fp)) { /* Standard requires no ops before setvbuf */
  670. return EOF; /* called. We'll try to be more flexible. */
  671. }
  672. if (mode & ~__MODE_BUF) { /* Illegal mode. */
  673. return EOF;
  674. }
  675. if ((mode == _IONBF) || (size <= sizeof(fp->unbuf))) {
  676. size = sizeof(fp->unbuf); /* Either no buffering requested or */
  677. buf = fp->unbuf; /* requested buffer size very small. */
  678. }
  679. fp->mode &= ~(__MODE_BUF); /* Clear current mode */
  680. fp->mode |= mode; /* and set new one. */
  681. allocated_buf_flag = 0;
  682. if ((!buf) && (size != (fp->bufend - fp->bufstart))) {
  683. /* No buffer supplied and requested size different from current. */
  684. allocated_buf_flag = __MODE_FREEBUF;
  685. if (!(buf = _alloc_stdio_buffer(size))) {
  686. return EOF;
  687. }
  688. }
  689. if (buf && (buf != (char *) fp->bufstart)) { /* Want different buffer. */
  690. if (fp->mode & __MODE_FREEBUF) {
  691. _free_stdio_buffer(fp->bufstart);
  692. fp->mode &= ~(__MODE_FREEBUF);
  693. }
  694. fp->mode |= allocated_buf_flag;
  695. fp->bufstart = buf;
  696. fp->bufend = buf + size;
  697. fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart;
  698. }
  699. return 0;
  700. }
  701. #endif
  702. #ifdef L_setbuf
  703. void setbuf(FILE *fp, char *buf)
  704. {
  705. int mode;
  706. mode = _IOFBF;
  707. if (!buf) {
  708. mode = _IONBF;
  709. }
  710. setvbuf(fp, buf, mode, BUFSIZ);
  711. }
  712. #endif
  713. #ifdef L_setlinebuf
  714. void setlinebuf(FILE *fp)
  715. {
  716. setvbuf(fp, NULL, _IOLBF, BUFSIZ);
  717. }
  718. #endif
  719. #ifdef L_ungetc
  720. int ungetc(c, fp)
  721. int c;
  722. FILE *fp;
  723. {
  724. if (fp->mode & __MODE_WRITING)
  725. fflush(fp);
  726. /* Can't read or there's been an error then return EOF */
  727. if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ)
  728. return EOF;
  729. /* Can't do fast fseeks */
  730. fp->mode |= __MODE_UNGOT;
  731. if (fp->bufpos > fp->bufstart)
  732. return *--fp->bufpos = (unsigned char) c;
  733. else if (fp->bufread == fp->bufstart)
  734. return *fp->bufread++ = (unsigned char) c;
  735. else
  736. return EOF;
  737. }
  738. #endif
  739. #ifdef L_fopen
  740. #undef fopen
  741. FILE *fopen(const char *__restrict filename,
  742. const char *__restrict mode)
  743. {
  744. return __fopen(filename, -1, NULL, mode);
  745. }
  746. #endif
  747. #ifdef L_freopen
  748. #undef freopen
  749. FILE *freopen(__const char *__restrict filename,
  750. __const char *__restrict mode, FILE *__restrict fp)
  751. {
  752. return __fopen(filename, -1, fp, mode);
  753. }
  754. #endif
  755. #ifdef L_fdopen
  756. #undef fdopen
  757. FILE *fdopen(int fd, __const char *mode)
  758. {
  759. return __fopen(NULL, fd, NULL, mode);
  760. }
  761. #endif
  762. #ifdef L_getchar
  763. #undef getchar
  764. int getchar(void)
  765. {
  766. return getc(stdin);
  767. }
  768. #endif
  769. #ifdef L_putchar
  770. #undef putchar
  771. int putchar(int c)
  772. {
  773. return putc(c, stdout);
  774. }
  775. #endif
  776. #ifdef L_clearerr
  777. #undef clearerr
  778. void clearerr(FILE *fp)
  779. {
  780. assert(fp);
  781. fp->mode &= ~(__MODE_EOF|__MODE_ERR);
  782. }
  783. #endif
  784. #ifdef L_feof
  785. #undef feof
  786. int feof(FILE *fp)
  787. {
  788. assert(fp);
  789. return ((fp->mode & __MODE_EOF) != 0);
  790. }
  791. #endif
  792. #ifdef L_ferror
  793. #undef ferror
  794. int ferror(FILE *fp)
  795. {
  796. assert(fp);
  797. return ((fp->mode & __MODE_ERR) != 0);
  798. }
  799. #endif
  800. #ifdef L_fileno
  801. int fileno(FILE *fp)
  802. {
  803. if (!fp || (fp->fd < 0)) {
  804. return -1;
  805. }
  806. return fp->fd;
  807. }
  808. #endif
  809. #ifdef L_fgetpos
  810. int fgetpos(FILE *fp, fpos_t *pos)
  811. {
  812. fpos_t p;
  813. if (!pos) { /* NULL pointer. */
  814. errno = EINVAL;
  815. return -1;
  816. }
  817. if ((p = ftell(fp)) < 0) { /* ftell failed. */
  818. return -1; /* errno set by ftell. */
  819. }
  820. *pos = p;
  821. return 0;
  822. }
  823. #endif
  824. #ifdef L_fsetpos
  825. int fsetpos(FILE *fp, __const fpos_t *pos)
  826. {
  827. if (pos) { /* Pointer ok. */
  828. return fseek(fp, *pos, SEEK_SET);
  829. }
  830. errno = EINVAL; /* NULL pointer. */
  831. return EOF;
  832. }
  833. #endif