差分表示
- 最後の更新で追加された行はこのように表示します。
- 最後の更新で削除された行は
このように表示します。
*背景
最近、全然書かなくなってきたので、復習?というかいま(2007-03-13)どんな感じの書き方が
自分のトレンドなのかを残しておいて、あとで一人ニヤニヤwするためにmkfileを書いてみました。
元々の動機は Solarisにある mkfile(1)が Linuxになかったので、
きっと類するのはあるかなと思いつつ、perlで書いてみようということでできた産物ですw
win/linux/solarisでは動くことを確認してます。
ただ win/unixのどちらにも対応する為に関数のreferenceを使っているので、
perlのversionは 5.6以上必須です。
ちなみに実装ですが、バリバリsolarisの[[mkfile>http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/mkfile/mkfile.c]]の実装をパクってます。
ちなみにsolarisの[[mkfile>http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/mkfile/mkfile.c]]の実装をパクってます。
*解説
TBD
-いつも通り、コメント無しのコードは載せても解説はとりあえず書きませんwバグレポートや解説の希望とかあれば、コメントしてください。 -- &new{2007-03-13 (Tue) 18:25:52};
#comment(noname)
*コード
---(
#!/usr/bin/env perl
use strict;
use Fcntl qw(:seek);
use Config;
$::size;
@::files;
$::cmd = "mkfile.pl";
$::debug = 0;
$::nobytes = 0;
$::verbose = 0;
$::onekbuf;
$::onekb = 1024;
$::devnull;
$::devnullpath = "/dev/null";
$::osname = $Config{osname};
&parseArgs(@ARGV);
&init();
&mainloop();
$::init;
$::generateBuffer;
sub mainloop {
my $f;
foreach $f ( @::files ) {
&validateFile($f);
&doIt($f);
}
}
sub init {
&_init();
&$::init();
}
sub doIt {
my $file = $_[0];
my ($fd, $loop, $wbuf);
$loop = 1;
if ( $::size > $::onekb ) {
my $loopSp = $::size % $::onekb;
$loop = ( ($::size - $::loopSp) / $::onekb );
}
open(WR, ">$file") or die "$!\n";
$fd = \*WR;
if ( $::nobytes ) {
my $sentinel = pack("C", 0x0);
seek($fd, $::size-1, SEEK_SET) or die "$!\n";
print $fd "$sentinel";
} else {
printf("loop : %d\n", $loop) if ( $::debug );
my ($alreadyWrite, $requestLength);
# init
$alreadyWrite = 0;
do {
$requestLength = $loop > 1
? $::onekb : ($::size - $alreadyWrite);
$wbuf = &$::generateBuffer($requestLength);
print $fd "$wbuf";
$alreadyWrite += $requestLength;
$loop -= 1;
} while ( $loop > 0 );
}
close($fd);
if ( $::verbose ) {
printf("%s %d bytes\n", $file, $::size);
}
}
sub validateSize {
my $eflag = 0;
my $backup = $_;
my ($s);
printf("\$::size = %s\n", $::size) if ( $::debug );
if ( $::size =~ /([0-9]{1,})([a-zA-Z])/ ) {
$s = $1;
$_ = $2;
VALIDATESIZE_SW:{
/m/ && do {
$::size = $s * 1024 * 1024;
last VALIDATESIZE_SW;
};
/k/ && do {
$::size = $s * 1024;
last VALIDATESIZE_SW;
};
/.*/ && do {
printf STDERR ("%s is NOT match suffix\n", $_);
exit(1);
last VALIDATESIZE_SW;
};
};# end of VALIDATESIZE_SW
} elsif ( $::size =~ /[0-9]{1,}/ ) {
# do nothing
} else {
$eflag = 1;
}
if ( $::size < 1 ) {
printf STDERR ("%d is lower than 0\n", $::size);
$eflag = 1;
}
&usage() if ( $eflag == 1 );
$_ = $backup;
}
sub validateFile {
my $file = $_[0];
# windows is NOT suppoted
printf("\$file = %s\n", $file) if ( $::debug );
my @_p = split(/\//, $file);
my ($i, $pp);
foreach $i ( 0 .. $#_p-1 ) {
$pp .= "$_p[$i]/";
}
if ( defined($pp) && !(-e $pp) ) {
printf STDERR ("Directory %s is NOT exist\n", $pp);
exit(1);
}
}
sub usage {
print <<"EOF";
Usage: $::cmd [-nv] <size>[k|m] <name1> [<name2>] ...
-n : specified size. suffix 'k' or 'm' can be parsed.
-v : verbose. Report the names and size of craeted file.
EOF
exit(1);
}
sub parseArgs {
my @argv = @_;
my $backup = $_;
my ($i, $st);
my @flags = ();
if ( $argv[0] =~ /^\-.*$/ ) {
@flags = split(//, $argv[0]);
foreach ( (@flags)[1 .. $#flags] ) {
GETOPT_SW:{
/n/ && do {
$::nobytes = 1;
last GETOPT_SW;
};
/v/ && do {
$::verbose = 1;
last GETOPT_SW;
};
/.*/ && do {
printf("illegal option %s\n", $_);
&usage();
last GETOPT_SW;
};
};# end of GETOPT_SW
}
}
$st = ( $#flags == -1 ) ? 0 : 1;
$::size = $argv[$st];
&validateSize();
foreach $i ( $st+1 .. $#argv ) {
push(@::files, $argv[$i]);
}
&usage() if ( !defined($::size) || $#::files < 0 );
printf("-n : %d -v : %d\n", $::nobytes, $::verbose) if ( $::debug );
$_ = $backup;
}
# default impl /w /dev/null
sub init_unix {
my $rbuf;
open(ZERO, "/dev/null") or die "$!\n";
$::devnull = \*ZERO;
read(ZERO, $rbuf, 1024);
$::onekbuf = pack("C1024", $rbuf);
}
sub generateBuffer_unix {
my $rbuf;
my $buflen = $_[0];
my $pstr = sprintf("C%d", $buflen);
printf("alloc $buflen PACK str = %s\n", $pstr) if ( $::debug );
if ( $buflen == $::onekb ) {
$rbuf = $::onekbuf;
} else {
my $t;
read($::devnull, $t, $buflen);
$rbuf = pack($pstr, $t);
}
return $rbuf;
}
# alternate impl if /dev/null does NOT exist.
sub init_win {
my @bzeros = (
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
);
my $i = 8;
my @zeros;
do {
push(@zeros, @bzeros);
$i -= 1;
} while ( $i > 0 );
$::onekbuf = pack("C1024", @zeros);
}
sub generateBuffer_win {
my $buf;
my $buflen = $_[0];
my $pstr = sprintf("C%d", $buflen);
my $zero = pack("C", 0x0);
my @zeros = ();
printf("alloc $buflen PACK str = %s\n", $pstr) if ( $::debug );
if ( $buflen == $::onekb ) {
$buf = $::onekbuf;
} else {
while ( $buflen > 0 ) {
push(@zeros, $zero);
$buflen -= 1;
}
$buf = pack($pstr, @zeros);
}
return $buf;
}
sub _init {
printf("osname = %s\n", $::osname) if ( $::debug );
if ( $::osname =~ /.*windows.*/i ) {
$::init = \&init_win;
$::generateBuffer = \&generateBuffer_win;
} else {
$::init = \&init_unix;
$::generateBuffer = \&generateBuffer_unix;
}
}
---)
Last-modified: 2007-03-13 18:31:26