diff options
author | kazu <kazu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-08-09 08:49:09 +0000 |
---|---|---|
committer | kazu <kazu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-08-09 08:49:09 +0000 |
commit | 842b735979f41169900af88a50e24d0d5e698a44 (patch) | |
tree | 5833eef0f25afb31e6be33e98e660f42f42ff600 /io.c | |
parent | 236e2993ef7667912f8dfb1b1de2d1d60a82127d (diff) | |
download | ruby-842b735979f41169900af88a50e24d0d5e698a44.tar.gz |
add 'x' mode character for O_EXCL
[Feature #11258]
Patch by cremno (cremno phobia)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64245 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 32 |
1 files changed, 28 insertions, 4 deletions
@@ -1369,6 +1369,11 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync) # define MODE_BTMODE(a,b,c) ((fmode & FMODE_BINMODE) ? (b) : \ (fmode & FMODE_TEXTMODE) ? (c) : (a)) + +#define MODE_BTXMODE(a, b, c, d, e, f) ((fmode & FMODE_EXCL) ? \ + MODE_BTMODE(d, e, f) : \ + MODE_BTMODE(a, b, c)) + static VALUE do_writeconv(VALUE str, rb_io_t *fptr, int *converted) { @@ -5360,10 +5365,10 @@ rb_io_fmode_modestr(int fmode) case FMODE_READABLE: return MODE_BTMODE("r", "rb", "rt"); case FMODE_WRITABLE: - return MODE_BTMODE("w", "wb", "wt"); + return MODE_BTXMODE("w", "wb", "wt", "wx", "wbx", "wtx"); case FMODE_READWRITE: if (fmode & FMODE_CREATE) { - return MODE_BTMODE("w+", "wb+", "wt+"); + return MODE_BTXMODE("w+", "wb+", "wt+", "w+x", "wb+x", "wt+x"); } return MODE_BTMODE("r+", "rb+", "rt+"); } @@ -5412,6 +5417,11 @@ rb_io_modestr_fmode(const char *modestr) case '+': fmode |= FMODE_READWRITE; break; + case 'x': + if (modestr[0] != 'w') + goto error; + fmode |= FMODE_EXCL; + break; default: goto error; case ':': @@ -5455,6 +5465,9 @@ rb_io_oflags_fmode(int oflags) if (oflags & O_CREAT) { fmode |= FMODE_CREATE; } + if (oflags & O_EXCL) { + fmode |= FMODE_EXCL; + } #ifdef O_BINARY if (oflags & O_BINARY) { fmode |= FMODE_BINMODE; @@ -5490,6 +5503,9 @@ rb_io_fmode_oflags(int fmode) if (fmode & FMODE_CREATE) { oflags |= O_CREAT; } + if (fmode & FMODE_EXCL) { + oflags |= O_EXCL; + } #ifdef O_BINARY if (fmode & FMODE_BINMODE) { oflags |= O_BINARY; @@ -5513,7 +5529,11 @@ rb_io_oflags_modestr(int oflags) #else # define MODE_BINARY(a,b) (a) #endif - int accmode = oflags & (O_RDONLY|O_WRONLY|O_RDWR); + int accmode; + if (oflags & O_EXCL) { + rb_raise(rb_eArgError, "exclusive access mode is not supported"); + } + accmode = oflags & (O_RDONLY|O_WRONLY|O_RDWR); if (oflags & O_APPEND) { if (accmode == O_WRONLY) { return MODE_BINARY("a", "ab"); @@ -5522,7 +5542,7 @@ rb_io_oflags_modestr(int oflags) return MODE_BINARY("a+", "ab+"); } } - switch (oflags & (O_RDONLY|O_WRONLY|O_RDWR)) { + switch (accmode) { default: rb_raise(rb_eArgError, "invalid access oflags 0x%x", oflags); case O_RDONLY: @@ -8052,6 +8072,10 @@ rb_io_make_open_file(VALUE obj) * * "t" Text file mode * + * The exclusive access mode ("x") can be used together with "w" to ensure + * the file is created. <code>Errno::EEXIST</code> is raised when it already + * exists. It may not be supported with all kinds of streams (e.g. pipes). + * * When the open mode of original IO is read only, the mode cannot be * changed to be writable. Similarly, the open mode cannot be changed from * write only to readable. |