void filebuf::init() { _fb._offset = 0; _link_in(); _fb._fileno = -1; }
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; }
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; }