URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libc/] [open.c] - Rev 173
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