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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems/] [c/] [src/] [lib/] [libc/] [open.c] - Blame information for rev 1767

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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