lockfile 1.4.3 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/gemspec.rb DELETED
@@ -1,27 +0,0 @@
1
-
2
- lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
3
-
4
- require 'rubygems'
5
-
6
- Gem::Specification::new do |spec|
7
- $VERBOSE = nil
8
- spec.name = lib
9
- spec.version = version
10
- spec.platform = Gem::Platform::RUBY
11
- spec.summary = lib
12
-
13
- spec.files = Dir::glob "**/**"
14
- spec.executables = Dir::glob("bin/*").map{|exe| File::basename exe}
15
-
16
- spec.require_path = "lib"
17
- spec.autorequire = lib
18
-
19
- spec.has_rdoc = File::exist? "doc"
20
- spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
21
-
22
- spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
23
-
24
- spec.author = "Ara T. Howard"
25
- spec.email = "ara.t.howard@noaa.gov"
26
- spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
27
- end
data/install.rb DELETED
@@ -1,210 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rbconfig'
3
- require 'find'
4
- require 'ftools'
5
- require 'tempfile'
6
- include Config
7
-
8
- LIBDIR = "lib"
9
- LIBDIR_MODE = 0644
10
-
11
- BINDIR = "bin"
12
- BINDIR_MODE = 0755
13
-
14
-
15
- $srcdir = CONFIG["srcdir"]
16
- $version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
17
- $libdir = File.join(CONFIG["libdir"], "ruby", $version)
18
- $archdir = File.join($libdir, CONFIG["arch"])
19
- $site_libdir = $:.find {|x| x =~ /site_ruby$/}
20
- $bindir = CONFIG["bindir"] || CONFIG['BINDIR']
21
- $ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
22
- $ruby_ext = CONFIG['EXEEXT'] || ''
23
- $ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
24
-
25
- if !$site_libdir
26
- $site_libdir = File.join($libdir, "site_ruby")
27
- elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
28
- $site_libdir = File.join($site_libdir, $version)
29
- end
30
-
31
- def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
32
- #{{{
33
- path = []
34
- dir = []
35
- Find.find(srcdir) do |f|
36
- next unless FileTest.file?(f)
37
- next if (f = f[srcdir.length+1..-1]) == nil
38
- next if (/CVS$/ =~ File.dirname(f))
39
- next if f =~ %r/\.lnk/
40
- path.push f
41
- dir |= [File.dirname(f)]
42
- end
43
- for f in dir
44
- next if f == "."
45
- next if f == "CVS"
46
- File::makedirs(File.join(destdir, f))
47
- end
48
- for f in path
49
- next if (/\~$/ =~ f)
50
- next if (/^\./ =~ File.basename(f))
51
- unless bin
52
- File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
53
- else
54
- from = File.join(srcdir, f)
55
- to = File.join(destdir, f)
56
- shebangify(from) do |sf|
57
- $deferr.print from, " -> ", File::catname(from, to), "\n"
58
- $deferr.printf "chmod %04o %s\n", mode, to
59
- File::install(sf, to, mode, false)
60
- end
61
- end
62
- end
63
- #}}}
64
- end
65
- def shebangify f
66
- #{{{
67
- open(f) do |fd|
68
- buf = fd.read 42
69
- if buf =~ %r/^\s*#\s*!.*ruby/o
70
- ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
71
- begin
72
- fd.rewind
73
- ftmp.puts "#!#{ $ruby }"
74
- while((buf = fd.read(8192)))
75
- ftmp.write buf
76
- end
77
- ftmp.close
78
- yield ftmp.path
79
- ensure
80
- ftmp.close!
81
- end
82
- else
83
- yield f
84
- end
85
- end
86
- #}}}
87
- end
88
- def ARGV.switch
89
- #{{{
90
- return nil if self.empty?
91
- arg = self.shift
92
- return nil if arg == '--'
93
- if arg =~ /^-(.)(.*)/
94
- return arg if $1 == '-'
95
- raise 'unknown switch "-"' if $2.index('-')
96
- self.unshift "-#{$2}" if $2.size > 0
97
- "-#{$1}"
98
- else
99
- self.unshift arg
100
- nil
101
- end
102
- #}}}
103
- end
104
- def ARGV.req_arg
105
- #{{{
106
- self.shift || raise('missing argument')
107
- #}}}
108
- end
109
- def linkify d, linked = []
110
- #--{{{
111
- if test ?d, d
112
- versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
113
- versioned.each do |v|
114
- src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
115
- lnk = nil
116
- begin
117
- if test ?l, dst
118
- lnk = "#{ dst }.lnk"
119
- puts "#{ dst } -> #{ lnk }"
120
- File::rename dst, lnk
121
- end
122
- unless test ?e, dst
123
- puts "#{ src } -> #{ dst }"
124
- File::copy src, dst
125
- linked << dst
126
- end
127
- ensure
128
- if lnk
129
- at_exit do
130
- puts "#{ lnk } -> #{ dst }"
131
- File::rename lnk, dst
132
- end
133
- end
134
- end
135
- end
136
- end
137
- linked
138
- #--}}}
139
- end
140
-
141
-
142
- #
143
- # main program
144
- #
145
-
146
- libdir = $site_libdir
147
- bindir = $bindir
148
- no_linkify = false
149
- linked = nil
150
- help = false
151
-
152
- usage = <<-usage
153
- #{ File::basename $0 }
154
- -d, --destdir <destdir>
155
- -l, --libdir <libdir>
156
- -b, --bindir <bindir>
157
- -r, --ruby <ruby>
158
- -n, --no_linkify
159
- -s, --sudo
160
- -h, --help
161
- usage
162
-
163
- begin
164
- while switch = ARGV.switch
165
- case switch
166
- when '-d', '--destdir'
167
- libdir = ARGV.req_arg
168
- when '-l', '--libdir'
169
- libdir = ARGV.req_arg
170
- when '-b', '--bindir'
171
- bindir = ARGV.req_arg
172
- when '-r', '--ruby'
173
- $ruby = ARGV.req_arg
174
- when '-n', '--no_linkify'
175
- no_linkify = true
176
- when '-s', '--sudo'
177
- sudo = 'sudo'
178
- when '-h', '--help'
179
- help = true
180
- else
181
- raise "unknown switch #{switch.dump}"
182
- end
183
- end
184
- rescue
185
- STDERR.puts $!.to_s
186
- STDERR.puts usage
187
- exit 1
188
- end
189
-
190
- if help
191
- STDOUT.puts usage
192
- exit
193
- end
194
-
195
- system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
196
-
197
- unless no_linkify
198
- linked = linkify('lib') + linkify('bin')
199
- end
200
-
201
- system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
202
-
203
- install_rb(LIBDIR, libdir, LIBDIR_MODE)
204
- install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
205
-
206
- if linked
207
- linked.each{|path| File::rm_f path}
208
- end
209
-
210
- system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
@@ -1,564 +0,0 @@
1
- unless(defined?($__lockfile__) or defined?(Lockfile))
2
-
3
- require 'socket'
4
- require 'timeout'
5
- require 'fileutils'
6
-
7
- class Lockfile
8
- #--{{{
9
- VERSION = '1.4.3'
10
- def version() VERSION end
11
-
12
- class LockError < StandardError; end
13
- class StolenLockError < LockError; end
14
- class StackingLockError < LockError; end
15
- class StatLockError < LockError; end
16
- class MaxTriesLockError < LockError; end
17
- class TimeoutLockError < LockError; end
18
- class NFSLockError < LockError; end
19
- class UnLockError < LockError; end
20
-
21
- class SleepCycle < Array
22
- #--{{{
23
- attr :min
24
- attr :max
25
- attr :range
26
- attr :inc
27
- def initialize min, max, inc
28
- #--{{{
29
- @min, @max, @inc = Float(min), Float(max), Float(inc)
30
- @range = @max - @min
31
- raise RangeError, "max(#{ @max }) <= min(#{ @min })" if @max <= @min
32
- raise RangeError, "inc(#{ @inc }) > range(#{ @range })" if @inc > @range
33
- raise RangeError, "inc(#{ @inc }) <= 0" if @inc <= 0
34
- raise RangeError, "range(#{ @range }) <= 0" if @range <= 0
35
- s = @min
36
- push(s) and s += @inc while(s <= @max)
37
- self[-1] = @max if self[-1] < @max
38
- reset
39
- #--}}}
40
- end
41
- def next
42
- #--{{{
43
- ret = self[@idx]
44
- @idx = ((@idx + 1) % self.size)
45
- ret
46
- #--}}}
47
- end
48
- def reset
49
- #--{{{
50
- @idx = 0
51
- #--}}}
52
- end
53
- #--}}}
54
- end
55
-
56
- HOSTNAME = Socket::gethostname
57
-
58
- DEFAULT_RETRIES = nil # maximum number of attempts
59
- DEFAULT_TIMEOUT = nil # the longest we will try
60
- DEFAULT_MAX_AGE = 3600 # lockfiles older than this are stale
61
- DEFAULT_SLEEP_INC = 2 # sleep cycle is this much longer each time
62
- DEFAULT_MIN_SLEEP = 2 # shortest sleep time
63
- DEFAULT_MAX_SLEEP = 32 # longest sleep time
64
- DEFAULT_SUSPEND = 1800 # iff we steal a lock wait this long before we go on
65
- DEFAULT_REFRESH = 8 # how often we touch/validate the lock
66
- DEFAULT_DONT_CLEAN = false # iff we leave lock files lying around
67
- DEFAULT_POLL_RETRIES = 16 # this many polls makes one 'try'
68
- DEFAULT_POLL_MAX_SLEEP = 0.08 # the longest we'll sleep between polls
69
- DEFAULT_DONT_SWEEP = false # if we cleanup after other process on our host
70
- DEFAULT_DONT_USE_LOCK_ID = false # if we dump lock info into lockfile
71
-
72
- DEFAULT_DEBUG = ENV['LOCKFILE_DEBUG'] || false
73
-
74
- class << self
75
- #--{{{
76
- attr :retries, true
77
- attr :max_age, true
78
- attr :sleep_inc, true
79
- attr :min_sleep, true
80
- attr :max_sleep, true
81
- attr :suspend, true
82
- attr :timeout, true
83
- attr :refresh, true
84
- attr :debug, true
85
- attr :dont_clean, true
86
- attr :poll_retries, true
87
- attr :poll_max_sleep, true
88
- attr :dont_sweep, true
89
- attr :dont_use_lock_id, true
90
-
91
- def init
92
- #--{{{
93
- @retries = DEFAULT_RETRIES
94
- @max_age = DEFAULT_MAX_AGE
95
- @sleep_inc = DEFAULT_SLEEP_INC
96
- @min_sleep = DEFAULT_MIN_SLEEP
97
- @max_sleep = DEFAULT_MAX_SLEEP
98
- @suspend = DEFAULT_SUSPEND
99
- @timeout = DEFAULT_TIMEOUT
100
- @refresh = DEFAULT_REFRESH
101
- @dont_clean = DEFAULT_DONT_CLEAN
102
- @poll_retries = DEFAULT_POLL_RETRIES
103
- @poll_max_sleep = DEFAULT_POLL_MAX_SLEEP
104
- @dont_sweep = DEFAULT_DONT_SWEEP
105
- @dont_use_lock_id = DEFAULT_DONT_USE_LOCK_ID
106
-
107
- @debug = DEFAULT_DEBUG
108
-
109
- STDOUT.sync = true if @debug
110
- STDERR.sync = true if @debug
111
- #--}}}
112
- end
113
- #--}}}
114
- end
115
- self.init
116
-
117
- attr :klass
118
- attr :path
119
- attr :opts
120
- attr :locked
121
- attr :thief
122
- attr :dirname
123
- attr :basename
124
- attr :clean
125
- attr :retries
126
- attr :max_age
127
- attr :sleep_inc
128
- attr :min_sleep
129
- attr :max_sleep
130
- attr :suspend
131
- attr :refresh
132
- attr :timeout
133
- attr :dont_clean
134
- attr :poll_retries
135
- attr :poll_max_sleep
136
- attr :dont_sweep
137
- attr :dont_use_lock_id
138
-
139
- attr :debug, true
140
-
141
- alias thief? thief
142
- alias locked? locked
143
- alias debug? debug
144
-
145
- def self::create(path, *a, &b)
146
- #--{{{
147
- opts = {
148
- 'retries' => 0,
149
- 'min_sleep' => 0,
150
- 'max_sleep' => 1,
151
- 'sleep_inc' => 1,
152
- 'max_age' => nil,
153
- 'suspend' => 0,
154
- 'refresh' => nil,
155
- 'timeout' => nil,
156
- 'poll_retries' => 0,
157
- 'dont_clean' => true,
158
- 'dont_sweep' => false,
159
- 'dont_use_lock_id' => true,
160
- }
161
- begin
162
- new(path, opts).lock
163
- rescue LockError
164
- raise Errno::EEXIST, path
165
- end
166
- open(path, *a, &b)
167
- #--}}}
168
- end
169
-
170
- def initialize(path, opts = {}, &block)
171
- #--{{{
172
- @klass = self.class
173
- @path = path
174
- @opts = opts
175
-
176
- @retries = getopt 'retries' , @klass.retries
177
- @max_age = getopt 'max_age' , @klass.max_age
178
- @sleep_inc = getopt 'sleep_inc' , @klass.sleep_inc
179
- @min_sleep = getopt 'min_sleep' , @klass.min_sleep
180
- @max_sleep = getopt 'max_sleep' , @klass.max_sleep
181
- @suspend = getopt 'suspend' , @klass.suspend
182
- @timeout = getopt 'timeout' , @klass.timeout
183
- @refresh = getopt 'refresh' , @klass.refresh
184
- @dont_clean = getopt 'dont_clean' , @klass.dont_clean
185
- @poll_retries = getopt 'poll_retries' , @klass.poll_retries
186
- @poll_max_sleep = getopt 'poll_max_sleep' , @klass.poll_max_sleep
187
- @dont_sweep = getopt 'dont_sweep' , @klass.dont_sweep
188
- @dont_use_lock_id = getopt 'dont_use_lock_id' , @klass.dont_use_lock_id
189
- @debug = getopt 'debug' , @klass.debug
190
-
191
- @sleep_cycle = SleepCycle::new @min_sleep, @max_sleep, @sleep_inc
192
-
193
- @clean = @dont_clean ? nil : lambda{ File::unlink @path rescue nil }
194
- @dirname = File::dirname @path
195
- @basename = File::basename @path
196
- @thief = false
197
- @locked = false
198
-
199
- lock(&block) if block
200
- #--}}}
201
- end
202
- def lock
203
- #--{{{
204
- raise StackingLockError, "<#{ @path }> is locked!" if @locked
205
-
206
- sweep unless @dont_sweep
207
-
208
- ret = nil
209
-
210
- attempt do
211
- begin
212
- @sleep_cycle.reset
213
- create_tmplock do |f|
214
- begin
215
- Timeout::timeout(@timeout) do
216
- tmp_path = f.path
217
- tmp_stat = f.lstat
218
- n_retries = 0
219
- trace{ "attempting to lock <#{ @path }>..." }
220
- begin
221
- i = 0
222
- begin
223
- trace{ "polling attempt <#{ i }>..." }
224
- begin
225
- File::link tmp_path, @path
226
- rescue Errno::ENOENT
227
- try_again!
228
- end
229
- lock_stat = File::lstat @path
230
- raise StatLockError, "stat's do not agree" unless
231
- tmp_stat.rdev == lock_stat.rdev and tmp_stat.ino == lock_stat.ino
232
- trace{ "aquired lock <#{ @path }>" }
233
- @locked = true
234
- rescue => e
235
- i += 1
236
- unless i >= @poll_retries
237
- t = [rand(@poll_max_sleep), @poll_max_sleep].min
238
- trace{ "poll sleep <#{ t }>..." }
239
- sleep t
240
- retry
241
- end
242
- raise
243
- end
244
-
245
- rescue => e
246
- n_retries += 1
247
- trace{ "n_retries <#{ n_retries }>" }
248
- case validlock?
249
- when true
250
- raise MaxTriesLockError, "surpased retries <#{ @retries }>" if
251
- @retries and n_retries >= @retries
252
- trace{ "found valid lock" }
253
- sleeptime = @sleep_cycle.next
254
- trace{ "sleep <#{ sleeptime }>..." }
255
- sleep sleeptime
256
- when false
257
- trace{ "found invalid lock and removing" }
258
- begin
259
- File::unlink @path
260
- @thief = true
261
- warn "<#{ @path }> stolen by <#{ Process.pid }> at <#{ timestamp }>"
262
- trace{ "i am a thief!" }
263
- rescue Errno::ENOENT
264
- end
265
- trace{ "suspending <#{ @suspend }>" }
266
- sleep @suspend
267
- when nil
268
- raise MaxTriesLockError, "surpased retries <#{ @retries }>" if
269
- @retries and n_retries >= @retries
270
- end
271
- retry
272
- end # begin
273
- end # timeout
274
- rescue Timeout::Error
275
- raise TimeoutLockError, "surpassed timeout <#{ @timeout }>"
276
- end # begin
277
- end # create_tmplock
278
-
279
- if block_given?
280
- stolen = false
281
- refresher = (@refresh ? new_refresher : nil)
282
- begin
283
- begin
284
- ret = yield @path
285
- rescue StolenLockError
286
- stolen = true
287
- raise
288
- end
289
- ensure
290
- begin
291
- refresher.kill if refresher and refresher.status
292
- ensure
293
- unlock unless stolen
294
- end
295
- end
296
- else
297
- ObjectSpace.define_finalizer self, @clean if @clean
298
- ret = self
299
- end
300
- rescue Errno::ESTALE, Errno::EIO => e
301
- raise(NFSLockError, errmsg(e))
302
- end
303
- end
304
-
305
- return ret
306
- #--}}}
307
- end
308
- def sweep
309
- #----{{{
310
- begin
311
- glob = File::join(@dirname, ".*lck")
312
- paths = Dir[glob]
313
- paths.each do |path|
314
- begin
315
- basename = File::basename path
316
- pat = %r/^\s*\.([^_]+)_([^_]+)/o
317
- if pat.match(basename)
318
- host, pid = $1, $2
319
- else
320
- next
321
- end
322
- host.gsub!(%r/^\.+|\.+$/,'')
323
- quad = host.split %r/\./
324
- host = quad.first
325
- pat = %r/^\s*#{ host }/i
326
- if pat.match(HOSTNAME) and %r/^\s*\d+\s*$/.match(pid)
327
- unless alive?(pid)
328
- trace{ "process <#{ pid }> on <#{ host }> is no longer alive" }
329
- trace{ "sweeping <#{ path }>" }
330
- FileUtils::rm_f path
331
- else
332
- trace{ "process <#{ pid }> on <#{ host }> is still alive" }
333
- trace{ "ignoring <#{ path }>" }
334
- end
335
- else
336
- trace{ "ignoring <#{ path }> generated by <#{ host }>" }
337
- end
338
- rescue
339
- next
340
- end
341
- end
342
- rescue => e
343
- warn(errmsg(e))
344
- end
345
- #----}}}
346
- end
347
- def alive? pid
348
- #----{{{
349
- pid = Integer("#{ pid }")
350
- begin
351
- Process::kill 0, pid
352
- true
353
- rescue Errno::ESRCH
354
- false
355
- end
356
- #----}}}
357
- end
358
- def unlock
359
- #--{{{
360
- raise UnLockError, "<#{ @path }> is not locked!" unless @locked
361
- begin
362
- File::unlink @path
363
- rescue Errno::ENOENT
364
- raise StolenLockError, @path
365
- ensure
366
- @thief = false
367
- @locked = false
368
- ObjectSpace.undefine_finalizer self if @clean
369
- end
370
- #--}}}
371
- end
372
- def new_refresher
373
- #--{{{
374
- Thread::new(Thread::current, @path, @refresh, @dont_use_lock_id) do |thread, path, refresh, dont_use_lock_id|
375
- loop do
376
- begin
377
- touch path
378
- trace{"touched <#{ path }> @ <#{ Time.now.to_f }>"}
379
- unless dont_use_lock_id
380
- loaded = load_lock_id(IO.read(path))
381
- trace{"loaded <\n#{ loaded.inspect }\n>"}
382
- raise unless loaded == @lock_id
383
- end
384
- sleep refresh
385
- rescue Exception => e
386
- trace{errmsg e}
387
- thread.raise StolenLockError
388
- Thread::exit
389
- end
390
- end
391
- end
392
- #--}}}
393
- end
394
- def validlock?
395
- #--{{{
396
- if @max_age
397
- uncache @path rescue nil
398
- begin
399
- return((Time.now - File::stat(@path).mtime) < @max_age)
400
- rescue Errno::ENOENT
401
- return nil
402
- end
403
- else
404
- exist = File::exist?(@path)
405
- return(exist ? true : nil)
406
- end
407
- #--}}}
408
- end
409
- def uncache file
410
- #--{{{
411
- refresh = nil
412
- begin
413
- is_a_file = File === file
414
- path = (is_a_file ? file.path : file.to_s)
415
- stat = (is_a_file ? file.stat : File::stat(file.to_s))
416
- refresh = tmpnam(File::dirname(path))
417
- File::link path, refresh
418
- File::chmod stat.mode, path
419
- File::utime stat.atime, stat.mtime, path
420
- ensure
421
- begin
422
- File::unlink refresh if refresh
423
- rescue Errno::ENOENT
424
- end
425
- end
426
- #--}}}
427
- end
428
- def create_tmplock
429
- #--{{{
430
- tmplock = tmpnam @dirname
431
- begin
432
- create(tmplock) do |f|
433
- unless dont_use_lock_id
434
- @lock_id = gen_lock_id
435
- dumped = dump_lock_id
436
- trace{"lock_id <\n#{ @lock_id.inspect }\n>"}
437
- f.write dumped
438
- f.flush
439
- end
440
- yield f
441
- end
442
- ensure
443
- begin; File::unlink tmplock; rescue Errno::ENOENT; end if tmplock
444
- end
445
- #--}}}
446
- end
447
- def gen_lock_id
448
- #--{{{
449
- Hash[
450
- 'host' => "#{ HOSTNAME }",
451
- 'pid' => "#{ Process.pid }",
452
- 'ppid' => "#{ Process.ppid }",
453
- 'time' => timestamp,
454
- ]
455
- #--}}}
456
- end
457
- def timestamp
458
- #--{{{
459
- time = Time.now
460
- usec = time.usec.to_s
461
- usec << '0' while usec.size < 6
462
- "#{ time.strftime('%Y-%m-%d %H:%M:%S') }.#{ usec }"
463
- #--}}}
464
- end
465
- def dump_lock_id lock_id = @lock_id
466
- #--{{{
467
- "host: %s\npid: %s\nppid: %s\ntime: %s\n" %
468
- lock_id.values_at('host','pid','ppid','time')
469
- #--}}}
470
- end
471
- def load_lock_id buf
472
- #--{{{
473
- lock_id = {}
474
- kv = %r/([^:]+):(.*)/o
475
- buf.each do |line|
476
- m = kv.match line
477
- k, v = m[1], m[2]
478
- next unless m and k and v
479
- lock_id[k.strip] = v.strip
480
- end
481
- lock_id
482
- #--}}}
483
- end
484
- def tmpnam dir, seed = File::basename($0)
485
- #--{{{
486
- pid = Process.pid
487
- time = Time.now
488
- sec = time.to_i
489
- usec = time.usec
490
- "%s%s.%s_%d_%s_%d_%d_%d.lck" %
491
- [dir, File::SEPARATOR, HOSTNAME, pid, seed, sec, usec, rand(sec)]
492
- #--}}}
493
- end
494
- def create path
495
- #--{{{
496
- umask = nil
497
- f = nil
498
- begin
499
- umask = File::umask 022
500
- f = open path, File::WRONLY|File::CREAT|File::EXCL, 0644
501
- ensure
502
- File::umask umask if umask
503
- end
504
- return(block_given? ? begin; yield f; ensure; f.close; end : f)
505
- #--}}}
506
- end
507
- def touch path
508
- #--{{{
509
- FileUtils.touch path
510
- #--}}}
511
- end
512
- def getopt key, default = nil
513
- #--{{{
514
- [ key, key.to_s, key.to_s.intern ].each do |k|
515
- return @opts[k] if @opts.has_key?(k)
516
- end
517
- return default
518
- #--}}}
519
- end
520
- def to_str
521
- #--{{{
522
- @path
523
- #--}}}
524
- end
525
- alias to_s to_str
526
- def trace s = nil
527
- #--{{{
528
- STDERR.puts((s ? s : yield)) if @debug
529
- #--}}}
530
- end
531
- def errmsg e
532
- #--{{{
533
- "%s (%s)\n%s\n" % [e.class, e.message, e.backtrace.join("\n")]
534
- #--}}}
535
- end
536
- def attempt
537
- #----{{{
538
- ret = nil
539
- loop{ break unless catch('attempt'){ ret = yield } == 'try_again' }
540
- ret
541
- #----}}}
542
- end
543
- def try_again!
544
- #----{{{
545
- throw 'attempt', 'try_again'
546
- #----}}}
547
- end
548
- alias again! try_again!
549
- def give_up!
550
- #----{{{
551
- throw 'attempt', 'give_up'
552
- #----}}}
553
- end
554
- #--}}}
555
- end
556
-
557
- def Lockfile path, *a, &b
558
- #--{{{
559
- Lockfile.new(path, *a, &b)
560
- #--}}}
561
- end
562
-
563
- $__lockfile__ = __FILE__
564
- end