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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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;
}