source: rtems/c/src/lib/libc/open.c @ 4154b62

4.104.114.84.95
Last change on this file since 4154b62 was 6f43d82, checked in by Joel Sherrill <joel.sherrill@…>, on 04/24/01 at 23:10:04

2001-04-24 Joel Sherrill <joel@…>

  • libc/libio.c (rtems_libio_allocate): Make sure size and offset

fields are cleared on each file open. Before this field was cleared,
this resulted in the value from the last time that IOP was used
being still in place. Discovered by Andrew Bythell
<abythell@…>.

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