line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package CGI::LogCarp; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# SCCS INFO: @(#) CGI::LogCarp.pm 4.48 20/06/06 |
4
|
|
|
|
|
|
|
# RCS INFO: $Id: CGI::LogCarp.pm,v 4.48 2020/06/06 mak Exp $ |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# Copyright (C) 1997,2020 Michael King (mikeking@cpan.org) |
7
|
|
|
|
|
|
|
# Saint Louis, MO USA. |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# This module is free software; you can redistribute it and/or |
10
|
|
|
|
|
|
|
# modify it under the terms of the Artistic License 2.0. |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# SPDX-License-Identifier: Artistic-2.0-Perl |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=head1 NAME |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
CGI::LogCarp - Error, log and debug streams, httpd style format |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
CGI::LogCarp redefines the STDERR stream and allows the definition |
19
|
|
|
|
|
|
|
of new STDBUG and STDLOG streams in such a way that all messages are |
20
|
|
|
|
|
|
|
formatted similar to an HTTPD error log. |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Methods are defined for directing messages to STDERR, STDBUG, and STDLOG. |
23
|
|
|
|
|
|
|
Each stream can be directed to its own location independent of the others. |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
It can be used as a version-compatible drop-in replacement for the |
26
|
|
|
|
|
|
|
CGI::Carp module. This means that version 4.48 of CGI::LogCarp provides |
27
|
|
|
|
|
|
|
the same functionality, usage, and features as at least version 4.48 |
28
|
|
|
|
|
|
|
of CGI::Carp. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head1 SYNOPSIS |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
use CGI::LogCarp qw( :STDBUG fatalsToBrowser ); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
print "CGI::LogCarp version: ", CGI::LogCarp::VERSION; |
35
|
|
|
|
|
|
|
DEBUGLEVEL 2; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
confess "It was my fault: $!"; |
38
|
|
|
|
|
|
|
cluck "What's going on here?"; |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
warn "This is most unusual."; |
41
|
|
|
|
|
|
|
carp "It was your fault!"; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
croak "We're outta here!"; |
44
|
|
|
|
|
|
|
die "I'm dying.\n"; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
debug "Just for debugging: somevar=", $somevar, "\n"; |
47
|
|
|
|
|
|
|
logmsg "Just for logging: We're here.\n"; |
48
|
|
|
|
|
|
|
trace "detail=", $detail, "\n"; |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
carpout \*ERRFILE; |
51
|
|
|
|
|
|
|
debugout \*DEBUGFILE; |
52
|
|
|
|
|
|
|
logmsgout \*LOGFILE; |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
is_STDOUT(\*ERRFILE) |
55
|
|
|
|
|
|
|
is_STDERR(\*LOGFILE) |
56
|
|
|
|
|
|
|
is_STDBUG(\*LOGFILE) |
57
|
|
|
|
|
|
|
is_STDLOG(\*ERRFILE) |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=head1 DESCRIPTION |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
CGI::LogCarp is a Perl package defining methods for directing |
62
|
|
|
|
|
|
|
the existing STDERR stream as well as creating and directing |
63
|
|
|
|
|
|
|
two new messaging streams, STDBUG and STDLOG. |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
Their use was intended mainly for a CGI development environment, |
66
|
|
|
|
|
|
|
or where separate facilities for errors, logging, and debugging |
67
|
|
|
|
|
|
|
output are needed. |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
This is because CGI scripts have a nasty habit of leaving warning messages |
70
|
|
|
|
|
|
|
in the error logs that are neither time stamped nor fully identified. |
71
|
|
|
|
|
|
|
Tracking down the script that caused the error is a pain. Differentiating |
72
|
|
|
|
|
|
|
debug output or activity logging from actual error messages is a pain. |
73
|
|
|
|
|
|
|
Logging application activity or producing debugging output are quite different |
74
|
|
|
|
|
|
|
tasks than (ab)using the server's error log for this purpose. |
75
|
|
|
|
|
|
|
This module fixes all of these problems. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
Replace the usual |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
use Carp; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
or |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
use CGI::Carp; |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
with |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
use CGI::LogCarp; |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
And the standard C, C, C, C, |
90
|
|
|
|
|
|
|
C, and C calls will automagically be replaced with methods |
91
|
|
|
|
|
|
|
that write out nicely time-, process-, program-, and stream- stamped messages |
92
|
|
|
|
|
|
|
to the STDERR, STDLOG, and STDBUG streams. |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
The method to generate messages on the new STDLOG stream |
95
|
|
|
|
|
|
|
is C. Calls to C will write out the same nicely |
96
|
|
|
|
|
|
|
time-, process-, program-, and stream-stamped messages |
97
|
|
|
|
|
|
|
described above to both the STDLOG and the STDBUG streams. |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
The process number and the stream on which the message appeared |
100
|
|
|
|
|
|
|
is embedded in the default message in order to disambiguate multiple |
101
|
|
|
|
|
|
|
simultaneous executions as well as multiple streams directed |
102
|
|
|
|
|
|
|
to the same location. |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
Messages on multiple streams directed to the same location |
105
|
|
|
|
|
|
|
do not receive multiple copies. |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
Methods to generate messages on the new STDBUG stream |
108
|
|
|
|
|
|
|
are C and C. |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=head2 Creating the New Streams |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
In order to create the new streams, you must name them on the C |
113
|
|
|
|
|
|
|
This is also referred to as importing a symbol. For example: |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
use CGI::LogCarp qw( :STDERR :STDLOG :STDBUG ); |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
Note the :STDERR is not really necessary, as it is already defined in perl. |
118
|
|
|
|
|
|
|
Importing the :STDERR symbol will not generate an error. |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
By default, the STDLOG stream is duplicated from the STDERR stream, |
121
|
|
|
|
|
|
|
and the STDBUG stream is duplicated from the STDOUT stream. |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=head2 Redirecting Error Messages |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
By default, error messages are sent to STDERR. Most HTTPD servers |
126
|
|
|
|
|
|
|
direct STDERR to the server's error log. Some applications may wish |
127
|
|
|
|
|
|
|
to keep private error logs, distinct from the server's error log, or |
128
|
|
|
|
|
|
|
they may wish to direct error messages to STDOUT so that the browser |
129
|
|
|
|
|
|
|
will receive them (for debugging, not for public consumption). |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
The C method is provided for this purpose. |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
Because C is not exported by default, |
134
|
|
|
|
|
|
|
you must import it explicitly by saying: |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
use CGI::LogCarp qw( carpout ); |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
Note that for C, the STDERR stream is already defined, |
139
|
|
|
|
|
|
|
so there is no need to explicitly create it by importing the STDERR symbol. |
140
|
|
|
|
|
|
|
However, |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
use CGI::LogCarp qw( :STDERR ); |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
will not generate an error, and will also import carpout for you. |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
For CGI programs that need to send something to the HTTPD server's |
147
|
|
|
|
|
|
|
real error log, the original STDERR stream has not been closed, |
148
|
|
|
|
|
|
|
it has been saved as _STDERR. The reason for this is twofold. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
The first is that your CGI application might really need to write something |
151
|
|
|
|
|
|
|
to the server's error log, unrelated to your own error log. To do so, |
152
|
|
|
|
|
|
|
simply write directly to the _STDERR stream. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
The second is that some servers, when dealing with CGI scripts, |
155
|
|
|
|
|
|
|
close their connection to the browser when the script closes |
156
|
|
|
|
|
|
|
either STDOUT or STDERR. Some consider this a (mis)feature. |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
Saving the program's initial STDERR in _STDERR is used |
159
|
|
|
|
|
|
|
to prevent this from happening prematurely. |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
Do not manipulate the _STDERR filehandle in any other way other than writing |
162
|
|
|
|
|
|
|
to it. |
163
|
|
|
|
|
|
|
For CGI applications, the C method formats and sends your message |
164
|
|
|
|
|
|
|
to the HTTPD error log (on the _STDERR stream). |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=head2 Redirecting Log Messages |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
A new stream, STDLOG, can be defined and used for log messages. |
169
|
|
|
|
|
|
|
By default, STDLOG will be routed to STDERR. Most HTTPD servers |
170
|
|
|
|
|
|
|
direct STDERR (and thus the default STDLOG also) to the server's error log. |
171
|
|
|
|
|
|
|
Some applications may wish to keep private activity logs, |
172
|
|
|
|
|
|
|
distinct from the server's error log, or they may wish to direct log messages |
173
|
|
|
|
|
|
|
to STDOUT so that the browser will receive them (for debugging, |
174
|
|
|
|
|
|
|
not for public consumption). |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
The C method is provided for this purpose. |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
Because C is not exported by default, |
179
|
|
|
|
|
|
|
you must create the STDLOG stream and import them explicitly by saying: |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
use CGI::LogCarp qw( :STDLOG ); |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=head2 Redirecting Debug Messages |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
A new stream, STDBUG, can be defined and used for debugging messages. |
186
|
|
|
|
|
|
|
Since this stream is for producing debugging output, |
187
|
|
|
|
|
|
|
the default STDBUG will be routed to STDOUT. Some applications may wish |
188
|
|
|
|
|
|
|
to keep private debug logs, distinct from the application output, or |
189
|
|
|
|
|
|
|
CGI applications may wish to leave debug messages directed to STDOUT |
190
|
|
|
|
|
|
|
so that the browser will receive them (only when debugging). |
191
|
|
|
|
|
|
|
Your program may also control the output by manipulating DEBUGLEVEL |
192
|
|
|
|
|
|
|
in the application. |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
The C method is provided for this purpose. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
Because the C method is not exported by default, |
197
|
|
|
|
|
|
|
you must create the STDBUG stream and import them explicitly by saying: |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
use CGI::LogCarp qw( :STDBUG ); |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=head2 Redirecting Messages in General |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
Each of these methods, C, C, and C, |
204
|
|
|
|
|
|
|
requires one argument, which should be a reference to an open filehandle |
205
|
|
|
|
|
|
|
for writing. |
206
|
|
|
|
|
|
|
They should be called in a C block at the top of the application |
207
|
|
|
|
|
|
|
so that compiler errors will be caught. |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
This example creates and redirects the STDLOG stream, |
210
|
|
|
|
|
|
|
as well as redirecting the STDERR stream to a browser, |
211
|
|
|
|
|
|
|
formatting the error message as an HTML document: |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
BEGIN { |
214
|
|
|
|
|
|
|
use CGI::LogCarp qw( :STDLOG fatalsToBrowser ); |
215
|
|
|
|
|
|
|
# fatalsToBrowser doesn't stop messages going to STDERR, |
216
|
|
|
|
|
|
|
# rather it replicates them on STDOUT. So we stop them here. |
217
|
|
|
|
|
|
|
open(_STDERR,'>&STDERR'); close STDERR; |
218
|
|
|
|
|
|
|
open(LOG,">>/var/logs/cgi-logs/mycgi-log") |
219
|
|
|
|
|
|
|
or die "Unable to open mycgi-log: $!\n"; |
220
|
|
|
|
|
|
|
logmsgout \*LOG; |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
NOTE: C, C, and C handle file locking |
224
|
|
|
|
|
|
|
on systems that support flock so multiple simultaneous CGIs are not an issue. |
225
|
|
|
|
|
|
|
However, flock might not operate as desired over network-mounted filesystems. |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
If you want to send errors to the browser, give C a reference |
228
|
|
|
|
|
|
|
to STDOUT: |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
BEGIN { |
231
|
|
|
|
|
|
|
use CGI::LogCarp qw( carpout ); |
232
|
|
|
|
|
|
|
carpout \*STDOUT; |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
If you do this, be sure to send a Content-Type header immediately -- |
236
|
|
|
|
|
|
|
perhaps even within the BEGIN block -- to prevent server errors. |
237
|
|
|
|
|
|
|
However, you probably want to take a look at importing the |
238
|
|
|
|
|
|
|
C symbol and closing STDERR instead of doing this. |
239
|
|
|
|
|
|
|
See the example above on how to do this. |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=head2 Passing filehandles |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
You can pass filehandles to C, C, and C |
244
|
|
|
|
|
|
|
in a variety of ways. The "correct" way according to Tom Christiansen |
245
|
|
|
|
|
|
|
is to pass a reference to a filehandle GLOB (or if you are using the |
246
|
|
|
|
|
|
|
FileHandle module, a reference to a anonymous filehandle GLOB): |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
carpout \*LOG; |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
This looks a little weird if you haven't mastered Perl's syntax, |
251
|
|
|
|
|
|
|
so the following syntaxes are accepted as well: |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
carpout(LOG) -or- carpout(\LOG) |
254
|
|
|
|
|
|
|
carpout('LOG') -or- carpout(\'LOG') |
255
|
|
|
|
|
|
|
carpout(main::LOG) -or- carpout(\main::LOG) |
256
|
|
|
|
|
|
|
carpout('main::LOG') -or- carpout(\'main::LOG') |
257
|
|
|
|
|
|
|
... and so on |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
FileHandle and other objects work as well. |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
Using C, C, and C, |
262
|
|
|
|
|
|
|
is not great for performance, so they are recommended for debugging purposes |
263
|
|
|
|
|
|
|
or for moderate-use applications. You can also manipulate DEBUGLEVEL |
264
|
|
|
|
|
|
|
to control the output during the execution of your program. |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head2 Changing the Default Message Formats |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
By default, the messages sent to the respective streams are formatted |
269
|
|
|
|
|
|
|
as helpful time-, process-, program-, and stream-stamped messages. |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
The process number (represented in the example output below as $$) |
272
|
|
|
|
|
|
|
and the stream on which the message appears are displayed in the default |
273
|
|
|
|
|
|
|
message format and serve to disambiguate multiple simultaneous executions |
274
|
|
|
|
|
|
|
as well as multiple streams directed to the same location. |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
For example: |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
[Mon Sep 15 09:04:55 1997] $$ test.pl ERR: I'm confused at test.pl line 3. |
279
|
|
|
|
|
|
|
[Mon Sep 15 09:04:55 1997] $$ test.pl BUG: answer=42. |
280
|
|
|
|
|
|
|
[Mon Sep 15 09:04:55 1997] $$ test.pl LOG: I did something. |
281
|
|
|
|
|
|
|
[Mon Sep 15 09:04:55 1997] $$ test.pl ERR: Got a warning: Permission denied. |
282
|
|
|
|
|
|
|
[Mon Sep 15 09:04:55 1997] $$ test.pl ERR: I'm dying. |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
You can, however, redefine your own message formats for each stream |
285
|
|
|
|
|
|
|
if you don't like this one by using the C method. |
286
|
|
|
|
|
|
|
This is not imported by default; you should import it on the use() line |
287
|
|
|
|
|
|
|
like thus: |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
use CGI::LogCarp qw( fatalsToBrowser set_message ); |
290
|
|
|
|
|
|
|
# fatalsToBrowser doesn't stop messages going to STDERR, |
291
|
|
|
|
|
|
|
# rather it replicates them on STDOUT. So we stop them here. |
292
|
|
|
|
|
|
|
open(_STDERR,'>&STDERR'); close STDERR; |
293
|
|
|
|
|
|
|
set_message("It's not a bug, it's a feature!"); |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
use CGI::LogCarp qw( :STDLOG ); |
296
|
|
|
|
|
|
|
set_message(STDLOG, "Control: I'm here."); |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
Note the varying syntax for C. |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
The first parameter, if it is a filehandle, identifies the stream whose |
301
|
|
|
|
|
|
|
message is being defined. Otherwise it specifies the message for the STDERR |
302
|
|
|
|
|
|
|
stream. This non-filehandle first parameter form preserves compatibility with |
303
|
|
|
|
|
|
|
CGI::Carp syntax. |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
You may also pass in a code reference in order to create a custom |
306
|
|
|
|
|
|
|
error message. At run time, your code will be called with the text |
307
|
|
|
|
|
|
|
of the error message that caused the script |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
BEGIN { |
310
|
|
|
|
|
|
|
use CGI::LogCarp qw( fatalsToBrowser set_message ); |
311
|
|
|
|
|
|
|
# fatalsToBrowser doesn't stop messages going to STDERR, |
312
|
|
|
|
|
|
|
# rather it replicates them on STDOUT. So we stop them here. |
313
|
|
|
|
|
|
|
open(_STDERR,'>&STDERR'); close STDERR; |
314
|
|
|
|
|
|
|
sub handle_errors { |
315
|
|
|
|
|
|
|
my $msg = shift; |
316
|
|
|
|
|
|
|
$msg =~ s/\&/&/gs; |
317
|
|
|
|
|
|
|
$msg =~ s/</gs; |
318
|
|
|
|
|
|
|
$msg =~ s/>/>/gs; |
319
|
|
|
|
|
|
|
$msg =~ s/"/"/gs; |
320
|
|
|
|
|
|
|
join("\n", |
321
|
|
|
|
|
|
|
"Aw shucks", |
322
|
|
|
|
|
|
|
"Got an error:", |
323
|
|
|
|
|
|
|
"", $msg, " ", |
324
|
|
|
|
|
|
|
""); |
325
|
|
|
|
|
|
|
} |
326
|
|
|
|
|
|
|
set_message(\&handle_errors); |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
In order to correctly intercept compile-time errors, you should |
330
|
|
|
|
|
|
|
call C from within a C block. |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=head2 Making perl Errors Appear in the Browser Window |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
If you want to send fatal (C or C) errors to the browser, |
335
|
|
|
|
|
|
|
ask to import the special C symbol: |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
BEGIN { |
338
|
|
|
|
|
|
|
use CGI::LogCarp qw( fatalsToBrowser ); |
339
|
|
|
|
|
|
|
# fatalsToBrowser doesn't stop messages going to STDERR, |
340
|
|
|
|
|
|
|
# rather it replicates them on STDOUT. So we stop them here. |
341
|
|
|
|
|
|
|
open(_STDERR,'>&STDERR'); close STDERR; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
die "Bad error here"; |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
Fatal errors will now be sent to the browser. Any messages sent to the |
346
|
|
|
|
|
|
|
STDERR stream are now I reproduced on the STDOUT stream. |
347
|
|
|
|
|
|
|
Using C also causes CGI::LogCarp to define a new message |
348
|
|
|
|
|
|
|
format that arranges to send a minimal HTTP header and HTML document to the |
349
|
|
|
|
|
|
|
browser so that even errors that occur early in the compile phase will be |
350
|
|
|
|
|
|
|
shown. Any fatal (C) and nonfatal (C) messages are I produced |
351
|
|
|
|
|
|
|
on the STDERR stream. They just also go to STDOUT. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
Certain web servers (Netscape) also send CGI STDERR output to the browser. |
354
|
|
|
|
|
|
|
This causes a problem for CGI's because the STDERR stream is not buffered, |
355
|
|
|
|
|
|
|
and thus if something gets sent to the STDERR stream before the normal |
356
|
|
|
|
|
|
|
document header is produced, the browser will get very confused. |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
The following line solves this problem. See above for examples with context. |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
open(_STDERR,'>&STDERR'); close STDERR; |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
=head2 Changing the fatalsToBrowser message format or document |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
The default message generated by C is not the normal |
365
|
|
|
|
|
|
|
C logging message, but instead displays the error message followed by |
366
|
|
|
|
|
|
|
a short note to contact the Webmaster by e-mail with the time and date of the |
367
|
|
|
|
|
|
|
error. You can use the C method to change it as described above. |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
The default message generated on the STDLOG and STDBUG streams is formatted |
370
|
|
|
|
|
|
|
differently, and is as described earlier. |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=head2 What are the Carp methods? |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
The Carp methods that are replaced by CGI::LogCarp are useful in your |
375
|
|
|
|
|
|
|
own modules, scripts, and CGI applications because they act like C |
376
|
|
|
|
|
|
|
or C, but report where the error was in the code they were called from. |
377
|
|
|
|
|
|
|
Thus, if you have a routine C that has a C in it, |
378
|
|
|
|
|
|
|
then the C will report the error as occurring where C was |
379
|
|
|
|
|
|
|
called, not where C was called. |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=head2 Forcing a Stack Trace |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
As a debugging aid, you can force C to treat a C |
384
|
|
|
|
|
|
|
as a C and a C as a C across I modules. |
385
|
|
|
|
|
|
|
In other words, force a detailed stack trace to be given. |
386
|
|
|
|
|
|
|
This can be very helpful when trying to understand why, or from where, |
387
|
|
|
|
|
|
|
a warning or error is being generated. |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
This feature is enabled by 'importing' the non-existant symbol |
390
|
|
|
|
|
|
|
'verbose'. You would typically enable it on the command line by saying: |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
perl -MCGI::LogCarp=verbose script.pl |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
or by including the string C in the C |
395
|
|
|
|
|
|
|
environment variable. |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
You would typically enable it in a CGI application by saying: |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
use CGI::LogCarp qw( verbose ); |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
Or, during your program's run by saying: |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
CGI::LogCarp::import( 'verbose' ); |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
and calling C's import function directly. |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
NOTE: This is a feature that is in Carp but apparently was not |
408
|
|
|
|
|
|
|
implemented in CGI::Carp (as of v1.10). |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
=head1 METHODS |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
Unless otherwise stated all methods return either a true or false value, |
413
|
|
|
|
|
|
|
with true meaning that the operation was a success. |
414
|
|
|
|
|
|
|
When a method states that it returns a value, |
415
|
|
|
|
|
|
|
failure will be returned as undef or an empty list. |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
=head2 Streams and their methods |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
The following methods are for generating a message on the respective stream: |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
The STDERR stream: warn() and die() |
422
|
|
|
|
|
|
|
The STDLOG stream: logmsg() |
423
|
|
|
|
|
|
|
The STDBUG stream: debug() and trace() |
424
|
|
|
|
|
|
|
The _STDERR stream: serverwarn() |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
The following methods are for generating a message on the respective stream, |
427
|
|
|
|
|
|
|
but will indicate the message location from the caller's perspective. |
428
|
|
|
|
|
|
|
See the standard B module for details. |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
The STDERR stream: carp(), croak(), cluck() and confess() |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
The following methods are for manipulating the respective stream: |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
The STDERR stream: carpout() |
435
|
|
|
|
|
|
|
The STDLOG stream: logmsgout() |
436
|
|
|
|
|
|
|
The STDBUG stream: debugout() |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
The following methods are for manipulating the amount (or level) |
439
|
|
|
|
|
|
|
of output filtering on the respective stream: |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
The STDBUG stream: DEBUGLEVEL() |
442
|
|
|
|
|
|
|
The STDLOG stream: LOGLEVEL() |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
The following method defines the format of messages directed to a stream. |
445
|
|
|
|
|
|
|
Often used by and/or in conjunction with C: |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
set_message() |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
=head2 Exported Package Methods |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
By default, the only methods exported into your namespace are: |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
warn, die, carp, croak, confess, and cluck |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
When you import the :STDBUG tag, these additional symbols are exported: |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
*STDBUG, debugmsgout, debug, trace, and DEBUGLEVEL |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
When you import the :STDLOG tag, these additional symbols are exported: |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
*STDLOG, logmsgout, logmsg and LOGLEVEL |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
When you import the :STDERR tag, these additional symbols are exported: |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
carpout |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
These additional methods are not exported by default, and must be named: |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
carpout, logmsgout, debugout, set_message |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
The following are pseudo-symbols, in that they change the way CGI::LogCarp |
472
|
|
|
|
|
|
|
works, but to not export any symbols in and of themselves. |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
verbose, fatalsToBrowser |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=head2 Internal Package Methods |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
The following methods are not exported but can be accessed directly |
479
|
|
|
|
|
|
|
in the CGI::LogCarp package. |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
The following methods are for comparing a filehandle to the respective stream: |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
is_STDOUT() |
484
|
|
|
|
|
|
|
is_STDERR() |
485
|
|
|
|
|
|
|
is_STDBUG() |
486
|
|
|
|
|
|
|
is_STDLOG() |
487
|
|
|
|
|
|
|
is_realSTDERR() |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Each is explained in its own section below. |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=head2 Exported Package Variables |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
No variables are exported into the caller's namespace. |
494
|
|
|
|
|
|
|
However, the STDLOG and STDBUG streams are defined using typeglobs |
495
|
|
|
|
|
|
|
in the C namespace. |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
=head2 Internal Package Variables |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=over |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=item $DEBUGLEVEL |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
A number indicating the level of debugging output that is to occur. |
504
|
|
|
|
|
|
|
At each increase in level, additional debugging output is allowed. |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
Currently three levels are defined: |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
0 - No messages are output on the STDBUG stream. |
509
|
|
|
|
|
|
|
1 - debug() messages are output on the STDBUG stream. |
510
|
|
|
|
|
|
|
2 - debug() and trace() messages are output on the STDBUG stream. |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
It is recommended to use the DEBUGLEVEL method to get/set this value. |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
=item $LOGLEVEL |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
A number indicating the level of logging output that is to occur. |
517
|
|
|
|
|
|
|
At each increase in level, additional logging output is allowed. |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
Currently two levels are defined: |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
0 - No messages are output on the STDLOG stream. |
522
|
|
|
|
|
|
|
1 - logmsg() messages are output on the STDLOG stream. |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
It is recommended to use the LOGLEVEL method to get/set this value. |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=back |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=head1 RETURN VALUE |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
The value returned by executing the package is 1 (or true). |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
=head1 ENVIRONMENT |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
=head1 FILES |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
=head1 ERRORS |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
=head1 WARNINGS |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
Operation on Win32 platforms has not been tested. |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
CGI::Carp has some references to a C import symbol, |
543
|
|
|
|
|
|
|
which appears to be an alternate name for C. |
544
|
|
|
|
|
|
|
Internal comments refer to errorWrap. Since this is poorly |
545
|
|
|
|
|
|
|
documented, I am speculating this is legacy and/or previous |
546
|
|
|
|
|
|
|
implementation coding, and as such, have chosen not implement |
547
|
|
|
|
|
|
|
the C symbol import in C. If some massively |
548
|
|
|
|
|
|
|
popular module(s) I am currently unaware of is/are indeed using |
549
|
|
|
|
|
|
|
this undocumented interface, please let me know. |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
=head1 DIAGNOSTICS |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
See importing the C pseudo-symbol in B. |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
=head1 BUGS |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
Check out what's left in the TODO file. |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
=head1 RESTRICTIONS |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
This module is free software; you can redistribute it and/or |
562
|
|
|
|
|
|
|
modify it under the same terms as Perl itself. |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
=head1 CPAN DEPENDENCIES |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
=head1 LOCAL DEPENDENCIES |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
=head1 SEE ALSO |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
Carp, CGI::Carp |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
=head1 NOTES |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
carpout(), debugout(), and logmsgout() now perform file locking. |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
I've attempted to track the features in C to the features in |
577
|
|
|
|
|
|
|
the C module by Lincoln Stein. The version number of C |
578
|
|
|
|
|
|
|
corresponds to the highest version of C module that this module |
579
|
|
|
|
|
|
|
replicates all features and functionality. Thus version 1.10 of C |
580
|
|
|
|
|
|
|
can be used as a drop-in replacement for versions 1.10 or lower of C. |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
Due to the implementation of the Symbol.pm module, I have no choice but to |
583
|
|
|
|
|
|
|
replace it with a version that supports extending the list of "global" |
584
|
|
|
|
|
|
|
symbols. It is part of the CGI::LogCarp distribution. |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
For speed reasons, the autoflush method is implemented here instead of |
587
|
|
|
|
|
|
|
pulling in the entire FileHandle module. |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
Based heavily on the C module by Lincoln D. Stein ( lstein@genome.wi.mit.edu ). |
592
|
|
|
|
|
|
|
Thanks to Andy Wardley ( abw@kfs.org ) for commenting the original C |
593
|
|
|
|
|
|
|
module. |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
Thanks to Michael G Schwern ( schwern@starmedia.net ) for the constructive input. |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
=head1 AUTHORZ<>(S) |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
mak - Michael King ( mikeking@cpan.org ) |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
=head1 HISTORY |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
CGI::LogCarp.pm |
604
|
|
|
|
|
|
|
v1.01 09/15/97 mak |
605
|
|
|
|
|
|
|
v1.12 08/14/98 mak |
606
|
|
|
|
|
|
|
v4.48 06/06/20 mak |
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
=head1 CHANGE LOG |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
1.05 first posting to CPAN |
611
|
|
|
|
|
|
|
1.12 major revision, tracking CGI::Carp |
612
|
|
|
|
|
|
|
4.48 major revision to track current version of CGI::Carp. |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
=head1 MODIFICATIONS |
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
=head1 COPYRIGHT |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
Copyright (C) 1997,2020 Michael King ( mikeking@cpan.org ) |
619
|
|
|
|
|
|
|
Saint Louis, MO USA. |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
This module is free software; you can redistribute it and/or |
622
|
|
|
|
|
|
|
modify it under the terms of the Artistic License 2.0. |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
This module is copyright (c) 1997,2020 by Michael King (mikeking@cpan.org) |
625
|
|
|
|
|
|
|
and is made available to the Perl public under terms of the |
626
|
|
|
|
|
|
|
Artistic License 2.0. See the file LICENSE for details |
627
|
|
|
|
|
|
|
of copy and distribution terms. |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
The authoritative text of the Artistic License 2.0 can be found here: |
630
|
|
|
|
|
|
|
https://www.perlfoundation.org/artistic-license-20.html |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
=head1 AVAILABILITY |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
The latest version of this module is likely to be available from: CPAN.org |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
The best place to discuss this code is via email with the author. |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
=cut |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
# --- END OF PAGE ---#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
# Play nice |
644
|
|
|
|
|
|
|
require 5.004; |
645
|
6
|
|
|
6
|
|
4866
|
use strict; |
|
6
|
|
|
|
|
40
|
|
|
6
|
|
|
|
|
308
|
|
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
# The package name |
648
|
|
|
|
|
|
|
package CGI::LogCarp; |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
# Define external interface |
651
|
6
|
|
|
6
|
|
46
|
use vars qw( @ISA @EXPORT @EXPORT_OK @EXPORT_FAIL %EXPORT_TAGS ); |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
365
|
|
652
|
6
|
|
|
6
|
|
35
|
use Exporter; |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
2720
|
|
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
# Inherit normal import/export mechanism from Exporter |
655
|
|
|
|
|
|
|
@ISA = qw( Exporter ); |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
# Always exported into caller namespace |
658
|
|
|
|
|
|
|
@EXPORT = qw( *STDERR confess croak carp cluck ); |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
# Externally visible if specified |
661
|
|
|
|
|
|
|
@EXPORT_OK = qw( |
662
|
|
|
|
|
|
|
logmsg trace debug |
663
|
|
|
|
|
|
|
carpout logmsgout debugout |
664
|
|
|
|
|
|
|
serverwarn |
665
|
|
|
|
|
|
|
DEBUGLEVEL LOGLEVEL |
666
|
|
|
|
|
|
|
is_STDOUT is_STDERR is_STDBUG is_STDLOG is_realSTDERR |
667
|
|
|
|
|
|
|
set_message |
668
|
|
|
|
|
|
|
*STDBUG *STDLOG |
669
|
|
|
|
|
|
|
); |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
# Export Tags |
672
|
|
|
|
|
|
|
%EXPORT_TAGS = ( |
673
|
|
|
|
|
|
|
'STDBUG' => [ qw( *STDBUG debug trace debugout DEBUGLEVEL ), @EXPORT ], |
674
|
|
|
|
|
|
|
'STDLOG' => [ qw( *STDLOG logmsg logmsgout LOGLEVEL ), @EXPORT ], |
675
|
|
|
|
|
|
|
'STDERR' => [ qw( *STDERR carpout ), @EXPORT ], |
676
|
|
|
|
|
|
|
); |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
# Hook for psuedo-symbols (or modes) |
679
|
|
|
|
|
|
|
@EXPORT_FAIL = qw( verbose *STDERR *STDLOG *STDBUG ); |
680
|
|
|
|
|
|
|
push @EXPORT_FAIL, qw( fatalsToBrowser ); # from CGI::Carp |
681
|
|
|
|
|
|
|
push @EXPORT_OK, @EXPORT_FAIL; |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
sub export_fail { |
684
|
|
|
|
|
|
|
MODE: { |
685
|
8
|
|
|
8
|
0
|
1983
|
shift; |
|
18
|
|
|
|
|
31
|
|
686
|
18
|
100
|
|
|
|
48
|
last MODE unless scalar @_; |
687
|
10
|
50
|
|
|
|
51
|
if ($_[0] eq 'verbose') { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
688
|
0
|
|
|
|
|
0
|
Carp->import($_[0]); # Let Carp know what's going on |
689
|
0
|
|
|
|
|
0
|
redo MODE; |
690
|
|
|
|
|
|
|
} elsif ($_[0] eq '*STDLOG') { # Create the STDLOG stream |
691
|
1
|
50
|
|
|
|
3
|
unless ($CGI::LogCarp::STDLOG) { |
692
|
1
|
50
|
|
|
|
16
|
open(CGI::LogCarp::STDLOG,'>&STDERR') |
693
|
|
|
|
|
|
|
or realdie("Could not create STDLOG stream: $!"); |
694
|
1
|
|
|
|
|
3
|
$CGI::LogCarp::STDLOG = $CGI::LogCarp::STDLOG = 1; |
695
|
|
|
|
|
|
|
#Symbol::add_global('STDLOG'); |
696
|
|
|
|
|
|
|
} |
697
|
1
|
|
|
|
|
2
|
redo MODE; |
698
|
|
|
|
|
|
|
} elsif ($_[0] eq '*STDBUG') { # Create the STDBUG stream |
699
|
1
|
50
|
|
|
|
3
|
unless ($CGI::LogCarp::STDBUG) { |
700
|
1
|
50
|
|
|
|
17
|
open(CGI::LogCarp::STDBUG,'>&STDOUT') |
701
|
|
|
|
|
|
|
or realdie("Could not create STDBUG stream: $!"); |
702
|
1
|
|
|
|
|
3
|
$CGI::LogCarp::STDBUG = $CGI::LogCarp::STDBUG = 1; |
703
|
|
|
|
|
|
|
#Symbol::add_global('STDBUG'); |
704
|
|
|
|
|
|
|
} |
705
|
1
|
|
|
|
|
2
|
redo MODE; |
706
|
|
|
|
|
|
|
} elsif ($_[0] eq '*STDERR') { # Create the STDERR stream |
707
|
8
|
100
|
|
|
|
37
|
unless (fileno(\*CGI::LogCarp::STDERR)) { |
708
|
6
|
50
|
|
|
|
131
|
open(CGI::LogCarp::STDERR,'>&STDERR') or realdie(); |
709
|
6
|
|
|
|
|
19
|
$CGI::LogCarp::STDERR = $CGI::LogCarp::STDERR = 1; |
710
|
|
|
|
|
|
|
} |
711
|
8
|
|
|
|
|
19
|
redo MODE; |
712
|
|
|
|
|
|
|
} elsif ($_[0] eq 'fatalsToBrowser') { # Turn it on |
713
|
0
|
|
|
|
|
0
|
$CGI::LogCARP::fatalsToBrowser = 1; |
714
|
0
|
|
|
|
|
0
|
redo MODE; |
715
|
|
|
|
|
|
|
} |
716
|
|
|
|
|
|
|
} |
717
|
8
|
|
|
|
|
1620
|
return @_; |
718
|
|
|
|
|
|
|
} |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
# Standard packages |
721
|
6
|
|
|
6
|
|
204
|
BEGIN { require Carp; } # We *DON'T* want to import Carp's symbols |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
# CPAN packages |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
# Local packages |
726
|
6
|
|
|
6
|
|
2945
|
use Symbol; # 1.0201; # Make sure we are using the new one |
|
6
|
|
|
|
|
4997
|
|
|
6
|
|
|
|
|
452
|
|
727
|
6
|
|
|
6
|
|
2851
|
use SelectSaver; # This must be *after* use Symbol 1.0201 |
|
6
|
|
|
|
|
1674
|
|
|
6
|
|
|
|
|
446
|
|
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
# Package Version |
730
|
|
|
|
|
|
|
$CGI::LogCarp::VERSION = "4.48"; |
731
|
0
|
|
|
0
|
0
|
0
|
sub VERSION () { $CGI::LogCarp::VERSION; }; |
732
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
# Constants |
734
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
736
|
|
|
|
|
|
|
|
737
|
|
|
|
|
|
|
# Compile-time initialization code |
738
|
|
|
|
|
|
|
BEGIN { |
739
|
|
|
|
|
|
|
# Save the real STDERR |
740
|
6
|
50
|
|
6
|
|
25181
|
open(main::_STDERR,'>&STDERR') or realdie(); |
741
|
|
|
|
|
|
|
#Symbol::add_global("_STDERR"); |
742
|
|
|
|
|
|
|
# Alias STDERR to ours |
743
|
|
|
|
|
|
|
#*STDERR = *main::STDERR; |
744
|
|
|
|
|
|
|
} |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
# Initialize the debug level (ON) |
747
|
|
|
|
|
|
|
$CGI::LogCarp::DEBUGLEVEL = 1; |
748
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
# Initialize the log level (ON) |
750
|
|
|
|
|
|
|
$CGI::LogCarp::LOGLEVEL = 1; |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
# Initialize fatalsToBrowser flag (OFF) |
753
|
|
|
|
|
|
|
$CGI::LogCARP::fatalsToBrowser = 0; |
754
|
|
|
|
|
|
|
# Does Lincoln Stein use this elsewhere? What's wrap and errorWrap? |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
# Initialize to default fatalsToBrowser message |
757
|
|
|
|
|
|
|
$CGI::LogCarp::CUSTOM_STDERR_MSG = undef; |
758
|
|
|
|
|
|
|
$CGI::LogCarp::CUSTOM_STDBUG_MSG = undef; |
759
|
|
|
|
|
|
|
$CGI::LogCarp::CUSTOM_STDLOG_MSG = undef; |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
# Grab Perl's signal handlers |
762
|
|
|
|
|
|
|
# Note: Do we want to stack ours on top of whatever was there? |
763
|
|
|
|
|
|
|
$main::SIG{'__WARN__'} = \&CGI::LogCarp::warn; |
764
|
|
|
|
|
|
|
$main::SIG{'__DIE__'} = \&CGI::LogCarp::die; |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
# Take over top-level definitions |
767
|
|
|
|
|
|
|
# Not sure if we need this anymore with new Symbol.pm - mak |
768
|
|
|
|
|
|
|
if ($CGI::LogCarp::STDLOG) { |
769
|
|
|
|
|
|
|
*main::logmsg = *main::logmsg = \&CGI::LogCarp::logmsg; |
770
|
|
|
|
|
|
|
} |
771
|
|
|
|
|
|
|
if ($CGI::LogCarp::STDBUG) { |
772
|
|
|
|
|
|
|
*main::debug = *main::debug = \&CGI::LogCarp::debug; |
773
|
|
|
|
|
|
|
*main::trace = *main::trace = \&CGI::LogCarp::trace; |
774
|
|
|
|
|
|
|
} |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
# Predeclare and prototype our methods |
777
|
|
|
|
|
|
|
sub stamp ($); |
778
|
|
|
|
|
|
|
sub lock (*); |
779
|
|
|
|
|
|
|
sub unlock (*); |
780
|
|
|
|
|
|
|
sub streams_are_equal (**); |
781
|
|
|
|
|
|
|
sub is_STDOUT (*); |
782
|
|
|
|
|
|
|
sub is_STDERR (*); |
783
|
|
|
|
|
|
|
sub is_STDLOG (*); |
784
|
|
|
|
|
|
|
sub is_STDBUG (*); |
785
|
|
|
|
|
|
|
sub is_realSTDERR (*); |
786
|
|
|
|
|
|
|
sub realdie (@); |
787
|
|
|
|
|
|
|
sub realwarn (@); |
788
|
|
|
|
|
|
|
sub realbug (@); |
789
|
|
|
|
|
|
|
sub reallog (@); |
790
|
|
|
|
|
|
|
sub realserverwarn (@); |
791
|
|
|
|
|
|
|
sub DEBUGLEVEL (;$); |
792
|
|
|
|
|
|
|
sub LOGLEVEL (;$); |
793
|
|
|
|
|
|
|
sub warn (@); |
794
|
|
|
|
|
|
|
sub die (@); |
795
|
|
|
|
|
|
|
sub logmsg (@); |
796
|
|
|
|
|
|
|
sub debug (@); |
797
|
|
|
|
|
|
|
sub trace (@); |
798
|
|
|
|
|
|
|
sub serverwarn (@); |
799
|
|
|
|
|
|
|
sub carp; |
800
|
|
|
|
|
|
|
sub croak; |
801
|
|
|
|
|
|
|
sub confess; |
802
|
|
|
|
|
|
|
sub cluck; |
803
|
|
|
|
|
|
|
sub carpout (;*); |
804
|
|
|
|
|
|
|
sub logmsgout (;*); |
805
|
|
|
|
|
|
|
sub debugout (;*); |
806
|
|
|
|
|
|
|
sub autoflush (*); |
807
|
|
|
|
|
|
|
sub to_filehandle; |
808
|
|
|
|
|
|
|
sub set_message; |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
# These are private aliases for various "levels" |
811
|
|
|
|
|
|
|
# Alter these to your language/dialect if you'd like |
812
|
|
|
|
|
|
|
my $NO = [ qw( no false off ) ]; |
813
|
|
|
|
|
|
|
my $YES = [ qw( yes true on ) ]; |
814
|
|
|
|
|
|
|
my $TRACE = [ qw( trace tracing ) ]; |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
=head1 PACKAGE PUBLIC METHODS |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
=head2 DEBUGLEVEL $LEVEL |
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
DEBUGLEVEL is a normal get/set method. |
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
When the scalar argument LEVEL is present, the DEBUGLEVEL will be set to LEVEL. |
825
|
|
|
|
|
|
|
LEVEL is expected to be numeric, with the following case-insensitive |
826
|
|
|
|
|
|
|
character-valued translations: |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
NO, FALSE, and OFF all equate to a value of 0 (ZERO). |
829
|
|
|
|
|
|
|
YES, TRUE, and ON all equate to a value of 1 (ONE). |
830
|
|
|
|
|
|
|
TRACE or TRACING equate to a value of 2 (TWO). |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
Values in scientific notation equate to their numeric equivalent. |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
NOTE: |
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
All other character values of LEVEL equate to 0 (ZERO). This |
837
|
|
|
|
|
|
|
will have the effect of turning off debug output. |
838
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
After this translation to a numeric value is performed, |
840
|
|
|
|
|
|
|
the DEBUGLEVEL is set to LEVEL. |
841
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
Whenever the DEBUGLEVEL is set to a non-zero value (i.e. ON or TRACE), |
843
|
|
|
|
|
|
|
the LOGLEVEL will be also set to 1 (ONE). |
844
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
The value of DEBUGLEVEL is then returned to the caller, |
846
|
|
|
|
|
|
|
whether or not LEVEL is present. |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
=cut |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
sub DEBUGLEVEL (;$) |
851
|
|
|
|
|
|
|
{ |
852
|
29
|
|
|
29
|
1
|
161
|
my ($value) = shift; |
853
|
29
|
100
|
|
|
|
56
|
if (defined $value) |
854
|
|
|
|
|
|
|
{ |
855
|
|
|
|
|
|
|
# Allow the usual non-numeric values |
856
|
3
|
50
|
|
|
|
6
|
$value = 0 if scalar grep { m/^$value$/i } @$NO; |
|
9
|
|
|
|
|
66
|
|
857
|
3
|
50
|
|
|
|
6
|
$value = 1 if scalar grep { m/^$value$/i } @$YES; |
|
9
|
|
|
|
|
40
|
|
858
|
3
|
50
|
|
|
|
16
|
$value = 2 if scalar grep { m/^$value$/i } @$TRACE; |
|
6
|
|
|
|
|
34
|
|
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
# Coerce to numeric - note scientific notation is OK |
861
|
3
|
|
|
|
|
8
|
$CGI::LogCarp::DEBUGLEVEL = 0 + $value; |
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
# Also turn on logging if we are debugging |
864
|
3
|
50
|
66
|
|
|
19
|
LOGLEVEL(1) if ($CGI::LogCarp::DEBUGLEVEL |
865
|
|
|
|
|
|
|
and not $CGI::LogCarp::LOGLEVEL); |
866
|
|
|
|
|
|
|
} |
867
|
29
|
|
|
|
|
98
|
$CGI::LogCarp::DEBUGLEVEL; |
868
|
|
|
|
|
|
|
} |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
=head2 LOGLEVEL $LEVEL |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
LOGLEVEL is a normal get/set method. |
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
When the scalar argument LEVEL is present, the LOGLEVEL will be set to LEVEL. |
877
|
|
|
|
|
|
|
LEVEL is expected to be numeric, with the following case-insensitive |
878
|
|
|
|
|
|
|
character-valued translations: |
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
NO, FALSE, and OFF all equate to a value of 0 (ZERO). |
881
|
|
|
|
|
|
|
YES, TRUE, and ON all equate to a value of 1 (ONE). |
882
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
Values in scientific notation equate to their numeric equivalent. |
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
NOTE: |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
All other character values of LEVEL equate to 0 (ZERO). This |
888
|
|
|
|
|
|
|
will have the effect of turning off log output. |
889
|
|
|
|
|
|
|
|
890
|
|
|
|
|
|
|
After this translation to a numeric value is performed, |
891
|
|
|
|
|
|
|
the LOGLEVEL is set to LEVEL. |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
The value of LOGLEVEL is then returned to the caller, |
894
|
|
|
|
|
|
|
whether or not LEVEL is present. |
895
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
=cut |
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
sub LOGLEVEL (;$) |
899
|
|
|
|
|
|
|
{ |
900
|
17
|
|
|
17
|
1
|
158
|
my ($value) = shift; |
901
|
17
|
100
|
|
|
|
35
|
if (defined $value) |
902
|
|
|
|
|
|
|
{ |
903
|
|
|
|
|
|
|
# Allow the usual non-numeric values |
904
|
3
|
50
|
|
|
|
6
|
$value = 0 if scalar grep { m/^$value$/i } @$NO; |
|
9
|
|
|
|
|
67
|
|
905
|
3
|
50
|
|
|
|
5
|
$value = 1 if scalar grep { m/^$value$/i } @$YES; |
|
9
|
|
|
|
|
41
|
|
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
# Coerce to numeric - note scientific notation is OK |
908
|
3
|
|
|
|
|
6
|
$CGI::LogCarp::LOGLEVEL = 0 + $value; |
909
|
|
|
|
|
|
|
} |
910
|
17
|
|
|
|
|
72
|
$CGI::LogCarp::LOGLEVEL; |
911
|
|
|
|
|
|
|
} |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
914
|
|
|
|
|
|
|
|
915
|
|
|
|
|
|
|
=head2 warn @message |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
This method is a replacement for Perl's builtin C. |
918
|
|
|
|
|
|
|
The message is sent to the STDERR, STDLOG, and STDBUG streams. |
919
|
|
|
|
|
|
|
|
920
|
|
|
|
|
|
|
=cut |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
sub warn (@) |
923
|
|
|
|
|
|
|
{ |
924
|
15
|
|
|
15
|
1
|
171
|
my $message = join "", @_; # Flatten the list |
925
|
15
|
|
|
|
|
46
|
my ($file,$line) = id(1); |
926
|
15
|
50
|
|
|
|
95
|
$message .= " at $file line $line.\n" unless $message =~ /\n$/; |
927
|
15
|
|
|
|
|
32
|
my $stamp = stamp "ERR"; |
928
|
15
|
|
|
|
|
76
|
$message =~ s/^/$stamp/gm; |
929
|
|
|
|
|
|
|
|
930
|
15
|
100
|
|
|
|
80
|
if ($CGI::LogCarp::STDBUG) { |
931
|
3
|
50
|
|
|
|
8
|
realbug $message unless is_STDERR \*main::STDBUG; |
932
|
|
|
|
|
|
|
} |
933
|
15
|
100
|
|
|
|
56
|
if ($CGI::LogCarp::STDLOG) { |
934
|
3
|
50
|
33
|
|
|
11
|
reallog $message unless ( |
935
|
|
|
|
|
|
|
is_STDERR(\*main::STDLOG) |
936
|
|
|
|
|
|
|
or |
937
|
|
|
|
|
|
|
is_STDBUG(\*main::STDLOG) |
938
|
|
|
|
|
|
|
); |
939
|
|
|
|
|
|
|
} |
940
|
15
|
|
|
|
|
56
|
realwarn $message; |
941
|
|
|
|
|
|
|
} |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
=head2 die @message |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
This method is a replacement for Perl's builtin C. |
948
|
|
|
|
|
|
|
The message is sent to the STDERR, STDLOG, and STDBUG streams. |
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
=cut |
951
|
|
|
|
|
|
|
|
952
|
|
|
|
|
|
|
sub die (@) |
953
|
|
|
|
|
|
|
{ |
954
|
1
|
|
|
1
|
1
|
5
|
my $message = join "", @_; # Flatten the list |
955
|
1
|
|
|
|
|
27
|
my $time = scalar localtime; |
956
|
1
|
|
|
|
|
5
|
my ($file,$line) = id(1); |
957
|
1
|
50
|
|
|
|
8
|
$message .= " at $file line $line.\n" unless $message =~ /\n$/; |
958
|
1
|
50
|
33
|
|
|
3
|
fatalsToBrowser($message) if ( |
959
|
|
|
|
|
|
|
$CGI::LogCARP::fatalsToBrowser |
960
|
|
|
|
|
|
|
and |
961
|
|
|
|
|
|
|
CGI::LogCarp::_longmess() !~ /eval [{']/m |
962
|
|
|
|
|
|
|
); |
963
|
1
|
|
|
|
|
3
|
my $stamp = stamp "ERR"; |
964
|
1
|
|
|
|
|
5
|
$message =~ s/^/$stamp/gm; |
965
|
|
|
|
|
|
|
|
966
|
1
|
50
|
|
|
|
4
|
if ($CGI::LogCarp::STDBUG) { |
967
|
0
|
0
|
|
|
|
0
|
realbug $message unless is_STDERR \*main::STDBUG; |
968
|
|
|
|
|
|
|
} |
969
|
1
|
50
|
|
|
|
3
|
if ($CGI::LogCarp::STDLOG) { |
970
|
0
|
0
|
0
|
|
|
0
|
reallog $message unless ( |
971
|
|
|
|
|
|
|
is_STDERR(\*main::STDLOG) |
972
|
|
|
|
|
|
|
or |
973
|
|
|
|
|
|
|
is_STDBUG(\*main::STDLOG) |
974
|
|
|
|
|
|
|
); |
975
|
|
|
|
|
|
|
} |
976
|
1
|
|
|
|
|
3
|
realdie $message; |
977
|
|
|
|
|
|
|
} |
978
|
|
|
|
|
|
|
|
979
|
|
|
|
|
|
|
# The mod_perl package Apache::Registry loads CGI programs by calling eval. |
980
|
|
|
|
|
|
|
# These evals don't count when looking at the stack backtrace. |
981
|
|
|
|
|
|
|
# I've also allowed Netscape::Registry this functionality. |
982
|
|
|
|
|
|
|
# You're welcome, Ben Sugars, nsapi_perl author. :) |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
sub _longmess { |
985
|
0
|
|
|
0
|
|
0
|
my $message = Carp::longmess(); |
986
|
|
|
|
|
|
|
my $mod_perl = ( |
987
|
|
|
|
|
|
|
$ENV{'GATEWAY_INTERFACE'} |
988
|
|
|
|
|
|
|
and |
989
|
0
|
|
0
|
|
|
0
|
$ENV{'GATEWAY_INTERFACE'} =~ /^CGI-Perl\// |
990
|
|
|
|
|
|
|
); |
991
|
0
|
0
|
|
|
|
0
|
$message =~ s,eval[^\n]+(Apache|Netscape)/Registry\.pm.*,,s if $mod_perl; |
992
|
0
|
|
|
|
|
0
|
return( $message ); |
993
|
|
|
|
|
|
|
} |
994
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
996
|
|
|
|
|
|
|
|
997
|
|
|
|
|
|
|
# Take over carp(), croak(), confess(), and cluck(); |
998
|
|
|
|
|
|
|
# We never imported them from Carp, so we're ok |
999
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
=head2 carp @message |
1001
|
|
|
|
|
|
|
|
1002
|
|
|
|
|
|
|
This method is a replacement for C. |
1003
|
|
|
|
|
|
|
The message is sent to the STDERR, STDLOG, and STDBUG streams. |
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
# mak - this fixes a problem when you passed Carp::carp a list |
1006
|
|
|
|
|
|
|
# like the documentation says ( shortmess uses $_[0] and not @_ ). |
1007
|
|
|
|
|
|
|
# This has been fixed in later (post-1997) versions of Carp.pm. |
1008
|
|
|
|
|
|
|
# Since Carp.pm has no version, I can't tell which one you have. |
1009
|
|
|
|
|
|
|
|
1010
|
|
|
|
|
|
|
=cut |
1011
|
|
|
|
|
|
|
|
1012
|
|
|
|
|
|
|
sub carp |
1013
|
|
|
|
|
|
|
{ |
1014
|
1
|
|
|
1
|
1
|
315
|
CGI::LogCarp::warn( Carp::shortmess(join("",@_)) ); |
1015
|
|
|
|
|
|
|
} |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
=head2 croak @message |
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
This method is a replacement for C. |
1020
|
|
|
|
|
|
|
The message is sent to the STDERR, STDLOG, and STDBUG streams. |
1021
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
# mak - this fixes a problem when you passed Carp::croak a list |
1023
|
|
|
|
|
|
|
# like the documentation says ( shortmess uses $_[0] and not @_ ). |
1024
|
|
|
|
|
|
|
# This has been fixed in later (post-1997) versions of Carp.pm. |
1025
|
|
|
|
|
|
|
# Since Carp.pm has no version, I can't tell which one you have. |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
=cut |
1028
|
|
|
|
|
|
|
|
1029
|
|
|
|
|
|
|
sub croak |
1030
|
|
|
|
|
|
|
{ |
1031
|
1
|
|
|
1
|
1
|
217
|
CGI::LogCarp::die( Carp::shortmess(join("",@_)) ); |
1032
|
|
|
|
|
|
|
} |
1033
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
=head2 confess @message |
1035
|
|
|
|
|
|
|
|
1036
|
|
|
|
|
|
|
This method is a replacement for C. |
1037
|
|
|
|
|
|
|
The message is sent to the STDERR, STDLOG, and STDBUG streams. |
1038
|
|
|
|
|
|
|
|
1039
|
|
|
|
|
|
|
=cut |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
sub confess |
1042
|
|
|
|
|
|
|
{ |
1043
|
0
|
|
|
0
|
1
|
0
|
CGI::LogCarp::die( Carp::longmess(join("",@_)) ); |
1044
|
|
|
|
|
|
|
} |
1045
|
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
=head2 cluck @message |
1047
|
|
|
|
|
|
|
|
1048
|
|
|
|
|
|
|
This method is a replacement for C. |
1049
|
|
|
|
|
|
|
The message is sent to the STDERR, STDLOG, and STDBUG streams. |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
=cut |
1052
|
|
|
|
|
|
|
|
1053
|
|
|
|
|
|
|
sub cluck |
1054
|
|
|
|
|
|
|
{ |
1055
|
0
|
|
|
0
|
1
|
0
|
CGI::LogCarp::warn( Carp::longmess(join("",@_)) ); |
1056
|
|
|
|
|
|
|
} |
1057
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
=head2 set_message $message |
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
=head2 set_message FILEHANDLE $message |
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
This method is a replacement for the CGI::Carp method of the same name. |
1063
|
|
|
|
|
|
|
It defines the message format for the STDERR stream if FILEHANDLE is |
1064
|
|
|
|
|
|
|
not specified. FILEHANDLE specifies which stream is having its message |
1065
|
|
|
|
|
|
|
redefined. C<$message> is typically a reference to a subroutine. |
1066
|
|
|
|
|
|
|
|
1067
|
|
|
|
|
|
|
=cut |
1068
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
sub set_message |
1070
|
|
|
|
|
|
|
{ |
1071
|
0
|
|
|
0
|
1
|
0
|
my $message = shift; |
1072
|
|
|
|
|
|
|
# CGI::Carp compatibility |
1073
|
0
|
0
|
|
|
|
0
|
unless (scalar @_) { |
1074
|
0
|
|
|
|
|
0
|
$CGI::LogCarp::CUSTOM_STDERR_MSG = $message; |
1075
|
0
|
|
|
|
|
0
|
return $message; |
1076
|
|
|
|
|
|
|
} |
1077
|
|
|
|
|
|
|
|
1078
|
0
|
|
|
|
|
0
|
my $fh = $message; |
1079
|
0
|
|
|
|
|
0
|
$message = shift; |
1080
|
0
|
0
|
|
|
|
0
|
if (is_STDERR $fh) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1081
|
0
|
|
|
|
|
0
|
$CGI::LogCarp::CUSTOM_STDERR_MSG = $message; |
1082
|
|
|
|
|
|
|
} elsif (is_STDLOG $fh) { |
1083
|
0
|
|
|
|
|
0
|
$CGI::LogCarp::CUSTOM_STDLOG_MSG = $message; |
1084
|
|
|
|
|
|
|
} elsif (is_STDBUG $fh) { |
1085
|
0
|
|
|
|
|
0
|
$CGI::LogCarp::CUSTOM_STDBUG_MSG = $message; |
1086
|
|
|
|
|
|
|
} |
1087
|
0
|
|
|
|
|
0
|
return $message; |
1088
|
|
|
|
|
|
|
} |
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1091
|
|
|
|
|
|
|
|
1092
|
|
|
|
|
|
|
=head2 logmsg @message |
1093
|
|
|
|
|
|
|
|
1094
|
|
|
|
|
|
|
This method operates similarly to the C method. |
1095
|
|
|
|
|
|
|
The message is sent to the STDLOG and STDBUG streams. |
1096
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
=cut |
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
sub logmsg (@) |
1100
|
|
|
|
|
|
|
{ |
1101
|
4
|
|
|
4
|
1
|
19
|
my $message = join "", @_; # Flatten the list |
1102
|
4
|
|
|
|
|
10
|
my ($file,$line) = id(1); |
1103
|
4
|
50
|
|
|
|
18
|
$message .= " at $file line $line.\n" unless $message =~ /\n$/; |
1104
|
4
|
|
|
|
|
10
|
my $stamp = stamp "LOG"; |
1105
|
4
|
|
|
|
|
20
|
$message =~ s/^/$stamp/gm; |
1106
|
|
|
|
|
|
|
|
1107
|
4
|
50
|
|
|
|
11
|
if ($CGI::LogCarp::STDBUG) { |
1108
|
0
|
0
|
|
|
|
0
|
realbug $message unless is_STDLOG \*main::STDBUG; |
1109
|
|
|
|
|
|
|
} |
1110
|
4
|
|
|
|
|
10
|
reallog $message; |
1111
|
|
|
|
|
|
|
} |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1114
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
=head2 debug @message |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
This method operates similarly to the C method. |
1118
|
|
|
|
|
|
|
The message is sent to the STDBUG stream when DEBUGLEVEL > 0. |
1119
|
|
|
|
|
|
|
|
1120
|
|
|
|
|
|
|
=cut |
1121
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
sub debug (@) |
1123
|
|
|
|
|
|
|
{ |
1124
|
4
|
100
|
|
4
|
1
|
8
|
return unless DEBUGLEVEL > 0; |
1125
|
3
|
|
|
|
|
8
|
my $message = join "", @_; # Flatten the list |
1126
|
3
|
|
|
|
|
7
|
my ($file,$line) = id(1); |
1127
|
3
|
50
|
|
|
|
14
|
$message .= " at $file line $line.\n" unless $message =~ /\n$/; |
1128
|
3
|
|
|
|
|
6
|
my $stamp = stamp "BUG"; |
1129
|
3
|
|
|
|
|
16
|
$message =~ s/^/$stamp/gm; |
1130
|
|
|
|
|
|
|
|
1131
|
3
|
|
|
|
|
8
|
realbug $message; |
1132
|
|
|
|
|
|
|
} |
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1135
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
=head2 trace @message |
1137
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
This method operates similarly to the C method. |
1139
|
|
|
|
|
|
|
The message is sent to the STDBUG stream |
1140
|
|
|
|
|
|
|
when DEBUGLEVEL is greater than one. |
1141
|
|
|
|
|
|
|
|
1142
|
|
|
|
|
|
|
=cut |
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
sub trace (@) |
1145
|
|
|
|
|
|
|
{ |
1146
|
4
|
100
|
|
4
|
1
|
8
|
return unless DEBUGLEVEL > 1; |
1147
|
1
|
|
|
|
|
3
|
my $message = join "", @_; # Flatten the list |
1148
|
1
|
|
|
|
|
3
|
my ($file,$line) = id(1); |
1149
|
1
|
50
|
|
|
|
6
|
$message .= " at $file line $line.\n" unless $message =~ /\n$/; |
1150
|
1
|
|
|
|
|
3
|
my $stamp = stamp "TRC"; |
1151
|
1
|
|
|
|
|
5
|
$message =~ s/^/$stamp/gm; |
1152
|
|
|
|
|
|
|
|
1153
|
1
|
|
|
|
|
3
|
realbug $message; |
1154
|
|
|
|
|
|
|
} |
1155
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1157
|
|
|
|
|
|
|
|
1158
|
|
|
|
|
|
|
=head2 serverwarn @message |
1159
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
This method operates similarly to the C method. |
1161
|
|
|
|
|
|
|
The message is sent to the STDBUG, STDLOG, STDERR and _STDERR streams. |
1162
|
|
|
|
|
|
|
The _STDERR stream is typically is sent to a webserver's error log |
1163
|
|
|
|
|
|
|
if used in a CGI program. |
1164
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
=cut |
1166
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
sub serverwarn (@) |
1168
|
|
|
|
|
|
|
{ |
1169
|
0
|
|
|
0
|
1
|
0
|
my $message = join "", @_; # Flatten the list |
1170
|
0
|
|
|
|
|
0
|
my ($file,$line) = id(1); |
1171
|
0
|
0
|
|
|
|
0
|
$message .= " at $file line $line.\n" unless $message =~ /\n$/; |
1172
|
0
|
|
|
|
|
0
|
my $stamp = stamp "SRV"; |
1173
|
0
|
|
|
|
|
0
|
$message =~ s/^/$stamp/gm; |
1174
|
|
|
|
|
|
|
|
1175
|
0
|
0
|
|
|
|
0
|
if ($CGI::LogCarp::STDBUG) { |
1176
|
0
|
0
|
0
|
|
|
0
|
realbug $message unless ( |
1177
|
|
|
|
|
|
|
is_STDERR(\*main::STDBUG) |
1178
|
|
|
|
|
|
|
or |
1179
|
|
|
|
|
|
|
is_realSTDERR(\*main::STDBUG) |
1180
|
|
|
|
|
|
|
); |
1181
|
|
|
|
|
|
|
} |
1182
|
0
|
0
|
|
|
|
0
|
if ($CGI::LogCarp::STDLOG) { |
1183
|
0
|
0
|
0
|
|
|
0
|
reallog $message unless ( |
|
|
|
0
|
|
|
|
|
1184
|
|
|
|
|
|
|
is_STDERR(\*main::STDLOG) |
1185
|
|
|
|
|
|
|
or |
1186
|
|
|
|
|
|
|
is_STDBUG(\*main::STDLOG) |
1187
|
|
|
|
|
|
|
or |
1188
|
|
|
|
|
|
|
is_realSTDERR(\*main::STDLOG) |
1189
|
|
|
|
|
|
|
); |
1190
|
|
|
|
|
|
|
} |
1191
|
0
|
0
|
|
|
|
0
|
realwarn $message unless is_realSTDERR \*STDERR; |
1192
|
0
|
|
|
|
|
0
|
realserverwarn $message; |
1193
|
|
|
|
|
|
|
} |
1194
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1196
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
=head2 carpout FILEHANDLE |
1198
|
|
|
|
|
|
|
|
1199
|
|
|
|
|
|
|
A method to redirect the STDERR stream to the given FILEHANDLE. |
1200
|
|
|
|
|
|
|
It accepts FILEHANDLE as a reference or a string. |
1201
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
See the section on B |
1203
|
|
|
|
|
|
|
and the section on B. |
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
=cut |
1206
|
|
|
|
|
|
|
|
1207
|
|
|
|
|
|
|
sub carpout (;*) |
1208
|
|
|
|
|
|
|
{ |
1209
|
6
|
|
100
|
6
|
1
|
600
|
my ($fh) = shift || \*STDERR; |
1210
|
6
|
50
|
|
|
|
27
|
$fh = to_filehandle($fh) or realdie "Invalid filehandle $fh\n"; |
1211
|
6
|
100
|
|
|
|
21
|
if (is_STDERR $fh) { |
1212
|
1
|
50
|
|
|
|
25
|
open(STDERR,'>&main::_STDERR') |
1213
|
|
|
|
|
|
|
or realdie "Unable to redirect STDERR: $!\n"; |
1214
|
|
|
|
|
|
|
} else { |
1215
|
5
|
50
|
|
|
|
21
|
my $no = fileno($fh) or realdie "Invalid filehandle $fh\n"; |
1216
|
5
|
50
|
|
|
|
136
|
open(STDERR,'>&'.$no) |
1217
|
|
|
|
|
|
|
or realdie "Unable to redirect STDERR: $!\n"; |
1218
|
|
|
|
|
|
|
} |
1219
|
6
|
|
|
|
|
40
|
autoflush \*STDERR; |
1220
|
6
|
|
|
|
|
58
|
\*STDERR; |
1221
|
|
|
|
|
|
|
} |
1222
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1224
|
|
|
|
|
|
|
|
1225
|
|
|
|
|
|
|
=head2 logmsgout FILEHANDLE |
1226
|
|
|
|
|
|
|
|
1227
|
|
|
|
|
|
|
A method to redirect the STDLOG stream to the given FILEHANDLE. |
1228
|
|
|
|
|
|
|
It accepts FILEHANDLE as a reference or a string. |
1229
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
See the section on B |
1231
|
|
|
|
|
|
|
and the section on B. |
1232
|
|
|
|
|
|
|
|
1233
|
|
|
|
|
|
|
=cut |
1234
|
|
|
|
|
|
|
|
1235
|
|
|
|
|
|
|
sub logmsgout (;*) |
1236
|
|
|
|
|
|
|
{ |
1237
|
2
|
|
100
|
2
|
1
|
260
|
my ($fh) = shift || \*main::STDLOG; |
1238
|
2
|
50
|
|
|
|
11
|
$fh = to_filehandle($fh) or realdie "Invalid filehandle $fh\n"; |
1239
|
2
|
100
|
|
|
|
7
|
if (is_STDLOG $fh) { |
1240
|
1
|
50
|
|
|
|
32
|
open(main::STDLOG,'>&main::_STDERR') |
1241
|
|
|
|
|
|
|
or realdie "Unable to redirect STDLOG: $!\n"; |
1242
|
|
|
|
|
|
|
} else { |
1243
|
1
|
50
|
|
|
|
5
|
my $no = fileno($fh) or realdie "Invalid filehandle $fh\n"; |
1244
|
1
|
50
|
|
|
|
31
|
open(main::STDLOG,'>&'.$no) |
1245
|
|
|
|
|
|
|
or realdie "Unable to redirect STDLOG: $!\n"; |
1246
|
|
|
|
|
|
|
} |
1247
|
2
|
|
|
|
|
9
|
autoflush \*main::STDLOG; |
1248
|
2
|
|
|
|
|
21
|
\*main::STDLOG; |
1249
|
|
|
|
|
|
|
} |
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1252
|
|
|
|
|
|
|
|
1253
|
|
|
|
|
|
|
=head2 debugout FILEHANDLE |
1254
|
|
|
|
|
|
|
|
1255
|
|
|
|
|
|
|
A method to redirect the STDBUG stream to the given FILEHANDLE. |
1256
|
|
|
|
|
|
|
It accepts FILEHANDLE as a reference or a string. |
1257
|
|
|
|
|
|
|
|
1258
|
|
|
|
|
|
|
See the section on B |
1259
|
|
|
|
|
|
|
and the section on B. |
1260
|
|
|
|
|
|
|
|
1261
|
|
|
|
|
|
|
=cut |
1262
|
|
|
|
|
|
|
|
1263
|
|
|
|
|
|
|
sub debugout (;*) |
1264
|
|
|
|
|
|
|
{ |
1265
|
2
|
|
100
|
2
|
1
|
232
|
my ($fh) = shift || \*main::STDBUG; |
1266
|
2
|
50
|
|
|
|
11
|
$fh = to_filehandle($fh) or realdie "Invalid filehandle $fh\n"; |
1267
|
2
|
100
|
|
|
|
4
|
if (is_STDBUG $fh) { |
1268
|
1
|
50
|
|
|
|
31
|
open(main::STDBUG,'>&STDOUT') |
1269
|
|
|
|
|
|
|
or realdie "Unable to redirect STDBUG: $!\n"; |
1270
|
|
|
|
|
|
|
} else { |
1271
|
1
|
50
|
|
|
|
4
|
my $no = fileno($fh) or realdie "Invalid filehandle $fh\n"; |
1272
|
1
|
50
|
|
|
|
27
|
open(main::STDBUG,'>&'.$no) |
1273
|
|
|
|
|
|
|
or realdie "Unable to redirect STDBUG: $!\n"; |
1274
|
|
|
|
|
|
|
} |
1275
|
2
|
|
|
|
|
9
|
autoflush \*main::STDBUG; |
1276
|
2
|
|
|
|
|
18
|
\*main::STDBUG; |
1277
|
|
|
|
|
|
|
} |
1278
|
|
|
|
|
|
|
|
1279
|
|
|
|
|
|
|
sub fatalsToBrowser |
1280
|
|
|
|
|
|
|
{ |
1281
|
0
|
|
|
0
|
1
|
0
|
my ($msg) = @_; |
1282
|
0
|
|
|
|
|
0
|
$msg =~ s/&/&/gs; |
1283
|
0
|
|
|
|
|
0
|
$msg =~ s/>/>/gs; |
1284
|
0
|
|
|
|
|
0
|
$msg =~ s/</gs; |
1285
|
0
|
|
|
|
|
0
|
$msg =~ s/\"/"/gs; |
1286
|
0
|
0
|
|
|
|
0
|
my ($wm) = $ENV{'SERVER_ADMIN'} ? |
1287
|
|
|
|
|
|
|
qq[the webmaster ($ENV{'SERVER_ADMIN'})] : |
1288
|
|
|
|
|
|
|
"this site's webmaster"; |
1289
|
0
|
|
|
|
|
0
|
my ($outer_message) = <
|
1290
|
|
|
|
|
|
|
For help, please send mail to $wm, giving this error message |
1291
|
|
|
|
|
|
|
and the time and date of the error. |
1292
|
|
|
|
|
|
|
END |
1293
|
|
|
|
|
|
|
|
1294
|
0
|
|
|
|
|
0
|
print STDOUT "Content-type: text/html\013\010"; |
1295
|
0
|
0
|
|
|
|
0
|
if ($CGI::LogCarp::CUSTOM_STDERR_MSG) { |
1296
|
0
|
0
|
|
|
|
0
|
if (ref($CGI::LogCarp::CUSTOM_STDERR_MSG) eq "CODE") { |
1297
|
0
|
|
|
|
|
0
|
print STDOUT &{$CGI::LogCarp::CUSTOM_STDERR_MSG}($msg); |
|
0
|
|
|
|
|
0
|
|
1298
|
0
|
|
|
|
|
0
|
return; |
1299
|
|
|
|
|
|
|
} else { |
1300
|
0
|
|
|
|
|
0
|
$outer_message = $CGI::LogCarp::CUSTOM_STDERR_MSG; |
1301
|
|
|
|
|
|
|
} |
1302
|
|
|
|
|
|
|
} |
1303
|
0
|
|
|
|
|
0
|
print STDOUT <
|
1304
|
|
|
|
|
|
|
Software Error: |
1305
|
|
|
|
|
|
|
$msg |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
$outer_message |
1308
|
|
|
|
|
|
|
END |
1309
|
|
|
|
|
|
|
|
1310
|
|
|
|
|
|
|
} |
1311
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
# --- END OF PAGE ---#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1313
|
|
|
|
|
|
|
|
1314
|
|
|
|
|
|
|
=head2 to_filehandle EXPR |
1315
|
|
|
|
|
|
|
|
1316
|
|
|
|
|
|
|
Borrowed directly from CGI.pm by Lincoln Stein. |
1317
|
|
|
|
|
|
|
It converts EXPR to a filehandle. |
1318
|
|
|
|
|
|
|
|
1319
|
|
|
|
|
|
|
=cut |
1320
|
|
|
|
|
|
|
|
1321
|
|
|
|
|
|
|
sub to_filehandle |
1322
|
|
|
|
|
|
|
{ |
1323
|
120
|
|
|
120
|
1
|
168
|
my ($thingy) = shift; |
1324
|
120
|
50
|
|
|
|
230
|
return undef unless $thingy; |
1325
|
120
|
50
|
|
|
|
443
|
return $thingy if UNIVERSAL::isa($thingy,'GLOB'); |
1326
|
0
|
0
|
|
|
|
0
|
return $thingy if UNIVERSAL::isa($thingy,'FileHandle'); |
1327
|
0
|
0
|
|
|
|
0
|
if (!ref($thingy)) { |
1328
|
0
|
|
|
|
|
0
|
my $caller = 1; |
1329
|
0
|
|
|
|
|
0
|
while (my $package = caller($caller++)) { |
1330
|
0
|
0
|
|
|
|
0
|
my ($tmp) = $thingy =~ m/[\':]/ ? $thingy : "$package\:\:$thingy"; |
1331
|
0
|
0
|
|
|
|
0
|
return $tmp if defined fileno($tmp); |
1332
|
|
|
|
|
|
|
} |
1333
|
|
|
|
|
|
|
} |
1334
|
0
|
|
|
|
|
0
|
return undef; |
1335
|
|
|
|
|
|
|
} |
1336
|
|
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
=head2 is_STDOUT FILEHANDLE |
1338
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
This method compares FILEHANDLE with the STDOUT stream |
1340
|
|
|
|
|
|
|
and returns the boolean result. |
1341
|
|
|
|
|
|
|
|
1342
|
|
|
|
|
|
|
This method is not exported by default. |
1343
|
|
|
|
|
|
|
|
1344
|
|
|
|
|
|
|
=cut |
1345
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
sub is_STDOUT (*) |
1347
|
|
|
|
|
|
|
{ |
1348
|
0
|
|
|
0
|
1
|
0
|
my ($stream) = shift; |
1349
|
0
|
|
|
|
|
0
|
streams_are_equal $stream, \*STDOUT; |
1350
|
|
|
|
|
|
|
} |
1351
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
=head2 is_STDERR FILEHANDLE |
1353
|
|
|
|
|
|
|
|
1354
|
|
|
|
|
|
|
This method compares FILEHANDLE with the STDERR stream |
1355
|
|
|
|
|
|
|
and returns the boolean result. |
1356
|
|
|
|
|
|
|
|
1357
|
|
|
|
|
|
|
This method is not exported by default. |
1358
|
|
|
|
|
|
|
|
1359
|
|
|
|
|
|
|
=cut |
1360
|
|
|
|
|
|
|
|
1361
|
|
|
|
|
|
|
sub is_STDERR (*) |
1362
|
|
|
|
|
|
|
{ |
1363
|
12
|
|
|
12
|
1
|
20
|
my ($stream) = shift; |
1364
|
12
|
|
|
|
|
28
|
streams_are_equal $stream, \*STDERR; |
1365
|
|
|
|
|
|
|
} |
1366
|
|
|
|
|
|
|
|
1367
|
|
|
|
|
|
|
=head2 is_STDBUG FILEHANDLE |
1368
|
|
|
|
|
|
|
|
1369
|
|
|
|
|
|
|
This method compares FILEHANDLE with the STDBUG stream |
1370
|
|
|
|
|
|
|
and returns the boolean result. |
1371
|
|
|
|
|
|
|
|
1372
|
|
|
|
|
|
|
This method is not exported by default. |
1373
|
|
|
|
|
|
|
|
1374
|
|
|
|
|
|
|
=cut |
1375
|
|
|
|
|
|
|
|
1376
|
|
|
|
|
|
|
sub is_STDBUG (*) |
1377
|
|
|
|
|
|
|
{ |
1378
|
5
|
|
|
5
|
1
|
12
|
my ($stream) = shift; |
1379
|
5
|
|
|
|
|
12
|
streams_are_equal $stream, \*main::STDBUG; |
1380
|
|
|
|
|
|
|
} |
1381
|
|
|
|
|
|
|
|
1382
|
|
|
|
|
|
|
=head2 is_STDLOG FILEHANDLE |
1383
|
|
|
|
|
|
|
|
1384
|
|
|
|
|
|
|
This method compares FILEHANDLE with the STDLOG stream |
1385
|
|
|
|
|
|
|
and returns the boolean result. |
1386
|
|
|
|
|
|
|
|
1387
|
|
|
|
|
|
|
This method is not exported by default. |
1388
|
|
|
|
|
|
|
|
1389
|
|
|
|
|
|
|
=cut |
1390
|
|
|
|
|
|
|
|
1391
|
|
|
|
|
|
|
sub is_STDLOG (*) |
1392
|
|
|
|
|
|
|
{ |
1393
|
2
|
|
|
2
|
1
|
4
|
my ($stream) = shift; |
1394
|
2
|
|
|
|
|
5
|
streams_are_equal $stream, \*main::STDLOG; |
1395
|
|
|
|
|
|
|
} |
1396
|
|
|
|
|
|
|
|
1397
|
|
|
|
|
|
|
=head2 is_realSTDERR FILEHANDLE |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
This method compares FILEHANDLE with the _STDERR stream |
1400
|
|
|
|
|
|
|
and returns the boolean result. |
1401
|
|
|
|
|
|
|
|
1402
|
|
|
|
|
|
|
This method is not exported by default. |
1403
|
|
|
|
|
|
|
|
1404
|
|
|
|
|
|
|
=cut |
1405
|
|
|
|
|
|
|
|
1406
|
|
|
|
|
|
|
sub is_realSTDERR (*) |
1407
|
|
|
|
|
|
|
{ |
1408
|
0
|
|
|
0
|
1
|
0
|
my ($stream) = shift; |
1409
|
0
|
|
|
|
|
0
|
streams_are_equal $stream, \*main::_STDERR; |
1410
|
|
|
|
|
|
|
} |
1411
|
|
|
|
|
|
|
|
1412
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1413
|
|
|
|
|
|
|
|
1414
|
|
|
|
|
|
|
=head1 PRIVATE METHODS |
1415
|
|
|
|
|
|
|
|
1416
|
|
|
|
|
|
|
=cut |
1417
|
|
|
|
|
|
|
|
1418
|
|
|
|
|
|
|
# Locks are fine grained |
1419
|
|
|
|
|
|
|
# Do we need a higher level lock/unlock around a block of messages? |
1420
|
|
|
|
|
|
|
# e.g.: lock \*STDLOG; iterated_log_writes @lines; unlock \*STDLOG; |
1421
|
|
|
|
|
|
|
|
1422
|
|
|
|
|
|
|
# These are the originals |
1423
|
|
|
|
|
|
|
|
1424
|
|
|
|
|
|
|
=head2 realwarn @MESSAGE |
1425
|
|
|
|
|
|
|
|
1426
|
|
|
|
|
|
|
This private method encapsulates Perl's underlying C method, |
1427
|
|
|
|
|
|
|
actually producing the message on the STDERR stream. |
1428
|
|
|
|
|
|
|
Locking is performed to ensure exclusive access while appending. |
1429
|
|
|
|
|
|
|
|
1430
|
|
|
|
|
|
|
This method is not exportable. |
1431
|
|
|
|
|
|
|
|
1432
|
|
|
|
|
|
|
=cut |
1433
|
|
|
|
|
|
|
|
1434
|
|
|
|
|
|
|
sub realwarn (@) |
1435
|
|
|
|
|
|
|
{ |
1436
|
15
|
|
|
15
|
1
|
80
|
my $msg = join("",@_); |
1437
|
15
|
50
|
|
|
|
34
|
if ($CGI::LogCarp::CUSTOM_STDERR_MSG) { |
1438
|
0
|
0
|
|
|
|
0
|
if (ref($CGI::LogCarp::CUSTOM_STDERR_MSG) eq "CODE") { |
1439
|
0
|
|
|
|
|
0
|
$msg = &{$CGI::LogCarp::CUSTOM_STDERR_MSG}($msg); |
|
0
|
|
|
|
|
0
|
|
1440
|
|
|
|
|
|
|
} |
1441
|
|
|
|
|
|
|
} |
1442
|
15
|
|
|
|
|
63
|
lock \*STDERR; |
1443
|
15
|
|
|
|
|
37
|
print { \*STDERR } $msg; |
|
15
|
|
|
|
|
1642
|
|
1444
|
15
|
|
|
|
|
74
|
unlock \*STDERR; |
1445
|
|
|
|
|
|
|
} |
1446
|
|
|
|
|
|
|
|
1447
|
|
|
|
|
|
|
=head2 realdie @MESSAGE |
1448
|
|
|
|
|
|
|
|
1449
|
|
|
|
|
|
|
This private method encapsulates Perl's underlying C method, |
1450
|
|
|
|
|
|
|
actually producing the message on the STDERR stream and then terminating |
1451
|
|
|
|
|
|
|
execution. |
1452
|
|
|
|
|
|
|
Locking is performed to ensure exclusive access while appending. |
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
This method is not exportable. |
1455
|
|
|
|
|
|
|
|
1456
|
|
|
|
|
|
|
=cut |
1457
|
|
|
|
|
|
|
|
1458
|
|
|
|
|
|
|
sub realdie (@) |
1459
|
|
|
|
|
|
|
{ |
1460
|
1
|
|
|
1
|
1
|
12
|
my $msg = join("",@_); |
1461
|
1
|
50
|
|
|
|
3
|
if ($CGI::LogCarp::CUSTOM_STDERR_MSG) { |
1462
|
0
|
0
|
|
|
|
0
|
if (ref($CGI::LogCarp::CUSTOM_STDERR_MSG) eq "CODE") { |
1463
|
0
|
|
|
|
|
0
|
$msg = &{$CGI::LogCarp::CUSTOM_STDERR_MSG}($msg); |
|
0
|
|
|
|
|
0
|
|
1464
|
|
|
|
|
|
|
} |
1465
|
|
|
|
|
|
|
} |
1466
|
1
|
|
|
|
|
4
|
lock \*STDERR; |
1467
|
1
|
|
|
|
|
3
|
print { \*STDERR } $msg; |
|
1
|
|
|
|
|
15
|
|
1468
|
1
|
|
|
|
|
5
|
unlock \*STDERR; |
1469
|
1
|
|
|
|
|
11
|
CORE::die $msg; # This still goes to the original STDERR ... why? |
1470
|
|
|
|
|
|
|
# my perl is 5.004_01 on BSD/OS 2.1 if that helps anyone |
1471
|
|
|
|
|
|
|
} |
1472
|
|
|
|
|
|
|
|
1473
|
|
|
|
|
|
|
# The OS *should* unlock the stream as the process ends, but ... |
1474
|
6
|
|
|
6
|
|
513
|
END { unlock \*STDERR; } |
1475
|
|
|
|
|
|
|
|
1476
|
|
|
|
|
|
|
=head2 reallog @MESSAGE |
1477
|
|
|
|
|
|
|
|
1478
|
|
|
|
|
|
|
This private method synthesizes an underlying C method, |
1479
|
|
|
|
|
|
|
actually producing the message on the STDLOG stream. |
1480
|
|
|
|
|
|
|
Locking is performed to ensure exclusive access while appending. |
1481
|
|
|
|
|
|
|
The message will only be sent when LOGLEVEL is greater than zero. |
1482
|
|
|
|
|
|
|
|
1483
|
|
|
|
|
|
|
This method is not exportable. |
1484
|
|
|
|
|
|
|
|
1485
|
|
|
|
|
|
|
=cut |
1486
|
|
|
|
|
|
|
|
1487
|
|
|
|
|
|
|
sub reallog (@) |
1488
|
|
|
|
|
|
|
{ |
1489
|
7
|
100
|
|
7
|
1
|
30
|
return unless LOGLEVEL > 0; |
1490
|
5
|
|
|
|
|
14
|
my $msg = join("",@_); |
1491
|
5
|
50
|
|
|
|
12
|
if ($CGI::LogCarp::CUSTOM_STDLOG_MSG) { |
1492
|
0
|
0
|
|
|
|
0
|
if (ref($CGI::LogCarp::CUSTOM_STDLOG_MSG) eq "CODE") { |
1493
|
0
|
|
|
|
|
0
|
$msg = &{$CGI::LogCarp::CUSTOM_STDLOG_MSG}($msg); |
|
0
|
|
|
|
|
0
|
|
1494
|
|
|
|
|
|
|
} |
1495
|
|
|
|
|
|
|
} |
1496
|
5
|
|
|
|
|
14
|
lock \*main::STDLOG; |
1497
|
5
|
|
|
|
|
11
|
print { \*main::STDLOG } $msg; |
|
5
|
|
|
|
|
109
|
|
1498
|
5
|
|
|
|
|
21
|
unlock \*main::STDLOG; |
1499
|
|
|
|
|
|
|
} |
1500
|
|
|
|
|
|
|
|
1501
|
|
|
|
|
|
|
=head2 realbug @message |
1502
|
|
|
|
|
|
|
|
1503
|
|
|
|
|
|
|
This private method synthesizes an underlying C method, |
1504
|
|
|
|
|
|
|
actually producing the message on the STDBUG stream. |
1505
|
|
|
|
|
|
|
Locking is performed to ensure exclusive access while appending. |
1506
|
|
|
|
|
|
|
The message will only be sent when DEBUGLEVEL is greater than zero. |
1507
|
|
|
|
|
|
|
|
1508
|
|
|
|
|
|
|
This method is not exportable. |
1509
|
|
|
|
|
|
|
|
1510
|
|
|
|
|
|
|
=cut |
1511
|
|
|
|
|
|
|
|
1512
|
|
|
|
|
|
|
sub realbug (@) |
1513
|
|
|
|
|
|
|
{ |
1514
|
7
|
100
|
|
7
|
1
|
13
|
return unless DEBUGLEVEL > 0; |
1515
|
6
|
|
|
|
|
15
|
my $msg = join("",@_); |
1516
|
6
|
50
|
|
|
|
13
|
if ($CGI::LogCarp::CUSTOM_STDBUG_MSG) { |
1517
|
0
|
0
|
|
|
|
0
|
if (ref($CGI::LogCarp::CUSTOM_STDBUG_MSG) eq "CODE") { |
1518
|
0
|
|
|
|
|
0
|
$msg = &{$CGI::LogCarp::CUSTOM_STDBUG_MSG}($msg); |
|
0
|
|
|
|
|
0
|
|
1519
|
|
|
|
|
|
|
} |
1520
|
|
|
|
|
|
|
} |
1521
|
6
|
|
|
|
|
17
|
lock \*main::STDBUG; |
1522
|
6
|
|
|
|
|
12
|
print { \*main::STDBUG } $msg; |
|
6
|
|
|
|
|
114
|
|
1523
|
6
|
|
|
|
|
25
|
unlock \*main::STDBUG; |
1524
|
|
|
|
|
|
|
} |
1525
|
|
|
|
|
|
|
|
1526
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1527
|
|
|
|
|
|
|
|
1528
|
|
|
|
|
|
|
=head2 realserverwarn @message |
1529
|
|
|
|
|
|
|
|
1530
|
|
|
|
|
|
|
This private method synthesizes an underlying C method, |
1531
|
|
|
|
|
|
|
actually producing the message on the _STDERR stream. |
1532
|
|
|
|
|
|
|
Locking is performed to ensure exclusive access while appending. |
1533
|
|
|
|
|
|
|
This stream is typically directed to the webserver's error log |
1534
|
|
|
|
|
|
|
if used in a CGI program. |
1535
|
|
|
|
|
|
|
|
1536
|
|
|
|
|
|
|
This method is not exportable. |
1537
|
|
|
|
|
|
|
|
1538
|
|
|
|
|
|
|
=cut |
1539
|
|
|
|
|
|
|
|
1540
|
|
|
|
|
|
|
sub realserverwarn (@) |
1541
|
|
|
|
|
|
|
{ |
1542
|
0
|
|
|
0
|
1
|
0
|
my $msg = join("",@_); |
1543
|
0
|
0
|
|
|
|
0
|
if ($CGI::LogCarp::CUSTOM_STDERR_MSG) { |
1544
|
0
|
0
|
|
|
|
0
|
if (ref($CGI::LogCarp::CUSTOM_STDERR_MSG) eq "CODE") { |
1545
|
0
|
|
|
|
|
0
|
$msg = &{$CGI::LogCarp::CUSTOM_STDERR_MSG}($msg); |
|
0
|
|
|
|
|
0
|
|
1546
|
|
|
|
|
|
|
} |
1547
|
|
|
|
|
|
|
} |
1548
|
0
|
|
|
|
|
0
|
lock \*main::_STDERR; |
1549
|
0
|
|
|
|
|
0
|
print { \*main::_STDERR } $msg; |
|
0
|
|
|
|
|
0
|
|
1550
|
0
|
|
|
|
|
0
|
unlock \*main::_STDERR; |
1551
|
|
|
|
|
|
|
} |
1552
|
|
|
|
|
|
|
|
1553
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1554
|
|
|
|
|
|
|
|
1555
|
|
|
|
|
|
|
=head2 id $level |
1556
|
|
|
|
|
|
|
|
1557
|
|
|
|
|
|
|
This private method returns the file, line, and basename |
1558
|
|
|
|
|
|
|
of the currently executing function. |
1559
|
|
|
|
|
|
|
|
1560
|
|
|
|
|
|
|
This method is not exportable. |
1561
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
=cut |
1563
|
|
|
|
|
|
|
|
1564
|
|
|
|
|
|
|
sub id ($) |
1565
|
|
|
|
|
|
|
{ |
1566
|
24
|
|
|
24
|
1
|
42
|
my ($level) = shift; |
1567
|
24
|
|
|
|
|
112
|
my ($pack, $file,$line, $sub) = caller $level; |
1568
|
24
|
|
|
|
|
72
|
return ($file,$line); |
1569
|
|
|
|
|
|
|
} |
1570
|
|
|
|
|
|
|
|
1571
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1572
|
|
|
|
|
|
|
|
1573
|
|
|
|
|
|
|
=head2 stamp $stream_id |
1574
|
|
|
|
|
|
|
|
1575
|
|
|
|
|
|
|
A private method to construct a normalized timestamp prefix for a message. |
1576
|
|
|
|
|
|
|
|
1577
|
|
|
|
|
|
|
This method is not exportable. |
1578
|
|
|
|
|
|
|
|
1579
|
|
|
|
|
|
|
=cut |
1580
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
sub stamp ($) |
1582
|
|
|
|
|
|
|
{ |
1583
|
24
|
|
|
24
|
1
|
52
|
my ($stream_id) = shift; |
1584
|
24
|
|
|
|
|
684
|
my $time = scalar localtime; |
1585
|
24
|
|
|
|
|
126
|
my $process = sprintf("%6d",$$); |
1586
|
24
|
|
|
|
|
74
|
my $frame = 0; |
1587
|
24
|
|
|
|
|
41
|
my ($id,$pkg,$file); |
1588
|
24
|
|
|
|
|
37
|
do { |
1589
|
81
|
|
|
|
|
123
|
$id = $file; |
1590
|
81
|
|
|
|
|
361
|
($pkg,$file) = caller $frame++; |
1591
|
|
|
|
|
|
|
} until !$file; |
1592
|
24
|
|
|
|
|
164
|
($id) = $id =~ m|([^/]+)$|; |
1593
|
24
|
|
|
|
|
96
|
return "[$time] $process $id $stream_id: "; |
1594
|
|
|
|
|
|
|
} |
1595
|
|
|
|
|
|
|
|
1596
|
|
|
|
|
|
|
# --- END OF PAGE ---#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1597
|
|
|
|
|
|
|
|
1598
|
|
|
|
|
|
|
=head2 streams_are_equal FILEHANDLE, FILEHANDLE |
1599
|
|
|
|
|
|
|
|
1600
|
|
|
|
|
|
|
This private method compares two FILEHANDLE streams to each other |
1601
|
|
|
|
|
|
|
and returns the boolean result. |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
This method is not exportable. |
1604
|
|
|
|
|
|
|
|
1605
|
|
|
|
|
|
|
Note: This function is probably not portable to non-Unix-based |
1606
|
|
|
|
|
|
|
operating systems (i.e. NT, VMS, etc.). |
1607
|
|
|
|
|
|
|
|
1608
|
|
|
|
|
|
|
=cut |
1609
|
|
|
|
|
|
|
|
1610
|
|
|
|
|
|
|
sub streams_are_equal (**) |
1611
|
|
|
|
|
|
|
{ |
1612
|
25
|
|
|
25
|
1
|
175
|
my ($fh1,$fh2) = @_; |
1613
|
25
|
50
|
|
|
|
46
|
$fh1 = to_filehandle($fh1) or realdie "Invalid filehandle $fh1\n"; |
1614
|
25
|
50
|
|
|
|
44
|
$fh2 = to_filehandle($fh2) or realdie "Invalid filehandle $fh2\n"; |
1615
|
25
|
|
|
|
|
59
|
my $fno1 = fileno($fh1); |
1616
|
25
|
|
|
|
|
50
|
my $fno2 = fileno($fh2); |
1617
|
25
|
50
|
33
|
|
|
64
|
return 1 unless (defined $fno1 or defined $fno2); # true if both undef |
1618
|
25
|
100
|
66
|
|
|
106
|
return unless (defined $fno1 and defined $fno2); # undef if one is undef |
1619
|
22
|
|
|
|
|
258
|
my ($device1,$inode1) = stat $fh1; |
1620
|
22
|
|
|
|
|
189
|
my ($device2,$inode2) = stat $fh2; |
1621
|
22
|
100
|
|
|
|
186
|
( $device1 == $device2 and $inode1 == $inode2 ); |
1622
|
|
|
|
|
|
|
} |
1623
|
|
|
|
|
|
|
|
1624
|
|
|
|
|
|
|
# --- END OF PAGE ---#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1625
|
|
|
|
|
|
|
|
1626
|
|
|
|
|
|
|
# Some flock-related globals for lock/unlock |
1627
|
6
|
|
|
6
|
|
57
|
use Fcntl qw( /^LOCK_/ ); |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
1546
|
|
1628
|
6
|
|
|
6
|
|
3400
|
use POSIX qw( /^SEEK_/ ); |
|
6
|
|
|
|
|
49146
|
|
|
6
|
|
|
|
|
32
|
|
1629
|
|
|
|
|
|
|
|
1630
|
|
|
|
|
|
|
=head2 lock FILEHANDLE |
1631
|
|
|
|
|
|
|
|
1632
|
|
|
|
|
|
|
A private method that uses Perl's builtin C and C |
1633
|
|
|
|
|
|
|
to obtain an exclusive lock on the stream specified by FILEHANDLE. |
1634
|
|
|
|
|
|
|
A lock is only attempted on actual files that are writeable. |
1635
|
|
|
|
|
|
|
|
1636
|
|
|
|
|
|
|
This method is not exportable. |
1637
|
|
|
|
|
|
|
|
1638
|
|
|
|
|
|
|
=cut |
1639
|
|
|
|
|
|
|
|
1640
|
|
|
|
|
|
|
sub lock (*) |
1641
|
|
|
|
|
|
|
{ |
1642
|
27
|
|
|
27
|
1
|
58
|
my ($fh) = shift; |
1643
|
27
|
50
|
|
|
|
50
|
$fh = to_filehandle($fh) or realdie "Invalid filehandle $fh\n"; |
1644
|
27
|
50
|
|
|
|
76
|
my $no = fileno($fh) or return; |
1645
|
27
|
50
|
33
|
|
|
466
|
return unless ( -f $fh and -w _ ); |
1646
|
27
|
|
|
|
|
234
|
flock $fh, LOCK_EX; |
1647
|
|
|
|
|
|
|
# Just in case someone appended while we weren't looking... |
1648
|
27
|
|
|
|
|
256
|
seek $fh, 0, SEEK_END; |
1649
|
|
|
|
|
|
|
} |
1650
|
|
|
|
|
|
|
|
1651
|
|
|
|
|
|
|
=head2 unlock FILEHANDLE |
1652
|
|
|
|
|
|
|
|
1653
|
|
|
|
|
|
|
A private method that uses Perl's builtin C |
1654
|
|
|
|
|
|
|
to release any exclusive lock on the stream specified by FILEHANDLE. |
1655
|
|
|
|
|
|
|
An unlock is only attempted on actual files that are writeable. |
1656
|
|
|
|
|
|
|
|
1657
|
|
|
|
|
|
|
This method is not exportable. |
1658
|
|
|
|
|
|
|
|
1659
|
|
|
|
|
|
|
=cut |
1660
|
|
|
|
|
|
|
|
1661
|
|
|
|
|
|
|
sub unlock (*) |
1662
|
|
|
|
|
|
|
{ |
1663
|
33
|
|
|
33
|
1
|
83
|
my ($fh) = shift; |
1664
|
33
|
50
|
|
|
|
65
|
$fh = to_filehandle($fh) or realdie "Invalid filehandle $fh\n"; |
1665
|
33
|
50
|
|
|
|
85
|
my $no = fileno($fh) or return; |
1666
|
33
|
100
|
66
|
|
|
506
|
return unless ( -f $fh and -w _ ); |
1667
|
31
|
|
|
|
|
343
|
flock $fh, LOCK_UN; |
1668
|
|
|
|
|
|
|
} |
1669
|
|
|
|
|
|
|
|
1670
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1671
|
|
|
|
|
|
|
|
1672
|
|
|
|
|
|
|
# Right out of IO::Handle 5.005_01 |
1673
|
|
|
|
|
|
|
|
1674
|
|
|
|
|
|
|
# This is the only method we need from FileHandle |
1675
|
|
|
|
|
|
|
sub autoflush (*) |
1676
|
|
|
|
|
|
|
{ |
1677
|
10
|
50
|
|
10
|
0
|
69
|
my $old = SelectSaver->new(qualify($_[0],caller)) if ref($_[0]); |
1678
|
10
|
|
|
|
|
289
|
my $prev = $|; |
1679
|
10
|
50
|
|
|
|
39
|
$| = @_ > 1 ? $_[1] : 1; |
1680
|
10
|
|
|
|
|
38
|
$prev; |
1681
|
|
|
|
|
|
|
} |
1682
|
|
|
|
|
|
|
|
1683
|
|
|
|
|
|
|
# --- END OF PAGE ---^L#- - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1684
|
|
|
|
|
|
|
# End of CGI::LogCarp.pm |
1685
|
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
1686
|
|
|
|
|
|
|
1; |