diff options
Diffstat (limited to 'firmware/include/file_internal.h')
-rw-r--r-- | firmware/include/file_internal.h | 91 |
1 files changed, 53 insertions, 38 deletions
diff --git a/firmware/include/file_internal.h b/firmware/include/file_internal.h index d1bb67406a..acec81206e 100644 --- a/firmware/include/file_internal.h +++ b/firmware/include/file_internal.h | |||
@@ -81,6 +81,7 @@ | |||
81 | #define ATTR_NEW_FILE (ATTR_ARCHIVE) | 81 | #define ATTR_NEW_FILE (ATTR_ARCHIVE) |
82 | #define ATTR_NEW_DIRECTORY (ATTR_DIRECTORY) | 82 | #define ATTR_NEW_DIRECTORY (ATTR_DIRECTORY) |
83 | 83 | ||
84 | #define ATTR_SYSTEM_ROOT (ATTR_SYSROOT | ATTR_DIRECTORY) | ||
84 | #define ATTR_MOUNT_POINT (ATTR_VOLUME | ATTR_DIRECTORY) | 85 | #define ATTR_MOUNT_POINT (ATTR_VOLUME | ATTR_DIRECTORY) |
85 | 86 | ||
86 | /** File sector cache **/ | 87 | /** File sector cache **/ |
@@ -110,33 +111,35 @@ void file_cache_free(struct filestr_cache *cachep); | |||
110 | enum fildes_and_obj_flags | 111 | enum fildes_and_obj_flags |
111 | { | 112 | { |
112 | /* used in descriptor and common */ | 113 | /* used in descriptor and common */ |
113 | FDO_BUSY = 0x0001, /* descriptor/object is in use */ | 114 | FDO_BUSY = 0x0001, /* descriptor/object is in use */ |
114 | /* only used in individual stream descriptor */ | 115 | /* only used in individual stream descriptor */ |
115 | FD_WRITE = 0x0002, /* descriptor has write mode */ | 116 | FD_WRITE = 0x0002, /* descriptor has write mode */ |
116 | FD_WRONLY = 0x0004, /* descriptor is write mode only */ | 117 | FD_WRONLY = 0x0004, /* descriptor is write mode only */ |
117 | FD_APPEND = 0x0008, /* descriptor is append mode */ | 118 | FD_APPEND = 0x0008, /* descriptor is append mode */ |
119 | FD_NONEXIST = 0x8000, /* closed but not freed (uncombined) */ | ||
118 | /* only used as common flags */ | 120 | /* only used as common flags */ |
119 | FO_DIRECTORY = 0x0010, /* fileobj is a directory */ | 121 | FO_DIRECTORY = 0x0010, /* fileobj is a directory */ |
120 | FO_TRUNC = 0x0020, /* fileobj is opened to be truncated */ | 122 | FO_TRUNC = 0x0020, /* fileobj is opened to be truncated */ |
121 | FO_REMOVED = 0x0040, /* fileobj was deleted while open */ | 123 | FO_REMOVED = 0x0040, /* fileobj was deleted while open */ |
122 | FO_SINGLE = 0x0080, /* fileobj has only one stream open */ | 124 | FO_SINGLE = 0x0080, /* fileobj has only one stream open */ |
123 | FDO_MASK = 0x00ff, | 125 | FDO_MASK = 0x00ff, |
124 | /* bitflags that instruct various 'open' functions how to behave */ | 126 | FDO_CHG_MASK = FO_TRUNC, /* fileobj permitted external change */ |
125 | FF_FILE = 0x0000, /* expect file; accept file only */ | 127 | /* bitflags that instruct various 'open' functions how to behave; |
126 | FF_DIR = 0x0100, /* expect dir; accept dir only */ | 128 | * saved in stream flags (only) but not used by manager */ |
127 | FF_ANYTYPE = 0x0200, /* succeed if either file or dir */ | 129 | FF_FILE = 0x00000000, /* expect file; accept file only */ |
128 | FF_TYPEMASK = 0x0300, /* mask of typeflags */ | 130 | FF_DIR = 0x00010000, /* expect dir; accept dir only */ |
129 | FF_CREAT = 0x0400, /* create if file doesn't exist */ | 131 | FF_ANYTYPE = 0x00020000, /* succeed if either file or dir */ |
130 | FF_EXCL = 0x0800, /* fail if creating and file exists */ | 132 | FF_TYPEMASK = 0x00030000, /* mask of typeflags */ |
131 | FF_CHECKPREFIX = 0x1000, /* detect if file is prefix of path */ | 133 | FF_CREAT = 0x00040000, /* create if file doesn't exist */ |
132 | FF_NOISO = 0x2000, /* do not decode ISO filenames to UTF-8 */ | 134 | FF_EXCL = 0x00080000, /* fail if creating and file exists */ |
133 | FF_MASK = 0x3f00, | 135 | FF_CHECKPREFIX = 0x00100000, /* detect if file is prefix of path */ |
134 | /* special values used in isolation */ | 136 | FF_NOISO = 0x00200000, /* do not decode ISO filenames to UTF-8 */ |
135 | FV_NONEXIST = 0x8000, /* closed but not freed (unmounted) */ | 137 | FF_PROBE = 0x00400000, /* only test existence; don't open */ |
136 | FV_OPENSYSROOT = 0xc001, /* open sysroot, volume 0 not mounted */ | 138 | FF_CACHEONLY = 0x00800000, /* succeed only if in dircache */ |
139 | FF_SELFINFO = 0x01000000, /* return info on self as well */ | ||
140 | FF_MASK = 0x01ff0000, | ||
137 | }; | 141 | }; |
138 | 142 | ||
139 | |||
140 | /** Common data structures used throughout **/ | 143 | /** Common data structures used throughout **/ |
141 | 144 | ||
142 | /* basic file information about its location */ | 145 | /* basic file information about its location */ |
@@ -183,8 +186,7 @@ struct dirscan_info | |||
183 | struct filestr_base | 186 | struct filestr_base |
184 | { | 187 | { |
185 | struct ll_node node; /* list item node (first!) */ | 188 | struct ll_node node; /* list item node (first!) */ |
186 | uint16_t flags; /* FD_* bits of this stream */ | 189 | uint32_t flags; /* F[DF]_* bits of this stream */ |
187 | uint16_t unused; /* not used */ | ||
188 | struct filestr_cache cache; /* stream-local cache */ | 190 | struct filestr_cache cache; /* stream-local cache */ |
189 | struct filestr_cache *cachep; /* the cache in use (local or shared) */ | 191 | struct filestr_cache *cachep; /* the cache in use (local or shared) */ |
190 | struct file_base_info *infop; /* base file information */ | 192 | struct file_base_info *infop; /* base file information */ |
@@ -235,17 +237,25 @@ static inline void filestr_unlock(struct filestr_base *stream) | |||
235 | #define FILESTR_UNLOCK(type, stream) \ | 237 | #define FILESTR_UNLOCK(type, stream) \ |
236 | ({ if (FILESTR_##type) filestr_unlock(stream); }) | 238 | ({ if (FILESTR_##type) filestr_unlock(stream); }) |
237 | 239 | ||
238 | #define ATTR_PREFIX (0x8000) /* out of the way of all ATTR_* bits */ | 240 | /* auxilliary attributes - out of the way of regular ATTR_* bits */ |
241 | #define ATTR_SYSROOT (0x8000) | ||
242 | #define ATTR_PREFIX (0x4000) | ||
239 | 243 | ||
240 | /* structure to return detailed information about what you opened */ | 244 | /* structure to return detailed information about what you opened */ |
241 | struct path_component_info | 245 | struct path_component_info |
242 | { | 246 | { |
243 | const char *name; /* pointer to name within 'path' */ | 247 | const char *name; /* pointer to name within 'path' (OUT) */ |
244 | size_t length; /* length of component within 'path' */ | 248 | size_t length; /* length of component within 'path' */ |
245 | file_size_t filesize; /* size of the opened file (0 if dir) */ | 249 | file_size_t filesize; /* size of the opened file (0 if dir) */ |
246 | unsigned int attr; /* attributes of this component */ | 250 | unsigned int attr; /* attributes of this component */ |
247 | struct file_base_info *prefixp; /* base info to check as prefix (IN) */ | 251 | struct file_base_info *prefixp; /* base info to check as prefix |
248 | struct file_base_info parentinfo; /* parent directory info of file */ | 252 | (IN if FF_CHECKPREFIX) */ |
253 | union { | ||
254 | struct file_base_info parentinfo; /* parent directory base info of file | ||
255 | (if not FF_SELFINFO) */ | ||
256 | struct file_base_info info; /* base info of file itself | ||
257 | (if FF_SELFINFO) */ | ||
258 | }; | ||
249 | }; | 259 | }; |
250 | 260 | ||
251 | int open_stream_internal(const char *path, unsigned int callflags, | 261 | int open_stream_internal(const char *path, unsigned int callflags, |
@@ -261,6 +271,7 @@ int remove_stream_internal(const char *path, struct filestr_base *stream, | |||
261 | int test_stream_exists_internal(const char *path, unsigned int callflags); | 271 | int test_stream_exists_internal(const char *path, unsigned int callflags); |
262 | 272 | ||
263 | int open_noiso_internal(const char *path, int oflag); /* file.c */ | 273 | int open_noiso_internal(const char *path, int oflag); /* file.c */ |
274 | void force_close_writer_internal(struct filestr_base *stream); /* file.c */ | ||
264 | 275 | ||
265 | struct dirent; | 276 | struct dirent; |
266 | int uncached_readdir_dirent(struct filestr_base *stream, | 277 | int uncached_readdir_dirent(struct filestr_base *stream, |
@@ -326,22 +337,26 @@ static inline void file_internal_unlock_WRITER(void) | |||
326 | * not in the macro | 337 | * not in the macro |
327 | */ | 338 | */ |
328 | 339 | ||
340 | #define FILE_SET_CODE(_name, _keepcode, _value) \ | ||
341 | ({ __builtin_constant_p(_value) ? \ | ||
342 | ({ if ((_value) != (_keepcode)) _name = (_value); }) : \ | ||
343 | ({ _name = (_value); }); }) | ||
344 | |||
329 | /* set errno and rc and proceed to the "file_error:" label */ | 345 | /* set errno and rc and proceed to the "file_error:" label */ |
330 | #define FILE_ERROR(_errno, _rc) \ | 346 | #define FILE_ERROR(_errno, _rc) \ |
331 | ({ __builtin_constant_p(_errno) ? \ | 347 | ({ FILE_SET_CODE(errno, ERRNO, (_errno)); \ |
332 | ({ if ((_errno) != ERRNO) errno = (_errno); }) : \ | 348 | FILE_SET_CODE(rc, RC, (_rc)); \ |
333 | ({ errno = (_errno); }); \ | ||
334 | __builtin_constant_p(_rc) ? \ | ||
335 | ({ if ((_rc) != RC) rc = (_rc); }) : \ | ||
336 | ({ rc = (_rc); }); \ | ||
337 | goto file_error; }) | 349 | goto file_error; }) |
338 | 350 | ||
339 | /* set errno and return a value at the point of invocation */ | 351 | /* set errno and return a value at the point of invocation */ |
340 | #define FILE_ERROR_RETURN(_errno, _rc...) \ | 352 | #define FILE_ERROR_RETURN(_errno, _rc...) \ |
341 | ({ __builtin_constant_p(_errno) ? \ | 353 | ({ FILE_SET_CODE(errno, ERRNO, _errno); \ |
342 | ({ if ((_errno) != ERRNO) errno = (_errno); }) : \ | 354 | return _rc; }) |
343 | ({ errno = (_errno); }); \ | 355 | |
344 | return _rc; }) | 356 | /* set errno and return code, no branching */ |
357 | #define FILE_ERROR_SET(_errno, _rc) \ | ||
358 | ({ FILE_SET_CODE(errno, ERRNO, (_errno)); \ | ||
359 | FILE_SET_CODE(rc, RC, (_rc)); }) | ||
345 | 360 | ||
346 | 361 | ||
347 | /** Misc. stuff **/ | 362 | /** Misc. stuff **/ |