sendfile 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +11 -0
- data/FILES +10 -0
- data/LICENSE +21 -0
- data/README +57 -0
- data/ext/extconf.rb +53 -0
- data/ext/sendfile.c +161 -0
- data/sendfile.gemspec +25 -0
- data/test/large.gz +0 -0
- data/test/small +1 -0
- data/test/test_sendfile.rb +174 -0
- metadata +54 -0
data/ChangeLog
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
* sendfile 0.9.1 - 2006.03.24 <toby@cbcg.net>
|
2
|
+
|
3
|
+
- Improved interface with non-blocking sockets
|
4
|
+
- Added unit tests for blocking sends
|
5
|
+
- Added unit tests for nonblocking sends
|
6
|
+
- Added README
|
7
|
+
- Packaged in a RubyGem
|
8
|
+
|
9
|
+
* sendfile 0.0.1 - 2005.11.16 <toby@cbcg.net>
|
10
|
+
|
11
|
+
- Initial release
|
data/FILES
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
Copyright (c) 2005 Tobias DiPasquale
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
copy of this software and associated documentation files (the "Software"),
|
6
|
+
to deal in the Software without restriction, including without limitation
|
7
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included
|
12
|
+
in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
15
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
19
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
20
|
+
DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
= Ruby sendfile(2) Interface
|
2
|
+
|
3
|
+
This module allows Ruby programs to access their OS's native
|
4
|
+
sendfile(2) system call from any IO object. Your kernel must
|
5
|
+
export a recognized signature for the sendfile(2) system call
|
6
|
+
to use this module. Currently, that includes Linux, Solaris
|
7
|
+
and FreeBSD.
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
Download and install the latest package from the rubyforge.org
|
12
|
+
RubyGems repository.
|
13
|
+
|
14
|
+
gem install sendfile --remote
|
15
|
+
gem check sendfile --test
|
16
|
+
|
17
|
+
If the tests all pass, you're ready to start using sendfile.
|
18
|
+
|
19
|
+
Or, if you don't have rubygems installed, you can install by
|
20
|
+
hand by downloading the tarball:
|
21
|
+
|
22
|
+
tar xzvf ruby-sendfile-<latest>.tar.gz
|
23
|
+
cd ruby-sendfile-<latest>/ext
|
24
|
+
ruby extconf.rb
|
25
|
+
make
|
26
|
+
sudo make install
|
27
|
+
|
28
|
+
You can then run the tests with:
|
29
|
+
|
30
|
+
ruby test/test_*.rb
|
31
|
+
|
32
|
+
== Usage
|
33
|
+
|
34
|
+
Here's a small example of a use of IO#sendfile.
|
35
|
+
|
36
|
+
require 'socket'
|
37
|
+
require 'rubygems'
|
38
|
+
require 'sendfile'
|
39
|
+
|
40
|
+
s = TCPSocket.new 'yourdomain.com', 5000
|
41
|
+
File.open 'somefile.txt' { |f| s.sendfile f }
|
42
|
+
s.close
|
43
|
+
|
44
|
+
See the test scripts for more examples on how to use this
|
45
|
+
module.
|
46
|
+
|
47
|
+
== Contact Information
|
48
|
+
|
49
|
+
This project's homepage is:
|
50
|
+
|
51
|
+
http://rubyforge.org/projects/ruby-sendfile
|
52
|
+
|
53
|
+
Thereupon are additional resources, such as news and forums
|
54
|
+
can be found for working out any issues you may have with this
|
55
|
+
module. In the last case, you can email questions or patches
|
56
|
+
to toby@cbcg.net.
|
57
|
+
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2005 Tobias DiPasquale
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
5
|
+
# copy of this software and associated documentation files (the "Software"),
|
6
|
+
# to deal in the Software without restriction, including without limitation
|
7
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
8
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
9
|
+
# Software is furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included
|
12
|
+
# in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
15
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
17
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
19
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
20
|
+
# DEALINGS IN THE SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
#
|
24
|
+
# $Id: extconf.rb,v 1.1 2006/03/25 01:42:02 codeslinger Exp $
|
25
|
+
#
|
26
|
+
require 'mkmf'
|
27
|
+
|
28
|
+
$config_h = ""
|
29
|
+
case RUBY_PLATFORM
|
30
|
+
when /solaris/
|
31
|
+
have_header( "sys/sendfile.h")
|
32
|
+
have_library( "sendfile", "sendfile")
|
33
|
+
$config_h << "#define RUBY_PLATFORM_SOLARIS"
|
34
|
+
when /linux/
|
35
|
+
have_header( "sys/sendfile.h")
|
36
|
+
have_library( "c", "sendfile")
|
37
|
+
$config_h << "#define RUBY_PLATFORM_LINUX"
|
38
|
+
when /freebsd/
|
39
|
+
have_library( "c", "sendfile")
|
40
|
+
$config_h << "#define RUBY_PLATFORM_FREEBSD"
|
41
|
+
end
|
42
|
+
|
43
|
+
File.open( "config.h", "w") do |f|
|
44
|
+
f.print <<EOF
|
45
|
+
#ifndef CONFIG_H
|
46
|
+
#define CONFIG_H
|
47
|
+
#{$config_h}
|
48
|
+
#endif /* CONFIG_H */
|
49
|
+
EOF
|
50
|
+
end
|
51
|
+
|
52
|
+
create_makefile( "sendfile")
|
53
|
+
|
data/ext/sendfile.c
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
/*
|
2
|
+
* ------------------------------------------------------------------------
|
3
|
+
*
|
4
|
+
* Copyright (c) 2005 Tobias DiPasquale
|
5
|
+
*
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a
|
7
|
+
* copy of this software and associated documentation files (the "Software"),
|
8
|
+
* to deal in the Software without restriction, including without limitation
|
9
|
+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
10
|
+
* and/or sell copies of the Software, and to permit persons to whom the
|
11
|
+
* Software is furnished to do so, subject to the following conditions:
|
12
|
+
*
|
13
|
+
* The above copyright notice and this permission notice shall be included
|
14
|
+
* in all copies or substantial portions of the Software.
|
15
|
+
*
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
17
|
+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
19
|
+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
22
|
+
* DEALINGS IN THE SOFTWARE.
|
23
|
+
*
|
24
|
+
* ------------------------------------------------------------------------
|
25
|
+
*
|
26
|
+
* Ruby binding for the UNIX sendfile(2) facility. Should work on FreeBSD,
|
27
|
+
* Linux and Solaris systems that support sendfile(2).
|
28
|
+
*
|
29
|
+
* Original Author: Toby DiPasquale <toby@cbcg.net>
|
30
|
+
* Current Maintainer: Toby DiPasquale <toby@cbcg.net>
|
31
|
+
*
|
32
|
+
* $Id: sendfile.c,v 1.3 2006/03/26 16:03:59 codeslinger Exp $
|
33
|
+
*/
|
34
|
+
#include "ruby.h"
|
35
|
+
#include "rubyio.h"
|
36
|
+
#include "rubysig.h"
|
37
|
+
#include "config.h"
|
38
|
+
|
39
|
+
#if defined(RUBY_PLATFORM_FREEBSD)
|
40
|
+
# include <sys/socket.h>
|
41
|
+
# include <sys/stat.h>
|
42
|
+
# include <sys/types.h>
|
43
|
+
# include <sys/uio.h>
|
44
|
+
#elif defined(RUBY_PLATFORM_LINUX)
|
45
|
+
# include <sys/sendfile.h>
|
46
|
+
# include <sys/stat.h>
|
47
|
+
# include <sys/types.h>
|
48
|
+
# include <unistd.h>
|
49
|
+
#elif defined(RUBY_PLATFORM_SOLARIS)
|
50
|
+
# include <sys/sendfile.h>
|
51
|
+
# include <sys/stat.h>
|
52
|
+
# include <sys/types.h>
|
53
|
+
#endif
|
54
|
+
|
55
|
+
#define SENDFILE_PAUSE_SEC 0
|
56
|
+
#define SENDFILE_PAUSE_USEC 500
|
57
|
+
|
58
|
+
#if defined(RUBY_PLATFORM_FREEBSD)
|
59
|
+
static off_t __sendfile( int out, int in, off_t off, size_t count, struct timeval *tv)
|
60
|
+
{
|
61
|
+
int rv;
|
62
|
+
off_t written, initial = off;
|
63
|
+
|
64
|
+
while (1) {
|
65
|
+
TRAP_BEG;
|
66
|
+
rv = sendfile( in, out, off, count, NULL, &written, 0);
|
67
|
+
TRAP_END;
|
68
|
+
off += written;
|
69
|
+
count -= written;
|
70
|
+
if (rv < 0 && errno != EAGAIN)
|
71
|
+
rv_sys_fail( "sendfile");
|
72
|
+
if (!rv)
|
73
|
+
break;
|
74
|
+
rb_thread_select( 0, NULL, NULL, NULL, tv);
|
75
|
+
}
|
76
|
+
return off - initial;
|
77
|
+
}
|
78
|
+
#else
|
79
|
+
static size_t __sendfile( int out, int in, off_t off, size_t count, struct timeval *tv)
|
80
|
+
{
|
81
|
+
ssize_t rv, remaining = count;
|
82
|
+
|
83
|
+
while (1) {
|
84
|
+
TRAP_BEG;
|
85
|
+
rv = sendfile( out, in, &off, remaining);
|
86
|
+
TRAP_END;
|
87
|
+
if (rv < 0 && errno != EAGAIN)
|
88
|
+
rb_sys_fail( "sendfile");
|
89
|
+
if (rv > 0)
|
90
|
+
remaining -= rv;
|
91
|
+
if (!remaining)
|
92
|
+
break;
|
93
|
+
rb_thread_select( 0, NULL, NULL, NULL, tv);
|
94
|
+
}
|
95
|
+
return count;
|
96
|
+
}
|
97
|
+
#endif
|
98
|
+
|
99
|
+
/* call-seq:
|
100
|
+
* writeIO.sendfile( readIO, offset=0, count=nil) => integer
|
101
|
+
*
|
102
|
+
* Transfers count bytes starting at offset from readIO directly to writeIO
|
103
|
+
* without copying (i.e. invoking the kernel to do it for you).
|
104
|
+
*
|
105
|
+
* If offset is omitted, transfer starts at the beginning of the file.
|
106
|
+
*
|
107
|
+
* If count is omitted, the full length of the file will be sent.
|
108
|
+
*
|
109
|
+
* Returns the number of bytes sent on success. Will throw system error
|
110
|
+
* exception on error. (check man sendfile(2) on your platform for
|
111
|
+
* information on what errors could result and how to handle them)
|
112
|
+
*/
|
113
|
+
static VALUE rb_io_sendfile( int argc, VALUE *argv, VALUE self)
|
114
|
+
{
|
115
|
+
int i, o;
|
116
|
+
size_t c;
|
117
|
+
off_t off;
|
118
|
+
OpenFile *iptr, *optr;
|
119
|
+
VALUE in, offset, count;
|
120
|
+
struct timeval _sendfile_sleep;
|
121
|
+
|
122
|
+
/* get fds for files involved to pass to sendfile(2) */
|
123
|
+
rb_scan_args( argc, argv, "12", &in, &offset, &count);
|
124
|
+
if (TYPE( in) != T_FILE)
|
125
|
+
rb_raise( rb_eArgError, "invalid first argument\n");
|
126
|
+
GetOpenFile( self, optr);
|
127
|
+
GetOpenFile( in, iptr);
|
128
|
+
o = fileno( optr->f);
|
129
|
+
i = fileno( iptr->f);
|
130
|
+
|
131
|
+
_sendfile_sleep.tv_sec = SENDFILE_PAUSE_SEC;
|
132
|
+
_sendfile_sleep.tv_usec = SENDFILE_PAUSE_USEC;
|
133
|
+
|
134
|
+
/* determine offset and count parameters */
|
135
|
+
off = (NIL_P( offset)) ? 0 : NUM2ULONG( offset);
|
136
|
+
if (NIL_P( count)) {
|
137
|
+
/* FreeBSD's sendfile() can take 0 as an indication to send
|
138
|
+
* until end of file, but Linux and Solaris can't, and anyway
|
139
|
+
* we need the file size to ensure we send it all in the case
|
140
|
+
* of a non-blocking fd */
|
141
|
+
struct stat s;
|
142
|
+
if (fstat( i, &s) == -1)
|
143
|
+
rb_sys_fail( "sendfile");
|
144
|
+
c = s.st_size;
|
145
|
+
c -= off;
|
146
|
+
} else {
|
147
|
+
c = NUM2ULONG( count);
|
148
|
+
}
|
149
|
+
|
150
|
+
/* now send the file */
|
151
|
+
return INT2FIX( __sendfile( o, i, off, c, &_sendfile_sleep));
|
152
|
+
}
|
153
|
+
|
154
|
+
/* Interface to the UNIX sendfile(2) system call. Should work on FreeBSD,
|
155
|
+
* Linux and Solaris systems that support the sendfile(2) system call.
|
156
|
+
*/
|
157
|
+
void Init_sendfile( void)
|
158
|
+
{
|
159
|
+
rb_define_method( rb_cIO, "sendfile", rb_io_sendfile, -1);
|
160
|
+
}
|
161
|
+
|
data/sendfile.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# vim:set ts=4 sw=4 ai syntax=ruby:
|
2
|
+
|
3
|
+
spec = Gem::Specification.new do |gs|
|
4
|
+
gs.name = 'sendfile'
|
5
|
+
gs.version = '0.9.1'
|
6
|
+
gs.summary = 'Ruby interface to sendfile(2) system call'
|
7
|
+
gs.description = <<-EOF
|
8
|
+
Allows Ruby programs to access sendfile(2) functionality on
|
9
|
+
any IO object. Works on Linux, Solaris and FreeBSD with
|
10
|
+
blocking and non-blocking sockets.
|
11
|
+
EOF
|
12
|
+
gs.author = 'Toby DiPasquale'
|
13
|
+
gs.email = 'toby@cbcg.net'
|
14
|
+
gs.rubyforge_project = 'ruby-sendfile'
|
15
|
+
|
16
|
+
gs.autorequire = 'sendfile'
|
17
|
+
gs.files = File.read( 'FILES').split( $/)
|
18
|
+
gs.test_files = Dir.glob 'test/test_*.rb'
|
19
|
+
gs.extensions << 'ext/extconf.rb'
|
20
|
+
|
21
|
+
gs.has_rdoc = true
|
22
|
+
gs.extra_rdoc_files = %w( README )
|
23
|
+
gs.required_ruby_version = '>= 1.8.0'
|
24
|
+
end
|
25
|
+
|
data/test/large.gz
ADDED
Binary file
|
data/test/small
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
I love Pocky!
|
@@ -0,0 +1,174 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim:set ts=4 sw=4 ai:
|
3
|
+
require 'io/nonblock'
|
4
|
+
begin
|
5
|
+
require 'rubygems'
|
6
|
+
rescue
|
7
|
+
nil
|
8
|
+
end
|
9
|
+
require 'sendfile'
|
10
|
+
require 'socket'
|
11
|
+
require 'tempfile'
|
12
|
+
require 'test/unit'
|
13
|
+
require 'zlib'
|
14
|
+
|
15
|
+
class TestSendfile < Test::Unit::TestCase
|
16
|
+
def __fork_server
|
17
|
+
# open pipe for backchannel
|
18
|
+
@rd, @wr = IO.pipe
|
19
|
+
# fork server child
|
20
|
+
@pid = fork do
|
21
|
+
# close read end in child
|
22
|
+
@rd.close
|
23
|
+
|
24
|
+
# start listening and send port back to parent
|
25
|
+
ss = TCPServer.new @host, 0
|
26
|
+
@wr.write( [ ss.addr[1] ].pack( "S"))
|
27
|
+
@wr.flush
|
28
|
+
|
29
|
+
# read what they send and push it back up the pipe
|
30
|
+
while s = ss.accept
|
31
|
+
data = s.read
|
32
|
+
s.close
|
33
|
+
@wr.write( [data.length].pack( "N"))
|
34
|
+
@wr.write data
|
35
|
+
@wr.flush
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# close write end in parent and get server port
|
40
|
+
@wr.close
|
41
|
+
@port = @rd.read( 2).unpack( "S")[0]
|
42
|
+
end
|
43
|
+
|
44
|
+
def setup
|
45
|
+
@dir = File.dirname __FILE__
|
46
|
+
@host = '127.0.0.1'
|
47
|
+
__fork_server
|
48
|
+
|
49
|
+
@smallfile = "#{@dir}/small"
|
50
|
+
@small = File.open @smallfile
|
51
|
+
@small_data = File.read @smallfile
|
52
|
+
|
53
|
+
File.open( "#{@dir}/large.gz") do |f|
|
54
|
+
gzipped = Zlib::GzipReader.new f
|
55
|
+
@large_data = gzipped.read
|
56
|
+
end
|
57
|
+
@largefile = "/tmp/sendfiletest"
|
58
|
+
@large = File.open @largefile, 'w+'
|
59
|
+
@large.write @large_data
|
60
|
+
@large.flush
|
61
|
+
end
|
62
|
+
|
63
|
+
def teardown
|
64
|
+
@small.close
|
65
|
+
@large.close
|
66
|
+
File.unlink @largefile
|
67
|
+
|
68
|
+
Process.kill 'KILL', @pid
|
69
|
+
Process.wait
|
70
|
+
end
|
71
|
+
|
72
|
+
def __do_sendfile file, off=nil, count=nil
|
73
|
+
s = TCPSocket.new @host, @port
|
74
|
+
yield s if block_given?
|
75
|
+
sent = s.sendfile file, off, count
|
76
|
+
s.close
|
77
|
+
len = @rd.read( 4).unpack( "N")[0]
|
78
|
+
read = @rd.read len
|
79
|
+
[ sent, read ]
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_blocking_full_small
|
83
|
+
sent, read = __do_sendfile( @small)
|
84
|
+
assert_equal @small_data.size, sent
|
85
|
+
assert_equal @small_data.size, read.size
|
86
|
+
assert_equal @small_data, read
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_nonblocking_full_small
|
90
|
+
sent, read = __do_sendfile( @small) { |s| s.nonblock = true }
|
91
|
+
assert_equal @small_data.size, sent
|
92
|
+
assert_equal @small_data.size, read.size
|
93
|
+
assert_equal @small_data, read
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_blocking_full_large
|
97
|
+
sent, read = __do_sendfile( @large)
|
98
|
+
assert_equal @large_data.size, sent
|
99
|
+
assert_equal @large_data.size, read.size
|
100
|
+
assert_equal @large_data, read
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_nonblocking_full_large
|
104
|
+
sent, read = __do_sendfile( @large) { |s| s.nonblock = true }
|
105
|
+
assert_equal @large_data.size, sent
|
106
|
+
assert_equal @large_data.size, read.size
|
107
|
+
assert_equal @large_data, read
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_blocking_from_offset
|
111
|
+
data = @large_data[4096..-1]
|
112
|
+
sent, read = __do_sendfile( @large, 4096)
|
113
|
+
assert_equal data.size, sent
|
114
|
+
assert_equal data.size, read.size
|
115
|
+
assert_equal data, read
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_blocking_partial_from_beginning
|
119
|
+
data = @large_data[0, 1048576]
|
120
|
+
sent, read = __do_sendfile( @large, 0, 1048576)
|
121
|
+
assert_equal data.size, sent
|
122
|
+
assert_equal data.size, read.size
|
123
|
+
assert_equal data, read
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_blocking_partial_from_middle
|
127
|
+
data = @large_data[2048, 1048576]
|
128
|
+
sent, read = __do_sendfile( @large, 2048, 1048576)
|
129
|
+
assert_equal data.size, sent
|
130
|
+
assert_equal data.size, read.size
|
131
|
+
assert_equal data, read
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_blocking_partial_to_end
|
135
|
+
data = @large_data[-1048576, 1048576]
|
136
|
+
sent, read = __do_sendfile( @large, @large_data.size - 1048576, 1048576)
|
137
|
+
assert_equal data.size, sent
|
138
|
+
assert_equal data.size, read.size
|
139
|
+
assert_equal data, read
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_nonblocking_from_offset
|
143
|
+
data = @large_data[4096..-1]
|
144
|
+
sent, read = __do_sendfile( @large, 4096) { |s| s.nonblock = true }
|
145
|
+
assert_equal data.size, sent
|
146
|
+
assert_equal data.size, read.size
|
147
|
+
assert_equal data, read
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_nonblocking_partial_from_beginning
|
151
|
+
data = @large_data[0, 1048576]
|
152
|
+
sent, read = __do_sendfile( @large, 0, 1048576) { |s| s.nonblock = true }
|
153
|
+
assert_equal data.size, sent
|
154
|
+
assert_equal data.size, read.size
|
155
|
+
assert_equal data, read
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_nonblocking_partial_from_middle
|
159
|
+
data = @large_data[2048, 1048576]
|
160
|
+
sent, read = __do_sendfile( @large, 2048, 1048576) { |s| s.nonblock = true }
|
161
|
+
assert_equal data.size, sent
|
162
|
+
assert_equal data.size, read.size
|
163
|
+
assert_equal data, read
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_nonblocking_partial_to_end
|
167
|
+
data = @large_data[-1048576, 1048576]
|
168
|
+
sent, read = __do_sendfile( @large, @large_data.size - 1048576, 1048576) { |s| s.nonblock = true }
|
169
|
+
assert_equal data.size, sent
|
170
|
+
assert_equal data.size, read.size
|
171
|
+
assert_equal data, read
|
172
|
+
end
|
173
|
+
end # class TestSendfile
|
174
|
+
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: sendfile
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.9.1
|
7
|
+
date: 2006-03-26 00:00:00 -05:00
|
8
|
+
summary: Ruby interface to sendfile(2) system call
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: toby@cbcg.net
|
12
|
+
homepage:
|
13
|
+
rubyforge_project: ruby-sendfile
|
14
|
+
description: Allows Ruby programs to access sendfile(2) functionality on any IO object. Works on Linux, Solaris and FreeBSD with blocking and non-blocking sockets.
|
15
|
+
autorequire: sendfile
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- Toby DiPasquale
|
30
|
+
files:
|
31
|
+
- FILES
|
32
|
+
- README
|
33
|
+
- LICENSE
|
34
|
+
- ChangeLog
|
35
|
+
- ext/extconf.rb
|
36
|
+
- ext/sendfile.c
|
37
|
+
- test/test_sendfile.rb
|
38
|
+
- test/large.gz
|
39
|
+
- test/small
|
40
|
+
- sendfile.gemspec
|
41
|
+
test_files:
|
42
|
+
- test/test_sendfile.rb
|
43
|
+
rdoc_options: []
|
44
|
+
|
45
|
+
extra_rdoc_files:
|
46
|
+
- README
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions:
|
50
|
+
- ext/extconf.rb
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
dependencies: []
|
54
|
+
|