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