OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems/] [c/] [src/] [lib/] [libc/] [open.c] - Rev 1767

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 *  open() - POSIX 1003.1 5.3.1 - Open a File
 *
 *  COPYRIGHT (c) 1989-1999.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.OARcorp.com/rtems/license.html.
 *
 *  $Id: open.c,v 1.2 2001-09-27 12:01:15 chris Exp $
 */
 
#include "libio_.h"
 
#include <unistd.h>
 
/*
 *  Returns file descriptor on success or -1 and errno set to one of the
 *  following:
 *
 *    EACCESS  - Seach permission is denied on a component of the path prefix,
 *               or the file exists and the permissions specified by the
 *               flags are denied, or the file does not exist and write
 *               permission is denied for the parent directory of the file
 *               to be created, or O_TRUNC is specified and write permission
 *               is denied.
 *    EEXIST   - O_CREAT and O_EXCL are set and the named file exists.
 *    EINTR    - The open( operation was interrupted by a signal.
 *    EINVAL   - This implementation does not support synchronized IO for this
 *               file.
 *    EISDIR   - The named file is a directory and the flags argument 
 *               specified write or read/write access.
 *    EMFILE   - Too many file descriptors are in used by this process.
 *    ENAMETOOLONG - 
 *               The length of the path exceeds PATH_MAX or a pathname
 *               component is longer than NAME_MAX while POSIX_NO_TRUNC
 *               is in effect.
 *    ENFILE   - Too many files are open in the system.
 *    ENOENT   - O_CREAT is not set and and the anmed file does not exist,
 *               or O_CREAT is set and eitehr the path prefix does not exist
 *               or the path argument points to an empty string.
 *    ENOSPC   - The directory or file system that would contain the new file
 *               cannot be extended.
 *    ENOTDIR  - A component of the path prefix is not a directory.
 *    ENXIO    - O_NONBLOCK is set, the named file is a FIFO, O_WRONLY is
 *               set, and no process has the file open for reading.
 *    EROFS    - The named file resides on a read-only file system and either
 *               O_WRONLY, O_RDWR, O_CREAT (if the file does not exist), or
 *               O_TRUNC is set in the flags argument.
 */
 
int open(
  const char   *pathname,
  int           flags,
  ...
)
{
  va_list                             ap;
  int                                 mode;
  int                                 rc;
  rtems_libio_t                      *iop = 0;
  int                                 status;
  rtems_filesystem_location_info_t    loc;
  int                                 eval_flags;
 
 
  /*
   * Set the Evaluation flags 
   */
 
  eval_flags = 0;
  status = flags + 1;
  if ( ( status & _FREAD ) == _FREAD )
    eval_flags |= RTEMS_LIBIO_PERMS_READ;
  if ( ( status & _FWRITE ) == _FWRITE )
    eval_flags |= RTEMS_LIBIO_PERMS_WRITE;
 
 
  va_start(ap, flags);
 
  mode = va_arg( ap, int );
 
  /*
   * NOTE: This comment is OBSOLETE.  The proper way to do this now
   *       would be to support a magic mounted file system.
   *
   *             Additional external I/O handlers would be supported by adding
   *             code to pick apart the pathname appropriately. The networking
   *             code does not require changes here since network file
   *             descriptors are obtained using socket(), not open().
   */
 
  /* allocate a file control block */
  iop = rtems_libio_allocate();
  if ( iop == 0 ) {
    rc = ENFILE;
    goto done;
  }
 
  /*
   *  See if the file exists.
   */
 
  status = rtems_filesystem_evaluate_path(
     pathname, eval_flags, &loc, TRUE );
 
  if ( status == -1 ) {
    if ( errno != ENOENT ) {
      rc = errno;
      goto done;
    }
 
    /* If the file does not exist and we are not trying to create it--> error */
    if ( !(flags & O_CREAT) ) {
      rc = ENOENT;
      goto done;
    }
 
    /* Create the node for the new regular file */
    rc = mknod( pathname, S_IFREG | mode, 0LL );
    if ( rc ) {
      rc = errno;
      goto done;
    }
 
    /* Sanity check to see if the file name exists after the mknod() */
    status = rtems_filesystem_evaluate_path( pathname, 0x0, &loc, TRUE );
    if ( status != 0 ) {   /* The file did not exist */
      rc = EACCES;
      goto done;
    }
 
  } else if ((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT)) {
    /* We were trying to create a file that already exists */
    rc = EEXIST;
    goto done;
  }
 
  /*
   *  Fill in the file control block based on the loc structure
   *  returned by successful path evaluation.
   */
 
  iop->offset     = 0;
  iop->handlers   = loc.handlers;
  iop->file_info  = loc.node_access;
  iop->flags     |= rtems_libio_fcntl_flags( flags );
  iop->pathinfo   = loc;
 
  if ( !iop->handlers->open ) {
    rc = ENOTSUP;
    goto done; 
  }
 
  rc = (*iop->handlers->open)( iop, pathname, flags, mode );
  if ( rc )
    goto done;
 
  /*
   *  Optionally truncate the file.
   */
 
  if ( (flags & O_TRUNC) == O_TRUNC ) {
    rc = ftruncate( iop - rtems_libio_iops, 0 );
  }
 
  /*
   *  Single exit and clean up path.
   */
 
done:
  va_end(ap);
 
  if ( rc ) {
    if ( iop )
      rtems_libio_free( iop );
    set_errno_and_return_minus_one( rc );
  }
 
  rtems_filesystem_freenode( &loc );
 
  return iop - rtems_libio_iops;
}
 
/*
 *  _open_r
 *
 *  This is the Newlib dependent reentrant version of open().
 */
 
#if defined(RTEMS_NEWLIB)
 
#include <reent.h>
 
int _open_r(
  struct _reent *ptr,
  const char    *buf,
  int            flags,
  int            mode
)
{
  return open( buf, flags, mode );
}
#endif
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.