summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libc/open.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-11-23 19:07:58 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-11-23 19:07:58 +0000
commit07a3253de2c3f9bc2d96a351680ec72548dadd2d (patch)
treeb4f85e78927202cffe01b194c708c3dd800d8e57 /c/src/lib/libc/open.c
parentAdded new tests in support of the file system infrastructure. (diff)
downloadrtems-07a3253de2c3f9bc2d96a351680ec72548dadd2d.tar.bz2
Added base version of file system infrastructure. This includes a major
overhaul of the RTEMS system call interface. This base file system is the "In-Memory File System" aka IMFS. The design and implementation was done by the following people: + Joel Sherrill (joel@OARcorp.com) + Jennifer Averett (jennifer@OARcorp.com) + Steve "Mr Mount" Salitasc (salitasc@OARcorp.com) + Kerwin Wade (wade@OARcorp.com) PROBLEMS ======== + It is VERY likely that merging this will break the UNIX port. This can/will be fixed. + There is likely some reentrancy/mutual exclusion needed. + Eventually, there should be a "mini-IMFS" description table to eliminate links, symlinks, etc to save memory. All you need to have "classic RTEMS" functionality is technically directories and device IO. All the rest could be left out to save memory.
Diffstat (limited to 'c/src/lib/libc/open.c')
-rw-r--r--c/src/lib/libc/open.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/c/src/lib/libc/open.c b/c/src/lib/libc/open.c
new file mode 100644
index 0000000000..4cdf5acf35
--- /dev/null
+++ b/c/src/lib/libc/open.c
@@ -0,0 +1,202 @@
+/*
+ * open() - POSIX 1003.1 5.3.1 - Open a File
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * 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$
+ */
+
+#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 temp_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, &temp_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, &temp_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 temp_loc structure
+ * returned by successful path evaluation.
+ */
+
+ iop->handlers = temp_loc.handlers;
+ iop->file_info = temp_loc.node_access;
+ iop->flags |= rtems_libio_fcntl_flags( flags );
+ iop->pathinfo = temp_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 );
+ }
+ 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