1#!./perl 2 3BEGIN { 4 $| = 1; 5 chdir 't' if -d 't'; 6 require './test.pl'; 7 set_up_inc( '../lib' ); 8 plan (tests => 208); # some tests are run in BEGIN block 9} 10 11# Test that defined() returns true for magic variables created on the fly, 12# even before they have been created. 13# This must come first, even before turning on warnings or setting up 14# $SIG{__WARN__}, to avoid invalidating the tests. warnings.pm currently 15# does not mention any special variables, but that could easily change. 16BEGIN { 17 # not available in miniperl 18 my %non_mini = map { $_ => 1 } qw(+ - [); 19 for (qw( 20 SIG ^OPEN ^TAINT ^UNICODE ^UTF8LOCALE ^WARNING_BITS 1 2 3 4 5 6 7 8 21 9 42 & ` ' : ? ! _ - [ ^ ~ = % . ( ) < > \ / $ | + ; ] ^A ^C ^D 22 ^E ^F ^H ^I ^L ^N ^O ^P ^S ^T ^V ^W ^UTF8CACHE ::12345 main::98732 23 ^LAST_FH 24 )) { 25 my $v = $_; 26 # avoid using any global vars here: 27 if ($v =~ s/^\^(?=.)//) { 28 for(substr $v, 0, 1) { 29 $_ = chr(utf8::native_to_unicode(ord($_)) - 64); 30 } 31 } 32 SKIP: 33 { 34 skip_if_miniperl("the module for *$_ may not be available in " 35 . "miniperl", 1) if $non_mini{$_}; 36 ok defined *$v, "*$_ appears to be defined at the outset"; 37 } 38 } 39} 40 41# This must be in a separate BEGIN block, as the mere mention of ${^TAINT} 42# will invalidate the test for it. 43BEGIN { 44 $ENV{PATH} = '/bin' if ${^TAINT}; 45 $SIG{__WARN__} = sub { die "Dying on warning: ", @_ }; 46} 47 48use warnings; 49use Config; 50 51 52$Is_MSWin32 = $^O eq 'MSWin32'; 53$Is_VMS = $^O eq 'VMS'; 54$Is_os2 = $^O eq 'os2'; 55$Is_Cygwin = $^O eq 'cygwin'; 56 57$PERL = 58 ($Is_VMS ? $^X : 59 $Is_MSWin32 ? '.\perl' : 60 './perl'); 61 62 63sub env_is { 64 my ($key, $val, $desc) = @_; 65 66 use open IN => ":raw"; 67 if ($Is_MSWin32) { 68 # cmd.exe will echo 'variable=value' but 4nt will echo just the value 69 # -- Nikola Knezevic 70 require Win32; 71 my $cp = Win32::GetConsoleOutputCP(); 72 Win32::SetConsoleOutputCP(Win32::GetACP()); 73 (my $set = `set $key 2>nul`) =~ s/\r\n$/\n/; 74 Win32::SetConsoleOutputCP($cp); 75 like $set, qr/^(?:\Q$key\E=)?\Q$val\E$/, $desc; 76 } elsif ($Is_VMS) { 77 my $eqv = `write sys\$output f\$trnlnm("\Q$key\E")`; 78 # A single null byte in the equivalence string means 79 # an undef value for Perl, so mimic that here. 80 $eqv = "\n" if length($eqv) == 2 and $eqv eq "\000\n"; 81 is $eqv, "$val\n", $desc; 82 } else { 83 my @env = `env`; 84 SKIP: { 85 skip("env doesn't work on this android", 1) if !@env && $^O =~ /android/; 86 chomp (my @env = grep { s/^$key=// } @env); 87 is "@env", $val, $desc; 88 } 89 } 90} 91 92END { 93 # On VMS, environment variable changes are peristent after perl exits 94 if ($Is_VMS) { 95 delete $ENV{'FOO'}; 96 delete $ENV{'__NoNeSuCh'}; 97 delete $ENV{'__NoNeSuCh2'}; 98 } 99} 100 101eval '$ENV{"FOO"} = "hi there";'; # check that ENV is inited inside eval 102# cmd.exe will echo 'variable=value' but 4nt will echo just the value 103# -- Nikola Knezevic 104if ($Is_MSWin32) { like `set FOO`, qr/^(?:FOO=)?hi there$/m; } 105elsif ($Is_VMS) { is `write sys\$output f\$trnlnm("FOO")`, "hi there\n"; } 106else { is `echo \$FOO`, "hi there\n"; } 107 108unlink_all 'ajslkdfpqjsjfk'; 109$! = 0; 110open(FOO,'ajslkdfpqjsjfk'); 111isnt($!, 0, "Unlinked file can't be opened"); 112close FOO; # just mention it, squelch used-only-once 113 114SKIP: { 115 skip('SIGINT not safe on this platform', 5) 116 if $Is_MSWin32; 117 # the next tests are done in a subprocess because sh spits out a 118 # newline onto stderr when a child process kills itself with SIGINT. 119 # We use a pipe rather than system() because the VMS command buffer 120 # would overflow with a command that long. 121 122 # For easy interpolation of test numbers: 123 $next_test = curr_test() - 1; 124 sub TIEARRAY {bless[]} 125 sub FETCH { $next_test + pop } 126 tie my @tn, __PACKAGE__; 127 128 open( CMDPIPE, "|-", $PERL); 129 130 print CMDPIPE "\$t1 = $tn[1]; \$t2 = $tn[2];\n", <<'END'; 131 132 $| = 1; # command buffering 133 134 $SIG{"INT"} = "ok1"; kill "INT",$$; sleep 1; 135 $SIG{"INT"} = "IGNORE"; kill "INT",$$; sleep 1; print "ok $t2\n"; 136 $SIG{"INT"} = "DEFAULT"; kill "INT",$$; sleep 1; print" not ok $t2\n"; 137 138 sub ok1 { 139 if (($x = pop(@_)) eq "INT") { 140 print "ok $t1\n"; 141 } 142 else { 143 print "not ok $t1 ($x @_)\n"; 144 } 145 } 146 147END 148 149 close CMDPIPE; 150 151 open( CMDPIPE, "|-", $PERL); 152 print CMDPIPE "\$t3 = $tn[3];\n", <<'END'; 153 154 { package X; 155 sub DESTROY { 156 kill "INT",$$; 157 } 158 } 159 sub x { 160 my $x=bless [], 'X'; 161 return sub { $x }; 162 } 163 $| = 1; # command buffering 164 $SIG{"INT"} = "ok3"; 165 { 166 local $SIG{"INT"}=x(); 167 print ""; # Needed to expose failure in 5.8.0 (why?) 168 } 169 sleep 1; 170 delete $SIG{"INT"}; 171 kill "INT",$$; sleep 1; 172 sub ok3 { 173 print "ok $t3\n"; 174 } 175END 176 close CMDPIPE; 177 $? >>= 8 if $^O eq 'VMS'; # POSIX status hiding in 2nd byte 178 my $todo = ($^O eq 'os2' ? ' # TODO: EMX v0.9d_fix4 bug: wrong nibble? ' : ''); 179 $todo = ($Config{usecrosscompile} ? '# TODO: Not sure whats going on here when cross-compiling' : ''); 180 print $? & 0xFF ? "ok $tn[4]$todo\n" : "not ok $tn[4]$todo\n"; 181 182 open(CMDPIPE, "|-", $PERL); 183 print CMDPIPE <<'END'; 184 185 sub PVBM () { 'foo' } 186 index 'foo', PVBM; 187 my $pvbm = PVBM; 188 189 sub foo { exit 0 } 190 191 $SIG{"INT"} = $pvbm; 192 kill "INT", $$; sleep 1; 193END 194 close CMDPIPE; 195 $? >>= 8 if $^O eq 'VMS'; 196 print $? ? "not ok $tn[5]\n" : "ok $tn[5]\n"; 197 198 curr_test(curr_test() + 5); 199} 200 201# can we slice ENV? 202@val1 = @ENV{keys(%ENV)}; 203@val2 = values(%ENV); 204is join(':',@val1), join(':',@val2); 205cmp_ok @val1, '>', 1; 206 207# deleting $::{ENV} 208is runperl(prog => 'delete $::{ENV}; chdir; print qq-ok\n-'), "ok\n", 209 'deleting $::{ENV}'; 210 211# regex vars 212'foobarbaz' =~ /b(a)r/; 213is $`, 'foo'; 214is $&, 'bar'; 215is $', 'baz'; 216is $+, 'a'; 217 218# [perl #24237] 219for (qw < ` & ' >) { 220 fresh_perl_is 221 qq < \@$_; q "fff" =~ /(?!^)./; print "[\$$_]\\n" >, 222 "[f]\n", {}, 223 "referencing \@$_ before \$$_ etc. still saws off ampersands"; 224} 225 226# $" 227@a = qw(foo bar baz); 228is "@a", "foo bar baz"; 229{ 230 local $" = ','; 231 is "@a", "foo,bar,baz"; 232} 233 234# $; 235%h = (); 236$h{'foo', 'bar'} = 1; 237is((keys %h)[0], "foo\034bar"); 238{ 239 local $; = 'x'; 240 %h = (); 241 $h{'foo', 'bar'} = 1; 242 is((keys %h)[0], 'fooxbar'); 243} 244 245# $?, $@, $$ 246system qq[$PERL "-I../lib" -e "use vmsish qw(hushed); exit(0)"]; 247is $?, 0; 248system qq[$PERL "-I../lib" -e "use vmsish qw(hushed); exit(1)"]; 249isnt $?, 0; 250 251eval { die "foo\n" }; 252is $@, "foo\n"; 253 254ok !*@{HASH}, 'no %@'; 255 256cmp_ok($$, '>', 0); 257my $pid = $$; 258eval { $$ = 42 }; 259is $$, 42, '$$ can be modified'; 260SKIP: { 261 skip "no fork", 1 unless $Config{d_fork}; 262 (my $kidpid = open my $fh, "-|") // skip "cannot fork: $!", 1; 263 if($kidpid) { # parent 264 my $kiddollars = <$fh>; 265 close $fh or die "cannot close pipe from kid proc: $!"; 266 is $kiddollars, $kidpid, '$$ is reset on fork'; 267 } 268 else { # child 269 print $$; 270 $::NO_ENDING = 1; # silence "Looks like you only ran..." 271 exit; 272 } 273} 274$$ = $pid; # Tests below use $$ 275 276# $^X and $0 277{ 278 my $is_abs = $Config{d_procselfexe} || $Config{usekernprocpathname} 279 || $Config{usensgetexecutablepath}; 280 if ($^O eq 'qnx') { 281 chomp($wd = `/usr/bin/fullpath -t`); 282 } 283 elsif($^O =~ /android/) { 284 chomp($wd = `sh -c 'pwd'`); 285 } 286 elsif($Is_Cygwin || $is_abs) { 287 # Cygwin turns the symlink into the real file 288 chomp($wd = `pwd`); 289 $wd =~ s#/t$##; 290 $wd =~ /(.*)/; $wd = $1; # untaint 291 if ($Is_Cygwin) { 292 $wd = Cygwin::win_to_posix_path(Cygwin::posix_to_win_path($wd, 1)); 293 } 294 } 295 elsif($Is_os2) { 296 $wd = Cwd::sys_cwd(); 297 } 298 else { 299 $wd = '.'; 300 } 301 my $perl = $Is_VMS || $is_abs ? $^X : "$wd/perl"; 302 my $headmaybe = ''; 303 my $middlemaybe = ''; 304 my $tailmaybe = ''; 305 $script = "$wd/show-shebang"; 306 if ($Is_MSWin32) { 307 chomp($wd = `cd`); 308 $wd =~ s|\\|/|g; 309 $perl = "$wd/perl.exe"; 310 $script = "$wd/show-shebang.bat"; 311 $headmaybe = <<EOH ; 312\@rem =' 313\@echo off 314$perl -x \%0 315goto endofperl 316\@rem '; 317EOH 318 $tailmaybe = <<EOT ; 319 320__END__ 321:endofperl 322EOT 323 } 324 elsif ($Is_os2) { 325 $script = "./show-shebang"; 326 } 327 elsif ($Is_VMS) { 328 $script = "[]show-shebang"; 329 } 330 elsif ($Is_Cygwin) { 331 $middlemaybe = <<'EOX' 332$^X = Cygwin::win_to_posix_path(Cygwin::posix_to_win_path($^X, 1)); 333$0 = Cygwin::win_to_posix_path(Cygwin::posix_to_win_path($0, 1)); 334EOX 335 } 336 if ($^O eq 'os390' or $^O eq 'posix-bc') { # no shebang 337 $headmaybe = <<EOH ; 338 eval 'exec ./perl -S \$0 \${1+"\$\@"}' 339 if 0; 340EOH 341 } 342 $s1 = "\$^X is $perl, \$0 is $script\n"; 343 ok open(SCRIPT, ">$script") or diag "Can't write to $script: $!"; 344 ok print(SCRIPT $headmaybe . <<EOB . $middlemaybe . <<'EOF' . $tailmaybe) or diag $!; 345#!$perl 346EOB 347print "\$^X is $^X, \$0 is $0\n"; 348EOF 349 ok close(SCRIPT) or diag $!; 350 ok chmod(0755, $script) or diag $!; 351 $_ = $Is_VMS ? `$perl $script` : `$script`; 352 s/\.exe//i if $Is_Cygwin or $Is_os2; 353 s{is perl}{is $perl}; # for systems where $^X is only a basename 354 s{\\}{/}g; 355 if ($Is_MSWin32 || $Is_os2) { 356 is uc $_, uc $s1; 357 } else { 358 SKIP: 359 { 360 skip "# TODO: Hit bug posix-2058; exec does not setup argv[0] correctly." if ($^O eq "vos"); 361 is $_, $s1; 362 } 363 } 364 $_ = `$perl $script`; 365 s/\.exe//i if $Is_os2 or $Is_Cygwin; 366 s{\\}{/}g; 367 if ($Is_MSWin32 || $Is_os2) { 368 is uc $_, uc $s1; 369 } else { 370 is $_, $s1; 371 } 372 ok unlink($script) or diag $!; 373 # CHECK 374 # Could this be replaced with: 375 # unlink_all($script); 376} 377 378# $], $^O, $^T 379cmp_ok $], '>=', 5.00319; 380ok $^O; 381cmp_ok $^T, '>', 850000000; 382 383# Test change 25062 is working 384my $orig_osname = $^O; 385{ 386local $^I = '.bak'; 387is $^O, $orig_osname, 'Assigning $^I does not clobber $^O'; 388} 389$^O = $orig_osname; 390 391{ 392 #RT #72422 393 foreach my $p (0, 1) { 394 fresh_perl_is(<<"EOP", '2 4 8', undef, "test \$^P = $p"); 395\$DB::single = 2; 396\$DB::trace = 4; 397\$DB::signal = 8; 398\$^P = $p; 399print "\$DB::single \$DB::trace \$DB::signal"; 400EOP 401 } 402} 403 404# Check that assigning to $0 on Linux sets the process name with both 405# argv[0] assignment and by calling prctl() 406{ 407 SKIP: { 408 skip "We don't have prctl() here, or we're on Android", 2 unless $Config{d_prctl_set_name} && $^O ne 'android'; 409 410 # We don't really need these tests. prctl() is tested in the 411 # Kernel, but test it anyway for our sanity. If something doesn't 412 # work (like if the system doesn't have a ps(1) for whatever 413 # reason) just bail out gracefully. 414 my $maybe_ps = sub { 415 my ($cmd) = @_; 416 local ($?, $!); 417 418 no warnings; 419 my $res = `$cmd`; 420 skip "Couldn't shell out to '$cmd', returned code $?", 2 if $?; 421 return $res; 422 }; 423 424 my $name = "Good Morning, Dave"; 425 $0 = $name; 426 427 chomp(my $argv0 = $maybe_ps->("ps h $$")); 428 chomp(my $prctl = $maybe_ps->("ps hc $$")); 429 430 like($argv0, qr/$name/, "Set process name through argv[0] ($argv0)"); 431 my $name_substr = substr($name, 0, 15); 432 like($prctl, qr/$name_substr/, "Set process name through prctl() ($prctl)"); 433 } 434} 435 436# Check that assigning to $0 properly handles UTF-8-stored strings: 437{ 438 439 # Test both ASCII and EBCDIC systems: 440 my $char = chr( utf8::native_to_unicode(0xe9) ); 441 442 # We want $char_with_utf8_pv's PV to be UTF-8-encoded because we need to 443 # test that Perl translates UTF-8-stored code points to plain octets when 444 # assigning to $0. 445 # 446 my $char_with_utf8_pv = $char; 447 utf8::upgrade($char_with_utf8_pv); 448 449 # This will be the same logical code point as $char_with_utf8_pv, but 450 # implemented in Perl internally as a raw byte rather than UTF-8. 451 # (NB: $char is *probably* already utf8::downgrade()d, but let's not 452 # assume that to be the case.) 453 # 454 my $char_with_plain_pv = $char; 455 utf8::downgrade($char_with_plain_pv); 456 457 $0 = $char_with_utf8_pv; 458 459 # In case the assignment to $0 changed $char_with_utf8_pv, ensure that 460 # it is still interally double-UTF-8-encoded: 461 # 462 utf8::upgrade($char_with_utf8_pv); 463 464 is ($0, $char_with_utf8_pv, 'compare $0 to UTF8-flagged'); 465 is ($0, $char_with_plain_pv, 'compare $0 to non-UTF8-flagged'); 466 467 my $linux_cmdline_cr = sub { 468 my $skip = shift // 1; 469 open my $rfh, '<', "/proc/$$/cmdline" 470 or skip "failed to read '/proc/$$/cmdline': $!", $skip; 471 my $got = do { local $/; <$rfh> }; 472 473 # Some kernels leave a trailing NUL on. Some add a bunch of spaces 474 # after that NUL. We want neither. 475 # 476 # A selection of kernels/distros tested: 477 # 478 # 4.18.0-348.20.1.el8_5.x86_64 (AlmaLinux 8.5): NUL then spaces 479 # 4.18.0-348.23.1.el8_5.x86_64 (AlmaLinux 8.5): NUL, spaces, then NUL 480 # 3.10.0-1160.62.1.el7.x86_64 (CentOS 7.9.2009): no NUL nor spaces 481 # 2.6.32-954.3.5.lve1.4.87.el6.x86_64 (CloudLinux 6.10): ^^ ditto 482 # 483 # 5.13.0-1025-raspi (Ubuntu 21.10): NUL only 484 # 5.10.103-v7+ (RaspiOS 10): NUL only 485 # 486 $got =~ s/\0[\s\0]*\z//; 487 488 return $got; 489 }; 490 491 SKIP: { 492 my $skip_tests = 2; 493 skip "Test is for Linux, not $^O", $skip_tests if $^O ne 'linux'; 494 my $slurp = $linux_cmdline_cr->($skip_tests); 495 is( $slurp, $char_with_utf8_pv, 496 '/proc cmdline shows as expected (compare to UTF8-flagged)' ); 497 is( $slurp, $char_with_plain_pv, 498 '/proc cmdline shows as expected (compare to non-UTF8-flagged)' ); 499 } 500 501 my $name_unicode = "haha\x{100}hoho"; 502 503 my $name_utf8_bytes = $name_unicode; 504 utf8::encode($name_utf8_bytes); 505 506 my @warnings; 507 { 508 local $SIG{'__WARN__'} = sub { push @warnings, @_ }; 509 $0 = $name_unicode; 510 } 511 512 is( 0 + @warnings, 1, 'warning after assignment of wide character' ); 513 like( $warnings[0], qr<wide>i, '.. and the warning is about a wide character' ); 514 is( $0, $name_utf8_bytes, '.. and the UTF-8 version is written' ); 515 516 SKIP: { 517 my $skip_tests = 1; 518 skip "Test is for Linux, not $^O" if $^O ne 'linux'; 519 is( $linux_cmdline_cr->($skip_tests), $name_utf8_bytes, '.. and /proc cmdline shows that'); 520 } 521 522 @warnings = (); 523 local $SIG{'__WARN__'} = sub { push @warnings, @_ }; 524 { local $0 = "alpha"; } 525 is( 0 + @warnings, 0, '$0 from wide -> local non-wide: no warning'); 526 527 { local $0 = "$name_unicode-redux" } 528 is( 0 + @warnings, 1, 'one warning: wide -> local wide' ); 529 530 $0 = "aaaa"; 531 @warnings = (); 532 { local $0 = "$name_unicode-redux" } 533 is( 0 + @warnings, 1, 'one warning: non-wide -> local wide' ); 534} 535 536{ 537 my $ok = 1; 538 my $warn = ''; 539 local $SIG{'__WARN__'} = sub { $ok = 0; $warn = join '', @_; $warn =~ s/\n$//; }; 540 $! = undef; 541 local $TODO = $Is_VMS ? "'\$!=undef' does throw a warning" : ''; 542 ok($ok, $warn); 543} 544 545SKIP: { 546 skip_if_miniperl("miniperl can't rely on loading %Errno", 2); 547 no warnings 'void'; 548 549# Make sure Errno hasn't been prematurely autoloaded 550 551 ok !keys %Errno::; 552 553# Test auto-loading of Errno when %! is used 554 555 ok scalar eval q{ 556 %!; 557 scalar %Errno::; 558 }, $@; 559} 560 561SKIP: { 562 skip_if_miniperl("miniperl can't rely on loading %Errno", 2); 563 # Make sure that Errno loading doesn't clobber $! 564 565 undef %Errno::; 566 delete $INC{"Errno.pm"}; 567 delete $::{"!"}; 568 569 open(FOO, "nonesuch"); # Generate ENOENT 570 my %errs = %{"!"}; # Cause Errno.pm to be loaded at run-time 571 ok ${"!"}{ENOENT}; 572 573 # Make sure defined(*{"!"}) before %! does not stop %! from working 574 is 575 runperl( 576 prog => 'BEGIN { defined *{q-!-} } print qq-ok\n- if tied %!', 577 ), 578 "ok\n", 579 'defined *{"!"} does not stop %! from working'; 580} 581 582# Check that we don't auto-load packages 583foreach (['powie::!', 'Errno']) { 584 my ($symbol, $package) = @$_; 585 SKIP: { 586 (my $extension = $package) =~ s|::|/|g; 587 skip "$package is statically linked", 2 588 if $Config{static_ext} =~ m|\b\Q$extension\E\b|; 589 foreach my $scalar_first ('', '$$symbol;') { 590 my $desc = qq{Referencing %{"$symbol"}}; 591 $desc .= qq{ after mentioning \${"$symbol"}} if $scalar_first; 592 $desc .= " doesn't load $package"; 593 594 fresh_perl_is(<<"EOP", 0, {}, $desc); 595use strict qw(vars subs); 596my \$symbol = '$symbol'; 597$scalar_first; 5981 if %{\$symbol}; 599print scalar %${package}::; 600EOP 601 } 602 } 603} 604 605is $^S, 0; 606eval { is $^S,1 }; 607eval " BEGIN { ok ! defined \$^S } "; 608is $^S, 0; 609 610my $taint = ${^TAINT}; 611is ${^TAINT}, $taint; 612eval { ${^TAINT} = 1 }; 613is ${^TAINT}, $taint; 614 615# 5.6.1 had a bug: @+ and @- were not properly interpolated 616# into double-quoted strings 617# 20020414 mjd-perl-patch+@plover.com 618"I like pie" =~ /(I) (like) (pie)/; 619is "@-", "0 0 2 7"; 620is "@+", "10 1 6 10"; 621 622# Tests for the magic get of $\ 623{ 624 my $ok = 0; 625 # [perl #19330] 626 { 627 local $\ = undef; 628 $\++; $\++; 629 $ok = $\ eq 2; 630 } 631 ok $ok; 632 $ok = 0; 633 { 634 local $\ = "a\0b"; 635 $ok = "a$\b" eq "aa\0bb"; 636 } 637 ok $ok; 638} 639 640# Test for bug [perl #36434] 641# Can not do this test on VMS according to comments 642# in mg.c/Perl_magic_clear_all_env() 643SKIP: { 644 skip('Can\'t make assignment to \%ENV on this system', 3) if $Is_VMS; 645 646 local @ISA; 647 local %ENV; 648 # This used to be __PACKAGE__, but that causes recursive 649 # inheritance, which is detected earlier now and broke 650 # this test 651 eval { push @ISA, __FILE__ }; 652 is $@, '', 'Push a constant on a magic array'; 653 $@ and print "# $@"; 654 eval { %ENV = (PATH => __PACKAGE__) }; 655 is $@, '', 'Assign a constant to a magic hash'; 656 $@ and print "# $@"; 657 eval { my %h = qw(A B); %ENV = (PATH => (keys %h)[0]) }; 658 is $@, '', 'Assign a shared key to a magic hash'; 659 $@ and print "# $@"; 660} 661 662# Tests for Perl_magic_clearsig 663foreach my $sig (qw(__WARN__ INT)) { 664 $SIG{$sig} = lc $sig; 665 is $SIG{$sig}, 'main::' . lc $sig, "Can assign to $sig"; 666 is delete $SIG{$sig}, 'main::' . lc $sig, "Can delete from $sig"; 667 is $SIG{$sig}, undef, "$sig is now gone"; 668 is delete $SIG{$sig}, undef, "$sig remains gone"; 669} 670 671# And now one which doesn't exist; 672{ 673 no warnings 'signal'; 674 $SIG{HUNGRY} = 'mmm, pie'; 675} 676is $SIG{HUNGRY}, 'mmm, pie', 'Can assign to HUNGRY'; 677is delete $SIG{HUNGRY}, 'mmm, pie', 'Can delete from HUNGRY'; 678is $SIG{HUNGRY}, undef, "HUNGRY is now gone"; 679is delete $SIG{HUNGRY}, undef, "HUNGRY remains gone"; 680 681# Test deleting signals that we never set 682foreach my $sig (qw(__DIE__ _BOGUS_HOOK KILL THIRSTY)) { 683 is $SIG{$sig}, undef, "$sig is not present"; 684 is delete $SIG{$sig}, undef, "delete of $sig returns undef"; 685} 686 687{ 688 $! = 9999; 689 is int $!, 9999, q{[perl #72850] Core dump in bleadperl from perl -e '$! = 9999; $a = $!;'}; 690 691} 692 693# %+ %- 694SKIP: { 695 skip_if_miniperl("No XS in miniperl", 2); 696 # Make sure defined(*{"+"}) before %+ does not stop %+ from working 697 is 698 runperl( 699 prog => 'BEGIN { defined *{q-+-} } print qq-ok\n- if tied %+', 700 ), 701 "ok\n", 702 'defined *{"+"} does not stop %+ from working'; 703 is 704 runperl( 705 prog => 'BEGIN { defined *{q=-=} } print qq-ok\n- if tied %-', 706 ), 707 "ok\n", 708 'defined *{"-"} does not stop %- from working'; 709} 710 711SKIP: { 712 skip_if_miniperl("No XS in miniperl", 1); 713 714 for ( [qw( %! Errno )] ) { 715 my ($var, $mod) = @$_; 716 my $modfile = $mod =~ s|::|/|gr . ".pm"; 717 fresh_perl_is 718 qq 'sub UNIVERSAL::AUTOLOAD{} 719 $mod\::foo() if 0; 720 $var; 721 print "ok\\n" if \$INC{"$modfile"}', 722 "ok\n", 723 { switches => [ '-X' ] }, 724 "$var still loads $mod when stash and UNIVERSAL::AUTOLOAD exist"; 725 } 726} 727 728# ${^LAST_FH} 729() = tell STDOUT; 730is ${^LAST_FH}, \*STDOUT, '${^LAST_FH} after tell'; 731() = tell STDIN; 732is ${^LAST_FH}, \*STDIN, '${^LAST_FH} after another tell'; 733{ 734 my $fh = *STDOUT; 735 () = tell $fh; 736 is ${^LAST_FH}, \$fh, '${^LAST_FH} referencing lexical coercible glob'; 737} 738# This also tests that ${^LAST_FH} is a weak reference: 739is ${^LAST_FH}, undef, '${^LAST_FH} is undef when PL_last_in_gv is NULL'; 740 741# all of these would set PL_last_in_gv to a non-GV which would 742# assert when referenced by the magic for ${^LAST_FH}. 743# The approach to fixing this has changed (#128263), but it's still useful 744# to check each op. 745for my $code ('tell $0', 'sysseek $0, 0, 0', 'seek $0, 0, 0', 'eof $0') { 746 fresh_perl_is("$code; print defined \${^LAST_FH} ? qq(not ok\n) : qq(ok\n)", "ok\n", 747 undef, "check $code doesn't define \${^LAST_FH}"); 748} 749 750# $| 751fresh_perl_is 'print $| = ~$|', "1\n", {switches => ['-l']}, 752 '[perl #4760] print $| = ~$|'; 753fresh_perl_is 754 'select f; undef *f; ${q/|/}; print STDOUT qq|ok\n|', "ok\n", {}, 755 '[perl #115206] no crash when vivifying $| while *{+select}{IO} is undef'; 756 757# ${^OPEN} and $^H interaction 758# Setting ${^OPEN} causes $^H to change, but setting $^H would only some- 759# times make ${^OPEN} change, depending on whether it was in the same BEGIN 760# block. Don’t test actual values (subject to change); just test for 761# consistency. 762my @stuff; 763eval ' 764 BEGIN { ${^OPEN} = "a\0b"; $^H = 0; push @stuff, ${^OPEN} } 765 BEGIN { ${^OPEN} = "a\0b"; $^H = 0 } BEGIN { push @stuff, ${^OPEN} } 7661' or die $@; 767is $stuff[0], $stuff[1], '$^H modifies ${^OPEN} consistently'; 768 769# deleting $::{"\cH"} 770is runperl(prog => 'delete $::{qq-\cH-}; ${^OPEN}=foo; print qq-ok\n-'), 771 "ok\n", 772 'deleting $::{"\cH"}'; 773 774# Tests for some non-magic names: 775is ${^MPE}, undef, '${^MPE} starts undefined'; 776is ++${^MPE}, 1, '${^MPE} can be incremented'; 777 778# This one used to behave as ${^MATCH} due to a missing break: 779is ${^MPEN}, undef, '${^MPEN} starts undefined'; 780# This one used to croak due to that missing break: 781is ++${^MPEN}, 1, '${^MPEN} can be incremented'; 782 783{ 784 no warnings 'deprecated'; 785 eval { ${^E_NCODING} = 1 }; 786 is $@, "", 'Setting ${^E_NCODING} does nothing'; 787 $_ = ${^E_NCODING}; 788 pass('can read ${^E_NCODING} without blowing up'); 789 is $_, 1, '${^E_NCODING} is whatever it was set to'; 790} 791 792{ 793 my $warned = 0; 794 local $SIG{__WARN__} = sub { ++$warned if $_[0] =~ /Use of uninitialized value in unshift/; print "# @_"; }; 795 unshift @RT12608::A::ISA, qw(RT12608::B RT12608::C); 796 is $warned, 0, '[perl #126082] unshifting onto @ISA doesn\'t trigger set magic for each item'; 797} 798 799{ 800 my $warned = 0; 801 local $SIG{__WARN__} = sub { ++$warned if $_[0] =~ /Use of uninitialized value in unshift/; print "# @_"; }; 802 803 my $x; tie $x, 'RT12608::F'; 804 unshift @RT12608::X::ISA, $x, "RT12608::Z"; 805 is $warned, 0, '[perl #126082] PL_delaymagic correctly/saved restored when pushing/unshifting onto @ISA'; 806 807 package RT12608::F; 808 use parent 'Tie::Scalar'; 809 sub TIESCALAR { bless {}; } 810 sub FETCH { push @RT12608::G::ISA, "RT12608::H"; "RT12608::Y"; } 811} 812 813 814# ^^^^^^^^^ New tests go here ^^^^^^^^^ 815 816SKIP: { 817 skip "Win32 needs XS for env/shell tests", 20 818 if $Is_MSWin32 && is_miniperl; 819 820 SKIP: { 821 skip("clearing \%ENV is not safe when running under valgrind or on VMS") 822 if $ENV{PERL_VALGRIND} || $Is_VMS; 823 824 $PATH = $ENV{PATH}; 825 $SYSTEMROOT = $ENV{SYSTEMROOT} if exists $ENV{SYSTEMROOT}; # win32 826 $PDL = $ENV{PERL_DESTRUCT_LEVEL} || 0; 827 $ENV{foo} = "bar"; 828 %ENV = (); 829 $ENV{PATH} = $PATH; 830 $ENV{SYSTEMROOT} = $SYSTEMROOT if defined $SYSTEMROOT; 831 $ENV{PERL_DESTRUCT_LEVEL} = $PDL || 0; 832 if ($Is_MSWin32) { 833 is `set foo 2>NUL`, ""; 834 } else { 835 is `echo \$foo`, "\n"; 836 } 837 } 838 839 $ENV{__NoNeSuCh} = 'foo'; 840 $0 = 'bar'; 841 env_is(__NoNeSuCh => 'foo', 'setting $0 does not break %ENV'); 842 843 $ENV{__NoNeSuCh2} = 'foo'; 844 $ENV{__NoNeSuCh2} = undef; 845 env_is(__NoNeSuCh2 => '', 'setting a key as undef does not delete it'); 846 847 # stringify a glob 848 $ENV{foo} = *TODO; 849 env_is(foo => '*main::TODO', 'ENV store of stringified glob'); 850 851 # stringify a ref 852 my $ref = []; 853 $ENV{foo} = $ref; 854 env_is(foo => "$ref", 'ENV store of stringified ref'); 855 856 # downgrade utf8 when possible 857 $bytes = "eh zero \x{A0}"; 858 utf8::upgrade($chars = $bytes); 859 $forced = $ENV{foo} = $chars; 860 ok(!utf8::is_utf8($forced) && $forced eq $bytes, 'ENV store downgrades utf8 in SV'); 861 env_is(foo => $bytes, 'ENV store downgrades utf8 in setenv'); 862 fail 'chars should still be wide!' if !utf8::is_utf8($chars); 863 $ENV{$chars} = 'widekey'; 864 env_is("eh zero \x{A0}" => 'widekey', 'ENV store downgrades utf8 key in setenv'); 865 fail 'chars should still be wide!' if !utf8::is_utf8($chars); 866 is( delete($ENV{$chars}), 'widekey', 'delete(%ENV) downgrades utf8 key' ); 867 868 # warn when downgrading utf8 is not possible 869 $chars = "X-Day \x{1998}"; 870 utf8::encode($bytes = $chars); 871 { 872 my $warned = 0; 873 local $SIG{__WARN__} = sub { ++$warned if $_[0] =~ /^Wide character in setenv/; print "# @_" }; 874 $forced = $ENV{foo} = $chars; 875 ok($warned == 1, 'ENV store warns about wide characters'); 876 877 fail 'chars should still be wide!' if !utf8::is_utf8($chars); 878 $ENV{$chars} = 'widekey'; 879 env_is($forced => 'widekey', 'ENV store takes utf8-encoded key in setenv'); 880 881 ok($warned == 2, 'ENV key store warns about wide characters'); 882 } 883 ok(!utf8::is_utf8($forced) && $forced eq $bytes, 'ENV store encodes high utf8 in SV'); 884 env_is(foo => $bytes, 'ENV store encodes high utf8 in SV'); 885 886 # test local $ENV{foo} on existing foo 887 { 888 local $ENV{__NoNeSuCh}; 889 { local $TODO = 'exists on %ENV should reflect real env'; 890 ok(!exists $ENV{__NoNeSuCh}, 'not exists $ENV{existing} during local $ENV{existing}'); } 891 env_is(__NoNeLoCaL => ''); 892 } 893 ok(exists $ENV{__NoNeSuCh}, 'exists $ENV{existing} after local $ENV{existing}'); 894 env_is(__NoNeSuCh => 'foo'); 895 896 # test local $ENV{foo} on new foo 897 { 898 local $ENV{__NoNeLoCaL} = 'foo'; 899 ok(exists $ENV{__NoNeLoCaL}, 'exists $ENV{new} during local $ENV{new}'); 900 env_is(__NoNeLoCaL => 'foo'); 901 } 902 ok(!exists $ENV{__NoNeLoCaL}, 'not exists $ENV{new} after local $ENV{new}'); 903 env_is(__NoNeLoCaL => ''); 904 905 SKIP: { 906 skip("\$0 check only on Linux, Dragonfly BSD and FreeBSD", 2) 907 unless $^O =~ /^(linux|android|dragonfly|freebsd)$/; 908 909 SKIP: { 910 skip("No procfs cmdline support", 1) 911 unless open CMDLINE, "/proc/$$/cmdline"; 912 913 chomp(my $line = scalar <CMDLINE>); 914 my $me = (split /\0/, $line)[0]; 915 is $me, $0, 'altering $0 is effective (testing with /proc/)'; 916 close CMDLINE; 917 } 918 skip("No \$0 check with 'ps' on Android", 1) if $^O eq 'android'; 919 # perlbug #22811 920 my $mydollarzero = sub { 921 my($arg) = shift; 922 $0 = $arg if defined $arg; 923 # In FreeBSD the ps -o command= will cause 924 # an empty header line, grab only the last line. 925 my $ps = (`ps -o command= -p $$`)[-1]; 926 return if $?; 927 chomp $ps; 928 $ps; 929 }; 930 my $ps = $mydollarzero->("x"); 931 # we allow that something goes wrong with the ps command 932 !$ps && skip("The ps command failed", 1); 933 my $ps_re = ( $^O =~ /^(dragonfly|freebsd)$/ ) 934 # FreeBSD cannot get rid of both the leading "perl :" 935 # and the trailing " (perl)": some FreeBSD versions 936 # can get rid of the first one. 937 ? qr/^(?:(?:mini)?perl: )?x(?: \((?:mini)?perl\))?$/ 938 # In Linux 2.4 we would get an exact match ($ps eq 'x') but 939 # in Linux 2.2 there seems to be something funny going on: 940 # it seems as if the original length of the argv[] would 941 # be stored in the proc struct and then used by ps(1), 942 # no matter what characters we use to pad the argv[]. 943 # (And if we use \0:s, they are shown as spaces.) Sigh. 944 : qr/^x\s*$/ 945 ; 946 like($ps, $ps_re, 'altering $0 is effective (testing with `ps`)'); 947 } 948} 949 950# in some situations $SIG{ALRM} might be 'IGNORE', eg: 951# git rebase --exec='perl -e "print \$SIG{ALRM}" && git co -f' HEAD~2 952# will print out 'IGNORE' 953my $sig_alarm_expect= $SIG{ALRM}; 954{ 955 local %SIG = (%SIG, ALRM => sub {}) 956}; 957is $SIG{ALRM}, $sig_alarm_expect, '$SIG{ALRM} is as expected'; 958 959# test case-insignificance of %ENV (these tests must be enabled only 960# when perl is compiled with -DENV_IS_CASELESS) 961SKIP: { 962 skip('no caseless %ENV support', 4) unless $Is_MSWin32; 963 964 %ENV = (); 965 $ENV{'Foo'} = 'bar'; 966 $ENV{'fOo'} = 'baz'; 967 is scalar(keys(%ENV)), 1; 968 ok exists $ENV{'FOo'}; 969 is delete $ENV{'foO'}, 'baz'; 970 is scalar(keys(%ENV)), 0; 971} 972 973__END__ 974 975# Put new tests before the various ENV tests, as they blow %ENV away. 976