io-extra 1.3.0 → 1.4.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGES +13 -0
- data/MANIFEST +2 -1
- data/README +6 -6
- data/ext/extconf.rb +0 -2
- data/ext/io/extra.c +4 -128
- data/lib/io-extra.rb +16 -0
- data/test/test_io_extra.rb +7 -22
- metadata +11 -12
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 413914a045cda689f991f043d5b314d6734777094d0f90359e5c10c1062d7648
|
4
|
+
data.tar.gz: beeb120887bf9e7c3af06f0f2a9cc733cce21f21ddf9738ef2830bab0be1931f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ad2db30be150d3837b182e6063f2db69faf0895fde33b5ba552029c1ba988093efdfd96421a155129543ae43b545eca656b2e9243bc6c0c13fd3a4dec37a842
|
7
|
+
data.tar.gz: 3611120e98da21cd73fd3960a6a1df6a05514a5436fbf29de3e9d0f27971ad5c94e2309fcc3399581439dc95735c78bb75303ca772cca8dcd0225631a266a1b3
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGES
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
== 1.4.0 - 8-Jul-2020
|
2
|
+
* Replaced the C versions of IO.pread and IO.pwrite singleton methods with
|
3
|
+
pure Ruby wrappers since core Ruby has implemented instance method versions
|
4
|
+
since Ruby 2.5. These now require filehandles (rather than fileno) as an
|
5
|
+
argument.
|
6
|
+
* Removed the pread_ptr method, I don't think anyone was using it. Might get
|
7
|
+
added back if there are complaints.
|
8
|
+
* Removed the DIRECT constant since that is now defined by core Ruby.
|
9
|
+
* Moved the VERSION constant into the pure Ruby file.
|
10
|
+
* Now requires Ruby 2.5 or later.
|
11
|
+
* Added a LICENSE file as required by the Apache-2.0 license.
|
12
|
+
* The 'io-extra' file is now the preferred way to require this library.
|
13
|
+
|
1
14
|
== 1.3.0 - 19-Oct-2018
|
2
15
|
* Now assumes Ruby 2.1 or later. This has no effect on the external API, but
|
3
16
|
it does allow for lots of internal cleanup.
|
data/MANIFEST
CHANGED
data/README
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
gem install io-extra
|
12
12
|
|
13
13
|
= Synopsis
|
14
|
-
require 'io
|
14
|
+
require 'io-extra' # Do not use 'io/extra'
|
15
15
|
|
16
16
|
# Close all file descriptors from 3 up.
|
17
17
|
IO.closefrom(3)
|
@@ -27,6 +27,10 @@
|
|
27
27
|
IO.writev(fh.fileno, %w[a b c])
|
28
28
|
|
29
29
|
= Developer's Notes
|
30
|
+
The "require 'io-extra'" is preferred over 'io/extra' because this is a mix
|
31
|
+
of pure Ruby and C extension. The former require's the latter, so that way
|
32
|
+
you get all the methods and constants that you expect.
|
33
|
+
|
30
34
|
You might be wondering what the difference is between my implementation of
|
31
35
|
IO.closefrom and a pure Ruby version that looks something like this:
|
32
36
|
|
@@ -73,10 +77,6 @@
|
|
73
77
|
Please file any bug reports on the project page at
|
74
78
|
https://github.com/djberg96/io-extra
|
75
79
|
|
76
|
-
= Future Plans
|
77
|
-
* Switch from C extension to FFI (maybe).
|
78
|
-
* Add the IO.pselect method.
|
79
|
-
|
80
80
|
= Acknowledgements
|
81
81
|
Eric Wong for some great work on Linux compatibility and other fixes, as
|
82
82
|
well as the code for the IO.writev method.
|
@@ -85,7 +85,7 @@
|
|
85
85
|
Apache-2.0
|
86
86
|
|
87
87
|
= Copyright
|
88
|
-
(C) 2003-
|
88
|
+
(C) 2003-2020 Daniel J. Berger
|
89
89
|
All Rights Reserved
|
90
90
|
|
91
91
|
= Warranty
|
data/ext/extconf.rb
CHANGED
data/ext/io/extra.c
CHANGED
@@ -284,117 +284,6 @@ static VALUE io_set_directio(VALUE self, VALUE v_advice){
|
|
284
284
|
}
|
285
285
|
#endif
|
286
286
|
|
287
|
-
#ifdef HAVE_PREAD
|
288
|
-
struct pread_args {
|
289
|
-
int fd;
|
290
|
-
void *buf;
|
291
|
-
size_t nbyte;
|
292
|
-
off_t offset;
|
293
|
-
};
|
294
|
-
|
295
|
-
static VALUE nogvl_pread(void *ptr)
|
296
|
-
{
|
297
|
-
struct pread_args *args = ptr;
|
298
|
-
return (VALUE)pread(args->fd, args->buf, args->nbyte, args->offset);
|
299
|
-
}
|
300
|
-
|
301
|
-
/*
|
302
|
-
* IO.pread(fd, length, offset)
|
303
|
-
*
|
304
|
-
* This is similar to the IO.read method, except that it reads from a given
|
305
|
-
* position in the file without changing the file pointer. And unlike IO.read,
|
306
|
-
* the +fd+, +length+ and +offset+ arguments are all mandatory.
|
307
|
-
*/
|
308
|
-
static VALUE s_io_pread(VALUE klass, VALUE fd, VALUE nbyte, VALUE offset){
|
309
|
-
struct pread_args args;
|
310
|
-
VALUE str;
|
311
|
-
ssize_t nread;
|
312
|
-
|
313
|
-
args.fd = NUM2INT(fd);
|
314
|
-
args.nbyte = NUM2ULONG(nbyte);
|
315
|
-
args.offset = NUM2OFFT(offset);
|
316
|
-
str = rb_str_new(NULL, args.nbyte);
|
317
|
-
args.buf = RSTRING_PTR(str);
|
318
|
-
|
319
|
-
nread = (ssize_t)rb_thread_call_without_gvl((void*)nogvl_pread, &args, RUBY_UBF_IO, 0);
|
320
|
-
|
321
|
-
if(nread == -1)
|
322
|
-
rb_sys_fail("pread");
|
323
|
-
|
324
|
-
if((size_t)nread != args.nbyte)
|
325
|
-
rb_str_set_len(str, nread);
|
326
|
-
|
327
|
-
return str;
|
328
|
-
}
|
329
|
-
|
330
|
-
/*
|
331
|
-
* IO.pread_ptr(fd, length, offset)
|
332
|
-
*
|
333
|
-
* This is identical to IO.pread, except that it returns the pointer address
|
334
|
-
* of the string, instead of the actual buffer.
|
335
|
-
*--
|
336
|
-
* This was added because, in some cases, the IO.pread buffer might return
|
337
|
-
* an empty string. In such situations we are unable to get the actual pointer
|
338
|
-
* address with pure Ruby.
|
339
|
-
*/
|
340
|
-
static VALUE s_io_pread_ptr(VALUE klass, VALUE v_fd, VALUE v_nbyte, VALUE v_offset){
|
341
|
-
int fd = NUM2INT(v_fd);
|
342
|
-
size_t nbyte = NUM2ULONG(v_nbyte);
|
343
|
-
off_t offset = NUM2OFFT(v_offset);
|
344
|
-
uintptr_t* vector = malloc(nbyte + 1);
|
345
|
-
|
346
|
-
if(pread(fd, vector, nbyte, offset) == -1){
|
347
|
-
free(vector);
|
348
|
-
rb_sys_fail("pread");
|
349
|
-
}
|
350
|
-
|
351
|
-
return ULL2NUM(vector[0]);
|
352
|
-
}
|
353
|
-
#endif
|
354
|
-
|
355
|
-
#ifdef HAVE_PWRITE
|
356
|
-
struct pwrite_args {
|
357
|
-
int fd;
|
358
|
-
const void *buf;
|
359
|
-
size_t nbyte;
|
360
|
-
off_t offset;
|
361
|
-
};
|
362
|
-
|
363
|
-
static VALUE nogvl_pwrite(void *ptr)
|
364
|
-
{
|
365
|
-
struct pwrite_args *args = ptr;
|
366
|
-
return (VALUE)pwrite(args->fd, args->buf, args->nbyte, args->offset);
|
367
|
-
}
|
368
|
-
|
369
|
-
/*
|
370
|
-
* IO.pwrite(fd, buf, offset)
|
371
|
-
*
|
372
|
-
* This method writes the +buf+, starting at +offset+, to the given +fd+,
|
373
|
-
* which must be opened with write permissions.
|
374
|
-
*
|
375
|
-
* This is similar to a seek & write in standard Ruby but the difference,
|
376
|
-
* beyond being a singleton method, is that the file pointer is never moved.
|
377
|
-
*
|
378
|
-
* Returns the number of bytes written.
|
379
|
-
*/
|
380
|
-
static VALUE s_io_pwrite(VALUE klass, VALUE fd, VALUE buf, VALUE offset){
|
381
|
-
ssize_t result;
|
382
|
-
struct pwrite_args args;
|
383
|
-
|
384
|
-
args.fd = NUM2INT(fd);
|
385
|
-
args.buf = RSTRING_PTR(buf);
|
386
|
-
args.nbyte = RSTRING_LEN(buf);
|
387
|
-
args.offset = NUM2OFFT(offset);
|
388
|
-
|
389
|
-
result = (ssize_t)rb_thread_call_without_gvl((void*)nogvl_pwrite, &args, RUBY_UBF_IO, 0);
|
390
|
-
|
391
|
-
if(result == -1)
|
392
|
-
rb_sys_fail("pwrite");
|
393
|
-
|
394
|
-
return ULL2NUM(result);
|
395
|
-
}
|
396
|
-
#endif
|
397
|
-
|
398
287
|
/* this can't be a function since we use alloca() */
|
399
288
|
#define ARY2IOVEC(iov,iovcnt,expect,ary) \
|
400
289
|
do { \
|
@@ -448,6 +337,10 @@ static VALUE s_io_writev(VALUE klass, VALUE fd, VALUE ary) {
|
|
448
337
|
ssize_t left;
|
449
338
|
struct writev_args args;
|
450
339
|
|
340
|
+
// Allow a fileno or filehandle
|
341
|
+
if(rb_respond_to(fd, rb_intern("fileno")))
|
342
|
+
fd = rb_funcall(fd, rb_intern("fileno"), 0, 0);
|
343
|
+
|
451
344
|
args.fd = NUM2INT(fd);
|
452
345
|
ARY2IOVEC(args.iov, args.iovcnt, left, ary);
|
453
346
|
|
@@ -553,22 +446,8 @@ void Init_extra(){
|
|
553
446
|
rb_define_const(rb_cIO, "DIRECTIO_ON", UINT2NUM(DIRECTIO_ON));
|
554
447
|
#endif
|
555
448
|
|
556
|
-
#ifdef O_DIRECT
|
557
|
-
/* 040000: direct disk access (in Linux) */
|
558
|
-
rb_define_const(rb_cIO, "DIRECT", UINT2NUM(O_DIRECT));
|
559
|
-
#endif
|
560
|
-
|
561
449
|
rb_define_const(rb_cIO, "IOV_MAX", LONG2NUM(IOV_MAX));
|
562
450
|
|
563
|
-
#ifdef HAVE_PREAD
|
564
|
-
rb_define_singleton_method(rb_cIO, "pread", s_io_pread, 3);
|
565
|
-
rb_define_singleton_method(rb_cIO, "pread_ptr", s_io_pread_ptr, 3);
|
566
|
-
#endif
|
567
|
-
|
568
|
-
#ifdef HAVE_PWRITE
|
569
|
-
rb_define_singleton_method(rb_cIO, "pwrite", s_io_pwrite, 3);
|
570
|
-
#endif
|
571
|
-
|
572
451
|
#ifdef HAVE_WRITEV
|
573
452
|
rb_define_singleton_method(rb_cIO, "writev", s_io_writev, 2);
|
574
453
|
#endif
|
@@ -576,7 +455,4 @@ void Init_extra(){
|
|
576
455
|
#ifdef HAVE_TTYNAME
|
577
456
|
rb_define_method(rb_cIO, "ttyname", io_get_ttyname, 0);
|
578
457
|
#endif
|
579
|
-
|
580
|
-
/* 1.3.0: The version of this library. */
|
581
|
-
rb_define_const(rb_cIO, "EXTRA_VERSION", rb_str_freeze(rb_str_new2("1.3.0")));
|
582
458
|
}
|
data/lib/io-extra.rb
CHANGED
@@ -1 +1,17 @@
|
|
1
1
|
require 'io/extra'
|
2
|
+
|
3
|
+
class IO
|
4
|
+
EXTRA_VERSION = '1.4.0'.freeze
|
5
|
+
|
6
|
+
# Singleton version of the IO#pwrite method.
|
7
|
+
#
|
8
|
+
def self.pwrite(fd, string, offset)
|
9
|
+
fd.pwrite(string, offset)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Singleton version of the IO#pread method.
|
13
|
+
#
|
14
|
+
def self.pread(fd, maxlen, offset)
|
15
|
+
fd.pread(maxlen, offset)
|
16
|
+
end
|
17
|
+
end
|
data/test/test_io_extra.rb
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
require 'test-unit'
|
8
8
|
require 'rbconfig'
|
9
9
|
require 'io/nonblock'
|
10
|
-
require 'io
|
10
|
+
require 'io-extra'
|
11
11
|
|
12
12
|
class TC_IO_Extra < Test::Unit::TestCase
|
13
13
|
def setup
|
@@ -17,16 +17,10 @@ class TC_IO_Extra < Test::Unit::TestCase
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_version
|
20
|
-
assert_equal('1.
|
20
|
+
assert_equal('1.4.0', IO::EXTRA_VERSION)
|
21
21
|
assert_true(IO::EXTRA_VERSION.frozen?)
|
22
22
|
end
|
23
23
|
|
24
|
-
def test_direct_constant
|
25
|
-
omit_unless(RbConfig::CONFIG['host_os'] =~ /linux/i, 'Linux-only')
|
26
|
-
assert_equal(040000, IO::DIRECT)
|
27
|
-
assert_equal(040000, File::DIRECT)
|
28
|
-
end
|
29
|
-
|
30
24
|
def test_open_direct
|
31
25
|
omit_unless(RbConfig::CONFIG['host_os'] =~ /linux/i, 'Linux-only')
|
32
26
|
assert_nothing_raised do
|
@@ -75,7 +69,7 @@ class TC_IO_Extra < Test::Unit::TestCase
|
|
75
69
|
@fh.close rescue nil
|
76
70
|
@fh = File.open(@file)
|
77
71
|
assert_respond_to(IO, :pread)
|
78
|
-
assert_equal("quick", IO.pread(@fh
|
72
|
+
assert_equal("quick", IO.pread(@fh, 5, 4))
|
79
73
|
end
|
80
74
|
|
81
75
|
def test_pread_binary
|
@@ -86,34 +80,26 @@ class TC_IO_Extra < Test::Unit::TestCase
|
|
86
80
|
assert_nothing_raised { @fh.syswrite("FOO\0HELLO") }
|
87
81
|
@fh.close rescue nil
|
88
82
|
@fh = File.open(@file)
|
89
|
-
assert_equal("O\0H", IO.pread(@fh
|
90
|
-
end
|
91
|
-
|
92
|
-
def test_pread_ptr
|
93
|
-
@fh.close rescue nil
|
94
|
-
@fh = File.open(@file)
|
95
|
-
assert_respond_to(IO, :pread_ptr)
|
96
|
-
assert_kind_of(Integer, IO.pread_ptr(@fh.fileno, 5, 4))
|
83
|
+
assert_equal("O\0H", IO.pread(@fh, 3, size + 2))
|
97
84
|
end
|
98
85
|
|
99
86
|
def test_pread_last
|
100
87
|
@fh.close rescue nil
|
101
88
|
@fh = File.open(@file)
|
102
89
|
size = @fh.stat.size
|
103
|
-
assert_equal("ck\n", IO.pread(@fh
|
90
|
+
assert_equal("ck\n", IO.pread(@fh, 5, size - 3))
|
104
91
|
end
|
105
92
|
|
106
93
|
def test_pwrite
|
107
94
|
assert_respond_to(IO, :pwrite)
|
108
|
-
assert_nothing_raised{ IO.pwrite(@fh
|
95
|
+
assert_nothing_raised{ IO.pwrite(@fh, "HAL", 0) }
|
109
96
|
end
|
110
97
|
|
111
98
|
def test_writev
|
112
99
|
assert_respond_to(IO, :writev)
|
113
|
-
assert_equal(10, IO.writev(@fh
|
100
|
+
assert_equal(10, IO.writev(@fh, %w[hello world]))
|
114
101
|
end
|
115
102
|
|
116
|
-
=begin
|
117
103
|
def test_writev_retry
|
118
104
|
empty = ""
|
119
105
|
if empty.respond_to?(:force_encoding)
|
@@ -147,7 +133,6 @@ class TC_IO_Extra < Test::Unit::TestCase
|
|
147
133
|
end
|
148
134
|
end
|
149
135
|
end
|
150
|
-
=end
|
151
136
|
|
152
137
|
def test_ttyname
|
153
138
|
assert_respond_to(@fh, :ttyname)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-extra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
@@ -35,26 +35,26 @@ cert_chain:
|
|
35
35
|
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
36
36
|
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date:
|
38
|
+
date:
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: test-unit
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- - "
|
44
|
+
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
46
|
+
version: '3.0'
|
47
47
|
type: :development
|
48
48
|
prerelease: false
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- - "
|
51
|
+
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: '3.0'
|
54
54
|
description: |2
|
55
|
-
Adds the IO.closefrom, IO.fdwalk, IO.pread, IO.
|
56
|
-
|
57
|
-
|
55
|
+
Adds the IO.closefrom, IO.fdwalk, IO.pread, IO.pwrite, and IO.writev
|
56
|
+
singleton methods as well as the IO#directio, IO#directio? and IO#ttyname
|
57
|
+
instance methods (for those platforms that support them).
|
58
58
|
email: djberg96@gmail.com
|
59
59
|
executables: []
|
60
60
|
extensions:
|
@@ -84,15 +84,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
84
|
requirements:
|
85
85
|
- - ">="
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
version: 2.
|
87
|
+
version: 2.5.0
|
88
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
89
|
requirements:
|
90
90
|
- - ">="
|
91
91
|
- !ruby/object:Gem::Version
|
92
92
|
version: '0'
|
93
93
|
requirements: []
|
94
|
-
|
95
|
-
rubygems_version: 2.7.6
|
94
|
+
rubygems_version: 3.0.6
|
96
95
|
signing_key:
|
97
96
|
specification_version: 4
|
98
97
|
summary: Adds extra methods to the IO class
|
metadata.gz.sig
CHANGED
Binary file
|