struct inotify_context {
ErlDrvPort erl_port;
int fd;
- uint8_t real_path;
struct watch *watches;
size_t nwatches;
size_t max_watches;
};
-static ssize_t copy_path(char *path, size_t path_len, char *output, int real);
+static ssize_t copy_path(char *path, size_t path_len, char *output);
static uint32_t flags_to_inotify(uint32_t flags);
static int send_inotify_event(struct inotify_context *context, struct inotify_event *event);
static int send_inotify_single_flag_event(struct inotify_context *context, struct inotify_event *event, ErlDrvTermData flag_atom);
driver_alloc(sizeof(struct inotify_context));
context->erl_port = port;
- context->real_path = 1;
context->watches = NULL;
context->nwatches = 0;
context->max_watches = 0;
ErlDrvTermData caller;
switch (command) {
- case 0: // initialize port {{{
- if (len != 2)
- return -1;
-
- //context->recursive = buf[0]; // TODO: implement me
- context->real_path = buf[1];
-
- return 0;
- // }}}
-
case 1: // add/update watch {{{
if (len < 5) // uint32_t + at least one character for filename
return -1;
request_flags = (uint8_t)buf[0] << (8 * 3) | (uint8_t)buf[1] << (8 * 2) |
(uint8_t)buf[2] << (8 * 1) | (uint8_t)buf[3] << (8 * 0);
inotify_flags = flags_to_inotify(request_flags);
- if (copy_path(buf + 4, len - 4, path, context->real_path) < 0)
+ if (copy_path(buf + 4, len - 4, path) < 0)
return store_errno(errno, *rbuf, rlen);
if ((wd = inotify_add_watch(context->fd, path, inotify_flags)) >= 0) {
if (len < 1) // at least one character for filename
return -1;
- if (copy_path(buf, len, path, context->real_path) < 0)
+ if (copy_path(buf, len, path) < 0)
return store_errno(errno, *rbuf, rlen);
wd = watch_find_wd(context, path);
// }}}
//----------------------------------------------------------------------------
-// copy path to NUL-terminated buffer, maybe with resolving symlinks {{{
+// copy path to NUL-terminated buffer {{{
static
-ssize_t copy_path(char *path, size_t path_len, char *output, int real)
+ssize_t copy_path(char *path, size_t path_len, char *output)
{
if (path_len >= PATH_MAX) {
errno = ENAMETOOLONG;
return -1;
}
- if (!real) {
- memcpy(output, path, path_len);
- output[path_len] = 0;
- return path_len;
- }
-
- char tmppath[PATH_MAX];
- memcpy(tmppath, path, path_len);
- tmppath[path_len] = 0;
-
- if (realpath(tmppath, output) == NULL)
- return -1;
-
- return 0;
+ memcpy(output, path, path_len);
+ output[path_len] = 0;
+ return path_len;
}
// }}}
-module(gen_inotify).
%% public interface
--export([open/0, open/1, close/1]).
+-export([open/0, close/1]).
-export([add/3, update/3, remove/2, list/1, count/1]).
-export([controlling_process/2]).
-export([format_error/1]).
{ok, handle()} | {error, system_limit | posix()}.
open() ->
- open([]).
-
-%% @doc Open a new <i>inotify</i> handle.
-
--spec open(Options :: [Option]) ->
- {ok, handle()} | {error, badarg | system_limit | posix()}
- when Option :: recursive | real_path.
-
-open(Options) ->
- case build_open_options_data(Options) of
- {ok, OptData} ->
- try open_port({spawn_driver, ?DRIVER_NAME}, [binary]) of
- Handle ->
- port_control(Handle, 0, OptData),
- {ok, Handle}
- catch
- error:Reason ->
- {error, Reason}
- end;
- {error, badarg} ->
- {error, badarg}
- end.
-
-%%----------------------------------------------------------
-%% build_open_options_data() {{{
-
-%% @doc Translate list of options to a `port_control(Port,0,_)' request
-%% payload.
-
--spec build_open_options_data(Options :: [Option]) ->
- {ok, {Recursive :: boolean(), UseRealPath :: boolean()}} | {error, badarg}
- when Option :: recursive | real_path.
-
-build_open_options_data(Options) ->
- DefaultOptions = {false, false}, % `{Recursive, UseRealPath}'
- try lists:foldr(fun add_open_option/2, DefaultOptions, Options) of
- {false, false} -> {ok, <<0:8, 0:8>>};
- {true, false} -> {ok, <<1:8, 0:8>>};
- {false, true} -> {ok, <<0:8, 1:8>>};
- {true, true} -> {ok, <<1:8, 1:8>>}
+ try open_port({spawn_driver, ?DRIVER_NAME}, [binary]) of
+ Handle -> {ok, Handle}
catch
- _:_ -> {error, badarg}
+ error:Reason -> {error, Reason}
end.
-%% @doc Workhorse for {@link build_open_options_data/1}.
-
--spec add_open_option(Option, {boolean(), boolean()}) ->
- {boolean(), boolean()}
- when Option :: recursive | real_path.
-
-add_open_option(recursive, {_Recursive, UseRealPath}) -> {true, UseRealPath};
-add_open_option(real_path, {Recursive, _UseRealPath}) -> {Recursive, true}.
-
-%% }}}
-%%----------------------------------------------------------
-
%% @doc Close a handle.
-spec close(handle()) ->