@@ -67,6 +67,12 @@ def reopen(log = nil)
6767
6868 private
6969
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+
7076 def set_dev ( log )
7177 if log . respond_to? ( :write ) and log . respond_to? ( :close )
7278 @dev = log
@@ -77,34 +83,54 @@ def set_dev(log)
7783 end
7884 else
7985 @dev = open_logfile ( log )
80- @dev . sync = true
81- @dev . binmode if @binmode
8286 @filename = log
8387 end
8488 end
8589
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+
86106 def open_logfile ( filename )
87107 begin
88- File . open ( filename , ( File :: WRONLY | File :: APPEND ) )
108+ dev = File . open ( filename , MODE_TO_OPEN )
89109 rescue Errno ::ENOENT
90110 create_logfile ( filename )
111+ else
112+ dev = fixup_mode ( dev , filename )
113+ dev . sync = true
114+ dev . binmode if @binmode
115+ dev
91116 end
92117 end
93118
94119 def create_logfile ( filename )
95120 begin
96- logdev = File . open ( filename , ( File :: WRONLY | File :: APPEND | File :: CREAT | File :: EXCL ) )
121+ logdev = File . open ( filename , MODE_TO_CREATE )
97122 logdev . flock ( File ::LOCK_EX )
123+ logdev = fixup_mode ( logdev , filename )
98124 logdev . sync = true
99125 logdev . binmode if @binmode
100126 add_log_header ( logdev )
101127 logdev . flock ( File ::LOCK_UN )
128+ logdev
102129 rescue Errno ::EEXIST
103130 # file is created by another process
104- logdev = open_logfile ( filename )
105- logdev . sync = true
131+ open_logfile ( filename )
106132 end
107- logdev
133+ end
108134
109135 def handle_write_errors ( mesg )
110136 yield
@@ -135,40 +161,33 @@ def check_shift_log
135161 end
136162 end
137163
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
162172 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 )
167176 end
168177 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
171188 end
189+ rescue
190+ warn ( "log rotation inter-process lock failed. #{ $!} " )
172191 end
173192
174193 def shift_log_age
@@ -203,3 +222,15 @@ def shift_log_period(period_end)
203222 end
204223 end
205224end
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