mirror of
https://github.com/uselessd/alcove.git
synced 2026-04-15 09:15:19 +00:00
open/4,5: allow atoms/lists as flags
Modify the open/4,5 function to take:
* integers
* lists of integers or atoms
The atoms are named the same as the O_* macros, except lowercased.
This commit is contained in:
@@ -620,10 +620,15 @@ probably confuse the process.
|
||||
open(Drv, Path, Flags, Mode) -> {ok, integer()} | {error, posix()}
|
||||
open(Drv, Pids, Path, Flags, Mode) -> {ok, integer()} | {error, posix()}
|
||||
|
||||
Types Flags = Mode = integer()
|
||||
Types Flags = integer() | [atom() | integer()]
|
||||
Mode = integer()
|
||||
|
||||
open(2) : returns a file descriptor associated with a file
|
||||
|
||||
Lists of values are OR'ed:
|
||||
|
||||
alcove:open(Drv, "/tmp/test", [o_wronly,o_creat], 8#644)
|
||||
|
||||
pid(Drv) -> [Pid]
|
||||
pid(Drv, Pids) -> [Pid]
|
||||
|
||||
|
||||
@@ -482,8 +482,8 @@ specs() ->
|
||||
-spec mount_define(alcove_drv:ref(),atom()) -> 'unknown' | non_neg_integer().
|
||||
-spec mount_define(alcove_drv:ref(),fork_path(),atom()) -> 'unknown' | non_neg_integer().
|
||||
|
||||
-spec open(alcove_drv:ref(),iodata(),integer(),integer()) -> {'ok',fd()} | {'error', file:posix()}.
|
||||
-spec open(alcove_drv:ref(),fork_path(),iodata(),integer(),integer()) -> {'ok',fd()} | {'error', file:posix()}.
|
||||
-spec open(alcove_drv:ref(),iodata(),integer() | [define()],integer()) -> {'ok',fd()} | {'error', file:posix()}.
|
||||
-spec open(alcove_drv:ref(),fork_path(),iodata(),integer() | [define()],integer()) -> {'ok',fd()} | {'error', file:posix()}.
|
||||
|
||||
-spec pid(alcove_drv:ref()) -> [#alcove_pid{}].
|
||||
-spec pid(alcove_drv:ref(),fork_path()) -> [#alcove_pid{}].
|
||||
|
||||
@@ -176,6 +176,8 @@ int alcove_decode_list_header(const char *, size_t, int *, int *);
|
||||
int alcove_decode_tuple_header(const char *, size_t, int *, int *);
|
||||
int alcove_decode_iolist(const char *, size_t, int *, char *, size_t *);
|
||||
int alcove_decode_define(const char *, size_t, int *, int *, alcove_define_t *);
|
||||
int alcove_decode_define_list(const char *, size_t, int *, int *,
|
||||
alcove_define_t *);
|
||||
|
||||
int alcove_encode_version(char *, size_t, int *);
|
||||
int alcove_encode_list_header(char *, size_t, int *, int);
|
||||
|
||||
@@ -48,7 +48,8 @@ alcove_open(alcove_state_t *ap, const char *arg, size_t len,
|
||||
return -1;
|
||||
|
||||
/* flags */
|
||||
if (alcove_decode_int(arg, len, &index, &flags) < 0)
|
||||
if (alcove_decode_define_list(arg, len, &index, &flags,
|
||||
alcove_file_constants) < 0)
|
||||
return -1;
|
||||
|
||||
/* mode */
|
||||
|
||||
@@ -313,6 +313,70 @@ alcove_decode_define(const char *buf, size_t len, int *index, int *val,
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
alcove_decode_define_list(const char *buf, size_t len, int *index, int *val,
|
||||
alcove_define_t *constants)
|
||||
{
|
||||
int type = 0;
|
||||
int arity = 0;
|
||||
|
||||
if (alcove_get_type(buf, len, index, &type, &arity) < 0)
|
||||
return -1;
|
||||
|
||||
switch (type) {
|
||||
case ERL_SMALL_INTEGER_EXT:
|
||||
case ERL_INTEGER_EXT:
|
||||
if (alcove_decode_int(buf, len, index, val) < 0)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case ERL_STRING_EXT: {
|
||||
char tmp[MAXMSGLEN] = {0};
|
||||
char *p = tmp;
|
||||
|
||||
if (arity >= sizeof(tmp))
|
||||
return -1;
|
||||
|
||||
if (ei_decode_string(buf, index, tmp) < 0)
|
||||
return -1;
|
||||
|
||||
for ( ; *p; p++)
|
||||
*val |= *p;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case ERL_LIST_EXT: {
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
int constant = 0;
|
||||
|
||||
if (ei_decode_list_header(buf, index, &length) < 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if (alcove_decode_define(buf, len, index, &constant,
|
||||
constants) < 0)
|
||||
return -1;
|
||||
|
||||
*val |= constant;
|
||||
}
|
||||
|
||||
/* [] */
|
||||
if (alcove_decode_list_header(buf, len, index, &length) < 0
|
||||
|| length != 0)
|
||||
return -1;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ run(State) ->
|
||||
stdout(State),
|
||||
stderr(State),
|
||||
execve(State),
|
||||
stream(State)
|
||||
stream(State),
|
||||
open(State)
|
||||
].
|
||||
|
||||
start() ->
|
||||
@@ -594,6 +595,21 @@ stream(#state{pid = Drv}) ->
|
||||
Reply = stream_count(Drv, Chain, Count*2),
|
||||
?_assertEqual(ok, Reply).
|
||||
|
||||
open(#state{pid = Drv}) ->
|
||||
O_RDONLY = alcove:define(Drv, o_rdonly),
|
||||
|
||||
File = "/nonexistent",
|
||||
|
||||
Reply0 = alcove:open(Drv, File, 0, 0),
|
||||
Reply1 = alcove:open(Drv, File, [0,0,0,0], 0),
|
||||
Reply2 = alcove:open(Drv, File, [o_rdonly, o_rdonly, o_rdonly], 0),
|
||||
|
||||
[
|
||||
?_assertEqual({error,enoent}, Reply0),
|
||||
?_assertEqual({error,enoent}, Reply1),
|
||||
?_assertEqual({error,enoent}, Reply2)
|
||||
].
|
||||
|
||||
%%
|
||||
%% Utility functions
|
||||
%%
|
||||
|
||||
Reference in New Issue
Block a user