Fixes for /usr/xbin binaries bootstrap dir.
[minix3.git] / lib / stdio / freopen.c
blob20a42505e0922576151184a4682d9375facfac20
1 /*
2 * freopen.c - open a file and associate a stream with it
3 */
4 /* $Header$ */
6 #if defined(_POSIX_SOURCE)
7 #include <sys/types.h>
8 #endif
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include "loc_incl.h"
12 #include <sys/stat.h>
14 #define PMODE 0666
16 /* Do not "optimize" this file to use the open with O_CREAT if the file
17 * does not exist. The reason is given in fopen.c.
19 #define O_RDONLY 0
20 #define O_WRONLY 1
21 #define O_RDWR 2
23 #define O_CREAT 0x010
24 #define O_TRUNC 0x020
25 #define O_APPEND 0x040
27 int _open(const char *path, int flags);
28 int _creat(const char *path, _mnx_Mode_t mode);
29 int _close(int d);
31 FILE *
32 freopen(const char *name, const char *mode, FILE *stream)
34 register int i;
35 struct stat st;
36 int rwmode = 0, rwflags = 0;
37 int fd, flags = stream->_flags & (_IONBF | _IOFBF | _IOLBF | _IOMYBUF);
39 (void) fflush(stream); /* ignore errors */
40 (void) _close(fileno(stream));
42 switch(*mode++) {
43 case 'r':
44 flags |= _IOREAD;
45 rwmode = O_RDONLY;
46 break;
47 case 'w':
48 flags |= _IOWRITE;
49 rwmode = O_WRONLY;
50 rwflags = O_CREAT | O_TRUNC;
51 break;
52 case 'a':
53 flags |= _IOWRITE | _IOAPPEND;
54 rwmode = O_WRONLY;
55 rwflags |= O_APPEND | O_CREAT;
56 break;
57 default:
58 goto loser;
61 while (*mode) {
62 switch(*mode++) {
63 case 'b':
64 continue;
65 case '+':
66 rwmode = O_RDWR;
67 flags |= _IOREAD | _IOWRITE;
68 continue;
69 /* The sequence may be followed by aditional characters */
70 default:
71 break;
73 break;
76 if ((rwflags & O_TRUNC)
77 || (((fd = _open(name, rwmode)) < 0)
78 && (rwflags & O_CREAT))) {
79 if (((fd = _creat(name, PMODE)) < 0) && flags | _IOREAD) {
80 (void) _close(fd);
81 fd = _open(name, rwmode);
85 if (fd < 0) {
86 goto loser;
89 if ( fstat( fd, &st ) == 0 ) {
90 if ( S_ISFIFO(st.st_mode) ) flags |= _IOFIFO;
91 } else {
92 goto loser;
95 stream->_count = 0;
96 stream->_fd = fd;
97 stream->_flags = flags;
98 return stream;
100 loser:
101 for( i = 0; i < FOPEN_MAX; i++) {
102 if (stream == __iotab[i]) {
103 __iotab[i] = 0;
104 break;
107 if (stream != stdin && stream != stdout && stream != stderr)
108 free((void *)stream);
109 return (FILE *)NULL;