unicorn 0.8.4
[unicorn.git] / lib / unicorn / util.rb
blobd2214b73e48157c1c6296890559dfe595a228de4
1 require 'fcntl'
2 require 'tmpdir'
4 module Unicorn
5   class Util
6     class << self
8       APPEND_FLAGS = File::WRONLY | File::APPEND
10       # this reopens logs that have been rotated (using logrotate(8) or
11       # similar).  It is recommended that you install
12       # A +File+ object is considered for reopening if it is:
13       #   1) opened with the O_APPEND and O_WRONLY flags
14       #   2) opened with an absolute path (starts with "/")
15       #   3) the current open file handle does not match its original open path
16       #   4) unbuffered (as far as userspace buffering goes)
17       # Returns the number of files reopened
18       def reopen_logs
19         nr = 0
20         ObjectSpace.each_object(File) do |fp|
21           next if fp.closed?
22           next unless (fp.sync && fp.path[0..0] == "/")
23           next unless (fp.fcntl(Fcntl::F_GETFL) & APPEND_FLAGS) == APPEND_FLAGS
25           begin
26             a, b = fp.stat, File.stat(fp.path)
27             next if a.ino == b.ino && a.dev == b.dev
28           rescue Errno::ENOENT
29           end
31           open_arg = 'a'
32           if fp.respond_to?(:external_encoding) && enc = fp.external_encoding
33             open_arg << ":#{enc.to_s}"
34             enc = fp.internal_encoding and open_arg << ":#{enc.to_s}"
35           end
36           fp.reopen(fp.path, open_arg)
37           fp.sync = true
38           nr += 1
39         end # each_object
40         nr
41       end
43       # creates and returns a new File object.  The File is unlinked
44       # immediately, switched to binary mode, and userspace output
45       # buffering is disabled
46       def tmpio
47         fp = begin
48           File.open("#{Dir::tmpdir}/#{rand}",
49                     File::RDWR|File::CREAT|File::EXCL, 0600)
50         rescue Errno::EEXIST
51           retry
52         end
53         File.unlink(fp.path)
54         fp.binmode
55         fp.sync = true
56         fp
57       end
59     end
61   end
62 end