OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libcsupport/] [src/] [open.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.