filebuf* filebuf::attach(int fd) { if (is_open()) return NULL; _fb._fileno = fd; xsetflags(0, _S_NO_READS+_S_NO_WRITES); return this; }
int filebuf::underflow() { #if 0 /* SysV does not make this test; take it out for compatibility */ if (fp->_flags & __SEOF) return (EOF); #endif if (xflags() & _S_NO_READS) return EOF; if (gptr() < egptr()) return *(unsigned char*)gptr(); allocbuf(); // FIXME This can/should be moved to __streambuf ?? if ((xflags() & _S_LINE_BUF) || unbuffered()) { // Flush all line buffered files before reading. streambuf::flush_all_linebuffered(); } #if 1 if (pptr() > pbase()) if (do_flush()) return EOF; #endif _G_ssize_t count = sys_read(base(), ebuf() - base()); if (count <= 0) { if (count == 0) xsetflags(_S_EOF_SEEN); else xsetflags(_S_ERR_SEEN), count = 0; } setg(base(), base(), base() + count); setp(base(), base()); if (count == 0) return EOF; if (_fb._offset >= 0) _fb._offset += count; return *(unsigned char*)gptr(); }
filebuf* filebuf::open(const char *filename, const char *mode) { if (is_open()) return NULL; int oflags = 0, omode; int read_write; int oprot = 0666; switch (*mode++) { case 'r': omode = O_RDONLY; read_write = _S_NO_WRITES; break; case 'w': omode = O_WRONLY; oflags = O_CREAT|O_TRUNC; read_write = _S_NO_READS; break; case 'a': omode = O_WRONLY; oflags = O_CREAT|O_APPEND; read_write = _S_NO_READS|_S_IS_APPENDING; break; default: errno = EINVAL; return NULL; } if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) { omode = O_RDWR; read_write = 0; } int fdesc = ::open(filename, omode|oflags, oprot); if (fdesc < 0) return NULL; _fb._fileno = fdesc; xsetflags(read_write, _S_NO_READS+_S_NO_WRITES+_S_IS_APPENDING); if (read_write & _S_IS_APPENDING) if (seekoff(0, ios::end) == EOF) return NULL; _link_in(); return this; }
procbuf *procbuf::open(const char *command, int mode) { int read_or_write; if (is_open()) return NULL; int pipe_fds[2]; int parent_end, child_end; if (::pipe(pipe_fds) < 0) return NULL; if (mode == ios::in) { parent_end = pipe_fds[0]; child_end = pipe_fds[1]; read_or_write = _S_NO_WRITES; } else { parent_end = pipe_fds[1]; child_end = pipe_fds[0]; read_or_write = _S_NO_READS; } _pid = FORK(); if (_pid == 0) { ::close(parent_end); int child_std_end = mode == ios::in ? 1 : 0; if (child_end != child_std_end) { ::dup2(child_end, child_std_end); ::close(child_end); } ::execl("/bin/sh", "sh", "-c", command, NULL); ::_exit(127); } ::close(child_end); if (_pid < 0) { ::close(parent_end); return NULL; } _fb._fileno = parent_end; xsetflags(read_or_write, _S_NO_READS|_S_NO_WRITES); return this; }
filebuf* filebuf::open(const char *filename, ios::openmode mode, int prot) { if (is_open()) return NULL; int posix_mode; int read_write; if (mode & ios::app) mode |= ios::out; if ((mode & (ios::in|ios::out)) == (ios::in|ios::out)) { posix_mode = O_RDWR; read_write = 0; } else if (mode & ios::out) posix_mode = O_WRONLY, read_write = _S_NO_READS; else if (mode & (int)ios::in) posix_mode = O_RDONLY, read_write = _S_NO_WRITES; else posix_mode = 0, read_write = _S_NO_READS+_S_NO_WRITES; if ((mode & (int)ios::trunc) || mode == (int)ios::out) posix_mode |= O_TRUNC; if (mode & ios::app) posix_mode |= O_APPEND, read_write |= _S_IS_APPENDING; if (!(mode & (int)ios::nocreate) && mode != ios::in) posix_mode |= O_CREAT; if (mode & (int)ios::noreplace) posix_mode |= O_EXCL; int fd = ::open(filename, posix_mode, prot); if (fd < 0) return NULL; _fb._fileno = fd; xsetflags(read_write, _S_NO_READS+_S_NO_WRITES+_S_IS_APPENDING); if (mode & (ios::ate|ios::app)) { if (seekoff(0, ios::end) == EOF) return NULL; } _link_in(); return this; }
filebuf* filebuf::open(const char *filename, const char *mode) { // fdopen in stdio need this. if (is_open()) { // file is open. we cannot open a new file if (filename) { errno = EINVAL; return NULL; } } else { // file is not open. we have to open a new file if (filename == NULL) { errno = EINVAL; return NULL; } } int oflags = 0, omode; int read_write; int oprot = 0666; switch (*mode++) { case 'r': omode = O_RDONLY; read_write = _S_NO_WRITES; break; case 'w': omode = O_WRONLY; oflags = O_CREAT|O_TRUNC; read_write = _S_NO_READS; break; case 'a': omode = O_WRONLY; oflags = O_CREAT|O_APPEND; read_write = _S_NO_READS|_S_IS_APPENDING; break; default: errno = EINVAL; return NULL; } if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) { omode = O_RDWR; read_write &= _S_IS_APPENDING; } xsetflags(read_write, _S_NO_READS+_S_NO_WRITES+_S_IS_APPENDING); if (filename) { int fdesc = ::open(filename, omode|oflags, oprot); if (fdesc < 0) return NULL; _fb._fileno = fdesc; if (read_write & _S_IS_APPENDING) if (seekoff(0, ios::end) == EOF && errno != ESPIPE) return NULL; } else { // Get old status flag. int status_flag = ::fcntl (_fb._fileno, F_GETFL); if (status_flag < 0) return NULL; // We should only do O_APPEND. #if 0 // We cannot change the access mode for an open file descriptor. if ((status_flag & O_ACCMODE) != omode) { errno = EINVAL; return NULL; } #endif // Get new status flag. oflags &= O_APPEND; // check if we need to change the status flag. if ((status_flag & O_APPEND) != oflags) { // Set new status flag. status_flag = (status_flag & ~O_APPEND) | oflags; if (::fcntl (_fb._fileno, F_SETFL, status_flag) < 0) return NULL; } // Seek off to the current file position. _fb._offset = -1; if (seekoff(0, ios::cur) == EOF) if (errno != ESPIPE) return NULL; else _fb._offset = 0; } _link_in(); return this; }
filebuf* filebuf::open(const char *filename, ios::openmode mode, int prot) { // fdopen in stdio need this. if (is_open()) { // file is open. we cannot open a new file if (filename) { errno = EINVAL; return NULL; } } else { // file is not open. we have to open a new file if (filename == NULL) { errno = EINVAL; return NULL; } } int posix_mode; int read_write; if (mode & ios::app) mode |= ios::out; if ((mode & (ios::in|ios::out)) == (ios::in|ios::out)) { posix_mode = O_RDWR; read_write = 0; } else if (mode & ios::out) posix_mode = O_WRONLY, read_write = _S_NO_READS; else if (mode & (int)ios::in) posix_mode = O_RDONLY, read_write = _S_NO_WRITES; else posix_mode = 0, read_write = _S_NO_READS+_S_NO_WRITES; if ((mode & (int)ios::trunc) || mode == (int)ios::out) posix_mode |= O_TRUNC; if (mode & ios::app) posix_mode |= O_APPEND, read_write |= _S_IS_APPENDING; if (!(mode & (int)ios::nocreate) && mode != ios::in) posix_mode |= O_CREAT; if (mode & (int)ios::noreplace) posix_mode |= O_EXCL; xsetflags(read_write, _S_NO_READS+_S_NO_WRITES+_S_IS_APPENDING); if (filename) { int fd = ::open(filename, posix_mode, prot); if (fd < 0) return NULL; _fb._fileno = fd; if (mode & (ios::ate|ios::app)) { if (seekoff(0, ios::end) == EOF && errno != ESPIPE) return NULL; } } else { // Get old status flag. int status_flag = ::fcntl (_fb._fileno, F_GETFL); if (status_flag < 0) return NULL; // We should only do O_APPEND. #if 0 // Get new access mode. int new_access_mode = posix_mode & (O_RDWR | O_WRONLY | O_RDONLY); // We cannot change the access mode for an open file descriptor. if ((status_flag & O_ACCMODE) != new_access_mode) { errno = EINVAL; return NULL; } #endif // Get new status flag. posix_mode &= O_APPEND; // check if we need to change the status flag. if ((status_flag & O_APPEND) != posix_mode) { // Set new status flag. status_flag = (status_flag & ~O_APPEND) | posix_mode; if (::fcntl (_fb._fileno, F_SETFL, status_flag) < 0) return NULL; } // Seek off to the current file position. _fb._offset = -1; if (seekoff(0, ios::cur) == EOF) if (errno != ESPIPE) return NULL; else _fb._offset = 0; } _link_in(); return this; }