source: rtems/cpukit/libcsupport/src/open.c @ da154e14

4.11
Last change on this file since da154e14 was da154e14, checked in by Sebastian Huber <sebastian.huber@…>, on May 14, 2012 at 2:55:41 PM

Filesystem: Move operations to mount table entry

The scope of the file system operations is the file system instance.
The scope of the file system node handlers is the file location. The
benefit of moving the operations to the mount table entry is a size
reduction of the file location (rtems_filesystem_location_info_t). The
code size is slightly increased due to additional load instructions.

Restructure rtems_filesystem_mount_table_entry_t to improve cache
efficiency.

  • Property mode set to 100644
File size: 3.7 KB
Line 
1/*
2 *  open() - POSIX 1003.1 5.3.1 - Open a File
3 *
4 *  COPYRIGHT (c) 1989-2010.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  Modifications to support reference counting in the file system are
8 *  Copyright (c) 2012 embedded brains GmbH.
9 *
10 *  The license and distribution terms for this file may be
11 *  found in the file LICENSE in this distribution or at
12 *  http://www.rtems.com/license/LICENSE.
13 */
14
15#if HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <sys/stat.h>
20#include <fcntl.h>
21#include <stdarg.h>
22#include <unistd.h>
23
24#include <rtems/libio_.h>
25
26static void create_regular_file(
27  rtems_filesystem_eval_path_context_t *ctx,
28  mode_t mode
29)
30{
31  int rv = 0;
32  const rtems_filesystem_location_info_t *currentloc = 
33    rtems_filesystem_eval_path_get_currentloc( ctx );
34  const char *token = rtems_filesystem_eval_path_get_token( ctx );
35  size_t tokenlen = rtems_filesystem_eval_path_get_tokenlen( ctx );
36
37  rv = rtems_filesystem_mknod(
38    currentloc,
39    token,
40    tokenlen,
41    S_IFREG | mode,
42    0
43  );
44
45  if ( rv == 0 ) {
46    /* The mode only applies to future accesses of the newly created file */
47    rtems_filesystem_eval_path_set_flags( ctx, 0 );
48
49    rtems_filesystem_eval_path_set_path( ctx, token, tokenlen );
50    rtems_filesystem_eval_path_continue( ctx );
51  } else {
52    rtems_filesystem_eval_path_error( ctx, 0 );
53  }
54}
55
56static int do_open(
57  rtems_libio_t *iop,
58  const char *path,
59  int oflag,
60  mode_t mode
61)
62{
63  int rv = 0;
64  int fd = iop - rtems_libio_iops;
65  int rwflag = oflag + 1;
66  bool read_access = (rwflag & _FREAD) == _FREAD;
67  bool write_access = (rwflag & _FWRITE) == _FWRITE;
68  bool make = (oflag & O_CREAT) == O_CREAT;
69  bool exclusive = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
70  bool truncate = (oflag & O_TRUNC) == O_TRUNC;
71  int eval_flags = RTEMS_FS_FOLLOW_LINK
72    | (read_access ? RTEMS_FS_PERMS_READ : 0)
73    | (write_access ? RTEMS_FS_PERMS_WRITE : 0)
74    | (make ? RTEMS_FS_MAKE : 0)
75    | (exclusive ?  RTEMS_FS_EXCLUSIVE : 0);
76  rtems_filesystem_eval_path_context_t ctx;
77
78  rtems_filesystem_eval_path_start( &ctx, path, eval_flags );
79
80  if ( rtems_filesystem_eval_path_has_token( &ctx ) ) {
81    create_regular_file( &ctx, mode );
82  }
83
84  if ( write_access ) {
85    const rtems_filesystem_location_info_t *currentloc =
86      rtems_filesystem_eval_path_get_currentloc( &ctx );
87    rtems_filesystem_node_types_t type =
88      (*currentloc->mt_entry->ops->node_type_h)( currentloc );
89
90    if ( type == RTEMS_FILESYSTEM_DIRECTORY ) {
91      rtems_filesystem_eval_path_error( &ctx, EISDIR );
92    }
93  }
94
95  iop->flags |= rtems_libio_fcntl_flags( oflag );
96  rtems_filesystem_eval_path_extract_currentloc( &ctx, &iop->pathinfo );
97  rtems_filesystem_eval_path_cleanup( &ctx );
98
99  rv = (*iop->pathinfo.handlers->open_h)( iop, path, oflag, mode );
100
101  if ( rv == 0 ) {
102    if ( truncate ) {
103      rv = ftruncate( fd, 0 );
104      if ( rv != 0 ) {
105        (*iop->pathinfo.handlers->close_h)( iop );
106      }
107    }
108
109    if ( rv == 0 ) {
110      rv = fd;
111    } else {
112      rv = -1;
113    }
114  }
115
116  if ( rv < 0 ) {
117    rtems_libio_free( iop );
118  }
119
120  return rv;
121}
122
123int open( const char *path, int oflag, ... )
124{
125  int rv = 0;
126  va_list ap;
127  mode_t mode = 0;
128  rtems_libio_t *iop = NULL;
129
130  va_start( ap, oflag );
131
132  mode = va_arg( ap, mode_t );
133
134  iop = rtems_libio_allocate();
135  if ( iop != NULL ) {
136    rv = do_open( iop, path, oflag, mode );
137  } else {
138    errno = ENFILE;
139    rv = -1;
140  }
141
142  va_end( ap );
143
144  return rv;
145}
146
147/*
148 *  _open_r
149 *
150 *  This is the Newlib dependent reentrant version of open().
151 */
152
153#if defined(RTEMS_NEWLIB) && !defined(HAVE__OPEN_R)
154
155#include <reent.h>
156
157int _open_r(
158  struct _reent *ptr __attribute__((unused)),
159  const char    *buf,
160  int            oflag,
161  int            mode
162)
163{
164  return open( buf, oflag, mode );
165}
166#endif
Note: See TracBrowser for help on using the repository browser.