source: rtems/c/src/lib/libc/open.c @ bde9bb5

4.104.114.84.95
Last change on this file since bde9bb5 was 9c49db4, checked in by Joel Sherrill <joel.sherrill@…>, on 01/08/01 at 18:26:44

2001-01-08 Ralf Corsepius <corsepiu@…>

  • configure.in: Add libc/config.h
  • libc/Makefile.am: Add INCLUDES += -I. to pickup config.h
  • libc/.cvsignore: Add config.h and stamp-h
  • libc/*.c: Add config.h support.
  • Property mode set to 100644
File size: 5.6 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->offset     = 0;
150  iop->handlers   = loc.handlers;
151  iop->file_info  = loc.node_access;
152  iop->flags     |= rtems_libio_fcntl_flags( flags );
153  iop->pathinfo   = loc;
154
155  if ( !iop->handlers->open_h ) {
156    rc = ENOTSUP;
157    goto done;
158  }
159
160  rc = (*iop->handlers->open_h)( iop, pathname, flags, mode );
161  if ( rc )
162    goto done;
163
164  /*
165   *  Optionally truncate the file.
166   */
167
168  if ( (flags & O_TRUNC) == O_TRUNC ) {
169    rc = ftruncate( iop - rtems_libio_iops, 0 );
170  }
171   
172  /*
173   *  Single exit and clean up path.
174   */
175
176done:
177  va_end(ap);
178
179  if ( rc ) {
180    if ( iop )
181      rtems_libio_free( iop );
182    set_errno_and_return_minus_one( rc );
183  }
184
185  rtems_filesystem_freenode( &loc );
186
187  return iop - rtems_libio_iops;
188}
189
190/*
191 *  _open_r
192 *
193 *  This is the Newlib dependent reentrant version of open().
194 */
195
196#if defined(RTEMS_NEWLIB)
197
198#include <reent.h>
199
200int _open_r(
201  struct _reent *ptr,
202  const char    *buf,
203  int            flags,
204  int            mode
205)
206{
207  return open( buf, flags, mode );
208}
209#endif
Note: See TracBrowser for help on using the repository browser.