Skip to content
Browse files

if sendfile hits EOVERFLOW send the file from Erlang code instead

  • Loading branch information...
1 parent 9cee816 commit 082f043c249ddce94cdfb75ae455e724bfc524fb @vinoski vinoski committed Dec 4, 2009
Showing with 42 additions and 13 deletions.
  1. +7 −2 c_src/yaws_sendfile_drv.c
  2. +6 −3 src/yaws_sendfile.erl
  3. +29 −8 src/yaws_sendfile_compat.erl
View
9 c_src/yaws_sendfile_drv.c
@@ -134,7 +134,11 @@ static size_t set_error_buffer(Buffer* b, int socket_fd, int err)
size_t result_size = sizeof *(b->result);
memset(b->result, 0, result_size);
put_int32(socket_fd, &(b->result->out_fd));
- for (s = erl_errno_id(err), t = b->result->errno_string; *s; s++, t++) {
+ s = erl_errno_id(err);
+ if (strcmp(s, "unknown") == 0 && err == EOVERFLOW) {
+ s = "EOVERFLOW";
+ }
+ for (t = b->result->errno_string; *s; s++, t++) {
*t = tolower(*s);
}
*t = '\0';
@@ -238,7 +242,8 @@ static void yaws_sendfile_drv_ready_output(ErlDrvData handle, ErlDrvEvent ev)
return;
}
cur_offset = xfer->offset;
- result = yaws_sendfile_call(sfd->socket_fd, xfer->file_fd, &xfer->offset, xfer->count);
+ result = yaws_sendfile_call(sfd->socket_fd, xfer->file_fd,
+ &xfer->offset, xfer->count);
if (result < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
off_t written = xfer->offset - cur_offset;
xfer->count -= written;
View
9 src/yaws_sendfile.erl
@@ -61,7 +61,8 @@ send(Out, Filename, Offset, Count) ->
call_port(
Socket_fd,
list_to_binary(
- [<<Offset:64, Count2:64, Socket_fd:32>>, Filename, <<0:8>>]));
+ [<<Offset:64, Count2:64, Socket_fd:32>>,
+ Filename, <<0:8>>]));
Error3 ->
Error3
end
@@ -103,9 +104,11 @@ loop(Port) ->
unregister(?MODULE),
exit(shutdown);
{'EXIT', Port, Posix_error} ->
- error_logger:format("Fatal error: sendfile port died, error ~p~n", [Posix_error]),
+ error_logger:format("Fatal error: sendfile port died, error ~p~n",
+ [Posix_error]),
exit(Posix_error);
{'EXIT', error, Reason} ->
- error_logger:format("Fatal error: sendfile driver failure: ~p~n", [Reason]),
+ error_logger:format("Fatal error: sendfile driver failure: ~p~n",
+ [Reason]),
exit(Reason)
end.
View
37 src/yaws_sendfile_compat.erl
@@ -9,6 +9,8 @@
-include_lib("kernel/include/file.hrl").
-include("yaws_configure.hrl").
+-include("../include/yaws.hrl").
+
%% will be true for MacOsX, FreeBSD, Linux
-ifdef(HAVE_SENDFILE).
@@ -21,18 +23,32 @@ stop() ->
init(ShLib) ->
yaws_sendfile:init(ShLib).
send(Out, FileName) ->
- yaws_sendfile:send(Out, FileName).
+ case yaws_sendfile:send(Out, FileName) of
+ {error, eoverflow} ->
+ compat_send(Out, FileName, 0, all);
+ Other ->
+ Other
+ end.
send(Out, FileName, Offset) ->
- yaws_sendfile:send(Out, FileName, Offset).
+ case yaws_sendfile:send(Out, FileName, Offset) of
+ {error, eoverflow} ->
+ compat_send(Out, FileName, Offset, all);
+ Other ->
+ Other
+ end.
send(Out, FileName, Offset, Count) ->
- yaws_sendfile:send(Out, FileName, Offset, Count).
-
+ case yaws_sendfile:send(Out, FileName, Offset, Count) of
+ {error, eoverflow} ->
+ compat_send(Out, FileName, Offset, Count);
+ Other ->
+ Other
+ end.
-else.
--include("../include/yaws.hrl").
+%% Emulate sendfile, this is true for win32, qnx, solaris. OpenBSD,NetBSD I
+%% still don't know
-%% Emulate sendfile, this is true for win32, qnx, solaris. OpenBSD,NetBSD I still don't know
enabled() ->
false.
start_link() ->
@@ -46,6 +62,11 @@ send(Out, Filename) ->
send(Out, Filename, Offset) ->
send(Out, Filename, Offset, all).
send(Out, Filename, Offset, Count) ->
+ compat_send(Out, Filename, Offset, Count).
+
+-endif.
+
+compat_send(Out, Filename, Offset, Count) ->
case file:open(Filename, [read, binary, raw]) of
{ok, Fd} ->
file:position(Fd, {bof, Offset}),
@@ -71,7 +92,8 @@ loop_send(Fd, ChunkSize, {ok, Bin}, Out, Count) ->
if Sz < Count ->
case gen_tcp:send(Out, Bin) of
true ->
- loop_send(Fd, ChunkSize, file:read(Fd, ChunkSize), Out, Count-Sz);
+ loop_send(Fd, ChunkSize, file:read(Fd, ChunkSize),
+ Out, Count-Sz);
Err ->
Err
end;
@@ -85,4 +107,3 @@ loop_send(_Fd, _, Err, _,_) ->
Err.
--endif.

0 comments on commit 082f043

Please sign in to comment.
Something went wrong with that request. Please try again.