File indexing completed on 2025-05-11 08:24:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #ifdef HAVE_CONFIG_H
0040 #include "config.h"
0041 #endif
0042
0043 #include <sys/stat.h>
0044 #include <fcntl.h>
0045 #include <stdarg.h>
0046 #include <unistd.h>
0047
0048 #include <rtems/libio_.h>
0049
0050 static void create_regular_file(
0051 rtems_filesystem_eval_path_context_t *ctx,
0052 mode_t mode
0053 )
0054 {
0055 int rv = 0;
0056 const rtems_filesystem_location_info_t *currentloc =
0057 rtems_filesystem_eval_path_get_currentloc( ctx );
0058 const char *token = rtems_filesystem_eval_path_get_token( ctx );
0059 size_t tokenlen = rtems_filesystem_eval_path_get_tokenlen( ctx );
0060
0061 rv = rtems_filesystem_mknod(
0062 currentloc,
0063 token,
0064 tokenlen,
0065 S_IFREG | mode,
0066 0
0067 );
0068
0069 if ( rv == 0 ) {
0070
0071 rtems_filesystem_eval_path_set_flags( ctx, 0 );
0072
0073 rtems_filesystem_eval_path_set_path( ctx, token, tokenlen );
0074 rtems_filesystem_eval_path_continue( ctx );
0075 } else {
0076 rtems_filesystem_eval_path_error( ctx, 0 );
0077 }
0078 }
0079
0080 static int do_open(
0081 rtems_libio_t *iop,
0082 const char *path,
0083 int oflag,
0084 mode_t mode
0085 )
0086 {
0087 int rv = 0;
0088 int fd = rtems_libio_iop_to_descriptor( iop );
0089 int rwflag = oflag + 1;
0090 bool read_access = (rwflag & _FREAD) == _FREAD;
0091 bool write_access = (rwflag & _FWRITE) == _FWRITE;
0092 bool make = (oflag & O_CREAT) == O_CREAT;
0093 bool exclusive = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
0094 bool truncate = (oflag & O_TRUNC) == O_TRUNC;
0095 bool open_dir;
0096 #ifdef O_NOFOLLOW
0097 int follow = (oflag & O_NOFOLLOW) == O_NOFOLLOW ? 0 : RTEMS_FS_FOLLOW_LINK;
0098 #else
0099 int follow = RTEMS_FS_FOLLOW_LINK;
0100 #endif
0101 int eval_flags = follow
0102 | (read_access ? RTEMS_FS_PERMS_READ : 0)
0103 | (write_access ? RTEMS_FS_PERMS_WRITE : 0)
0104 | (make ? RTEMS_FS_MAKE : 0)
0105 | (exclusive ? RTEMS_FS_EXCLUSIVE : 0);
0106 rtems_filesystem_eval_path_context_t ctx;
0107 const rtems_filesystem_location_info_t *currentloc;
0108 bool create_reg_file;
0109
0110 rtems_filesystem_eval_path_start( &ctx, path, eval_flags );
0111
0112 currentloc = rtems_filesystem_eval_path_get_currentloc( &ctx );
0113 create_reg_file = !currentloc->mt_entry->no_regular_file_mknod;
0114
0115 if ( create_reg_file && rtems_filesystem_eval_path_has_token( &ctx ) ) {
0116 create_regular_file( &ctx, mode );
0117 }
0118
0119 #ifdef O_DIRECTORY
0120 open_dir = ( oflag & O_DIRECTORY ) == O_DIRECTORY;
0121 #else
0122 open_dir = false;
0123 #endif
0124
0125 if ( write_access || open_dir ) {
0126 mode_t type = rtems_filesystem_location_type( currentloc );
0127
0128 if ( create_reg_file && write_access && S_ISDIR( type ) ) {
0129 rtems_filesystem_eval_path_error( &ctx, EISDIR );
0130 }
0131
0132 if ( open_dir && !S_ISDIR( type ) ) {
0133 rtems_filesystem_eval_path_error( &ctx, ENOTDIR );
0134 }
0135 }
0136
0137 rtems_filesystem_eval_path_extract_currentloc( &ctx, &iop->pathinfo );
0138 rtems_filesystem_eval_path_cleanup( &ctx );
0139
0140 rtems_libio_iop_flags_set( iop, rtems_libio_fcntl_flags( oflag ) );
0141
0142 rv = (*iop->pathinfo.handlers->open_h)( iop, path, oflag, mode );
0143
0144 if ( rv == 0 ) {
0145
0146
0147
0148
0149
0150 if ( truncate ) {
0151 if ( write_access ) {
0152 rv = (*iop->pathinfo.handlers->ftruncate_h)( iop, 0 );
0153 } else {
0154 rv = -1;
0155 errno = EINVAL;
0156 }
0157
0158 if ( rv != 0 ) {
0159 (*iop->pathinfo.handlers->close_h)( iop );
0160 }
0161 }
0162
0163 if ( rv == 0 ) {
0164 rtems_libio_iop_flags_set( iop, LIBIO_FLAGS_OPEN );
0165 rv = fd;
0166 } else {
0167 rv = -1;
0168 }
0169 }
0170
0171 if ( rv < 0 ) {
0172 rtems_libio_free( iop );
0173 }
0174
0175 return rv;
0176 }
0177
0178
0179
0180
0181 int open( const char *path, int oflag, ... )
0182 {
0183 int rv = 0;
0184 va_list ap;
0185 mode_t mode = 0;
0186 rtems_libio_t *iop = NULL;
0187
0188 va_start( ap, oflag );
0189
0190 mode = va_arg( ap, mode_t );
0191
0192 iop = rtems_libio_allocate();
0193 if ( iop != NULL ) {
0194 rv = do_open( iop, path, oflag, mode );
0195 } else {
0196 errno = ENFILE;
0197 rv = -1;
0198 }
0199
0200 va_end( ap );
0201
0202 return rv;
0203 }
0204
0205
0206
0207 #if defined(RTEMS_NEWLIB) && !defined(HAVE__OPEN_R)
0208
0209 #include <reent.h>
0210
0211
0212
0213
0214 int _open_r(
0215 struct _reent *ptr RTEMS_UNUSED,
0216 const char *buf,
0217 int oflag,
0218 int mode
0219 )
0220 {
0221 return open( buf, oflag, mode );
0222 }
0223 #endif