sendfile 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|