defmacro-unicorn 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,90 @@
1
+ # -*- encoding: binary -*-
2
+
3
+ require 'fcntl'
4
+ require 'tmpdir'
5
+
6
+ module Unicorn
7
+
8
+ class TmpIO < ::File
9
+
10
+ # for easier env["rack.input"] compatibility
11
+ def size
12
+ # flush if sync
13
+ stat.size
14
+ end
15
+ end
16
+
17
+ class Util
18
+ class << self
19
+
20
+ def is_log?(fp)
21
+ append_flags = File::WRONLY | File::APPEND
22
+
23
+ ! fp.closed? &&
24
+ fp.sync &&
25
+ fp.path[0] == ?/ &&
26
+ (fp.fcntl(Fcntl::F_GETFL) & append_flags) == append_flags
27
+ end
28
+
29
+ def chown_logs(uid, gid)
30
+ ObjectSpace.each_object(File) do |fp|
31
+ fp.chown(uid, gid) if is_log?(fp)
32
+ end
33
+ end
34
+
35
+ # This reopens ALL logfiles in the process that have been rotated
36
+ # using logrotate(8) (without copytruncate) or similar tools.
37
+ # A +File+ object is considered for reopening if it is:
38
+ # 1) opened with the O_APPEND and O_WRONLY flags
39
+ # 2) opened with an absolute path (starts with "/")
40
+ # 3) the current open file handle does not match its original open path
41
+ # 4) unbuffered (as far as userspace buffering goes, not O_SYNC)
42
+ # Returns the number of files reopened
43
+ def reopen_logs
44
+ nr = 0
45
+
46
+ ObjectSpace.each_object(File) do |fp|
47
+ is_log?(fp) or next
48
+ orig_st = fp.stat
49
+ begin
50
+ b = File.stat(fp.path)
51
+ next if orig_st.ino == b.ino && orig_st.dev == b.dev
52
+ rescue Errno::ENOENT
53
+ end
54
+
55
+ open_arg = 'a'
56
+ if fp.respond_to?(:external_encoding) && enc = fp.external_encoding
57
+ open_arg << ":#{enc.to_s}"
58
+ enc = fp.internal_encoding and open_arg << ":#{enc.to_s}"
59
+ end
60
+ fp.reopen(fp.path, open_arg)
61
+ fp.sync = true
62
+ new_st = fp.stat
63
+ if orig_st.uid != new_st.uid || orig_st.gid != new_st.gid
64
+ fp.chown(orig_st.uid, orig_st.gid)
65
+ end
66
+ nr += 1
67
+ end # each_object
68
+ nr
69
+ end
70
+
71
+ # creates and returns a new File object. The File is unlinked
72
+ # immediately, switched to binary mode, and userspace output
73
+ # buffering is disabled
74
+ def tmpio
75
+ fp = begin
76
+ TmpIO.open("#{Dir::tmpdir}/#{rand}",
77
+ File::RDWR|File::CREAT|File::EXCL, 0600)
78
+ rescue Errno::EEXIST
79
+ retry
80
+ end
81
+ File.unlink(fp.path)
82
+ fp.binmode
83
+ fp.sync = true
84
+ fp
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+ end