1
1
package iTools::System ;
2
2
use base Exporter;
3
- $VERSION = " 0.01 " ;
3
+ $VERSION = " 0.02 " ;
4
4
5
- @EXPORT_OK = ( qw(
5
+ @EXPORT_OK = qw(
6
6
fatal nofatal
7
7
die warn
8
8
system command
9
9
mkdir chdir mkcd symlink pushdir popdir
10
10
rename link unlink
11
11
vbase
12
- ) ,
13
- # ! it's getting close to the time to deprecate these:
14
- # qw(
15
- # colored
16
- # indent verbosity vprint vprintf vnprint vnprintf vtmp
17
- # )
18
12
) ;
19
13
20
14
use Carp qw( cluck confess ) ;
21
15
use Cwd;
22
16
use iTools::Term::ANSI qw( color ) ;
23
17
use iTools::Verbosity qw( verbosity vpush vpop vprint vprintf vindent ) ;
24
18
use IPC::Open3;
19
+ use POSIX qw( WNOHANG ) ;
25
20
use Symbol;
21
+ use Time::HiRes qw( usleep ) ;
26
22
27
23
use strict;
28
24
use warnings;
@@ -32,24 +28,11 @@ our $CONFIG = { };
32
28
33
29
# === Deprecated Calls ======================================================
34
30
sub vbase { _varDefault(2, ' vbase' , @_ ) }
35
- # --- the following calls will be removed in the next version of iTools::System ---
36
- # sub verbosity { iTools::Verbosity::verbosity(@_) }
37
- # sub vnprint { iTools::Verbosity::vprint(@_) }
38
- # sub vnprintf { iTools::Verbosity::vprintf(@_) }
39
- # sub vprint { iTools::Verbosity::vprint(shift, '>'. shift, @_) }
40
- # sub vprintf { iTools::Verbosity::vprintf(shift, '>'. shift, @_) }
41
- # sub indent { iTools::Verbosity::vindent(@_) }
42
- # sub vtmp(&$) {
43
- # my ($code, $level) = @_;
44
- # vpush $level; my $retval = &$code; vpop;
45
- # return $retval;
46
- # }
47
31
sub logfile { iTools::Verbosity::vlogfile(@_ ) }
48
32
sub logonly {
49
33
iTools::Verbosity::vloglevel(iTools::Verbosity::verbosity());
50
34
vpush -3;
51
35
}
52
- # sub colored { iTools::Term::ANSI::colored(@_) }
53
36
54
37
# === Accessors =============================================================
55
38
# --- should errors be fatal? ---
@@ -115,10 +98,10 @@ sub system {
115
98
}
116
99
117
100
# --- run the command ---
118
- vprint vbase(), color(' c' , " executing: " ) . join (' ' , @cmd ) ." \n " ;
101
+ vprint vbase(), ' > ' . color(' c' , " executing: " ) . join (' ' , @cmd ) ." \n " ;
119
102
my $retval = system (@cmd ) == 0 && do {
120
103
# --- clean exit ---
121
- vprint vbase() + 1, color(' g' , " command completed successfully" ) ." \n " ;
104
+ vprint vbase() + 1, ' > ' . color(' g' , " command completed successfully" ) ." \n " ;
122
105
return 0;
123
106
};
124
107
@@ -138,16 +121,26 @@ sub system {
138
121
}
139
122
140
123
# --- qx replacement ---
141
- sub command ($; %) {
142
- my ($cmd , % extinfo ) = @_ ;
124
+ sub command ($; \ %) {
125
+ my ($cmd , $ extinfo ) = @_ ;
143
126
144
127
# --- use open3 to run command and capture stdout and stderr ---
145
128
my ($out , $err ) = (gensym, gensym);
146
- vprint vbase(), color(' c' , " executing: " ) ." $cmd \n " ;
129
+ vprint vbase(), ' > ' . color(' c' , " executing: " ) ." $cmd \n " ;
147
130
my $pid = open3 undef , $out , $err , $cmd ;
148
131
149
132
# --- wait for process to complete and capture return status ---
150
- waitpid $pid , 0;
133
+ local $/ ;
134
+ my ($outbuff , $errbuff ) = (' ' , ' ' );
135
+
136
+ my $deadpid ;
137
+ do {
138
+ usleep 10000;
139
+ $deadpid = waitpid $pid , WNOHANG;
140
+ $outbuff .= <$out > || ' ' ;
141
+ $errbuff .= <$err > || ' ' ;
142
+ } until $deadpid ;
143
+
151
144
my $stat = $? >> 8;
152
145
my $message ;
153
146
@@ -166,21 +159,21 @@ sub command($;%) {
166
159
# --- command executed successfully ---
167
160
else {
168
161
$message = ' command completed successfully' ;
169
- vprint vbase() + 1, color(' g' , " $message " ) ." \n " ;
162
+ vprint vbase() + 1, ' > ' . color(' g' , " $message " ) ." \n " ;
170
163
}
171
164
172
165
# --- build the %extinfo hash ---
173
166
local $/ ;
174
- %extinfo = (
175
- stdout => < $out > || ' ' ,
176
- stderr => < $err > || ' ' ,
167
+ %$ extinfo = (
168
+ stdout => $outbuff || ' ' ,
169
+ stderr => $errbuff || ' ' ,
177
170
pid => $pid ,
178
171
status => $stat ,
179
172
message => $message ,
180
173
);
181
174
182
175
# --- return stdout ---
183
- return wantarray ? split (/ [\r\n ]/ , $extinfo {stdout }) : $extinfo {stdout };
176
+ return wantarray ? split (/ [\r\n ]/ , $extinfo -> {stdout }) : $extinfo -> {stdout };
184
177
}
185
178
186
179
# === Filesystem Tools ======================================================
@@ -192,7 +185,7 @@ sub mkdir {
192
185
PATH: foreach my $path (@_ ) {
193
186
next if -d $path ; # do nothing if it already exists
194
187
195
- vprint vbase(), color(' c' , " mkdir: " ) ." $path \n " ;
188
+ vprint vbase(), ' > ' . color(' c' , " mkdir: " ) ." $path \n " ;
196
189
197
190
# --- make a directory list ---
198
191
my @dirs = split /\//, $path ; # split path into components
@@ -205,7 +198,7 @@ sub mkdir {
205
198
206
199
# --- skip dir if it already exists ---
207
200
if (-d $path ) {
208
- vprint vbase() + 1, " mkdir $path " . color(' y' , " (already exists)" ) ." \n " ;
201
+ vprint vbase() + 1, ' > ' . " mkdir $path " . color(' y' , " (already exists)" ) ." \n " ;
209
202
next ;
210
203
}
211
204
@@ -217,14 +210,14 @@ sub mkdir {
217
210
$goodpath = $retval = 0;
218
211
last ;
219
212
}
220
- vprint vbase() + 1, " mkdir $path \n " ;
213
+ vprint vbase() + 1, ' > ' . " mkdir $path \n " ;
221
214
mkdir $path , 0755 or do {
222
215
iTools::System::die (" error creating directory '$path ': $! " );
223
216
$goodpath = $retval = 0;
224
217
last ;
225
218
}
226
219
}
227
- vprint vbase() + 1, color(' g' , " path created" ) ." \n "
220
+ vprint vbase() + 1, ' > ' . color(' g' , " path created" ) ." \n "
228
221
if $goodpath ;
229
222
}
230
223
@@ -237,7 +230,7 @@ sub mkdir {
237
230
# --- chdir wrapper ---
238
231
sub chdir {
239
232
my $path = shift ;
240
- vprint vbase(), color(' c' , " chdir: " ) ." $path \n " ;
233
+ vprint vbase(), ' > ' . color(' c' , " chdir: " ) ." $path \n " ;
241
234
chdir $path or iTools::System::die (" can't chdir to '$path ': $! " ) && return undef ;
242
235
return $path ;
243
236
}
@@ -272,38 +265,38 @@ sub symlink {
272
265
return undef ;
273
266
}
274
267
275
- vprint vbase(), color(' c' , " symlink: " ) ." $source -> $dest \n " ;
268
+ vprint vbase(), ' > ' . color(' c' , " symlink: " ) ." $source -> $dest \n " ;
276
269
277
270
# --- delete old symlink if possible ---
278
271
if (-l $dest ) {
279
- vprint vbase() + 1, color(' y' , " deleteting old symlink" ) ." \n " ;
272
+ vprint vbase() + 1, ' > ' . color(' y' , " deleteting old symlink" ) ." \n " ;
280
273
unlink $dest or iTools::System::die " could not delete old symlink\n " && return undef ;
281
274
} elsif (-e $dest ) {
282
275
iTools::System::die " cannot create symlink $dest , file is in the way\n " && return undef ;
283
276
}
284
277
285
278
symlink $source , $dest or iTools::System::die " error creating symlink $dest " && return undef ;
286
- vprint vbase() + 1, color(' g' , " symlink created" ) ." \n " ;
279
+ vprint vbase() + 1, ' > ' . color(' g' , " symlink created" ) ." \n " ;
287
280
return 1;
288
281
}
289
282
# --- create a hard link ---
290
283
sub link {
291
284
my ($ori , $new ) = @_ ;
292
- vprint vbase(), color(' c' , " link: " ) ." $ori -> $new \n " ;
285
+ vprint vbase(), ' > ' . color(' c' , " link: " ) ." $ori -> $new \n " ;
293
286
link $ori , $new
294
287
or iTools::System::die " could not create link\n " && return undef ;
295
288
}
296
289
297
290
# --- delete a file ---
298
291
sub unlink {
299
- vprint vbase(), color(' c' , " unlink: " ) . join (' ' , @_ ) ." \n " ;
292
+ vprint vbase(), ' > ' . color(' c' , " unlink: " ) . join (' ' , @_ ) ." \n " ;
300
293
unlink @_ or iTools::System::die " could not delete files\n " && return ;
301
294
}
302
295
303
296
# --- rename wrapper ---
304
297
sub rename {
305
298
my ($old , $new ) = @_ ;
306
- vprint vbase(), color(' c' , " rename: " ) ." $old -> $new \n " ;
299
+ vprint vbase(), ' > ' . color(' c' , " rename: " ) ." $old -> $new \n " ;
307
300
rename $old , $new or return iTools::System::die (" can't rename '$old ' to '$new ': $! " ) && return undef ;
308
301
return $new ;
309
302
}
0 commit comments