source: trunk/minix/lib/stdio/freopen.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 2.1 KB
Line 
1/*
2 * freopen.c - open a file and associate a stream with it
3 */
4/* $Header: /cvsup/minix/src/lib/stdio/freopen.c,v 1.4 2006/02/02 16:59:07 beng Exp $ */
5
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>
13
14#define PMODE 0666
15
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.
18 */
19#define O_RDONLY 0
20#define O_WRONLY 1
21#define O_RDWR 2
22
23#define O_CREAT 0x010
24#define O_TRUNC 0x020
25#define O_APPEND 0x040
26
27int _open(const char *path, int flags);
28int _creat(const char *path, _mnx_Mode_t mode);
29int _close(int d);
30
31FILE *
32freopen(const char *name, const char *mode, FILE *stream)
33{
34 register int i;
35 struct stat st;
36 int rwmode = 0, rwflags = 0;
37 int fd, flags = stream->_flags & (_IONBF | _IOFBF | _IOLBF | _IOMYBUF);
38
39 (void) fflush(stream); /* ignore errors */
40 (void) _close(fileno(stream));
41
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;
59 }
60
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;
72 }
73 break;
74 }
75
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);
82 }
83 }
84
85 if (fd < 0) {
86 goto loser;
87 }
88
89 if ( fstat( fd, &st ) == 0 ) {
90 if ( S_ISFIFO(st.st_mode) ) flags |= _IOFIFO;
91 } else {
92 goto loser;
93 }
94
95 stream->_count = 0;
96 stream->_fd = fd;
97 stream->_flags = flags;
98 return stream;
99
100loser:
101 for( i = 0; i < FOPEN_MAX; i++) {
102 if (stream == __iotab[i]) {
103 __iotab[i] = 0;
104 break;
105 }
106 }
107 if (stream != stdin && stream != stdout && stream != stderr)
108 free((void *)stream);
109 return (FILE *)NULL;
110}
Note: See TracBrowser for help on using the repository browser.