aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorMichael Santos <[email protected]>2010-04-30 12:22:11 -0400
committerRaimo Niskanen <[email protected]>2010-06-04 10:47:56 +0200
commit4bd026cccb2c22279dd9c88e704642c5a65d3c53 (patch)
tree5c801bf9813b575eb302039f78b07b50364b6696 /erts
parentcbd1378ee1fde835e55614bac9290b281bafe49a (diff)
downloadotp-4bd026cccb2c22279dd9c88e704642c5a65d3c53.tar.gz
otp-4bd026cccb2c22279dd9c88e704642c5a65d3c53.tar.bz2
otp-4bd026cccb2c22279dd9c88e704642c5a65d3c53.zip
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]).
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/drivers/common/erl_efile.h3
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c3
-rw-r--r--erts/emulator/drivers/win32/win_efile.c3
-rw-r--r--erts/preloaded/src/prim_file.erl5
4 files changed, 12 insertions, 2 deletions
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);