source: rtems/cpukit/libcsupport/src/open.c @ 2f87c843

4.104.114.84.9
Last change on this file since 2f87c843 was 2f87c843, checked in by Joel Sherrill <joel.sherrill@…>, on Feb 5, 1999 at 12:28:43 AM

Corrected spacing and added some new error checks that were needed
to avoid dereferencing NULLs.

  • 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  status = rtems_filesystem_evaluate_path(
107     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.