source: rtems/cpukit/libcsupport/src/open.c @ 07a3253d

4.104.114.84.9
Last change on this file since 07a3253d was 07a3253d, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 23, 1998 at 7:07:58 PM

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@…)
+ Jennifer Averett (jennifer@…)
+ Steve "Mr Mount" Salitasc (salitasc@…)
+ Kerwin Wade (wade@…)

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.

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 *  open() - POSIX 1003.1 5.3.1 - Open a File
3 *
4 *  COPYRIGHT (c) 1989-1998.
5 *  On-Line Applications Research Corporation (OAR).
6 *  Copyright assigned to U.S. Government, 1994.
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14
15#include "libio_.h"
16
17#include <unistd.h>
18
19/*
20 *  Returns file descriptor on success or -1 and errno set to one of the
21 *  following:
22 *
23 *    EACCESS  - Seach permission is denied on a component of the path prefix,
24 *               or the file exists and the permissions specified by the
25 *               flags are denied, or the file does not exist and write
26 *               permission is denied for the parent directory of the file
27 *               to be created, or O_TRUNC is specified and write permission
28 *               is denied.
29 *    EEXIST   - O_CREAT and O_EXCL are set and the named file exists.
30 *    EINTR    - The open( operation was interrupted by a signal.
31 *    EINVAL   - This implementation does not support synchronized IO for this
32 *               file.
33 *    EISDIR   - The named file is a directory and the flags argument
34 *               specified write or read/write access.
35 *    EMFILE   - Too many file descriptors are in used by this process.
36 *    ENAMETOOLONG -
37 *               The length of the path exceeds PATH_MAX or a pathname
38 *               component is longer than NAME_MAX while POSIX_NO_TRUNC
39 *               is in effect.
40 *    ENFILE   - Too many files are open in the system.
41 *    ENOENT   - O_CREAT is not set and and the anmed file does not exist,
42 *               or O_CREAT is set and eitehr the path prefix does not exist
43 *               or the path argument points to an empty string.
44 *    ENOSPC   - The directory or file system that would contain the new file
45 *               cannot be extended.
46 *    ENOTDIR  - A component of the path prefix is not a directory.
47 *    ENXIO    - O_NONBLOCK is set, the named file is a FIFO, O_WRONLY is
48 *               set, and no process has the file open for reading.
49 *    EROFS    - The named file resides on a read-only file system and either
50 *               O_WRONLY, O_RDWR, O_CREAT (if the file does not exist), or
51 *               O_TRUNC is set in the flags argument.
52 */
53
54int open(
55  const char   *pathname,
56  int           flags,
57  ...
58)
59{
60  va_list                             ap;
61  int                                 mode;
62  int                                 rc;
63  rtems_libio_t                      *iop = 0;
64  int                                 status;
65  rtems_filesystem_location_info_t    temp_loc;
66  int                                 eval_flags;
67
68
69  /*
70   * Set the Evaluation flags
71   */
72
73  eval_flags = 0;
74  status = flags + 1;
75  if ( ( status & _FREAD ) == _FREAD )
76    eval_flags |= RTEMS_LIBIO_PERMS_READ;
77  if ( ( status & _FWRITE ) == _FWRITE )
78    eval_flags |= RTEMS_LIBIO_PERMS_WRITE;
79
80 
81  va_start(ap, flags);
82
83  mode = va_arg( ap, int );
84
85  /*
86   * NOTE: This comment is OBSOLETE.  The proper way to do this now
87   *       would be to support a magic mounted file system.
88   *
89   *             Additional external I/O handlers would be supported by adding
90   *             code to pick apart the pathname appropriately. The networking
91   *             code does not require changes here since network file
92   *             descriptors are obtained using socket(), not open().
93   */
94
95  /* allocate a file control block */
96  iop = rtems_libio_allocate();
97  if ( iop == 0 ) {
98    rc = ENFILE;
99    goto done;
100  }
101
102  /*
103   *  See if the file exists.
104   */
105 
106
107  status = rtems_filesystem_evaluate_path( pathname, eval_flags, &temp_loc, TRUE );
108
109  if ( status == -1 ) {
110    if ( errno != ENOENT ) {
111      rc = errno;
112      goto done;
113    }
114
115    /* If the file does not exist and we are not trying to create it--> error */
116    if ( !(flags & O_CREAT) ) {
117      rc = ENOENT;
118      goto done;
119    }
120
121    /* Create the node for the new regular file */
122    rc = mknod( pathname, S_IFREG | mode, 0LL );
123    if ( rc ) {
124      rc = errno;
125      goto done;
126    }
127
128    /* Sanity check to see if the file name exists after the mknod() */
129    status = rtems_filesystem_evaluate_path( pathname, 0x0, &temp_loc, TRUE );
130    if ( status != 0 ) {   /* The file did not exist */
131      rc = EACCES;
132      goto done;
133    }
134
135  } else if ((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT)) {
136    /* We were trying to create a file that already exists */
137    rc = EEXIST;
138    goto done;
139  }
140
141  /*
142   *  Fill in the file control block based on the temp_loc structure
143   *  returned by successful path evaluation.
144   */
145
146  iop->handlers   = temp_loc.handlers;
147  iop->file_info  = temp_loc.node_access;
148  iop->flags     |= rtems_libio_fcntl_flags( flags );
149  iop->pathinfo   = temp_loc;
150
151  if ( !iop->handlers->open ) {
152    rc = ENOTSUP;
153    goto done; 
154  }
155
156  rc = (*iop->handlers->open)( iop, pathname, flags, mode );
157  if ( rc )
158    goto done;
159
160  /*
161   *  Optionally truncate the file.
162   */
163
164  if ( (flags & O_TRUNC) == O_TRUNC ) {
165    rc = ftruncate( iop - rtems_libio_iops, 0 );
166  }
167   
168  /*
169   *  Single exit and clean up path.
170   */
171
172done:
173  va_end(ap);
174
175  if ( rc ) {
176    if ( iop )
177      rtems_libio_free( iop );
178    set_errno_and_return_minus_one( rc );
179  }
180  return iop - rtems_libio_iops;
181}
182
183/*
184 *  _open_r
185 *
186 *  This is the Newlib dependent reentrant version of open().
187 */
188
189#if defined(RTEMS_NEWLIB)
190
191#include <reent.h>
192
193int _open_r(
194  struct _reent *ptr,
195  const char    *buf,
196  int            flags,
197  int            mode
198)
199{
200  return open( buf, flags, mode );
201}
202#endif
Note: See TracBrowser for help on using the repository browser.