stdio.c 19 KB

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