Example #1
0
int TXTFAM::GetFileLength(PGLOBAL g)
  {
  char    filename[_MAX_PATH];
  int     h;
  int    len;

  PlugSetPath(filename, To_File, Tdbp->GetPath());
  h= global_open(g, MSGID_OPEN_MODE_STRERROR, filename, _O_RDONLY);

  if (trace)
    htrc("GetFileLength: fn=%s h=%d\n", filename, h);

  if (h == -1) {
    if (errno != ENOENT) {
      if (trace)
        htrc("%s\n", g->Message);
      len = -1;
    }
    else
    {
      len = 0;          // File does not exist yet
      g->Message[0]= '\0';
    }
  } else {
    if ((len = _filelength(h)) < 0)
      sprintf(g->Message, MSG(FILELEN_ERROR), "_filelength", filename);

    if (Eof && len)
      len--;              // Do not count the EOF character

    close(h);
  } // endif h

  return len;
  } // end of GetFileLength
Example #2
0
HANDLE CreateFileMap(PGLOBAL g, LPCSTR fileName, 
                         MEMMAP *mm, MODE mode, bool del) 
  {
  unsigned int openMode;
  int          protmode;
  HANDLE       fd;
  size_t       filesize;
  struct stat  st; 

  memset(mm, 0, sizeof(MEMMAP));
  *g->Message = '\0';

  switch (mode) {
    case MODE_READ:
      openMode = O_RDONLY;
      protmode = PROT_READ;
      break;
    case MODE_UPDATE:
    case MODE_DELETE:
      openMode = (del) ? (O_RDWR | O_TRUNC) : O_RDWR;
      protmode = PROT_READ | PROT_WRITE;
      break;
    case MODE_INSERT:
      openMode = (O_WRONLY | O_CREAT | O_APPEND);
      protmode = PROT_WRITE;
      break;
     default:
      sprintf(g->Message, MSG(BAD_FUNC_MODE), "CreateFileMap", mode);
      return INVALID_HANDLE_VALUE;
   } // endswitch

  // Try to open the addressed file.
  fd= global_open(g, MSGID_NONE, fileName, openMode);

  if (fd != INVALID_HANDLE_VALUE && mode != MODE_INSERT) {
    /* We must know about the size of the file. */
    if (fstat(fd, &st)) {
      sprintf(g->Message, MSG(FILE_MAP_ERROR), fileName, errno);
      close(fd);
      return INVALID_HANDLE_VALUE;
      }  // endif fstat
    
    if ((filesize = st.st_size))
      // Now we are ready to load the file.  If mmap() is available we try
      //   this first.  If not available or it failed we try to load it.
      mm->memory = mmap(NULL, filesize, protmode, MAP_SHARED, fd, 0);
    else
      mm->memory = 0;

    if (mm->memory != MAP_FAILED) {
      mm->lenL = (mm->memory != 0) ? filesize : 0;
      mm->lenH = 0;
    } else {
      strcpy(g->Message, "Memory mapping failed");
      close(fd);
      return INVALID_HANDLE_VALUE;
    } // endif memory

    }  /* endif fd */
  
  // mmap() call was successful. ??????????
  return fd;
  }  // end of CreateFileMap
Example #3
0
int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
  {
  bool moved;
  int curpos = ftell(Stream);

  /*********************************************************************/
  /*  There is an alternative here:                                    */
  /*  1 - use a temporary file in which are copied all not deleted     */
  /*      lines, at the end the original file will be deleted and      */
  /*      the temporary file renamed to the original file name.        */
  /*  2 - directly move the not deleted lines inside the original      */
  /*      file, and at the end erase all trailing records.             */
  /*  This will be experimented, but method 1 must be used for Unix as */
  /*  the function needed to erase trailing records is not available.  */
  /*********************************************************************/
  if (trace)
    htrc(
  "DOS DeleteDB: rc=%d UseTemp=%d curpos=%d Fpos=%d Tpos=%d Spos=%d\n",
                irc, UseTemp, curpos, Fpos, Tpos, Spos);

  if (irc != RC_OK) {
    /*******************************************************************/
    /*  EOF: position Fpos at the end-of-file position.                */
    /*******************************************************************/
    fseek(Stream, 0, SEEK_END);
    Fpos = ftell(Stream);

    if (trace)
      htrc("Fpos placed at file end=%d\n", Fpos);

    } // endif irc

  if (Tpos == Spos) {
    /*******************************************************************/
    /*  First line to delete, Open temporary file.                     */
    /*******************************************************************/
    if (UseTemp) {
      if (OpenTempFile(g))
        return RC_FX;

    } else {
      /*****************************************************************/
      /*  Move of eventual preceeding lines is not required here.      */
      /*  Set the target file as being the source file itself.         */
      /*  Set the future Tpos, and give Spos a value to block copying. */
      /*****************************************************************/
      T_Stream = Stream;
      Spos = Tpos = Fpos;
    } // endif UseTemp

    } // endif Tpos == Spos

  /*********************************************************************/
  /*  Move any intermediate lines.                                     */
  /*********************************************************************/
  if (MoveIntermediateLines(g, &moved))
    return RC_FX;

  if (irc == RC_OK) {
    /*******************************************************************/
    /*  Reposition the file pointer and set Spos.                      */
    /*******************************************************************/
    if (!UseTemp || moved)
      if (fseek(Stream, curpos, SEEK_SET)) {
        sprintf(g->Message, MSG(FSETPOS_ERROR), 0);
        return RC_FX;
        } // endif

    Spos = GetNextPos();                     // New start position

    if (trace)
      htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);

  } else {
    /*******************************************************************/
    /*  Last call after EOF has been reached.                          */
    /*  The UseTemp case is treated in CloseTableFile.                 */
    /*******************************************************************/
    if (!UseTemp) {
      /*****************************************************************/
      /*  Because the chsize functionality is only accessible with a   */
      /*  system call we must close the file and reopen it with the    */
      /*  open function (_fopen for MS ??) this is still to be checked */
      /*  for compatibility with Text files and other OS's.            */
      /*****************************************************************/
      char filename[_MAX_PATH];
      int  h;                           // File handle, return code

      PlugSetPath(filename, To_File, Tdbp->GetPath());
      /*rc=*/ PlugCloseFile(g, To_Fb);

      if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
        return RC_FX;

      /*****************************************************************/
      /*  Remove extra records.                                        */
      /*****************************************************************/
#if defined(UNIX)
      if (ftruncate(h, (off_t)Tpos)) {
        sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno));
        close(h);
        return RC_FX;
        } // endif
#else
      if (chsize(h, Tpos)) {
        sprintf(g->Message, MSG(CHSIZE_ERROR), strerror(errno));
        close(h);
        return RC_FX;
        } // endif
#endif

      close(h);

      if (trace)
        htrc("done, h=%d irc=%d\n", h, irc);

      } // endif !UseTemp

  } // endif irc

  return RC_OK;                                      // All is correct
  } // end of DeleteRecords