From 4bd026cccb2c22279dd9c88e704642c5a65d3c53 Mon Sep 17 00:00:00 2001 From: Michael Santos Date: Fri, 30 Apr 2010 12:22:11 -0400 Subject: Support opening files in exclusive mode Add an option that atomically tests for the existence of a file and creates it if the file does not exist, by passing the O_EXCL flag to open() on Unix and CREATE_NEW flag on Windows. Support for O_EXCL varies across platforms and filesystems. {ok, Fd} = file:open("/tmp/foo", [write,exclusive]), {error, eexist} = file:open("/tmp/foo", [write,exclusive]). --- erts/emulator/drivers/common/erl_efile.h | 3 ++- erts/emulator/drivers/unix/unix_efile.c | 3 +++ erts/emulator/drivers/win32/win_efile.c | 3 +++ erts/preloaded/src/prim_file.erl | 5 ++++- 4 files changed, 12 insertions(+), 2 deletions(-) (limited to 'erts') diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h index bbc973d58b..ac95c1f949 100644 --- a/erts/emulator/drivers/common/erl_efile.h +++ b/erts/emulator/drivers/common/erl_efile.h @@ -32,7 +32,8 @@ #define EFILE_MODE_READ_WRITE 3 #define EFILE_MODE_APPEND 4 #define EFILE_COMPRESSED 8 -#define EFILE_NO_TRUNCATE 16 /* Special for reopening on VxWorks */ +#define EFILE_MODE_EXCL 16 +#define EFILE_NO_TRUNCATE 32 /* Special for reopening on VxWorks */ /* * Seek modes for efile_seek(). diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c index ea016526ef..0052ac0739 100644 --- a/erts/emulator/drivers/unix/unix_efile.c +++ b/erts/emulator/drivers/unix/unix_efile.c @@ -706,6 +706,9 @@ efile_openfile(Efile_error* errInfo, /* Where to return error codes. */ #endif } + if (flags & EFILE_MODE_EXCL) { + mode |= O_EXCL; + } #ifdef VXWORKS if (*name != '/') { diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c index 24b6fb30dc..04bd1139f5 100644 --- a/erts/emulator/drivers/win32/win_efile.c +++ b/erts/emulator/drivers/win32/win_efile.c @@ -689,6 +689,9 @@ Sint64* pSize; /* Where to store the size of the file. */ if (flags & EFILE_MODE_APPEND) { crFlags = OPEN_ALWAYS; } + if (flags & EFILE_MODE_EXCL) { + crFlags = CREATE_NEW; + } fd = CreateFile(name, access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, crFlags, FILE_ATTRIBUTE_NORMAL, NULL); diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl index 2d177bf80e..7f24889bb2 100644 --- a/erts/preloaded/src/prim_file.erl +++ b/erts/preloaded/src/prim_file.erl @@ -116,9 +116,10 @@ -define(EFILE_MODE_READ_WRITE, 3). -define(EFILE_MODE_APPEND, 4). -define(EFILE_COMPRESSED, 8). +-define(EFILE_MODE_EXCL, 16). %% Use this mask to get just the mode bits to be passed to the driver. --define(EFILE_MODE_MASK, 15). +-define(EFILE_MODE_MASK, 31). %% Seek modes for the driver's seek function. -define(EFILE_SEEK_SET, 0). @@ -958,6 +959,8 @@ open_mode([compressed|Rest], Mode, Portopts, Setopts) -> open_mode([append|Rest], Mode, Portopts, Setopts) -> open_mode(Rest, Mode bor ?EFILE_MODE_APPEND bor ?EFILE_MODE_WRITE, Portopts, Setopts); +open_mode([exclusive|Rest], Mode, Portopts, Setopts) -> + open_mode(Rest, Mode bor ?EFILE_MODE_EXCL, Portopts, Setopts); open_mode([delayed_write|Rest], Mode, Portopts, Setopts) -> open_mode([{delayed_write, 64*1024, 2000}|Rest], Mode, Portopts, Setopts); -- cgit v1.2.3 From bac96ae5bb5bfaa0c160a603c6db01dbcd7c83df Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 4 Jun 2010 10:55:07 +0200 Subject: Update preloaded modules --- erts/preloaded/ebin/prim_file.beam | Bin 30452 -> 30548 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'erts') diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam index d39d2d1135..7e99523527 100644 Binary files a/erts/preloaded/ebin/prim_file.beam and b/erts/preloaded/ebin/prim_file.beam differ -- cgit v1.2.3