stdio_streambuf_base::pos_type stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir, ios_base::openmode /* mode */) { int whence; switch (dir) { case ios_base::beg: whence = SEEK_SET; break; case ios_base::cur: whence = SEEK_CUR; break; case ios_base::end: whence = SEEK_END; break; default: return pos_type(-1); } if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) { FPOS_T pos; FGETPOS(_M_file, &pos); // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead // of a primitive type return pos_type(pos); } else return pos_type(-1); }
stdio_streambuf_base::pos_type stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir, ios_base::openmode /* mode */) { int whence; switch (dir) { case ios_base::beg: whence = SEEK_SET; break; case ios_base::cur: whence = SEEK_CUR; break; case ios_base::end: whence = SEEK_END; break; default: return pos_type(-1); } if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) { FPOS_T pos; FGETPOS(_M_file, &pos); // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead // of a primitive type #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2)))) || defined (__ARMCC_VERSION) return pos_type((streamoff)pos.__pos); #elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__) return pos_type(pos.__fpos_elem[ 0 ]); #elif defined (__EMX__) return pos_type((streamoff)pos._pos); #else return pos_type(pos); #endif } else return pos_type(-1); }
FILE *open_file(flow_state_t *flow_state) { char *filename = flow_filename(flow_state->flow); int done; /* This shouldn't be called if the file is already open */ if (flow_state->fp) { DEBUG(20) ("huh -- trying to open already open file!"); return flow_state->fp; } /* Now try and open the file */ do { if (attempt_fopen(flow_state, filename) != NULL) { /* open succeeded... great */ done = 1; } else { if (errno == ENFILE || errno == EMFILE) { /* open failed because too many files are open... close one and try again */ contract_fd_ring(); DEBUG(5) ("too many open files -- contracting FD ring to %d", max_fds); done = 0; } else { /* open failed for some other reason... give up */ done = 1; } } } while (!done); /* If the file isn't open at this point, there's a problem */ if (flow_state->fp == NULL) { /* we had some problem opening the file -- set FINISHED so we * don't keep trying over and over again to reopen it */ SET_BIT(flow_state->flags, FLOW_FINISHED); perror(filename); return NULL; } /* Now we decide which FD slot we use, and close the file that's * there (if any). Note that even if flow_state is not NULL, its * associated file pointer may already be closed. Note well that we * DO NOT free the state that we find in our slot; the state stays * around forever (pointed to by the hash table). This table only * keeps a pointer to state structures that have open files so that * we can close them later. * * We are putting the close after the open so that we don't bother * closing files if the open fails. (For this, we pay a price of * needing to keep a spare, idle FD around.) */ if (++next_slot == max_fds) { /* take this opportunity to sort from oldest to newest -- * optimally we'd like to do this before every close, but that * might take too long. */ sort_fds(); next_slot = 0; } /* close the next one in line */ if (fd_ring[next_slot] != NULL) close_file(fd_ring[next_slot]); /* put ourslves in its place */ fd_ring[next_slot] = flow_state; /* set flags and remember where in the file we are */ SET_BIT(flow_state->flags, FLOW_FILE_EXISTS); FGETPOS(flow_state->fp, &(flow_state->pos)); return flow_state->fp; }