예제 #1
0
off_t lseek(int fid, off_t offset, int whence)
{
  off_t rc;
  FILE *file;

#if OS_PARM_CHECK
  /*-------------------------------------------------------------------*/
  /* If the file descriptor is invalid, return error.                  */
  /*-------------------------------------------------------------------*/
  if (fid < 0 || fid >= FOPEN_MAX)
  {
    set_errno(EBADF);
    return -1;
  }
  if (Files[fid].flags & FCB_DIR)
  {
    set_errno(EISDIR);
    return -1;
  }
#endif

  /*-------------------------------------------------------------------*/
  /* Get exclusive access to upper file system.                        */
  /*-------------------------------------------------------------------*/
  semPend(FileSysSem, WAIT_FOREVER);

  /*-------------------------------------------------------------------*/
  /* Return error if file is closed.                                   */
  /*-------------------------------------------------------------------*/
  file = &Files[fid];
  if (file->ioctl == NULL)
  {
    set_errno(EBADF);
    semPost(FileSysSem);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Acquire exclusive access to lower file system.                    */
  /*-------------------------------------------------------------------*/
  file->acquire(file, F_READ | F_WRITE);

  /*-------------------------------------------------------------------*/
  /* Call file system specific FSEEK routine.                          */
  /*-------------------------------------------------------------------*/
  rc = (off_t)file->ioctl(file, FSEEK, (long)offset, whence);

  /*-------------------------------------------------------------------*/
  /* Release exclusive access to file systems and return result.       */
  /*-------------------------------------------------------------------*/
  file->release(file, F_READ | F_WRITE);
  semPost(FileSysSem);
  return rc;
}
예제 #2
0
int fcntl(int fid, int cmd, ...)
{
  va_list ap;
  FILE *file;

#if OS_PARM_CHECK
  /*-------------------------------------------------------------------*/
  /* If the file descriptor is invalid, return error.                  */
  /*-------------------------------------------------------------------*/
  if (fid < 0 || fid >= FOPEN_MAX)
  {
    set_errno(EBADF);
    return -1;
  }
#endif

  /*-------------------------------------------------------------------*/
  /* Get exclusive access to upper file system.                        */
  /*-------------------------------------------------------------------*/
  semPend(FileSysSem, WAIT_FOREVER);

  /*-------------------------------------------------------------------*/
  /* Return error if file is closed.                                   */
  /*-------------------------------------------------------------------*/
  file = &Files[fid];
  if (file->ioctl == NULL)
  {
    semPost(FileSysSem);
    set_errno(EBADF);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Based on the command, execute the right instructions.             */
  /*-------------------------------------------------------------------*/
  switch (cmd)
  {
    case F_DUPFD:
    {
      /*---------------------------------------------------------------*/
      /* Use the va_arg mechanism to get the argument.                 */
      /*---------------------------------------------------------------*/
      va_start(ap, cmd);
      fid = va_arg(ap, int);
      va_end(ap);

#if OS_PARM_CHECK
      /*---------------------------------------------------------------*/
      /* If the file descriptor is invalid, return error.              */
      /*---------------------------------------------------------------*/
      if (fid < 0 || fid >= FOPEN_MAX)
      {
        semPost(FileSysSem);
        set_errno(EINVAL);
        return -1;
      }
#endif
      /*---------------------------------------------------------------*/
      /* Look for free file control block identifier >= fid.           */
      /*---------------------------------------------------------------*/
      for (;;)
      {
        FILE *file2 = &Files[fid];

        /*-------------------------------------------------------------*/
        /* Check if file control block is free.                        */
        /*-------------------------------------------------------------*/
        if (file2->ioctl == NULL)
        {
          /*-----------------------------------------------------------*/
          /* Copy previous file control block to new one.              */
          /*-----------------------------------------------------------*/
          *file2 = *file;

          /*-----------------------------------------------------------*/
          /* Acquire exclusive access to lower file system.            */
          /*-----------------------------------------------------------*/
          file2->acquire(file2, F_READ | F_WRITE);

          /*-----------------------------------------------------------*/
          /* Call file system specific DUP routine.                    */
          /*-----------------------------------------------------------*/
          file2->ioctl(file2, DUP);

          /*-----------------------------------------------------------*/
          /* Release exclusive access to lower file system.            */
          /*-----------------------------------------------------------*/
          file2->release(file2, F_READ | F_WRITE);
          break;
        }

        /*-------------------------------------------------------------*/
        /* If none are free, set errno and break.                      */
        /*-------------------------------------------------------------*/
        if (++fid >= FOPEN_MAX)
        {
          set_errno(EMFILE);
          fid = -1;
          break;
        }
      }

      /*---------------------------------------------------------------*/
      /* Release access to upper file system and return result.        */
      /*---------------------------------------------------------------*/
      semPost(FileSysSem);
      return fid;
    }

    case F_SETFL:
    {
      int oflag, r_val;

      /*---------------------------------------------------------------*/
      /* Acquire exclusive access to lower file system.                */
      /*---------------------------------------------------------------*/
      file->acquire(file, F_READ | F_WRITE);

      /*---------------------------------------------------------------*/
      /* Use the va_arg mechanism to get the argument.                 */
      /*---------------------------------------------------------------*/
      va_start(ap, cmd);
      oflag = va_arg(ap, int);
      va_end(ap);

      /*---------------------------------------------------------------*/
      /* Call specific ioctl to set flag.                              */
      /*---------------------------------------------------------------*/
      r_val = (int)file->ioctl(file, SET_FL, oflag);

      /*---------------------------------------------------------------*/
      /* Release exclusive access to lower file system.                */
      /*---------------------------------------------------------------*/
      file->release(file, F_READ | F_WRITE);

      /*---------------------------------------------------------------*/
      /* Release access to upper file system and return result.        */
      /*---------------------------------------------------------------*/
      semPost(FileSysSem);
      return r_val;
    }

    case F_GETFL:
    {
      int r_val;

      /*---------------------------------------------------------------*/
      /* Acquire exclusive access to lower file system.                */
      /*---------------------------------------------------------------*/
      file->acquire(file, F_READ);

      /*---------------------------------------------------------------*/
      /* Call specific ioctl to get flag.                              */
      /*---------------------------------------------------------------*/
      r_val = (int)file->ioctl(file, GET_FL);

      /*---------------------------------------------------------------*/
      /* Release exclusive access to lower file system.                */
      /*---------------------------------------------------------------*/
      file->release(file, F_READ);

      /*---------------------------------------------------------------*/
      /* Release access to upper file system and return result.        */
      /*---------------------------------------------------------------*/
      semPost(FileSysSem);
      return r_val;
    }
  }

  /*-------------------------------------------------------------------*/
  /* An unsupported command was requested.                             */
  /*-------------------------------------------------------------------*/
  set_errno(EINVAL);
  semPost(FileSysSem);
  return -1;
}
예제 #3
0
int creatn(const char *path, mode_t mode, size_t size)
{
  int rv = -1;
  void *dir;
  FILE *file;
#if !_PATH_NO_TRUNC
  char trunc_path[PATH_MAX + 1];
#endif

#if OS_PARM_CHECK
  /*-------------------------------------------------------------------*/
  /* If path is NULL, return -1.                                       */
  /*-------------------------------------------------------------------*/
  if (path == NULL)
  {
    set_errno(EFAULT);
    return -1;
  }
#endif

  /*-------------------------------------------------------------------*/
  /* Acquire exclusive access to upper file system.                    */
  /*-------------------------------------------------------------------*/
  semPend(FileSysSem, WAIT_FOREVER);

  /*-------------------------------------------------------------------*/
  /* Find a free file control block and initialize it.                 */
  /*-------------------------------------------------------------------*/
  for (file = &Files[0]; file->ioctl; ++file)
  {
    /*-----------------------------------------------------------------*/
    /* If none are free, return error.                                 */
    /*-----------------------------------------------------------------*/
    if (file == &Files[FOPEN_MAX - 1])
    {
      set_errno(EMFILE);
      semPost(FileSysSem);
      return -1;
    }
  }
  FsInitFCB(file, FCB_FILE);

  /*-------------------------------------------------------------------*/
  /* Ensure path is valid.                                             */
  /*-------------------------------------------------------------------*/
  dir = FSearch(file, &path, PARENT_DIR);
  if (dir == NULL)
    goto end;

  /*-------------------------------------------------------------------*/
  /* If path too long, return error if no truncation, else truncate.   */
  /*-------------------------------------------------------------------*/
  if (strlen(path) > PATH_MAX)
  {
#if _PATH_NO_TRUNC
    set_errno(ENAMETOOLONG);
    goto end;
#else
    strncpy(trunc_path, path, PATH_MAX);
    trunc_path[PATH_MAX] = '\0';
    path = trunc_path;
#endif
  }

  /*-------------------------------------------------------------------*/
  /* Acquire exclusive access to lower file system.                    */
  /*-------------------------------------------------------------------*/
  file->acquire(file, F_READ | F_WRITE);

  /*-------------------------------------------------------------------*/
  /* Call file system specific CREATN routine.                         */
  /*-------------------------------------------------------------------*/
  rv = (int)file->ioctl(file, CREATN, path, mode, size, dir);

  /*-------------------------------------------------------------------*/
  /* Release exclusive access to lower file system.                    */
  /*-------------------------------------------------------------------*/
  file->release(file, F_READ | F_WRITE);

  /*-------------------------------------------------------------------*/
  /* Free control block if error, else set return value.               */
  /*-------------------------------------------------------------------*/
end:
  if (rv == -1)
    file->ioctl = NULL;
  else
    rv = file - &Files[0];

  /*-------------------------------------------------------------------*/
  /* Release exclusive access to upper file system and return result.  */
  /*-------------------------------------------------------------------*/
  semPost(FileSysSem);
  return rv;
}
예제 #4
0
int write(int fid, const void *buf, unsigned int nbytes)
{
  int written;
  FILE *file;

#if OS_PARM_CHECK
  /*-------------------------------------------------------------------*/
  /* Ensure file descriptor is valid.                                  */
  /*-------------------------------------------------------------------*/
  if (fid < 0 || fid >= FOPEN_MAX)
  {
    set_errno(EBADF);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Return error if buffer pointer is invalid.                        */
  /*-------------------------------------------------------------------*/
  if (buf == NULL)
  {
    Files[fid].errcode = EFAULT;
    set_errno(EFAULT);
    return -1;
  }
#endif

  /*-------------------------------------------------------------------*/
  /* Acquire exclusive write access to stream.                         */
  /*-------------------------------------------------------------------*/
  file = &Files[fid];
  file->acquire(file, F_WRITE);

  /*-------------------------------------------------------------------*/
  /* Return error if file is closed.                                   */
  /*-------------------------------------------------------------------*/
  if (file->ioctl == NULL)
  {
    set_errno(EBADF);
    file->release(file, F_WRITE);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Call file system specific write routine.                          */
  /*-------------------------------------------------------------------*/
  written = file->write(file, buf, nbytes);

  /*-------------------------------------------------------------------*/
  /* Set file's errno if less than requested number was written.       */
  /*-------------------------------------------------------------------*/
  if (written < (int)nbytes)
  {
    file->errcode = get_errno();
    if (written == 0)
      written = -1;
  }

  /*-------------------------------------------------------------------*/
  /* Release exclusive write access to stream.                         */
  /*-------------------------------------------------------------------*/
  file->release(file, F_WRITE);

  /*-------------------------------------------------------------------*/
  /* Return -1 or actual number of bytes read.                         */
  /*-------------------------------------------------------------------*/
  return written;
}
예제 #5
0
파일: _READ.C 프로젝트: lubing521/protocols
int read(int fid, void *buf, unsigned int nbytes)
{
  int hchar = 0, read = 0;
  FILE *file;

  /*-------------------------------------------------------------------*/
  /* If number of requested bytes is zero, return zero.                */
  /*-------------------------------------------------------------------*/
  if (nbytes == 0)
    return 0;

#if OS_PARM_CHECK
  /*-------------------------------------------------------------------*/
  /* Ensure file descriptor is valid.                                  */
  /*-------------------------------------------------------------------*/
  if (fid < 0 || fid >= FOPEN_MAX)
  {
    set_errno(EBADF);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Return error if buffer pointer is invalid.                        */
  /*-------------------------------------------------------------------*/
  if (buf == NULL)
  {
    Files[fid].errcode = EFAULT;
    set_errno(EFAULT);
    return -1;
  }
#endif

  /*-------------------------------------------------------------------*/
  /* Acquire exclusive read access to file.                            */
  /*-------------------------------------------------------------------*/
  file = &Files[fid];
  file->acquire(file, F_READ);

  /*-------------------------------------------------------------------*/
  /* Return error if file is closed.                                   */
  /*-------------------------------------------------------------------*/
  if (file->ioctl == NULL)
  {
    set_errno(EBADF);
    file->release(file, F_READ);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* If available, read pushed-back character first.                   */
  /*-------------------------------------------------------------------*/
  if (file->hold_char)
  {
    ui8 *cp = buf;

    *cp = (ui8)file->hold_char;
    buf = cp + 1;
    file->hold_char = 0;
    hchar = 1;
    --nbytes;
  }

  /*-------------------------------------------------------------------*/
  /* Check if there are more characters to read.                       */
  /*-------------------------------------------------------------------*/
  if (nbytes)
  {
    /*-----------------------------------------------------------------*/
    /* Pass read request to file system or device driver.              */
    /*-----------------------------------------------------------------*/
    read = file->read(file, buf, nbytes);

    /*-----------------------------------------------------------------*/
    /* Read error is disregarded iff pushed-back character was read.   */
    /*-----------------------------------------------------------------*/
    if (read == -1)
    {
      if (hchar)
        read = 0;
      else
        file->errcode = get_errno();
    }
  }

  /*-------------------------------------------------------------------*/
  /* Release exclusive read access to file.                            */
  /*-------------------------------------------------------------------*/
  file->release(file, F_READ);

  /*-------------------------------------------------------------------*/
  /* Return number of bytes successfully read or -1.                   */
  /*-------------------------------------------------------------------*/
  return read + hchar;
}