freopen.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * freopen.c - open a file and associate a stream with it
  3. */
  4. /* $Id$ */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include "loc_incl.h"
  8. #define PMODE 0666
  9. /* Do not "optimize" this file to use the open with O_CREAT if the file
  10. * does not exist. The reason is given in fopen.c.
  11. */
  12. #define O_RDONLY 0
  13. #define O_WRONLY 1
  14. #define O_RDWR 2
  15. #define O_CREAT 0x010
  16. #define O_TRUNC 0x020
  17. #define O_APPEND 0x040
  18. int _open(const char *path, int flags);
  19. int _creat(const char *path, int mode);
  20. int _close(int d);
  21. FILE *
  22. freopen(const char *name, const char *mode, FILE *stream)
  23. {
  24. register int i;
  25. int rwmode = 0, rwflags = 0;
  26. int fd, flags = stream->_flags & (_IONBF | _IOFBF | _IOLBF | _IOMYBUF);
  27. (void) fflush(stream); /* ignore errors */
  28. (void) _close(fileno(stream));
  29. switch(*mode++) {
  30. case 'r':
  31. flags |= _IOREAD;
  32. rwmode = O_RDONLY;
  33. break;
  34. case 'w':
  35. flags |= _IOWRITE;
  36. rwmode = O_WRONLY;
  37. rwflags = O_CREAT | O_TRUNC;
  38. break;
  39. case 'a':
  40. flags |= _IOWRITE | _IOAPPEND;
  41. rwmode = O_WRONLY;
  42. rwflags |= O_APPEND | O_CREAT;
  43. break;
  44. default:
  45. return (FILE *)NULL;
  46. }
  47. while (*mode) {
  48. switch(*mode++) {
  49. case 'b':
  50. continue;
  51. case '+':
  52. rwmode = O_RDWR;
  53. flags |= _IOREAD | _IOWRITE;
  54. continue;
  55. /* The sequence may be followed by aditional characters */
  56. default:
  57. break;
  58. }
  59. break;
  60. }
  61. if ((rwflags & O_TRUNC)
  62. || (((fd = _open(name, rwmode)) < 0)
  63. && (rwflags & O_CREAT))) {
  64. if (((fd = _creat(name, PMODE)) < 0) && flags | _IOREAD) {
  65. (void) _close(fd);
  66. fd = _open(name, rwmode);
  67. }
  68. }
  69. if (fd < 0) {
  70. for( i = 0; i < FOPEN_MAX; i++) {
  71. if (stream == __iotab[i]) {
  72. __iotab[i] = 0;
  73. break;
  74. }
  75. }
  76. if (stream != stdin && stream != stdout && stream != stderr)
  77. free((void *)stream);
  78. return (FILE *)NULL;
  79. }
  80. stream->_count = 0;
  81. stream->_fd = fd;
  82. stream->_flags = flags;
  83. return stream;
  84. }