activeldap 4.0.6 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|