BATsh
view release on metacpan or search on metacpan
lib/BATsh/SH.pm view on Meta::CPAN
my $opt = shift @w;
$mode = 'v' if $opt =~ /v/;
$mode = 'V' if $opt =~ /V/;
# -p: accepted, no effect
}
# A bare "--" ends option parsing.
shift @w if @w && $w[0] eq '--';
if (!@w) { $LAST_STATUS = ($mode ne '') ? 1 : 0; return $LAST_STATUS }
if ($mode eq 'v' || $mode eq 'V') {
my $status = 0;
for my $name (@w) {
my ($kind, $detail) = _sh_name_kind($name);
if ($mode eq 'V') {
_print_type_verbose($name, $kind, $detail) or $status = 1;
}
else { # -v
if ($kind eq 'alias') { print "alias $name='" . (defined $detail ? $detail : '') . "'\n" }
elsif ($kind eq 'file') { print $detail, "\n" }
elsif ($kind eq '') { $status = 1 }
else { print $name, "\n" } # keyword/function/builtin
}
}
$LAST_STATUS = $status;
return $status;
}
# Plain run form: re-dispatch the raw remainder with function lookup
# suppressed. Recover the text after the leading "command" word (and any
# -p / -- options) from the pre-expansion source so _expand() runs once.
my $raw = defined $raw_pre ? $raw_pre : $rest;
$raw =~ s/\A\s*//;
$raw =~ s/\A[Cc][Oo][Mm][Mm][Aa][Nn][Dd]\b//;
$raw =~ s/\A\s+//;
while ($raw =~ /\A(-[pvV]+|--)\s/) {
my $tok = $1;
$raw =~ s/\A(?:-[pvV]+|--)\s+//;
last if $tok eq '--';
}
local $_CMD_NO_FUNC = 1;
return _exec_line($class, $raw, $opts_ref);
}
# ----------------------------------------------------------------
# Background execution helpers (v1)
# ----------------------------------------------------------------
# ----------------------------------------------------------------
# umask / hash / readonly / mapfile (v0.08)
# ----------------------------------------------------------------
# _sh_is_readonly(NAME): true when NAME carries the readonly attribute.
sub _sh_is_readonly {
my ($name) = @_;
return 0 unless defined $name;
return $_SH_READONLY{ uc($name) } ? 1 : 0;
}
# _sh_store_scalar(NAME, VALUE): the single choke point for a plain scalar
# assignment. Honours the readonly attribute (refused, status source
# returns 0) and the integer attribute (VALUE evaluated as arithmetic).
# Returns 1 when the value was stored, 0 when a readonly variable blocked
# it. All the ordinary assignment paths (VAR=val, prefix VAR=val cmd,
# export VAR=val) funnel through here so the attributes are enforced
# uniformly.
sub _sh_store_scalar {
my ($name, $val) = @_;
$val = _unprotect_lit($val) if defined $val;
my $ik = uc($name);
if ($_SH_READONLY{$ik}) {
print STDERR "sh: $name: readonly variable\n";
return 0;
}
if ($_SH_INTATTR{$ik}) {
$val = _eval_arith(defined $val ? $val : '');
}
BATsh::Env->set($name, $val);
return 1;
}
# umask [-S] [MODE]
# With no MODE, print the current file-creation mask (octal, or symbolic
# with -S). A numeric (octal) MODE sets the mask. Uses Perl's umask, so
# it is a genuine process mask on Unix-like systems (a no-op reflecting
# whatever the C library reports on Win32).
sub _cmd_umask {
my ($rest) = @_;
$rest = '' unless defined $rest;
$rest =~ s/\A\s+//; $rest =~ s/\s+\z//;
# Seed the shell mask from the real process umask on first use.
if (!$_SH_UMASK_INIT) {
my $u = umask();
$_SH_UMASK = defined $u ? $u : 0;
$_SH_UMASK_INIT = 1;
}
my $symbolic = 0;
if ($rest =~ s/\A-S\b\s*//) { $symbolic = 1 }
if ($rest eq '') {
if ($symbolic) { print _umask_symbolic($_SH_UMASK), "\n" }
else { printf "%04o\n", $_SH_UMASK }
$LAST_STATUS = 0;
return 0;
}
if ($rest =~ /\A[0-7]+\z/) {
$_SH_UMASK = oct($rest) & 0777;
umask($_SH_UMASK); # honoured on Unix, harmless where it is not
$LAST_STATUS = 0;
return 0;
}
# Symbolic mode: "u=rwx,g=rx,o=rx" (and +/- ops). The operand names the
# permissions to LEAVE enabled; the mask is their complement.
my $sym = _umask_apply_symbolic($_SH_UMASK, $rest);
if (defined $sym) {
$_SH_UMASK = $sym;
umask($_SH_UMASK);
$LAST_STATUS = 0;
return 0;
}
print STDERR "sh: umask: $rest: invalid mask\n";
( run in 2.385 seconds using v1.01-cache-2.11-cpan-800906f7e73 )