activeldap 4.0.6 → 5.1.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
- data/doc/text/news.textile +30 -0
- data/lib/active_ldap.rb +0 -6
- data/lib/active_ldap/adapter/base.rb +9 -7
- data/lib/active_ldap/associations.rb +5 -5
- data/lib/active_ldap/base.rb +29 -5
- data/lib/active_ldap/callbacks.rb +7 -8
- data/lib/active_ldap/connection.rb +1 -19
- data/lib/active_ldap/version.rb +1 -1
- data/po/en/active-ldap.po +2 -2
- data/po/ja/active-ldap.po +3 -3
- data/test/command.rb +13 -16
- data/test/test_base.rb +37 -0
- data/test/test_callback.rb +10 -8
- metadata +17 -6
- data/lib/active_ldap/timeout.rb +0 -75
- data/lib/active_ldap/timeout_stub.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c8e12943a7cec9dc82ccb3d0691ef449ac50218
|
4
|
+
data.tar.gz: 7a5902d6f963ff74d9bb54c8f7f52a0e063c1929
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f0106de394d61a8ca1524676c88d00cfbf8cf8839fa6004509685e1c30b0f37ddf3efee78d8a53eb23e7c905daa3fc0322cf4f5c2d9cff65bb9c4b4b4a6c42f
|
7
|
+
data.tar.gz: 71532cb3525dc88eb99f9dfe19203f2fd294e7e6575b589fe61649bd0fbd13f8d7b78ced72f8d6803b549b1f20a591c3b886b17951b15a8b9a97e31c8e9d906e
|
data/doc/text/news.textile
CHANGED
@@ -1,5 +1,35 @@
|
|
1
1
|
h1. News
|
2
2
|
|
3
|
+
h2(#release-5-1-0). 5.1.0: 2017-05-01
|
4
|
+
|
5
|
+
h3. Improvements
|
6
|
+
|
7
|
+
* Supported Rails 5.1.0.
|
8
|
+
|
9
|
+
* Supported sub class instantiate by objectClass.
|
10
|
+
[GitHub#134][Patch by Chris Garrigues]
|
11
|
+
|
12
|
+
* Improved error messages.
|
13
|
+
|
14
|
+
* Changed to the default LDAP client to net-ldap from ruby-ldap
|
15
|
+
because ruby-ldap doesn't support timeout.
|
16
|
+
|
17
|
+
* Suppressed warnings.
|
18
|
+
[GitHub#146][Reported by jas01]
|
19
|
+
|
20
|
+
h3. Fixes
|
21
|
+
|
22
|
+
* Added missing dependency.
|
23
|
+
[GitHub#145][Reported by Tom Wardrop]
|
24
|
+
|
25
|
+
h3. Thanks
|
26
|
+
|
27
|
+
* Chris Garrigues
|
28
|
+
|
29
|
+
* Tom Wardrop
|
30
|
+
|
31
|
+
* jas01
|
32
|
+
|
3
33
|
h2(#release-4-0-6). 4.0.6: 2016-04-07
|
4
34
|
|
5
35
|
h3. Improvements
|
data/lib/active_ldap.rb
CHANGED
@@ -8,12 +8,6 @@ module ActiveLdap
|
|
8
8
|
autoload :Command, "active_ldap/command"
|
9
9
|
end
|
10
10
|
|
11
|
-
if RUBY_PLATFORM.match('linux')
|
12
|
-
require 'active_ldap/timeout'
|
13
|
-
else
|
14
|
-
require 'active_ldap/timeout_stub'
|
15
|
-
end
|
16
|
-
|
17
11
|
require 'active_ldap/get_text'
|
18
12
|
|
19
13
|
require 'active_ldap/compatible'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
1
3
|
require 'active_ldap/schema'
|
2
4
|
require 'active_ldap/entry_attribute'
|
3
5
|
require 'active_ldap/ldap_error'
|
@@ -328,7 +330,7 @@ module ActiveLdap
|
|
328
330
|
n_retries = 0
|
329
331
|
retry_limit = options[:retry_limit] || @retry_limit
|
330
332
|
begin
|
331
|
-
|
333
|
+
Timeout.timeout(@timeout, &block)
|
332
334
|
rescue Timeout::Error => e
|
333
335
|
@logger.error {_('Requested action timed out.')}
|
334
336
|
if @retry_on_timeout and (retry_limit < 0 or n_retries <= retry_limit)
|
@@ -344,10 +346,6 @@ module ActiveLdap
|
|
344
346
|
end
|
345
347
|
end
|
346
348
|
|
347
|
-
def do_in_timeout(timeout, &block)
|
348
|
-
Timeout.alarm(timeout, &block)
|
349
|
-
end
|
350
|
-
|
351
349
|
def sasl_bind(bind_dn, options={})
|
352
350
|
# Get all SASL mechanisms
|
353
351
|
mechanisms = operation(options) do
|
@@ -601,9 +599,13 @@ module ActiveLdap
|
|
601
599
|
raise
|
602
600
|
rescue => detail
|
603
601
|
@logger.error do
|
604
|
-
_("Reconnect to server failed: %s\n" \
|
602
|
+
_("Reconnect to server failed: %s: %s\n" \
|
605
603
|
"Reconnect to server failed backtrace:\n" \
|
606
|
-
"%s") % [
|
604
|
+
"%s") % [
|
605
|
+
detail.class,
|
606
|
+
detail.message,
|
607
|
+
detail.backtrace.join("\n"),
|
608
|
+
]
|
607
609
|
end
|
608
610
|
# Do not loop if forced
|
609
611
|
raise ConnectionError, detail.message if force
|
@@ -75,15 +75,15 @@ module ActiveLdap
|
|
75
75
|
association_class = Association::BelongsTo
|
76
76
|
opts[:foreign_key_name] ||= "#{association_id}_id"
|
77
77
|
|
78
|
-
before_save
|
79
|
-
if
|
80
|
-
association = @#{association_id}
|
78
|
+
before_save do
|
79
|
+
if instance_variable_defined?(:"@#{association_id}")
|
80
|
+
association = instance_variable_get(:"@#{association_id}")
|
81
81
|
if association and association.updated?
|
82
82
|
self[association.__send__(:primary_key)] =
|
83
|
-
association[
|
83
|
+
association[opts[:foreign_key_name]]
|
84
84
|
end
|
85
85
|
end
|
86
|
-
|
86
|
+
end
|
87
87
|
end
|
88
88
|
|
89
89
|
association_accessor(association_id) do |target|
|
data/lib/active_ldap/base.rb
CHANGED
@@ -32,6 +32,7 @@
|
|
32
32
|
require 'English'
|
33
33
|
require 'thread'
|
34
34
|
require 'erb'
|
35
|
+
require 'set'
|
35
36
|
|
36
37
|
module ActiveLdap
|
37
38
|
# OO-interface to LDAP assuming pam/nss_ldap-style organization with
|
@@ -330,6 +331,7 @@ module ActiveLdap
|
|
330
331
|
class_local_attr_accessor true, :dn_attribute, :scope, :sort_by, :order
|
331
332
|
class_local_attr_accessor true, :required_classes, :recommended_classes
|
332
333
|
class_local_attr_accessor true, :excluded_classes
|
334
|
+
class_local_attr_accessor false, :sub_classes
|
333
335
|
|
334
336
|
class << self
|
335
337
|
# Hide new in Base
|
@@ -340,6 +342,7 @@ module ActiveLdap
|
|
340
342
|
sub_class.module_eval do
|
341
343
|
include GetTextSupport
|
342
344
|
end
|
345
|
+
(self.sub_classes ||= []) << sub_class
|
343
346
|
end
|
344
347
|
|
345
348
|
# Set LDAP connection configuration up. It doesn't connect
|
@@ -548,6 +551,20 @@ module ActiveLdap
|
|
548
551
|
defaults.first || name || to_s
|
549
552
|
end
|
550
553
|
|
554
|
+
protected
|
555
|
+
def find_real_class(object_classes)
|
556
|
+
(sub_classes || []).each do |sub_class|
|
557
|
+
real_class = sub_class.find_real_class(object_classes)
|
558
|
+
return real_class if real_class
|
559
|
+
end
|
560
|
+
|
561
|
+
if object_classes.superset?(Set.new(classes))
|
562
|
+
self
|
563
|
+
else
|
564
|
+
nil
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
551
568
|
private
|
552
569
|
def inspect_attributes(attributes)
|
553
570
|
inspected_attribute_names = {}
|
@@ -594,12 +611,19 @@ module ActiveLdap
|
|
594
611
|
def instantiate(args)
|
595
612
|
dn, attributes, options = args
|
596
613
|
options ||= {}
|
597
|
-
|
598
|
-
|
599
|
-
|
614
|
+
|
615
|
+
object_classes_raw =
|
616
|
+
attributes["objectClass"] ||
|
617
|
+
attributes["objectclass"] ||
|
618
|
+
[]
|
619
|
+
if sub_classes.nil? or object_classes_raw.empty?
|
620
|
+
real_klass = self
|
600
621
|
else
|
601
|
-
|
602
|
-
|
622
|
+
object_classes = Set.new
|
623
|
+
object_classes_raw.each do |object_class_raw|
|
624
|
+
object_classes << schema.object_class(object_class_raw)
|
625
|
+
end
|
626
|
+
real_klass = find_real_class(object_classes) || self
|
603
627
|
end
|
604
628
|
|
605
629
|
obj = real_klass.allocate
|
@@ -14,13 +14,12 @@ module ActiveLdap
|
|
14
14
|
included do
|
15
15
|
extend ActiveModel::Callbacks
|
16
16
|
include ActiveModel::Validations::Callbacks
|
17
|
-
|
17
|
+
singleton_class.class_eval do
|
18
|
+
prepend CallbackedInstantiatable
|
19
|
+
end
|
20
|
+
|
18
21
|
define_model_callbacks :initialize, :find, :touch, :only => :after
|
19
22
|
define_model_callbacks :save, :create, :update, :destroy
|
20
|
-
|
21
|
-
class << self
|
22
|
-
alias_method_chain :instantiate, :callbacks
|
23
|
-
end
|
24
23
|
end
|
25
24
|
|
26
25
|
module ClassMethods
|
@@ -33,9 +32,9 @@ module ActiveLdap
|
|
33
32
|
end
|
34
33
|
end
|
35
34
|
|
36
|
-
module
|
37
|
-
def
|
38
|
-
object =
|
35
|
+
module CallbackedInstantiatable
|
36
|
+
def instantiate(record)
|
37
|
+
object = super(record)
|
39
38
|
object.run_callbacks(:find)
|
40
39
|
object.run_callbacks(:initialize)
|
41
40
|
object
|
@@ -197,27 +197,9 @@ module ActiveLdap
|
|
197
197
|
if Object.respond_to?(:java)
|
198
198
|
"jndi"
|
199
199
|
else
|
200
|
-
|
201
|
-
$LOAD_PATH.each do |path|
|
202
|
-
if File.exist?(File.join(path, "ldap", "ldif.rb"))
|
203
|
-
ruby_ldap_available = true
|
204
|
-
break
|
205
|
-
end
|
206
|
-
end
|
207
|
-
if !ruby_ldap_available and Object.const_defined?(:Gem)
|
208
|
-
ruby_ldap_available = gem_available?("ruby-ldap")
|
209
|
-
end
|
210
|
-
if ruby_ldap_available
|
211
|
-
"ldap"
|
212
|
-
else
|
213
|
-
"net-ldap"
|
214
|
-
end
|
200
|
+
"net-ldap"
|
215
201
|
end
|
216
202
|
end
|
217
|
-
|
218
|
-
def gem_available?(name)
|
219
|
-
not Gem::Specification.find_all_by_name(name).empty?
|
220
|
-
end
|
221
203
|
end
|
222
204
|
|
223
205
|
def setup_connection(config=nil)
|
data/lib/active_ldap/version.rb
CHANGED
data/po/en/active-ldap.po
CHANGED
@@ -7,7 +7,7 @@ msgid ""
|
|
7
7
|
msgstr ""
|
8
8
|
"Project-Id-Version: Ruby/ActiveLdap 1.1.1\n"
|
9
9
|
"POT-Creation-Date: 2009-08-04 23:26+0900\n"
|
10
|
-
"PO-Revision-Date:
|
10
|
+
"PO-Revision-Date: 2016-05-13 21:52+0900\n"
|
11
11
|
"Last-Translator: Kouhei Sutou <kou@cozmixng.org>\n"
|
12
12
|
"Language-Team: English\n"
|
13
13
|
"MIME-Version: 1.0\n"
|
@@ -3524,7 +3524,7 @@ msgstr ""
|
|
3524
3524
|
|
3525
3525
|
#: lib/active_ldap/adapter/base.rb:579
|
3526
3526
|
msgid ""
|
3527
|
-
"Reconnect to server failed: %s\n"
|
3527
|
+
"Reconnect to server failed: %s: %s\n"
|
3528
3528
|
"Reconnect to server failed backtrace:\n"
|
3529
3529
|
"%s"
|
3530
3530
|
msgstr ""
|
data/po/ja/active-ldap.po
CHANGED
@@ -7,7 +7,7 @@ msgid ""
|
|
7
7
|
msgstr ""
|
8
8
|
"Project-Id-Version: Ruby/ActiveLdap 1.1.1\n"
|
9
9
|
"POT-Creation-Date: 2009-08-04 23:26+0900\n"
|
10
|
-
"PO-Revision-Date:
|
10
|
+
"PO-Revision-Date: 2016-05-13 21:53+0900\n"
|
11
11
|
"Last-Translator: Kouhei Sutou <kou@cozmixng.org>\n"
|
12
12
|
"Language-Team: Japanese\n"
|
13
13
|
"MIME-Version: 1.0\n"
|
@@ -3533,11 +3533,11 @@ msgstr "再接続を試みています"
|
|
3533
3533
|
|
3534
3534
|
#: lib/active_ldap/adapter/base.rb:579
|
3535
3535
|
msgid ""
|
3536
|
-
"Reconnect to server failed: %s\n"
|
3536
|
+
"Reconnect to server failed: %s: %s\n"
|
3537
3537
|
"Reconnect to server failed backtrace:\n"
|
3538
3538
|
"%s"
|
3539
3539
|
msgstr ""
|
3540
|
-
"サーバへの再接続が失敗しました: %s\n"
|
3540
|
+
"サーバへの再接続が失敗しました: %s: %s\n"
|
3541
3541
|
"サーバへの再接続失敗時のバックトレース:\n"
|
3542
3542
|
"%s"
|
3543
3543
|
|
data/test/command.rb
CHANGED
@@ -36,24 +36,21 @@ module Command
|
|
36
36
|
return java_run(cmd, *args, &block) if Object.respond_to?(:java)
|
37
37
|
in_r, in_w = IO.pipe
|
38
38
|
out_r, out_w = IO.pipe
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
$VERBOSE = nil
|
44
|
-
pid = fork do
|
45
|
-
$VERBOSE = verbose
|
46
|
-
detach_io
|
47
|
-
STDIN.reopen(in_r)
|
48
|
-
in_r.close
|
49
|
-
STDOUT.reopen(out_w)
|
50
|
-
STDERR.reopen(out_w)
|
51
|
-
out_w.close
|
52
|
-
exec(cmd, *args)
|
53
|
-
exit!(-1)
|
54
|
-
end
|
39
|
+
verbose = $VERBOSE
|
40
|
+
# ruby(>=1.8)'s fork terminates other threads with warning messages
|
41
|
+
$VERBOSE = nil
|
42
|
+
pid = fork do
|
55
43
|
$VERBOSE = verbose
|
44
|
+
detach_io
|
45
|
+
STDIN.reopen(in_r)
|
46
|
+
in_r.close
|
47
|
+
STDOUT.reopen(out_w)
|
48
|
+
STDERR.reopen(out_w)
|
49
|
+
out_w.close
|
50
|
+
exec(cmd, *args)
|
51
|
+
exit!(-1)
|
56
52
|
end
|
53
|
+
$VERBOSE = verbose
|
57
54
|
yield(out_r, in_w) if block_given?
|
58
55
|
in_r.close unless in_r.closed?
|
59
56
|
out_w.close unless out_w.closed?
|
data/test/test_base.rb
CHANGED
@@ -663,6 +663,43 @@ class TestBase < Test::Unit::TestCase
|
|
663
663
|
end
|
664
664
|
end
|
665
665
|
|
666
|
+
class TestInstantiate < self
|
667
|
+
class Person < ActiveLdap::Base
|
668
|
+
ldap_mapping dn_attribute: "cn",
|
669
|
+
prefix: "ou=People",
|
670
|
+
scope: :one,
|
671
|
+
classes: ["top", "person"]
|
672
|
+
end
|
673
|
+
|
674
|
+
class OrganizationalPerson < Person
|
675
|
+
ldap_mapping dn_attribute: "cn",
|
676
|
+
prefix: "",
|
677
|
+
classes: ["top", "person", "organizationalPerson"]
|
678
|
+
end
|
679
|
+
|
680
|
+
class ResidentialPerson < Person
|
681
|
+
ldap_mapping dn_attribute: "cn",
|
682
|
+
prefix: "",
|
683
|
+
classes: ["top", "person", "residentialPerson"]
|
684
|
+
end
|
685
|
+
|
686
|
+
def test_sub_class
|
687
|
+
make_ou("People")
|
688
|
+
residential_person = ResidentialPerson.new(cn: "John Doe",
|
689
|
+
sn: "Doe",
|
690
|
+
street: "123 Main Street",
|
691
|
+
l: "Anytown")
|
692
|
+
residential_person.save!
|
693
|
+
organizational_person = OrganizationalPerson.new(cn: "Jane Smith",
|
694
|
+
sn: "Smith",
|
695
|
+
title: "General Manager")
|
696
|
+
organizational_person.save!
|
697
|
+
people = Person.all
|
698
|
+
assert_equal([ResidentialPerson, OrganizationalPerson],
|
699
|
+
people.collect(&:class))
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
666
703
|
def test_reload_of_not_exists_entry
|
667
704
|
make_temporary_user do |user,|
|
668
705
|
assert_nothing_raised do
|
data/test/test_callback.rb
CHANGED
@@ -6,10 +6,10 @@ class TestCallback < Test::Unit::TestCase
|
|
6
6
|
priority :must
|
7
7
|
def test_new
|
8
8
|
initialized_entries = []
|
9
|
-
@group_class.instance_variable_set("@initialized_entries",
|
10
|
-
initialized_entries)
|
11
9
|
@group_class.module_eval do
|
12
|
-
after_initialize
|
10
|
+
after_initialize do
|
11
|
+
initialized_entries << self
|
12
|
+
end
|
13
13
|
end
|
14
14
|
assert_equal([], initialized_entries)
|
15
15
|
new_group = @group_class.new(:cn => "new-cn")
|
@@ -22,12 +22,14 @@ class TestCallback < Test::Unit::TestCase
|
|
22
22
|
make_temporary_group do |group|
|
23
23
|
found_entries = []
|
24
24
|
initialized_entries = []
|
25
|
-
@group_class.instance_variable_set("@found_entries", found_entries)
|
26
|
-
@group_class.instance_variable_set("@initialized_entries",
|
27
|
-
initialized_entries)
|
28
25
|
@group_class.module_eval do
|
29
|
-
|
30
|
-
|
26
|
+
prepend ActiveLdap::Callbacks::CallbackedInstantiatable
|
27
|
+
after_find do
|
28
|
+
found_entries << self
|
29
|
+
end
|
30
|
+
after_initialize do
|
31
|
+
initialized_entries << self
|
32
|
+
end
|
31
33
|
end
|
32
34
|
|
33
35
|
assert_equal([], found_entries)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activeldap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Will Drewry
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-05-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -67,6 +67,20 @@ dependencies:
|
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: builder
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
70
84
|
- !ruby/object:Gem::Dependency
|
71
85
|
name: bundler
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -265,8 +279,6 @@ files:
|
|
265
279
|
- lib/active_ldap/schema.rb
|
266
280
|
- lib/active_ldap/schema/syntaxes.rb
|
267
281
|
- lib/active_ldap/supported_control.rb
|
268
|
-
- lib/active_ldap/timeout.rb
|
269
|
-
- lib/active_ldap/timeout_stub.rb
|
270
282
|
- lib/active_ldap/user_password.rb
|
271
283
|
- lib/active_ldap/validations.rb
|
272
284
|
- lib/active_ldap/version.rb
|
@@ -347,7 +359,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
347
359
|
version: '0'
|
348
360
|
requirements: []
|
349
361
|
rubyforge_project: ruby-activeldap
|
350
|
-
rubygems_version: 2.5.
|
362
|
+
rubygems_version: 2.5.2
|
351
363
|
signing_key:
|
352
364
|
specification_version: 4
|
353
365
|
summary: ActiveLdap is a object-oriented API to LDAP
|
@@ -400,4 +412,3 @@ test_files:
|
|
400
412
|
- test/test_usermod-lang-add.rb
|
401
413
|
- test/test_usermod.rb
|
402
414
|
- test/test_validation.rb
|
403
|
-
has_rdoc:
|
data/lib/active_ldap/timeout.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'timeout'
|
2
|
-
|
3
|
-
module Timeout
|
4
|
-
|
5
|
-
# A forking timeout implementation that relies on
|
6
|
-
# signals to interrupt blocking I/O instead of passing
|
7
|
-
# that code to run in a separate process.
|
8
|
-
#
|
9
|
-
# A process is fork()ed, sleeps for _sec_,
|
10
|
-
# then sends a ALRM signal to the Process.ppid
|
11
|
-
# process. ALRM is used to avoid conflicts with sleep()
|
12
|
-
#
|
13
|
-
# This overwrites any signal
|
14
|
-
def Timeout.alarm(sec, exception=Timeout::Error, &block)
|
15
|
-
return block.call if sec == nil or sec.zero?
|
16
|
-
|
17
|
-
|
18
|
-
# Trap an alarm in case it comes before we're ready
|
19
|
-
orig_alrm = trap(:ALRM, 'IGNORE')
|
20
|
-
|
21
|
-
# Setup a fallback in case of a race condition of an
|
22
|
-
# alarm before we set the other trap
|
23
|
-
trap(:ALRM) do
|
24
|
-
# Don't leave zombies
|
25
|
-
Process.wait2()
|
26
|
-
# Restore the original handler
|
27
|
-
trap('ALRM', orig_alrm)
|
28
|
-
# Now raise an exception!
|
29
|
-
raise exception, 'execution expired'
|
30
|
-
end
|
31
|
-
|
32
|
-
# Spawn the sleeper
|
33
|
-
pid = Process.fork {
|
34
|
-
begin
|
35
|
-
# Sleep x seconds then send SIGALRM
|
36
|
-
sleep(sec)
|
37
|
-
# Send alarm!
|
38
|
-
Process.kill(:ALRM, Process.ppid)
|
39
|
-
end
|
40
|
-
exit! 0
|
41
|
-
}
|
42
|
-
|
43
|
-
# Setup the real handler
|
44
|
-
trap(:ALRM) do
|
45
|
-
# Make sure we clean up any zombies
|
46
|
-
Process.waitpid(pid)
|
47
|
-
# Restore the original handler
|
48
|
-
trap(:ALRM, orig_alrm)
|
49
|
-
# Now raise an exception!
|
50
|
-
raise exception, 'execution expired'
|
51
|
-
end
|
52
|
-
|
53
|
-
begin
|
54
|
-
# Run the code!
|
55
|
-
return block.call
|
56
|
-
ensure
|
57
|
-
# Restore old alarm handler since we're done
|
58
|
-
trap(:ALRM, orig_alrm)
|
59
|
-
# Make sure the process is dead
|
60
|
-
# This may be run twice (trap occurs during execution) so ignore ESRCH
|
61
|
-
Process.kill(:TERM, pid) rescue Errno::ESRCH
|
62
|
-
# Don't leave zombies
|
63
|
-
Process.waitpid(pid) rescue Errno::ECHILD
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end # Timeout
|
67
|
-
|
68
|
-
if __FILE__ == $0
|
69
|
-
require 'time'
|
70
|
-
Timeout.alarm(2) do
|
71
|
-
loop do
|
72
|
-
p Time.now
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'timeout'
|
2
|
-
|
3
|
-
module Timeout
|
4
|
-
# STUB
|
5
|
-
def Timeout.alarm(sec, exception=Timeout::Error, &block)
|
6
|
-
timeout(sec, exception, &block)
|
7
|
-
end
|
8
|
-
end # Timeout
|
9
|
-
|
10
|
-
if __FILE__ == $0
|
11
|
-
require 'time'
|
12
|
-
Timeout.alarm(2) do
|
13
|
-
loop do
|
14
|
-
p Time.now
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|