Project

General

Profile

Feature #11258 » excl_mode_v1.diff

cremno (cremno phobia), 06/16/2015 06:47 PM

View differences:

include/ruby/io.h
} rb_io_t;
#define HAVE_RB_IO_T 1
#define FMODE_READABLE 0x00000001
#define FMODE_WRITABLE 0x00000002
#define FMODE_READWRITE (FMODE_READABLE|FMODE_WRITABLE)
......
#define FMODE_APPEND 0x00000040
#define FMODE_CREATE 0x00000080
/* #define FMODE_NOREVLOOKUP 0x00000100 */
#define FMODE_EXCL 0x00000400
#define FMODE_TRUNC 0x00000800
#define FMODE_TEXTMODE 0x00001000
/* #define FMODE_PREP 0x00010000 */
io.c
case FMODE_READABLE:
return MODE_BTMODE("r", "rb", "rt");
case FMODE_WRITABLE:
if (fmode & FMODE_EXCL)
return MODE_BTMODE("wx", "wbx", "wtx");
return MODE_BTMODE("w", "wb", "wt");
case FMODE_READWRITE:
if (fmode & FMODE_CREATE) {
if (fmode & FMODE_EXCL)
return MODE_BTMODE("w+x", "wb+x", "wt+x");
return MODE_BTMODE("w+", "wb+", "wt+");
}
return MODE_BTMODE("r+", "rb+", "rt+");
......
case '+':
fmode |= FMODE_READWRITE;
break;
case 'x':
if (!(fmode & FMODE_TRUNC))
goto error;
fmode |= FMODE_EXCL;
break;
default:
goto error;
case ':':
......
if (oflags & O_CREAT) {
fmode |= FMODE_CREATE;
}
if (oflags & O_EXCL) {
fmode |= FMODE_EXCL;
}
#ifdef O_BINARY
if (oflags & O_BINARY) {
fmode |= FMODE_BINMODE;
......
if (fmode & FMODE_CREATE) {
oflags |= O_CREAT;
}
if (fmode & FMODE_EXCL) {
oflags |= O_EXCL;
}
#ifdef O_BINARY
if (fmode & FMODE_BINMODE) {
oflags |= O_BINARY;
......
#else
# define MODE_BINARY(a,b) (a)
#endif
#define MODE_BINARY_EXCL(a,b,c,d) \
((oflags & O_EXCL) ? MODE_BINARY(d, c) : MODE_BINARY(b, a))
int accmode = oflags & (O_RDONLY|O_WRONLY|O_RDWR);
if (oflags & O_APPEND) {
if (accmode == O_WRONLY) {
......
case O_RDONLY:
return MODE_BINARY("r", "rb");
case O_WRONLY:
return MODE_BINARY("w", "wb");
return MODE_BINARY_EXCL("w", "wb", "wx", "wbx");
case O_RDWR:
if (oflags & O_CREAT)
return MODE_BINARY_EXCL("w+", "wb+", "w+x", "wb+x");
return MODE_BINARY("r+", "rb+");
}
}
test/ruby/test_file.rb
assert_file.not_exist?(path)
end
end
def test_exclusive_mode
Dir.mktmpdir('feature11258') do |tmpdir|
fname = "#{tmpdir}/tmp.txt"
# file must be created and not just opened
assert_nothing_raised { File.new(fname, 'wx').close }
assert_raise(Errno::EEXIST) { File.new(fname, 'wx') }
# mode must not be read or append mode
assert_raise(ArgumentError) { File.new(fname, 'rx') }
assert_raise(ArgumentError) { File.new(fname, 'ax') }
end
end
end
(1-1/2)