cde2563767602cba3508b631a3674d6569de5aa1
[unicorn.git] / lib / unicorn / util.rb
blobcde2563767602cba3508b631a3674d6569de5aa1
1 # -*- encoding: binary -*-
3 module Unicorn::Util
5 # :stopdoc:
6   def self.is_log?(fp)
7     append_flags = File::WRONLY | File::APPEND
9     ! fp.closed? &&
10       fp.sync &&
11       (fp.fcntl(Fcntl::F_GETFL) & append_flags) == append_flags
12     rescue IOError, Errno::EBADF
13       false
14   end
16   def self.chown_logs(uid, gid)
17     ObjectSpace.each_object(File) do |fp|
18       fp.chown(uid, gid) if is_log?(fp)
19     end
20   end
21 # :startdoc:
23   # This reopens ALL logfiles in the process that have been rotated
24   # using logrotate(8) (without copytruncate) or similar tools.
25   # A +File+ object is considered for reopening if it is:
26   #   1) opened with the O_APPEND and O_WRONLY flags
27   #   2) the current open file handle does not match its original open path
28   #   3) unbuffered (as far as userspace buffering goes, not O_SYNC)
29   # Returns the number of files reopened
30   #
31   # In Unicorn 3.5.x and earlier, files must be opened with an absolute
32   # path to be considered a log file.
33   def self.reopen_logs
34     to_reopen = []
35     nr = 0
36     ObjectSpace.each_object(File) { |fp| is_log?(fp) and to_reopen << fp }
38     to_reopen.each do |fp|
39       orig_st = begin
40         fp.stat
41       rescue IOError, Errno::EBADF
42         next
43       end
45       begin
46         b = File.stat(fp.path)
47         next if orig_st.ino == b.ino && orig_st.dev == b.dev
48       rescue Errno::ENOENT
49       end
51       begin
52         File.open(fp.path, 'a') { |tmpfp| fp.reopen(tmpfp) }
53         fp.sync = true
54         new_st = fp.stat
56         # this should only happen in the master:
57         if orig_st.uid != new_st.uid || orig_st.gid != new_st.gid
58           fp.chown(orig_st.uid, orig_st.gid)
59         end
61         nr += 1
62       rescue IOError, Errno::EBADF
63         # not much we can do...
64       end
65     end
66     nr
67   end
68 end