@@ -67,6 +67,12 @@ def reopen(log = nil)
67
67
68
68
private
69
69
70
+ # :stopdoc:
71
+
72
+ MODE = File ::WRONLY | File ::APPEND
73
+ MODE_TO_OPEN = MODE | File ::SHARE_DELETE | File ::BINARY
74
+ MODE_TO_CREATE = MODE_TO_OPEN | File ::CREAT | File ::EXCL
75
+
70
76
def set_dev ( log )
71
77
if log . respond_to? ( :write ) and log . respond_to? ( :close )
72
78
@dev = log
@@ -77,34 +83,54 @@ def set_dev(log)
77
83
end
78
84
else
79
85
@dev = open_logfile ( log )
80
- @dev . sync = true
81
- @dev . binmode if @binmode
82
86
@filename = log
83
87
end
84
88
end
85
89
90
+ if MODE_TO_OPEN == MODE
91
+ def fixup_mode ( dev , filename )
92
+ dev
93
+ end
94
+ else
95
+ def fixup_mode ( dev , filename )
96
+ return dev if @binmode
97
+ dev . autoclose = false
98
+ old_dev = dev
99
+ dev = File . new ( dev . fileno , mode : MODE , path : filename )
100
+ old_dev . close
101
+ PathAttr . set_path ( dev , filename ) if defined? ( PathAttr )
102
+ dev
103
+ end
104
+ end
105
+
86
106
def open_logfile ( filename )
87
107
begin
88
- File . open ( filename , ( File :: WRONLY | File :: APPEND ) )
108
+ dev = File . open ( filename , MODE_TO_OPEN )
89
109
rescue Errno ::ENOENT
90
110
create_logfile ( filename )
111
+ else
112
+ dev = fixup_mode ( dev , filename )
113
+ dev . sync = true
114
+ dev . binmode if @binmode
115
+ dev
91
116
end
92
117
end
93
118
94
119
def create_logfile ( filename )
95
120
begin
96
- logdev = File . open ( filename , ( File :: WRONLY | File :: APPEND | File :: CREAT | File :: EXCL ) )
121
+ logdev = File . open ( filename , MODE_TO_CREATE )
97
122
logdev . flock ( File ::LOCK_EX )
123
+ logdev = fixup_mode ( logdev , filename )
98
124
logdev . sync = true
99
125
logdev . binmode if @binmode
100
126
add_log_header ( logdev )
101
127
logdev . flock ( File ::LOCK_UN )
128
+ logdev
102
129
rescue Errno ::EEXIST
103
130
# file is created by another process
104
- logdev = open_logfile ( filename )
105
- logdev . sync = true
131
+ open_logfile ( filename )
106
132
end
107
- logdev
133
+ end
108
134
109
135
def handle_write_errors ( mesg )
110
136
yield
@@ -135,40 +161,33 @@ def check_shift_log
135
161
end
136
162
end
137
163
138
- if /mswin|mingw|cygwin/ =~ RbConfig ::CONFIG [ 'host_os' ]
139
- def lock_shift_log
140
- yield
141
- end
142
- else
143
- def lock_shift_log
144
- retry_limit = 8
145
- retry_sleep = 0.1
146
- begin
147
- File . open ( @filename , File ::WRONLY | File ::APPEND ) do |lock |
148
- lock . flock ( File ::LOCK_EX ) # inter-process locking. will be unlocked at closing file
149
- if File . identical? ( @filename , lock ) and File . identical? ( lock , @dev )
150
- yield # log shifting
151
- else
152
- # log shifted by another process (i-node before locking and i-node after locking are different)
153
- @dev . close rescue nil
154
- @dev = open_logfile ( @filename )
155
- @dev . sync = true
156
- end
157
- end
158
- rescue Errno ::ENOENT
159
- # @filename file would not exist right after #rename and before #create_logfile
160
- if retry_limit <= 0
161
- warn ( "log rotation inter-process lock failed. #{ $!} " )
164
+ def lock_shift_log
165
+ retry_limit = 8
166
+ retry_sleep = 0.1
167
+ begin
168
+ File . open ( @filename , MODE_TO_OPEN ) do |lock |
169
+ lock . flock ( File ::LOCK_EX ) # inter-process locking. will be unlocked at closing file
170
+ if File . identical? ( @filename , lock ) and File . identical? ( lock , @dev )
171
+ yield # log shifting
162
172
else
163
- sleep retry_sleep
164
- retry_limit -= 1
165
- retry_sleep *= 2
166
- retry
173
+ # log shifted by another process (i-node before locking and i-node after locking are different)
174
+ @dev . close rescue nil
175
+ @dev = open_logfile ( @filename )
167
176
end
168
177
end
169
- rescue
170
- warn ( "log rotation inter-process lock failed. #{ $!} " )
178
+ rescue Errno ::ENOENT
179
+ # @filename file would not exist right after #rename and before #create_logfile
180
+ if retry_limit <= 0
181
+ warn ( "log rotation inter-process lock failed. #{ $!} " )
182
+ else
183
+ sleep retry_sleep
184
+ retry_limit -= 1
185
+ retry_sleep *= 2
186
+ retry
187
+ end
171
188
end
189
+ rescue
190
+ warn ( "log rotation inter-process lock failed. #{ $!} " )
172
191
end
173
192
174
193
def shift_log_age
@@ -203,3 +222,15 @@ def shift_log_period(period_end)
203
222
end
204
223
end
205
224
end
225
+
226
+ File . open ( IO ::NULL ) do |f |
227
+ File . new ( f . fileno , autoclose : false , path : "" ) . path
228
+ rescue IOError
229
+ module PathAttr # :nodoc:
230
+ attr_reader :path
231
+
232
+ def self . set_path ( file , path )
233
+ file . extend ( self ) . instance_variable_set ( :@path , path )
234
+ end
235
+ end
236
+ end
0 commit comments