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: 437SKIP: 438{ 439 # setproctitle() misbehaves on dragonfly 440 # https://bugs.dragonflybsd.org/issues/3319 441 # https://github.com/Perl/perl5/issues/19894 442 skip "setproctitle() is flaky on DragonflyBSD", 11 443 if $^O eq "dragonfly"; 444 # Test both ASCII and EBCDIC systems: 445 my $char = chr( utf8::native_to_unicode(0xe9) ); 446 447 # We want $char_with_utf8_pv's PV to be UTF-8-encoded because we need to 448 # test that Perl translates UTF-8-stored code points to plain octets when 449 # assigning to $0. 450 # 451 my $char_with_utf8_pv = $char; 452 utf8::upgrade($char_with_utf8_pv); 453 454 # This will be the same logical code point as $char_with_utf8_pv, but 455 # implemented in Perl internally as a raw byte rather than UTF-8. 456 # (NB: $char is *probably* already utf8::downgrade()d, but let's not 457 # assume that to be the case.) 458 # 459 my $char_with_plain_pv = $char; 460 utf8::downgrade($char_with_plain_pv); 461 462 $0 = $char_with_utf8_pv; 463 464 # In case the assignment to $0 changed $char_with_utf8_pv, ensure that 465 # it is still interally double-UTF-8-encoded: 466 # 467 utf8::upgrade($char_with_utf8_pv); 468 469 is ($0, $char_with_utf8_pv, 'compare $0 to UTF8-flagged'); 470 is ($0, $char_with_plain_pv, 'compare $0 to non-UTF8-flagged'); 471 472 my $linux_cmdline_cr = sub { 473 my $skip = shift // 1; 474 open my $rfh, '<', "/proc/$$/cmdline" 475 or skip "failed to read '/proc/$$/cmdline': $!", $skip; 476 my $got = do { local $/; <$rfh> }; 477 478 # Some kernels leave a trailing NUL on. Some add a bunch of spaces 479 # after that NUL. We want neither. 480 # 481 # A selection of kernels/distros tested: 482 # 483 # 4.18.0-348.20.1.el8_5.x86_64 (AlmaLinux 8.5): NUL then spaces 484 # 4.18.0-348.23.1.el8_5.x86_64 (AlmaLinux 8.5): NUL, spaces, then NUL 485 # 3.10.0-1160.62.1.el7.x86_64 (CentOS 7.9.2009): no NUL nor spaces 486 # 2.6.32-954.3.5.lve1.4.87.el6.x86_64 (CloudLinux 6.10): ^^ ditto 487 # 488 # 5.13.0-1025-raspi (Ubuntu 21.10): NUL only 489 # 5.10.103-v7+ (RaspiOS 10): NUL only 490 # 491 $got =~ s/\0[\s\0]*\z//; 492 493 return $got; 494 }; 495 496 SKIP: { 497 my $skip_tests = 2; 498 skip "Test is for Linux, not $^O", $skip_tests if $^O ne 'linux'; 499 my $slurp = $linux_cmdline_cr->($skip_tests); 500 is( $slurp, $char_with_utf8_pv, 501 '/proc cmdline shows as expected (compare to UTF8-flagged)' ); 502 is( $slurp, $char_with_plain_pv, 503 '/proc cmdline shows as expected (compare to non-UTF8-flagged)' ); 504 } 505 506 my $name_unicode = "haha\x{100}hoho"; 507 508 my $name_utf8_bytes = $name_unicode; 509 utf8::encode($name_utf8_bytes); 510 511 my @warnings; 512 { 513 local $SIG{'__WARN__'} = sub { push @warnings, @_ }; 514 $0 = $name_unicode; 515 } 516 517 is( 0 + @warnings, 1, 'warning after assignment of wide character' ); 518 like( $warnings[0], qr<wide>i, '.. and the warning is about a wide character' ); 519 is( $0, $name_utf8_bytes, '.. and the UTF-8 version is written' ); 520 521 SKIP: { 522 my $skip_tests = 1; 523 skip "Test is for Linux, not $^O" if $^O ne 'linux'; 524 is( $linux_cmdline_cr->($skip_tests), $name_utf8_bytes, '.. and /proc cmdline shows that'); 525 } 526 527 @warnings = (); 528 local $SIG{'__WARN__'} = sub { push @warnings, @_ }; 529 { local $0 = "alpha"; } 530 is( 0 + @warnings, 0, '$0 from wide -> local non-wide: no warning'); 531 532 { local $0 = "$name_unicode-redux" } 533 is( 0 + @warnings, 1, 'one warning: wide -> local wide' ); 534 535 $0 = "aaaa"; 536 @warnings = (); 537 { local $0 = "$name_unicode-redux" } 538 is( 0 + @warnings, 1, 'one warning: non-wide -> local wide' ); 539} 540 541{ 542 my $ok = 1; 543 my $warn = ''; 544 local $SIG{'__WARN__'} = sub { $ok = 0; $warn = join '', @_; $warn =~ s/\n$//; }; 545 $! = undef; 546 local $TODO = $Is_VMS ? "'\$!=undef' does throw a warning" : ''; 547 ok($ok, $warn); 548} 549 550SKIP: { 551 skip_if_miniperl("miniperl can't rely on loading %Errno", 2); 552 no warnings 'void'; 553 554# Make sure Errno hasn't been prematurely autoloaded 555 556 ok !keys %Errno::; 557 558# Test auto-loading of Errno when %! is used 559 560 ok scalar eval q{ 561 %!; 562 scalar %Errno::; 563 }, $@; 564} 565 566SKIP: { 567 skip_if_miniperl("miniperl can't rely on loading %Errno", 2); 568 # Make sure that Errno loading doesn't clobber $! 569 570 undef %Errno::; 571 delete $INC{"Errno.pm"}; 572 delete $::{"!"}; 573 574 open(FOO, "nonesuch"); # Generate ENOENT 575 my %errs = %{"!"}; # Cause Errno.pm to be loaded at run-time 576 ok ${"!"}{ENOENT}; 577 578 # Make sure defined(*{"!"}) before %! does not stop %! from working 579 is 580 runperl( 581 prog => 'BEGIN { defined *{q-!-} } print qq-ok\n- if tied %!', 582 ), 583 "ok\n", 584 'defined *{"!"} does not stop %! from working'; 585} 586 587# Check that we don't auto-load packages 588foreach (['powie::!', 'Errno']) { 589 my ($symbol, $package) = @$_; 590 SKIP: { 591 (my $extension = $package) =~ s|::|/|g; 592 skip "$package is statically linked", 2 593 if $Config{static_ext} =~ m|\b\Q$extension\E\b|; 594 foreach my $scalar_first ('', '$$symbol;') { 595 my $desc = qq{Referencing %{"$symbol"}}; 596 $desc .= qq{ after mentioning \${"$symbol"}} if $scalar_first; 597 $desc .= " doesn't load $package"; 598 599 fresh_perl_is(<<"EOP", 0, {}, $desc); 600use strict qw(vars subs); 601my \$symbol = '$symbol'; 602$scalar_first; 6031 if %{\$symbol}; 604print scalar %${package}::; 605EOP 606 } 607 } 608} 609 610is $^S, 0; 611eval { is $^S,1 }; 612eval " BEGIN { ok ! defined \$^S } "; 613is $^S, 0; 614 615my $taint = ${^TAINT}; 616is ${^TAINT}, $taint; 617eval { ${^TAINT} = 1 }; 618is ${^TAINT}, $taint; 619 620# 5.6.1 had a bug: @+ and @- were not properly interpolated 621# into double-quoted strings 622# 20020414 mjd-perl-patch+@plover.com 623"I like pie" =~ /(I) (like) (pie)/; 624is "@-", "0 0 2 7"; 625is "@+", "10 1 6 10"; 626 627# Tests for the magic get of $\ 628{ 629 my $ok = 0; 630 # [perl #19330] 631 { 632 local $\ = undef; 633 $\++; $\++; 634 $ok = $\ eq 2; 635 } 636 ok $ok; 637 $ok = 0; 638 { 639 local $\ = "a\0b"; 640 $ok = "a$\b" eq "aa\0bb"; 641 } 642 ok $ok; 643} 644 645# Test for bug [perl #36434] 646# Can not do this test on VMS according to comments 647# in mg.c/Perl_magic_clear_all_env() 648SKIP: { 649 skip('Can\'t make assignment to \%ENV on this system', 3) if $Is_VMS; 650 651 local @ISA; 652 local %ENV; 653 # This used to be __PACKAGE__, but that causes recursive 654 # inheritance, which is detected earlier now and broke 655 # this test 656 eval { push @ISA, __FILE__ }; 657 is $@, '', 'Push a constant on a magic array'; 658 $@ and print "# $@"; 659 eval { %ENV = (PATH => __PACKAGE__) }; 660 is $@, '', 'Assign a constant to a magic hash'; 661 $@ and print "# $@"; 662 eval { my %h = qw(A B); %ENV = (PATH => (keys %h)[0]) }; 663 is $@, '', 'Assign a shared key to a magic hash'; 664 $@ and print "# $@"; 665} 666 667# Tests for Perl_magic_clearsig 668foreach my $sig (qw(__WARN__ INT)) { 669 $SIG{$sig} = lc $sig; 670 is $SIG{$sig}, 'main::' . lc $sig, "Can assign to $sig"; 671 is delete $SIG{$sig}, 'main::' . lc $sig, "Can delete from $sig"; 672 is $SIG{$sig}, undef, "$sig is now gone"; 673 is delete $SIG{$sig}, undef, "$sig remains gone"; 674} 675 676# And now one which doesn't exist; 677{ 678 no warnings 'signal'; 679 $SIG{HUNGRY} = 'mmm, pie'; 680} 681is $SIG{HUNGRY}, 'mmm, pie', 'Can assign to HUNGRY'; 682is delete $SIG{HUNGRY}, 'mmm, pie', 'Can delete from HUNGRY'; 683is $SIG{HUNGRY}, undef, "HUNGRY is now gone"; 684is delete $SIG{HUNGRY}, undef, "HUNGRY remains gone"; 685 686# Test deleting signals that we never set 687foreach my $sig (qw(__DIE__ _BOGUS_HOOK KILL THIRSTY)) { 688 is $SIG{$sig}, undef, "$sig is not present"; 689 is delete $SIG{$sig}, undef, "delete of $sig returns undef"; 690} 691 692{ 693 $! = 9999; 694 is int $!, 9999, q{[perl #72850] Core dump in bleadperl from perl -e '$! = 9999; $a = $!;'}; 695 696} 697 698# %+ %- 699SKIP: { 700 skip_if_miniperl("No XS in miniperl", 2); 701 # Make sure defined(*{"+"}) before %+ does not stop %+ from working 702 is 703 runperl( 704 prog => 'BEGIN { defined *{q-+-} } print qq-ok\n- if tied %+', 705 ), 706 "ok\n", 707 'defined *{"+"} does not stop %+ from working'; 708 is 709 runperl( 710 prog => 'BEGIN { defined *{q=-=} } print qq-ok\n- if tied %-', 711 ), 712 "ok\n", 713 'defined *{"-"} does not stop %- from working'; 714} 715 716SKIP: { 717 skip_if_miniperl("No XS in miniperl", 1); 718 719 for ( [qw( %! Errno )] ) { 720 my ($var, $mod) = @$_; 721 my $modfile = $mod =~ s|::|/|gr . ".pm"; 722 fresh_perl_is 723 qq 'sub UNIVERSAL::AUTOLOAD{} 724 $mod\::foo() if 0; 725 $var; 726 print "ok\\n" if \$INC{"$modfile"}', 727 "ok\n", 728 { switches => [ '-X' ] }, 729 "$var still loads $mod when stash and UNIVERSAL::AUTOLOAD exist"; 730 } 731} 732 733# ${^LAST_FH} 734() = tell STDOUT; 735is ${^LAST_FH}, \*STDOUT, '${^LAST_FH} after tell'; 736() = tell STDIN; 737is ${^LAST_FH}, \*STDIN, '${^LAST_FH} after another tell'; 738{ 739 my $fh = *STDOUT; 740 () = tell $fh; 741 is ${^LAST_FH}, \$fh, '${^LAST_FH} referencing lexical coercible glob'; 742} 743# This also tests that ${^LAST_FH} is a weak reference: 744is ${^LAST_FH}, undef, '${^LAST_FH} is undef when PL_last_in_gv is NULL'; 745 746# all of these would set PL_last_in_gv to a non-GV which would 747# assert when referenced by the magic for ${^LAST_FH}. 748# The approach to fixing this has changed (#128263), but it's still useful 749# to check each op. 750for my $code ('tell $0', 'sysseek $0, 0, 0', 'seek $0, 0, 0', 'eof $0') { 751 fresh_perl_is("$code; print defined \${^LAST_FH} ? qq(not ok\n) : qq(ok\n)", "ok\n", 752 undef, "check $code doesn't define \${^LAST_FH}"); 753} 754 755# $| 756fresh_perl_is 'print $| = ~$|', "1\n", {switches => ['-l']}, 757 '[perl #4760] print $| = ~$|'; 758fresh_perl_is 759 'select f; undef *f; ${q/|/}; print STDOUT qq|ok\n|', "ok\n", {}, 760 '[perl #115206] no crash when vivifying $| while *{+select}{IO} is undef'; 761 762# ${^OPEN} and $^H interaction 763# Setting ${^OPEN} causes $^H to change, but setting $^H would only some- 764# times make ${^OPEN} change, depending on whether it was in the same BEGIN 765# block. Don’t test actual values (subject to change); just test for 766# consistency. 767my @stuff; 768eval ' 769 BEGIN { ${^OPEN} = "a\0b"; $^H = 0; push @stuff, ${^OPEN} } 770 BEGIN { ${^OPEN} = "a\0b"; $^H = 0 } BEGIN { push @stuff, ${^OPEN} } 7711' or die $@; 772is $stuff[0], $stuff[1], '$^H modifies ${^OPEN} consistently'; 773 774# deleting $::{"\cH"} 775is runperl(prog => 'delete $::{qq-\cH-}; ${^OPEN}=foo; print qq-ok\n-'), 776 "ok\n", 777 'deleting $::{"\cH"}'; 778 779# Tests for some non-magic names: 780is ${^MPE}, undef, '${^MPE} starts undefined'; 781is ++${^MPE}, 1, '${^MPE} can be incremented'; 782 783# This one used to behave as ${^MATCH} due to a missing break: 784is ${^MPEN}, undef, '${^MPEN} starts undefined'; 785# This one used to croak due to that missing break: 786is ++${^MPEN}, 1, '${^MPEN} can be incremented'; 787 788{ 789 no warnings 'deprecated'; 790 eval { ${^E_NCODING} = 1 }; 791 is $@, "", 'Setting ${^E_NCODING} does nothing'; 792 $_ = ${^E_NCODING}; 793 pass('can read ${^E_NCODING} without blowing up'); 794 is $_, 1, '${^E_NCODING} is whatever it was set to'; 795} 796 797{ 798 my $warned = 0; 799 local $SIG{__WARN__} = sub { ++$warned if $_[0] =~ /Use of uninitialized value in unshift/; print "# @_"; }; 800 unshift @RT12608::A::ISA, qw(RT12608::B RT12608::C); 801 is $warned, 0, '[perl #126082] unshifting onto @ISA doesn\'t trigger set magic for each item'; 802} 803 804{ 805 my $warned = 0; 806 local $SIG{__WARN__} = sub { ++$warned if $_[0] =~ /Use of uninitialized value in unshift/; print "# @_"; }; 807 808 my $x; tie $x, 'RT12608::F'; 809 unshift @RT12608::X::ISA, $x, "RT12608::Z"; 810 is $warned, 0, '[perl #126082] PL_delaymagic correctly/saved restored when pushing/unshifting onto @ISA'; 811 812 package RT12608::F; 813 use parent 'Tie::Scalar'; 814 sub TIESCALAR { bless {}; } 815 sub FETCH { push @RT12608::G::ISA, "RT12608::H"; "RT12608::Y"; } 816} 817 818 819# ^^^^^^^^^ New tests go here ^^^^^^^^^ 820 821SKIP: { 822 skip "Win32 needs XS for env/shell tests", 20 823 if $Is_MSWin32 && is_miniperl; 824 825 SKIP: { 826 skip("clearing \%ENV is not safe when running under valgrind or on VMS") 827 if $ENV{PERL_VALGRIND} || $Is_VMS; 828 829 $PATH = $ENV{PATH}; 830 $SYSTEMROOT = $ENV{SYSTEMROOT} if exists $ENV{SYSTEMROOT}; # win32 831 $PDL = $ENV{PERL_DESTRUCT_LEVEL} || 0; 832 $ENV{foo} = "bar"; 833 %ENV = (); 834 $ENV{PATH} = $PATH; 835 $ENV{SYSTEMROOT} = $SYSTEMROOT if defined $SYSTEMROOT; 836 $ENV{PERL_DESTRUCT_LEVEL} = $PDL || 0; 837 if ($Is_MSWin32) { 838 is `set foo 2>NUL`, ""; 839 } else { 840 is `echo \$foo`, "\n"; 841 } 842 } 843 844 $ENV{__NoNeSuCh} = 'foo'; 845 $0 = 'bar'; 846 env_is(__NoNeSuCh => 'foo', 'setting $0 does not break %ENV'); 847 848 $ENV{__NoNeSuCh2} = 'foo'; 849 $ENV{__NoNeSuCh2} = undef; 850 env_is(__NoNeSuCh2 => '', 'setting a key as undef does not delete it'); 851 852 # stringify a glob 853 $ENV{foo} = *TODO; 854 env_is(foo => '*main::TODO', 'ENV store of stringified glob'); 855 856 # stringify a ref 857 my $ref = []; 858 $ENV{foo} = $ref; 859 env_is(foo => "$ref", 'ENV store of stringified ref'); 860 861 # downgrade utf8 when possible 862 $bytes = "eh zero \x{A0}"; 863 utf8::upgrade($chars = $bytes); 864 $forced = $ENV{foo} = $chars; 865 ok(!utf8::is_utf8($forced) && $forced eq $bytes, 'ENV store downgrades utf8 in SV'); 866 env_is(foo => $bytes, 'ENV store downgrades utf8 in setenv'); 867 fail 'chars should still be wide!' if !utf8::is_utf8($chars); 868 $ENV{$chars} = 'widekey'; 869 env_is("eh zero \x{A0}" => 'widekey', 'ENV store downgrades utf8 key in setenv'); 870 fail 'chars should still be wide!' if !utf8::is_utf8($chars); 871 is( delete($ENV{$chars}), 'widekey', 'delete(%ENV) downgrades utf8 key' ); 872 873 # warn when downgrading utf8 is not possible 874 $chars = "X-Day \x{1998}"; 875 utf8::encode($bytes = $chars); 876 { 877 my $warned = 0; 878 local $SIG{__WARN__} = sub { ++$warned if $_[0] =~ /^Wide character in setenv/; print "# @_" }; 879 $forced = $ENV{foo} = $chars; 880 ok($warned == 1, 'ENV store warns about wide characters'); 881 882 fail 'chars should still be wide!' if !utf8::is_utf8($chars); 883 $ENV{$chars} = 'widekey'; 884 env_is($forced => 'widekey', 'ENV store takes utf8-encoded key in setenv'); 885 886 ok($warned == 2, 'ENV key store warns about wide characters'); 887 } 888 ok(!utf8::is_utf8($forced) && $forced eq $bytes, 'ENV store encodes high utf8 in SV'); 889 env_is(foo => $bytes, 'ENV store encodes high utf8 in SV'); 890 891 # test local $ENV{foo} on existing foo 892 { 893 local $ENV{__NoNeSuCh}; 894 { local $TODO = 'exists on %ENV should reflect real env'; 895 ok(!exists $ENV{__NoNeSuCh}, 'not exists $ENV{existing} during local $ENV{existing}'); } 896 env_is(__NoNeLoCaL => ''); 897 } 898 ok(exists $ENV{__NoNeSuCh}, 'exists $ENV{existing} after local $ENV{existing}'); 899 env_is(__NoNeSuCh => 'foo'); 900 901 # test local $ENV{foo} on new foo 902 { 903 local $ENV{__NoNeLoCaL} = 'foo'; 904 ok(exists $ENV{__NoNeLoCaL}, 'exists $ENV{new} during local $ENV{new}'); 905 env_is(__NoNeLoCaL => 'foo'); 906 } 907 ok(!exists $ENV{__NoNeLoCaL}, 'not exists $ENV{new} after local $ENV{new}'); 908 env_is(__NoNeLoCaL => ''); 909 910 SKIP: { 911 skip("\$0 check only on Linux, Dragonfly BSD and FreeBSD", 2) 912 unless $^O =~ /^(linux|android|dragonfly|freebsd)$/; 913 914 SKIP: { 915 skip("No procfs cmdline support", 1) 916 unless open CMDLINE, "/proc/$$/cmdline"; 917 918 chomp(my $line = scalar <CMDLINE>); 919 my $me = (split /\0/, $line)[0]; 920 is $me, $0, 'altering $0 is effective (testing with /proc/)'; 921 close CMDLINE; 922 } 923 skip("No \$0 check with 'ps' on Android", 1) if $^O eq 'android'; 924 # perlbug #22811 925 my $mydollarzero = sub { 926 my($arg) = shift; 927 $0 = $arg if defined $arg; 928 # In FreeBSD the ps -o command= will cause 929 # an empty header line, grab only the last line. 930 my $ps = (`ps -o command= -p $$`)[-1]; 931 return if $?; 932 chomp $ps; 933 $ps; 934 }; 935 my $ps = $mydollarzero->("x"); 936 # we allow that something goes wrong with the ps command 937 !$ps && skip("The ps command failed", 1); 938 my $ps_re = ( $^O =~ /^(dragonfly|freebsd)$/ ) 939 # FreeBSD cannot get rid of both the leading "perl :" 940 # and the trailing " (perl)": some FreeBSD versions 941 # can get rid of the first one. 942 ? qr/^(?:(?:mini)?perl: )?x(?: \((?:mini)?perl\))?$/ 943 # In Linux 2.4 we would get an exact match ($ps eq 'x') but 944 # in Linux 2.2 there seems to be something funny going on: 945 # it seems as if the original length of the argv[] would 946 # be stored in the proc struct and then used by ps(1), 947 # no matter what characters we use to pad the argv[]. 948 # (And if we use \0:s, they are shown as spaces.) Sigh. 949 : qr/^x\s*$/ 950 ; 951 like($ps, $ps_re, 'altering $0 is effective (testing with `ps`)'); 952 } 953} 954 955# in some situations $SIG{ALRM} might be 'IGNORE', eg: 956# git rebase --exec='perl -e "print \$SIG{ALRM}" && git co -f' HEAD~2 957# will print out 'IGNORE' 958my $sig_alarm_expect= $SIG{ALRM}; 959{ 960 local %SIG = (%SIG, ALRM => sub {}) 961}; 962is $SIG{ALRM}, $sig_alarm_expect, '$SIG{ALRM} is as expected'; 963 964# test case-insignificance of %ENV (these tests must be enabled only 965# when perl is compiled with -DENV_IS_CASELESS) 966SKIP: { 967 skip('no caseless %ENV support', 4) unless $Is_MSWin32; 968 969 %ENV = (); 970 $ENV{'Foo'} = 'bar'; 971 $ENV{'fOo'} = 'baz'; 972 is scalar(keys(%ENV)), 1; 973 ok exists $ENV{'FOo'}; 974 is delete $ENV{'foO'}, 'baz'; 975 is scalar(keys(%ENV)), 0; 976} 977 978__END__ 979 980# Put new tests before the various ENV tests, as they blow %ENV away. 981