Browse files

Merge pull request #11 from vinoski/sbv-r16

move port creation to Erlang to fix issue #9
  • Loading branch information...
2 parents a67e9b6 + 28e26bc commit 1db6c4ed028a25068f8516b418e1916a50d6c661 @Vagabond committed Jun 17, 2013
Showing with 30 additions and 121 deletions.
  1. +14 −83 c_src/syslog_drv.c
  2. +16 −38 src/syslog.erl
View
97 c_src/syslog_drv.c
@@ -103,6 +103,9 @@ static ErlDrvSSizeT syslogdrv_control(ErlDrvData handle, unsigned int command,
char **rbuf, ErlDrvSizeT rlen)
{
syslogdrv_t* d = (syslogdrv_t*)handle;
+ if (d->open) {
+ return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
+ }
int index = 0, version, arity, type, size;
if (command != SYSLOGDRV_OPEN) {
@@ -112,110 +115,38 @@ static ErlDrvSSizeT syslogdrv_control(ErlDrvData handle, unsigned int command,
if (ei_decode_version(buf, &index, &version)) {
return encode_error(*rbuf, "badver");
}
- if (ei_decode_tuple_header(buf, &index, &arity) || arity != 4) {
+ if (ei_decode_tuple_header(buf, &index, &arity) || arity != 3) {
return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
}
if (ei_get_type(buf, &index, &type, &size)) {
return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
}
if (type == ERL_STRING_EXT) {
- long logopt, facility, len;
- ErlDrvBinary* ref = 0;
+ long logopt, facility;
- syslogdrv_t* nd = (syslogdrv_t*)driver_alloc(sizeof(syslogdrv_t));
- if (nd == NULL) {
- return encode_error(*rbuf, "enomem");
+ if (d->ident) {
+ driver_free(d->ident);
}
- nd->ident = driver_alloc(size+1);
- if (nd->ident == NULL) {
+ d->ident = driver_alloc(size+1);
+ if (d->ident == NULL) {
return encode_error(*rbuf, "enomem");
}
- if (ei_decode_string(buf, &index, nd->ident)) {
- driver_free(nd->ident);
- driver_free(nd);
+ if (ei_decode_string(buf, &index, d->ident)) {
return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
}
if (ei_decode_long(buf, &index, &logopt) ||
ei_decode_long(buf, &index, &facility)) {
- driver_free(nd->ident);
- driver_free(nd);
- return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
- }
- if (ei_get_type(buf, &index, &type, &size)) {
- driver_free(nd->ident);
- driver_free(nd);
- return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
- }
- if (type != ERL_BINARY_EXT) {
- driver_free(nd->ident);
- driver_free(nd);
return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
}
- ref = driver_alloc_binary(size);
- if (ref == NULL) {
- return encode_error(*rbuf, "enomem");
- }
- if (ei_decode_binary(buf, &index, ref->orig_bytes, &len)) {
- driver_free_binary(ref);
- driver_free(nd->ident);
- driver_free(nd);
- return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
- }
- nd->logopt = (int)logopt;
- nd->facility = (int)facility;
- nd->open = 1;
- {
- ErlDrvTermData refdata = TERM_DATA(ref->orig_bytes);
- ErlDrvPort port = d->port;
- ErlDrvTermData pid = driver_caller(port);
- ErlDrvData data = (ErlDrvData)nd;
- nd->port = driver_create_port(port, pid, DRV_NAME, data);
- if (nd->port == (ErlDrvPort)-1) {
- driver_free_binary(ref);
- driver_free(nd->ident);
- driver_free(nd);
- return (ErlDrvSSizeT)ERL_DRV_ERROR_GENERAL;
- }
- set_port_control_flags(nd->port, PORT_CONTROL_FLAG_BINARY);
- ErlDrvTermData term[] = {
- ERL_DRV_EXT2TERM, refdata, ref->orig_size,
- ERL_DRV_ATOM, driver_mk_atom("ok"),
- ERL_DRV_PORT, driver_mk_port(nd->port),
- ERL_DRV_TUPLE, 2,
- ERL_DRV_TUPLE, 2,
- };
- driver_output_term(port, term, sizeof term/sizeof *term);
- }
- driver_free_binary(ref);
+ d->logopt = (int)logopt;
+ d->facility = (int)facility;
+ d->open = 1;
return 0;
} else {
return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
}
}
-static ErlDrvSSizeT syslogdrv_call(ErlDrvData handle, unsigned int command,
- char *buf, ErlDrvSizeT len,
- char **rbuf, ErlDrvSizeT rlen, unsigned int* flags)
-{
- syslogdrv_t* d = (syslogdrv_t*)handle;
- int index = 0;
-
- if (command != SYSLOGDRV_CLOSE) {
- return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
- }
-
- if (d->ident) {
- driver_free(d->ident);
- }
- d->ident = NULL;
- d->open = 0;
- if (ei_encode_version(*rbuf, &index) ||
- ei_encode_atom(*rbuf, &index, "ok")) {
- return (ErlDrvSSizeT)ERL_DRV_ERROR_GENERAL;
- }
- return index+1;
-}
-
/*
* Initialize and return a driver entry struct
*/
@@ -234,7 +165,7 @@ static ErlDrvEntry syslogdrv_driver_entry = {
NULL,
NULL,
NULL,
- syslogdrv_call,
+ NULL,
NULL,
ERL_DRV_EXTENDED_MARKER,
ERL_DRV_EXTENDED_MAJOR_VERSION,
View
54 src/syslog.erl
@@ -28,9 +28,8 @@
-define(DRV_NAME, "syslog_drv").
-%% these constants must match those in syslog_drv.c
+%% this constant must match the same in syslog_drv.c
-define(SYSLOGDRV_OPEN, 1).
--define(SYSLOGDRV_CLOSE, 2).
%% API
-export([
@@ -57,7 +56,7 @@
-include_lib("eunit/include/eunit.hrl").
-endif.
--record(state, {port}).
+-record(state, {}).
start() ->
gen_server:start({local, ?MODULE}, ?MODULE, [], []).
@@ -69,11 +68,16 @@ stop() ->
gen_server:cast(?MODULE, stop).
open(Ident, Logopt, Facility) ->
- case gen_server:call(?MODULE, {open, Ident, logopt(Logopt), facility(Facility)}) of
- {error, badarg} ->
- erlang:error(badarg);
- Else ->
- Else
+ Log = erlang:open_port({spawn, ?DRV_NAME}, [binary]),
+ Args = term_to_binary({Ident, logopt(Logopt), facility(Facility)}),
+ try erlang:port_control(Log, ?SYSLOGDRV_OPEN, Args) of
+ <<>> ->
+ {ok, Log};
+ BinError ->
+ binary_to_term(BinError)
+ catch
+ _:Reason ->
+ {error, Reason}
end.
log(_Log, _Priority, []) ->
@@ -88,12 +92,8 @@ log(Log, Priority, FormatStr, FormatArgs) ->
log(Log, Priority, io_lib:format(FormatStr, FormatArgs)).
close(Log) ->
- try erlang:port_call(Log, ?SYSLOGDRV_CLOSE, <<>>) of
- Result ->
- Result
- after
- port_close(Log)
- end.
+ true = erlang:port_close(Log),
+ ok.
%%% API %%%
@@ -121,32 +121,11 @@ init([]) ->
end,
case LoadResult of
ok ->
- Port = erlang:open_port({spawn, ?DRV_NAME}, [binary]),
- {ok, #state{port = Port}};
+ {ok, #state{}};
Error ->
Error
end.
-handle_call({open, Ident, Logopt, Facility}, {Pid,_}, #state{port = Port} = State) ->
- Ref = make_ref(),
- Args = term_to_binary({Ident, Logopt, Facility, term_to_binary(Ref)}),
- Reply = try erlang:port_control(Port, ?SYSLOGDRV_OPEN, Args) of
- <<>> ->
- receive
- {Ref, {ok, Log}=Result} ->
- erlang:port_connect(Log, Pid),
- unlink(Log),
- Result;
- {Ref, Result} ->
- Result
- end;
- BinError ->
- binary_to_term(BinError)
- catch
- _:Reason ->
- {error, Reason}
- end,
- {reply, Reply, State};
handle_call(_Msg, _From, State) ->
{reply, ok, State}.
@@ -158,8 +137,7 @@ handle_cast(_Msg, State) ->
handle_info(_Info, State) ->
{noreply, State}.
-terminate(_Reason, #state{port = Port}) ->
- erlang:port_close(Port),
+terminate(_Reason, _State) ->
ok.
code_change(_, _, _) ->

0 comments on commit 1db6c4e

Please sign in to comment.