Adopted common O_RDONLY/WRONLY/RDWR bit patterns
This should, in theory, be a transparent change for users (https://xkcd.com/1172). The motivation for this change: 1. Basically everyone uses O_RDONLY=0, O_WRONLY=1, O_RDWR=2, so deviating from this ad-hoc standard risks surprising POSIX-familiar users, though may confused POSIX-unfamiliar users. But for the latter, we really shouldn't allow them to fall into the trap that O_RDONLY | O_WRONLY == O_RDWR, because this will not work on basically any other POSIX-like system. 2. I realized one benefit of the POSIX encoding is that it reserves the value 3. Maybe this could be useful in the future? Being able to create a file that neither readable nor writable isn't all that useful... Also, if you really think about the literal meaning of O_RDONLY | O_WRONLY, these are negations. So O_RDONLY | O_WRONLY means you can only write and only read? That sounds like an oxymoron. Of course no one should be relying on these exact values, but these are embedded systems! Someone somewhere is going to hack something together that expects these to be their historically expected value. And we shouldn't make things any harder for them unless there's a good reason.
This commit is contained in:
@@ -8916,12 +8916,12 @@ static inline lfs_off_t lfsr_ftree_size(const lfsr_ftree_t *ftree) {
|
||||
}
|
||||
|
||||
// flag things
|
||||
static inline bool lfsr_o_isreadable(uint32_t flags) {
|
||||
return (flags & LFS_O_RDONLY) == LFS_O_RDONLY;
|
||||
static inline bool lfsr_o_isrdonly(uint32_t flags) {
|
||||
return (flags & 3) == LFS_O_RDONLY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_iswriteable(uint32_t flags) {
|
||||
return (flags & LFS_O_WRONLY) == LFS_O_WRONLY;
|
||||
static inline bool lfsr_o_iswronly(uint32_t flags) {
|
||||
return (flags & 3) == LFS_O_WRONLY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_iscreat(uint32_t flags) {
|
||||
@@ -8975,7 +8975,10 @@ static lfs_ssize_t lfsr_file_read_(lfs_t *lfs, const lfsr_file_t *file,
|
||||
int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
||||
const char *path, uint32_t flags,
|
||||
const struct lfs_file_config *cfg) {
|
||||
if (lfsr_o_iswriteable(flags)) {
|
||||
// don't allow the forbidden mode!
|
||||
LFS_ASSERT((flags & 3) != 3);
|
||||
|
||||
if (!lfsr_o_isrdonly(flags)) {
|
||||
// prepare our filesystem for writing
|
||||
int err = lfsr_fs_preparemutation(lfs);
|
||||
if (err) {
|
||||
@@ -9008,7 +9011,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
||||
if (!lfsr_o_iscreat(flags)) {
|
||||
return LFS_ERR_NOENT;
|
||||
}
|
||||
LFS_ASSERT(lfsr_o_iswriteable(flags));
|
||||
LFS_ASSERT(!lfsr_o_isrdonly(flags));
|
||||
|
||||
// check that name fits
|
||||
if (name_size > lfs->name_limit) {
|
||||
@@ -9144,7 +9147,7 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file);
|
||||
int lfsr_file_close(lfs_t *lfs, lfsr_file_t *file) {
|
||||
// don't call lfsr_file_sync if we're readonly or desynced
|
||||
int err = 0;
|
||||
if (lfsr_o_iswriteable(file->flags)
|
||||
if (!lfsr_o_isrdonly(file->flags)
|
||||
&& !lfsr_o_isdesync(file->flags)) {
|
||||
err = lfsr_file_sync(lfs, file);
|
||||
if (err) {
|
||||
@@ -10418,7 +10421,7 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
|
||||
lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file,
|
||||
void *buffer, lfs_size_t size) {
|
||||
// can't read from writeonly files
|
||||
LFS_ASSERT(lfsr_o_isreadable(file->flags));
|
||||
LFS_ASSERT(!lfsr_o_iswronly(file->flags));
|
||||
LFS_ASSERT(file->pos + size <= 0x7fffffff);
|
||||
|
||||
lfs_off_t pos_ = file->pos;
|
||||
@@ -10509,7 +10512,7 @@ lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file,
|
||||
lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file,
|
||||
const void *buffer, lfs_size_t size) {
|
||||
// can't write to readonly files
|
||||
LFS_ASSERT(lfsr_o_iswriteable(file->flags));
|
||||
LFS_ASSERT(!lfsr_o_isrdonly(file->flags));
|
||||
|
||||
// would this write make our file larger than our size limit?
|
||||
if (size > lfs->size_limit - file->pos) {
|
||||
@@ -10660,7 +10663,7 @@ failed:;
|
||||
|
||||
int lfsr_file_flush(lfs_t *lfs, lfsr_file_t *file) {
|
||||
// readonly files should do nothing
|
||||
LFS_ASSERT(lfsr_o_iswriteable(file->flags)
|
||||
LFS_ASSERT(!lfsr_o_isrdonly(file->flags)
|
||||
|| !lfsr_f_isunflushed(file->flags)
|
||||
|| (lfsr_file_size_(file) <= lfs->cfg->cache_size
|
||||
&& lfsr_file_size_(file) <= lfs->cfg->inline_size
|
||||
@@ -10756,7 +10759,7 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
|
||||
// 3. we try to sync our original file handle
|
||||
//
|
||||
// the best thing we can do in this case is return an error
|
||||
if (!lfsr_o_iswriteable(file->flags)) {
|
||||
if (lfsr_o_isrdonly(file->flags)) {
|
||||
err = LFS_ERR_INVAL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@@ -123,10 +123,10 @@ enum lfs_type {
|
||||
// File open flags
|
||||
enum lfs_open_flags {
|
||||
// open flags
|
||||
LFS_O_RDONLY = 1, // Open a file as read only
|
||||
LFS_O_RDONLY = 0, // Open a file as read only
|
||||
#ifndef LFS_READONLY
|
||||
LFS_O_WRONLY = 2, // Open a file as write only
|
||||
LFS_O_RDWR = 3, // Open a file as read and write
|
||||
LFS_O_WRONLY = 1, // Open a file as write only
|
||||
LFS_O_RDWR = 2, // Open a file as read and write
|
||||
LFS_O_CREAT = 0x0004, // Create a file if it does not exist
|
||||
LFS_O_EXCL = 0x0008, // Fail if a file already exists
|
||||
LFS_O_TRUNC = 0x0010, // Truncate the existing file to zero size
|
||||
|
||||
Reference in New Issue
Block a user