Erlang/OTP Forums

Author Message

<  Erlang patches mailing list  ~  [PATCH] Support opening files in exclusive mode

Guest
Posted: Fri Apr 30, 2010 4:22 pm Reply with quote
Guest
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 ++++-
lib/kernel/doc/src/file.xml | 8 +++++++-
lib/kernel/src/file.erl | 2 +-
lib/kernel/test/file_SUITE.erl | 20 ++++++++++++++++++--
lib/kernel/test/prim_file_SUITE.erl | 20 ++++++++++++++++++--
8 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h
index 9aa941e..d2ef9c0 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 d395b68..6171272 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -751,6 +751,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 89aaad3..de5cd21 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,
NULL, crFlags, FILE_ATTRIBUTE_NORMAL, NULL);

diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index 43e6f6c..035ff3e 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -114,9 +114,10 @@
-define(EFILE_MODE_READ_WRITE, 3).
-define(EFILE_MODE_APPEND, 4).
-define(EFILE_COMPRESSED, Cool.
+-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).
@@ -918,6 +919,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);
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 50f9722..eed92d2 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -584,7 +584,7 @@ f.txt: {person, "kalle", 25}.
<type>
<v>Filename = name()</v>
<v>Modes = [Mode]</v>
- <v>&nbsp;Mode = read | write | append | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed</v>
+ <v>&nbsp;Mode = read | write | append | exclusive | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed</v>
<v>&nbsp;&nbsp;Size = Delay = int()</v>
<v>IoDevice = io_device()</v>
<v>Reason = ext_posix() | system_limit</v>
@@ -611,6 +611,12 @@ f.txt: {person, "kalle", 25}.
file opened with <c>append</c> will take place at
the end of the file.</p>
</item>
+ <tag><c>exclusive</c></tag>
+ <item>
+ <p>The file, when opened for writing, is created if it
+ does not exist. If the file exists, open will return
+ <c>{error, eexist}</c>.</p>
+ </item>
<tag><c>raw</c></tag>
<item>
<p>The <c>raw</c> option allows faster access to a file,
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 46ffa9d..419d8db 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -81,7 +81,7 @@
-type mode() :: 'read' | 'write' | 'append' | 'raw' | 'binary' |
{'delayed_write', non_neg_integer(), non_neg_integer()} |
'delayed_write' | {'read_ahead', pos_integer()} |
- 'read_ahead' | 'compressed'.
+ 'read_ahead' | 'compressed' | 'exclusive'.
-type name() :: string() | atom() | [name()].
-type posix() :: atom().
-type bindings() :: any().
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index d01e1f1..b9d57ce 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -53,7 +53,7 @@
-export([file_info/1, file_info_basic_file/1, file_info_basic_directory/1,
file_info_bad/1, file_info_times/1, file_write_file_info/1]).
-export([rename/1, access/1, truncate/1, sync/1,
- read_write/1, pread_write/1, append/1]).
+ read_write/1, pread_write/1, append/1, exclusive/1]).
-export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).
-export([otp_5814/1]).

@@ -377,7 +377,7 @@ win_cur_dir_1(_Config) ->
files(suite) -> [open,pos,file_info,consult,eval,script,truncate,sync].

open(suite) -> [open1,old_modes,new_modes,path_open,close,access,read_write,
- pread_write,append,open_errors].
+ pread_write,append,open_errors,exclusive].

open1(suite) -> [];
open1(doc) -> [];
@@ -751,6 +751,22 @@ open_errors(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.

+exclusive(suite) -> [];
+exclusive(doc) -> "Test exclusive access to a file.";
+exclusive(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line RootDir = ?config(priv_dir,Config),
+ ?line NewDir = filename:join(RootDir,
+ atom_to_list(?MODULE)
+ ++"_exclusive"),
+ ?line ok = ?FILE_MODULE:make_dir(NewDir),
+ ?line Name = filename:join(NewDir, "ex_file.txt"),
+ ?line {ok, Fd} = ?FILE_MODULE:open(Name, [write, exclusive]),
+ ?line {error, eexist} = ?FILE_MODULE:open(Name, [write, exclusive]),
+ ?line ok = ?FILE_MODULE:close(Fd),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

pos(suite) -> [pos1,pos2].
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 860aeec..9f6dd78 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -35,7 +35,7 @@
file_write_file_info_a/1, file_write_file_info_b/1]).
-export([rename_a/1, rename_b/1,
access/1, truncate/1, sync/1,
- read_write/1, pread_write/1, append/1]).
+ read_write/1, pread_write/1, append/1, exclusive/1]).
-export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).

-export([compression/1, read_not_really_compressed/1,
@@ -380,7 +380,7 @@ win_cur_dir_1(_Config, Handle) ->
files(suite) -> [open,pos,file_info,truncate,sync].

open(suite) -> [open1,modes,close,access,read_write,
- pread_write,append].
+ pread_write,append,exclusive].

open1(suite) -> [];
open1(doc) -> [];
@@ -605,6 +605,22 @@ append(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.

+exclusive(suite) -> [];
+exclusive(doc) -> "Test exclusive access to a file.";
+exclusive(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line RootDir = ?config(priv_dir,Config),
+ ?line NewDir = filename:join(RootDir,
+ atom_to_list(?MODULE)
+ ++"_exclusive"),
+ ?line ok = ?PRIM_FILE:make_dir(NewDir),
+ ?line Name = filename:join(NewDir, "ex_file.txt"),
+ ?line {ok,Fd} = ?PRIM_FILE:open(Name, [write, exclusive]),
+ ?line {error, eexist} = ?PRIM_FILE:open(Name, [write, exclusive]),
+ ?line ok = ?PRIM_FILE:close(Fd),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

pos(suite) -> [pos1,pos2].
--
1.5.6.4


________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org

Post received from mailinglist
Guest
Posted: Fri Apr 30, 2010 4:22 pm Reply with quote
Guest
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 ++++-
lib/kernel/doc/src/file.xml | 8 +++++++-
lib/kernel/src/file.erl | 2 +-
lib/kernel/test/file_SUITE.erl | 20 ++++++++++++++++++--
lib/kernel/test/prim_file_SUITE.erl | 20 ++++++++++++++++++--
8 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h
index 9aa941e..d2ef9c0 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 d395b68..6171272 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -751,6 +751,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 89aaad3..de5cd21 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,
NULL, crFlags, FILE_ATTRIBUTE_NORMAL, NULL);

diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index 43e6f6c..035ff3e 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -114,9 +114,10 @@
-define(EFILE_MODE_READ_WRITE, 3).
-define(EFILE_MODE_APPEND, 4).
-define(EFILE_COMPRESSED, Cool.
+-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).
@@ -918,6 +919,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);
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 50f9722..eed92d2 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -584,7 +584,7 @@ f.txt: {person, "kalle", 25}.
<type>
<v>Filename = name()</v>
<v>Modes = [Mode]</v>
- <v>&nbsp;Mode = read | write | append | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed</v>
+ <v>&nbsp;Mode = read | write | append | exclusive | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed</v>
<v>&nbsp;&nbsp;Size = Delay = int()</v>
<v>IoDevice = io_device()</v>
<v>Reason = ext_posix() | system_limit</v>
@@ -611,6 +611,12 @@ f.txt: {person, "kalle", 25}.
file opened with <c>append</c> will take place at
the end of the file.</p>
</item>
+ <tag><c>exclusive</c></tag>
+ <item>
+ <p>The file, when opened for writing, is created if it
+ does not exist. If the file exists, open will return
+ <c>{error, eexist}</c>.</p>
+ </item>
<tag><c>raw</c></tag>
<item>
<p>The <c>raw</c> option allows faster access to a file,
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 46ffa9d..419d8db 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -81,7 +81,7 @@
-type mode() :: 'read' | 'write' | 'append' | 'raw' | 'binary' |
{'delayed_write', non_neg_integer(), non_neg_integer()} |
'delayed_write' | {'read_ahead', pos_integer()} |
- 'read_ahead' | 'compressed'.
+ 'read_ahead' | 'compressed' | 'exclusive'.
-type name() :: string() | atom() | [name()].
-type posix() :: atom().
-type bindings() :: any().
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index d01e1f1..b9d57ce 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -53,7 +53,7 @@
-export([file_info/1, file_info_basic_file/1, file_info_basic_directory/1,
file_info_bad/1, file_info_times/1, file_write_file_info/1]).
-export([rename/1, access/1, truncate/1, sync/1,
- read_write/1, pread_write/1, append/1]).
+ read_write/1, pread_write/1, append/1, exclusive/1]).
-export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).
-export([otp_5814/1]).

@@ -377,7 +377,7 @@ win_cur_dir_1(_Config) ->
files(suite) -> [open,pos,file_info,consult,eval,script,truncate,sync].

open(suite) -> [open1,old_modes,new_modes,path_open,close,access,read_write,
- pread_write,append,open_errors].
+ pread_write,append,open_errors,exclusive].

open1(suite) -> [];
open1(doc) -> [];
@@ -751,6 +751,22 @@ open_errors(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.

+exclusive(suite) -> [];
+exclusive(doc) -> "Test exclusive access to a file.";
+exclusive(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line RootDir = ?config(priv_dir,Config),
+ ?line NewDir = filename:join(RootDir,
+ atom_to_list(?MODULE)
+ ++"_exclusive"),
+ ?line ok = ?FILE_MODULE:make_dir(NewDir),
+ ?line Name = filename:join(NewDir, "ex_file.txt"),
+ ?line {ok, Fd} = ?FILE_MODULE:open(Name, [write, exclusive]),
+ ?line {error, eexist} = ?FILE_MODULE:open(Name, [write, exclusive]),
+ ?line ok = ?FILE_MODULE:close(Fd),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

pos(suite) -> [pos1,pos2].
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 860aeec..9f6dd78 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -35,7 +35,7 @@
file_write_file_info_a/1, file_write_file_info_b/1]).
-export([rename_a/1, rename_b/1,
access/1, truncate/1, sync/1,
- read_write/1, pread_write/1, append/1]).
+ read_write/1, pread_write/1, append/1, exclusive/1]).
-export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).

-export([compression/1, read_not_really_compressed/1,
@@ -380,7 +380,7 @@ win_cur_dir_1(_Config, Handle) ->
files(suite) -> [open,pos,file_info,truncate,sync].

open(suite) -> [open1,modes,close,access,read_write,
- pread_write,append].
+ pread_write,append,exclusive].

open1(suite) -> [];
open1(doc) -> [];
@@ -605,6 +605,22 @@ append(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.

+exclusive(suite) -> [];
+exclusive(doc) -> "Test exclusive access to a file.";
+exclusive(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line RootDir = ?config(priv_dir,Config),
+ ?line NewDir = filename:join(RootDir,
+ atom_to_list(?MODULE)
+ ++"_exclusive"),
+ ?line ok = ?PRIM_FILE:make_dir(NewDir),
+ ?line Name = filename:join(NewDir, "ex_file.txt"),
+ ?line {ok,Fd} = ?PRIM_FILE:open(Name, [write, exclusive]),
+ ?line {error, eexist} = ?PRIM_FILE:open(Name, [write, exclusive]),
+ ?line ok = ?PRIM_FILE:close(Fd),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

pos(suite) -> [pos1,pos2].
--
1.5.6.4


________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org

Post received from mailinglist
Guest
Posted: Mon May 03, 2010 5:42 am Reply with quote
Guest
On Fri, Apr 30, 2010 at 6:22 PM, Michael Santos
<michael.santos@gmail.com> wrote:
> 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]).

Thanks! Will include in 'pu'.

--
Björn Gustavsson, Erlang/OTP, Ericsson AB

________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org

Post received from mailinglist
Guest
Posted: Mon May 03, 2010 5:42 am Reply with quote
Guest
On Fri, Apr 30, 2010 at 6:22 PM, Michael Santos
<michael.santos@gmail.com> wrote:
> 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]).

Thanks! Will include in 'pu'.

--
Björn Gustavsson, Erlang/OTP, Ericsson AB

________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org

Post received from mailinglist

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum