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