freopen.c

Go to the documentation of this file.
00001 /*
00002  * freopen.c - open a file and associate a stream with it
00003  */
00004 /* $Header: /opt/proj/minix/cvsroot/src/lib/stdio/freopen.c,v 1.4 2006/02/02 16:59:07 beng Exp $ */
00005 
00006 #if     defined(_POSIX_SOURCE)
00007 #include        <sys/types.h>
00008 #endif
00009 #include        <stdio.h>
00010 #include        <stdlib.h>
00011 #include        "loc_incl.h"
00012 #include        <sys/stat.h>
00013 
00014 #define PMODE           0666
00015 
00016 /* Do not "optimize" this file to use the open with O_CREAT if the file
00017  * does not exist. The reason is given in fopen.c.
00018  */
00019 #define O_RDONLY        0
00020 #define O_WRONLY        1
00021 #define O_RDWR          2
00022 
00023 #define O_CREAT         0x010
00024 #define O_TRUNC         0x020
00025 #define O_APPEND        0x040
00026 
00027 int _open(const char *path, int flags);
00028 int _creat(const char *path, _mnx_Mode_t mode);
00029 int _close(int d);
00030 
00031 FILE *
00032 freopen(const char *name, const char *mode, FILE *stream)
00033 {
00034         register int i;
00035         struct stat st;
00036         int rwmode = 0, rwflags = 0;
00037         int fd, flags = stream->_flags & (_IONBF | _IOFBF | _IOLBF | _IOMYBUF);
00038 
00039         (void) fflush(stream);                          /* ignore errors */
00040         (void) _close(fileno(stream));
00041 
00042         switch(*mode++) {
00043         case 'r':
00044                 flags |= _IOREAD;       
00045                 rwmode = O_RDONLY;
00046                 break;
00047         case 'w':
00048                 flags |= _IOWRITE;
00049                 rwmode = O_WRONLY;
00050                 rwflags = O_CREAT | O_TRUNC;
00051                 break;
00052         case 'a': 
00053                 flags |= _IOWRITE | _IOAPPEND;
00054                 rwmode = O_WRONLY;
00055                 rwflags |= O_APPEND | O_CREAT;
00056                 break;         
00057         default:
00058                 goto loser;
00059         }
00060 
00061         while (*mode) {
00062                 switch(*mode++) {
00063                 case 'b':
00064                         continue;
00065                 case '+':
00066                         rwmode = O_RDWR;
00067                         flags |= _IOREAD | _IOWRITE;
00068                         continue;
00069                 /* The sequence may be followed by aditional characters */
00070                 default:
00071                         break;
00072                 }
00073                 break;
00074         }
00075 
00076         if ((rwflags & O_TRUNC)
00077             || (((fd = _open(name, rwmode)) < 0)
00078                     && (rwflags & O_CREAT))) {
00079                 if (((fd = _creat(name, PMODE)) < 0) && flags | _IOREAD) {
00080                         (void) _close(fd);
00081                         fd = _open(name, rwmode);
00082                 }
00083         }
00084 
00085         if (fd < 0) {
00086                 goto loser;
00087         }
00088 
00089         if ( fstat( fd, &st ) == 0 ) {
00090                 if ( S_ISFIFO(st.st_mode) ) flags |= _IOFIFO;
00091         } else {
00092                 goto loser;
00093         }
00094         
00095         stream->_count = 0;
00096         stream->_fd = fd;
00097         stream->_flags = flags;
00098         return stream;
00099 
00100 loser:
00101         for( i = 0; i < FOPEN_MAX; i++) {
00102                 if (stream == __iotab[i]) {
00103                         __iotab[i] = 0;
00104                         break;
00105                 }
00106         }
00107         if (stream != stdin && stream != stdout && stream != stderr)
00108                 free((void *)stream);
00109         return (FILE *)NULL;    
00110 }

Generated on Fri Apr 14 22:57:27 2006 for minix by  doxygen 1.4.6