file: Use own constants, do not rely on fcntl.h

One of the reasons is that O_RDONLY is zero, which makes checking whether file
is opened read- or write-only harder. It is not guaranteed that on other system
O_WRONLY will not be zero (e.g. because file can only be opened in read-write
mode).
This commit is contained in:
ZyX 2016-06-21 22:18:03 +03:00
parent 2ac5f1138b
commit a8f3849bc0
3 changed files with 43 additions and 21 deletions

View File

@ -8,6 +8,7 @@
#include <assert.h> #include <assert.h>
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include <fcntl.h>
#include "auto/config.h" #include "auto/config.h"
@ -46,15 +47,37 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
const int flags, const int mode) const int flags, const int mode)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{ {
int os_open_flags = 0;
int fd; int fd;
TriState wr = kNone;
#define FLAG(flags, flag, fcntl_flags, wrval, cond) \
do { \
if (flags & flag) { \
os_open_flags |= fcntl_flags; \
assert(cond); \
if (wrval != kNone) { \
wr = wrval; \
} \
} \
} while (0)
FLAG(flags, kFileWriteOnly, O_WRONLY, kTrue, true);
FLAG(flags, kFileCreateOnly, O_CREAT|O_EXCL|O_WRONLY, kTrue, true);
FLAG(flags, kFileCreate, O_CREAT|O_WRONLY, kTrue, !(flags & kFileCreateOnly));
FLAG(flags, kFileTruncate, O_TRUNC|O_WRONLY, kTrue,
!(flags & kFileCreateOnly));
FLAG(flags, kFileReadOnly, O_RDONLY, kFalse, wr != kTrue);
#ifdef O_NOFOLLOW
FLAG(flags, kFileNoSymlink, O_NOFOLLOW, kNone, true);
#endif
#undef FLAG
fd = os_open(fname, flags, mode); fd = os_open(fname, os_open_flags, mode);
if (fd < 0) { if (fd < 0) {
return fd; return fd;
} }
ret_fp->wr = (bool)(!!(flags & FILE_WRITE_ONLY)); ret_fp->wr = (wr == kTrue);
ret_fp->fd = fd; ret_fp->fd = fd;
ret_fp->eof = false; ret_fp->eof = false;
ret_fp->rv = rbuffer_new(RWBUFSIZE); ret_fp->rv = rbuffer_new(RWBUFSIZE);

View File

@ -3,7 +3,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <fcntl.h>
#include "nvim/func_attr.h" #include "nvim/func_attr.h"
#include "nvim/rbuffer.h" #include "nvim/rbuffer.h"
@ -19,17 +18,18 @@ typedef struct {
/// file_open() flags /// file_open() flags
typedef enum { typedef enum {
FILE_READ_ONLY = O_RDONLY, ///< Open file read-only. kFileReadOnly = 1, ///< Open file read-only. Default.
FILE_CREATE = O_CREAT, ///< Create file if it does not exist yet. kFileCreate = 2, ///< Create file if it does not exist yet.
FILE_WRITE_ONLY = O_WRONLY, ///< Open file for writing only. ///< Implies kFileWriteOnly.
#ifdef O_NOFOLLOW kFileWriteOnly = 4, ///< Open file for writing only.
FILE_NOSYMLINK = O_NOFOLLOW, ///< Do not allow symbolic links. ///< Cannot be used with kFileReadOnly.
#else kFileNoSymlink = 8, ///< Do not allow symbolic links.
FILE_NOSYMLINK = 0, kFileCreateOnly = 16, ///< Only create the file, failing if it already
#endif ///< exists. Implies kFileWriteOnly. Cannot be used
FILE_CREATE_ONLY = O_CREAT|O_EXCL, ///< Only create the file, failing ///< with kFileCreate.
///< if it already exists. kFileTruncate = 32, ///< Truncate the file if it exists.
FILE_TRUNCATE = O_TRUNC, ///< Truncate the file if it exists. ///< Implies kFileWriteOnly. Cannot be used with
///< kFileCreateOnly.
} FileOpenFlags; } FileOpenFlags;
/// Check whether end of file was encountered /// Check whether end of file was encountered

View File

@ -672,7 +672,7 @@ static ptrdiff_t read_file(ShaDaReadDef *const sd_reader, void *const dest,
sd_reader->error = os_strerror((int)ret); sd_reader->error = os_strerror((int)ret);
return -1; return -1;
} }
sd_reader->fpos += (size_t) ret; sd_reader->fpos += (size_t)ret;
return ret; return ret;
} }
@ -796,7 +796,7 @@ static int open_shada_file_for_reading(const char *const fname,
.error = NULL, .error = NULL,
.eof = false, .eof = false,
.fpos = 0, .fpos = 0,
.cookie = file_open_new(&error, fname, FILE_READ_ONLY, 0), .cookie = file_open_new(&error, fname, kFileReadOnly, 0),
}; };
if (sd_reader->cookie == NULL) { if (sd_reader->cookie == NULL) {
return error; return error;
@ -1336,7 +1336,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
} }
} }
if (!op_register_set(cur_entry.data.reg.name, (yankreg_T) { if (!op_register_set(cur_entry.data.reg.name, (yankreg_T) {
.y_array = (char_u **) cur_entry.data.reg.contents, .y_array = (char_u **)cur_entry.data.reg.contents,
.y_size = cur_entry.data.reg.contents_size, .y_size = cur_entry.data.reg.contents_size,
.y_type = cur_entry.data.reg.type, .y_type = cur_entry.data.reg.type,
.y_width = (colnr_T) cur_entry.data.reg.width, .y_width = (colnr_T) cur_entry.data.reg.width,
@ -2919,8 +2919,7 @@ int shada_write_file(const char *const file, bool nomerge)
// reading use u=rw permissions. // reading use u=rw permissions.
shada_write_file_open: {} shada_write_file_open: {}
sd_writer.cookie = file_open_new( sd_writer.cookie = file_open_new(
&error, tempname, FILE_CREATE_ONLY|FILE_NOSYMLINK|FILE_WRITE_ONLY, &error, tempname, kFileCreateOnly|kFileNoSymlink, perm);
perm);
if (sd_writer.cookie == NULL) { if (sd_writer.cookie == NULL) {
if (error == UV_EEXIST || error == UV_ELOOP) { if (error == UV_EEXIST || error == UV_ELOOP) {
// File already exists, try another name // File already exists, try another name
@ -2964,8 +2963,8 @@ shada_write_file_nomerge: {}
*tail = tail_save; *tail = tail_save;
} }
int error; int error;
sd_writer.cookie = file_open_new( sd_writer.cookie = file_open_new(&error, fname, kFileCreate|kFileTruncate,
&error, fname, FILE_CREATE|FILE_WRITE_ONLY|FILE_TRUNCATE, 0600); 0600);
if (sd_writer.cookie == NULL) { if (sd_writer.cookie == NULL) {
emsgf(_(SERR "System error while opening ShaDa file %s for writing: %s"), emsgf(_(SERR "System error while opening ShaDa file %s for writing: %s"),
fname, os_strerror(error)); fname, os_strerror(error));