1 # STDIO/FOPEN.D - Implement fopen() and fclose()
6 # Open or create a buffered file object with the modes specified.
7 # Bidirectional mode is enabled if the descriptor is not a regular file.
8 # Any newly created descriptors are automatically O_CLOEXEC (the caller
9 # does not have to supply the 'e' flag in the mode string).
11 # fdopen() and fdreopen() do not change the current O_CLOEXEC state of
12 # the underlying descriptor unless you pass the 'e' flag, in which case
13 # O_CLOEXEC is set. But it is likely already set.
19 File.fdopen(int fd, const char *mode)
23 fp.fdreopen(fd, mode);
33 File.fopen(const char *path, const char *mode)
37 fp.freopen(path, mode);
48 File.fdreopen(int fd, const char *mode)
54 this.mode = File.M_FULL;
63 File.freopen(const char *path, const char *mode)
68 if (this.opflags & Fs.O_APPEND)
69 this.fs.fappend(TRUE);
71 this.fs.fappend(FALSE);
76 this.fs.open(path, this.opflags, 0666);
90 # Ok to call fflush() even for in-stream as long as the out
98 # Clean-out the buffer in case of reuse. This will free the buffers.
115 File.parsemode(const char *mode)
119 # note that the Rune open() automatically sets O_CLOEXEC, but do it
122 this.opflags = Fs.O_CLOEXEC;
130 this.opflags |= Fs.O_TRUNC | Fs.O_CREAT;
134 this.opflags |= Fs.O_TRUNC | Fs.O_CREAT | Fs.O_APPEND;
137 this.fs.error = Sys.EINVAL;
140 for (++mode; *mode; ++mode) {
142 case '+': # reading and writing
146 this.opflags |= Fs.O_EXCL;
148 case 'e': # O_CLOEXEC - no effect (on by default)
149 case 'b': # O_BINARY - no effect (implied by system)
162 if (st.fstat(this.fs.fd) == 0 && st.S_ISREG())
163 this.flags |= F_ISREG;
165 this.flags &= ~F_ISREG;
168 public destructor method
172 stdout->show("DESTRUCT");