1*5486feefSafresh1#!./perl 2*5486feefSafresh1 3*5486feefSafresh1BEGIN { 4*5486feefSafresh1 chdir 't' if -d 't'; 5*5486feefSafresh1 require './test.pl'; 6*5486feefSafresh1 set_up_inc('../lib'); 7*5486feefSafresh1 skip_all('Can\'t run under miniperl') if is_miniperl(); 8*5486feefSafresh1} 9*5486feefSafresh1 10*5486feefSafresh1use strict; 11*5486feefSafresh1 12*5486feefSafresh1use Fcntl qw(SEEK_SET SEEK_CUR SEEK_END); # Not 0, 1, 2 everywhere. 13*5486feefSafresh1use Errno qw(EACCES); 14*5486feefSafresh1 15*5486feefSafresh1plan(128); 16*5486feefSafresh1 17*5486feefSafresh1my $fh; 18*5486feefSafresh1my $var = "aaa\n"; 19*5486feefSafresh1ok(open($fh,"+<",\$var)); 20*5486feefSafresh1 21*5486feefSafresh1is(<$fh>, $var); 22*5486feefSafresh1 23*5486feefSafresh1ok(eof($fh)); 24*5486feefSafresh1 25*5486feefSafresh1ok(seek($fh,0,SEEK_SET)); 26*5486feefSafresh1ok(!eof($fh)); 27*5486feefSafresh1 28*5486feefSafresh1ok(print $fh "bbb\n"); 29*5486feefSafresh1is($var, "bbb\n"); 30*5486feefSafresh1$var = "foo\nbar\n"; 31*5486feefSafresh1ok(seek($fh,0,SEEK_SET)); 32*5486feefSafresh1ok(!eof($fh)); 33*5486feefSafresh1is(<$fh>, "foo\n"); 34*5486feefSafresh1ok(close $fh, $!); 35*5486feefSafresh1 36*5486feefSafresh1# Test that semantics are similar to normal file-based I/O 37*5486feefSafresh1# Check that ">" clobbers the scalar 38*5486feefSafresh1$var = "Something"; 39*5486feefSafresh1open $fh, ">", \$var; 40*5486feefSafresh1is($var, ""); 41*5486feefSafresh1# Check that file offset set to beginning of scalar 42*5486feefSafresh1my $off = tell($fh); 43*5486feefSafresh1is($off, 0); 44*5486feefSafresh1# Check that writes go where they should and update the offset 45*5486feefSafresh1$var = "Something"; 46*5486feefSafresh1print $fh "Brea"; 47*5486feefSafresh1$off = tell($fh); 48*5486feefSafresh1is($off, 4); 49*5486feefSafresh1is($var, "Breathing"); 50*5486feefSafresh1close $fh; 51*5486feefSafresh1 52*5486feefSafresh1# Check that ">>" appends to the scalar 53*5486feefSafresh1$var = "Something "; 54*5486feefSafresh1open $fh, ">>", \$var; 55*5486feefSafresh1$off = tell($fh); 56*5486feefSafresh1is($off, 10); 57*5486feefSafresh1is($var, "Something "); 58*5486feefSafresh1# Check that further writes go to the very end of the scalar 59*5486feefSafresh1$var .= "else "; 60*5486feefSafresh1is($var, "Something else "); 61*5486feefSafresh1 62*5486feefSafresh1$off = tell($fh); 63*5486feefSafresh1is($off, 10); 64*5486feefSafresh1 65*5486feefSafresh1print $fh "is here"; 66*5486feefSafresh1is($var, "Something else is here"); 67*5486feefSafresh1close $fh; 68*5486feefSafresh1 69*5486feefSafresh1# Check that updates to the scalar from elsewhere do not 70*5486feefSafresh1# cause problems 71*5486feefSafresh1$var = "line one\nline two\line three\n"; 72*5486feefSafresh1open $fh, "<", \$var; 73*5486feefSafresh1while (<$fh>) { 74*5486feefSafresh1 $var = "foo"; 75*5486feefSafresh1} 76*5486feefSafresh1close $fh; 77*5486feefSafresh1is($var, "foo"); 78*5486feefSafresh1 79*5486feefSafresh1# Check that dup'ing the handle works 80*5486feefSafresh1 81*5486feefSafresh1$var = ''; 82*5486feefSafresh1open $fh, "+>", \$var; 83*5486feefSafresh1print $fh "xxx\n"; 84*5486feefSafresh1open my $dup,'+<&',$fh; 85*5486feefSafresh1print $dup "yyy\n"; 86*5486feefSafresh1seek($dup,0,SEEK_SET); 87*5486feefSafresh1is(<$dup>, "xxx\n"); 88*5486feefSafresh1is(<$dup>, "yyy\n"); 89*5486feefSafresh1close($fh); 90*5486feefSafresh1close($dup); 91*5486feefSafresh1 92*5486feefSafresh1open $fh, '<', \42; 93*5486feefSafresh1is(<$fh>, "42", "reading from non-string scalars"); 94*5486feefSafresh1close $fh; 95*5486feefSafresh1 96*5486feefSafresh1{ package P; sub TIESCALAR {bless{}} sub FETCH { "shazam" } sub STORE {} } 97*5486feefSafresh1tie my $p, 'P'; open $fh, '<', \$p; 98*5486feefSafresh1is(<$fh>, "shazam", "reading from magic scalars"); 99*5486feefSafresh1 100*5486feefSafresh1{ 101*5486feefSafresh1 use warnings; 102*5486feefSafresh1 my $warn = 0; 103*5486feefSafresh1 local $SIG{__WARN__} = sub { $warn++ }; 104*5486feefSafresh1 open my $fh, '>', \my $scalar; 105*5486feefSafresh1 print $fh "foo"; 106*5486feefSafresh1 close $fh; 107*5486feefSafresh1 is($warn, 0, "no warnings when writing to an undefined scalar"); 108*5486feefSafresh1 undef $scalar; 109*5486feefSafresh1 open $fh, '>>', \$scalar; 110*5486feefSafresh1 print $fh "oof"; 111*5486feefSafresh1 close $fh; 112*5486feefSafresh1 is($warn, 0, "no warnings when appending to an undefined scalar"); 113*5486feefSafresh1} 114*5486feefSafresh1 115*5486feefSafresh1{ 116*5486feefSafresh1 use warnings; 117*5486feefSafresh1 my $warn = 0; 118*5486feefSafresh1 local $SIG{__WARN__} = sub { $warn++ }; 119*5486feefSafresh1 for (1..2) { 120*5486feefSafresh1 open my $fh, '>', \my $scalar; 121*5486feefSafresh1 close $fh; 122*5486feefSafresh1 } 123*5486feefSafresh1 is($warn, 0, "no warnings when reusing a lexical"); 124*5486feefSafresh1} 125*5486feefSafresh1 126*5486feefSafresh1{ 127*5486feefSafresh1 use warnings; 128*5486feefSafresh1 my $warn = 0; 129*5486feefSafresh1 local $SIG{__WARN__} = sub { $warn++ }; 130*5486feefSafresh1 131*5486feefSafresh1 my $fetch = 0; 132*5486feefSafresh1 { 133*5486feefSafresh1 package MgUndef; 134*5486feefSafresh1 sub TIESCALAR { bless [] } 135*5486feefSafresh1 sub FETCH { $fetch++; return undef } 136*5486feefSafresh1 sub STORE {} 137*5486feefSafresh1 } 138*5486feefSafresh1 tie my $scalar, 'MgUndef'; 139*5486feefSafresh1 140*5486feefSafresh1 open my $fh, '<', \$scalar; 141*5486feefSafresh1 close $fh; 142*5486feefSafresh1 is($warn, 0, "no warnings reading a magical undef scalar"); 143*5486feefSafresh1 is($fetch, 1, "FETCH only called once"); 144*5486feefSafresh1} 145*5486feefSafresh1 146*5486feefSafresh1{ 147*5486feefSafresh1 use warnings; 148*5486feefSafresh1 my $warn = 0; 149*5486feefSafresh1 local $SIG{__WARN__} = sub { $warn++ }; 150*5486feefSafresh1 my $scalar = 3; 151*5486feefSafresh1 undef $scalar; 152*5486feefSafresh1 open my $fh, '<', \$scalar; 153*5486feefSafresh1 close $fh; 154*5486feefSafresh1 is($warn, 0, "no warnings reading an undef, allocated scalar"); 155*5486feefSafresh1} 156*5486feefSafresh1 157*5486feefSafresh1my $data = "a non-empty PV"; 158*5486feefSafresh1$data = undef; 159*5486feefSafresh1open(MEM, '<', \$data) or die "Fail: $!\n"; 160*5486feefSafresh1my $x = join '', <MEM>; 161*5486feefSafresh1is($x, ''); 162*5486feefSafresh1 163*5486feefSafresh1{ 164*5486feefSafresh1 # [perl #35929] verify that works with $/ (i.e. test PerlIOScalar_unread) 165*5486feefSafresh1 my $s = <<'EOF'; 166*5486feefSafresh1line A 167*5486feefSafresh1line B 168*5486feefSafresh1a third line 169*5486feefSafresh1EOF 170*5486feefSafresh1 open(F, '<', \$s) or die "Could not open string as a file"; 171*5486feefSafresh1 local $/ = ""; 172*5486feefSafresh1 my $ln = <F>; 173*5486feefSafresh1 close F; 174*5486feefSafresh1 is($ln, $s, "[perl #35929]"); 175*5486feefSafresh1} 176*5486feefSafresh1 177*5486feefSafresh1# [perl #40267] PerlIO::scalar doesn't respect readonly-ness 178*5486feefSafresh1{ 179*5486feefSafresh1 my $warn; 180*5486feefSafresh1 local $SIG{__WARN__} = sub { $warn = "@_" }; 181*5486feefSafresh1 ok(!(defined open(F, '>', \undef)), "[perl #40267] - $!"); 182*5486feefSafresh1 is($warn, undef, "no warning with warnings off"); 183*5486feefSafresh1 close F; 184*5486feefSafresh1 185*5486feefSafresh1 use warnings 'layer'; 186*5486feefSafresh1 undef $warn; 187*5486feefSafresh1 my $ro = \43; 188*5486feefSafresh1 ok(!(defined open(F, '>', $ro)), $!); 189*5486feefSafresh1 is($!+0, EACCES, "check we get a read-onlyish error code"); 190*5486feefSafresh1 like($warn, qr/Modification of a read-only value attempted/, 191*5486feefSafresh1 "check we did warn"); 192*5486feefSafresh1 close F; 193*5486feefSafresh1 # but we can read from it 194*5486feefSafresh1 ok(open(F, '<', $ro), $!); 195*5486feefSafresh1 is(<F>, 43); 196*5486feefSafresh1 close F; 197*5486feefSafresh1} 198*5486feefSafresh1 199*5486feefSafresh1{ 200*5486feefSafresh1 # Check that we zero fill when needed when seeking, 201*5486feefSafresh1 # and that seeking negative off the string does not do bad things. 202*5486feefSafresh1 203*5486feefSafresh1 my $foo; 204*5486feefSafresh1 205*5486feefSafresh1 ok(open(F, '>', \$foo)); 206*5486feefSafresh1 207*5486feefSafresh1 # Seeking forward should zero fill. 208*5486feefSafresh1 209*5486feefSafresh1 ok(seek(F, 50, SEEK_SET)); 210*5486feefSafresh1 print F "x"; 211*5486feefSafresh1 is(length($foo), 51); 212*5486feefSafresh1 like($foo, qr/^\0{50}x$/); 213*5486feefSafresh1 214*5486feefSafresh1 is(tell(F), 51); 215*5486feefSafresh1 ok(seek(F, 0, SEEK_SET)); 216*5486feefSafresh1 is(length($foo), 51); 217*5486feefSafresh1 218*5486feefSafresh1 # Seeking forward again should zero fill but only the new bytes. 219*5486feefSafresh1 220*5486feefSafresh1 ok(seek(F, 100, SEEK_SET)); 221*5486feefSafresh1 print F "y"; 222*5486feefSafresh1 is(length($foo), 101); 223*5486feefSafresh1 like($foo, qr/^\0{50}x\0{49}y$/); 224*5486feefSafresh1 is(tell(F), 101); 225*5486feefSafresh1 226*5486feefSafresh1 # Seeking back and writing should not zero fill. 227*5486feefSafresh1 228*5486feefSafresh1 ok(seek(F, 75, SEEK_SET)); 229*5486feefSafresh1 print F "z"; 230*5486feefSafresh1 is(length($foo), 101); 231*5486feefSafresh1 like($foo, qr/^\0{50}x\0{24}z\0{24}y$/); 232*5486feefSafresh1 is(tell(F), 76); 233*5486feefSafresh1 234*5486feefSafresh1 # Seeking negative should not do funny business. 235*5486feefSafresh1 236*5486feefSafresh1 ok(!seek(F, -50, SEEK_SET), $!); 237*5486feefSafresh1 ok(seek(F, 0, SEEK_SET)); 238*5486feefSafresh1 ok(!seek(F, -50, SEEK_CUR), $!); 239*5486feefSafresh1 ok(!seek(F, -150, SEEK_END), $!); 240*5486feefSafresh1} 241*5486feefSafresh1 242*5486feefSafresh1# RT #43789: should respect tied scalar 243*5486feefSafresh1 244*5486feefSafresh1{ 245*5486feefSafresh1 package TS; 246*5486feefSafresh1 my $s; 247*5486feefSafresh1 sub TIESCALAR { bless \my $x } 248*5486feefSafresh1 sub FETCH { $s .= ':F'; ${$_[0]} } 249*5486feefSafresh1 sub STORE { $s .= ":S($_[1])"; ${$_[0]} = $_[1] } 250*5486feefSafresh1 251*5486feefSafresh1 package main; 252*5486feefSafresh1 253*5486feefSafresh1 my $x; 254*5486feefSafresh1 $s = ''; 255*5486feefSafresh1 tie $x, 'TS'; 256*5486feefSafresh1 my $fh; 257*5486feefSafresh1 258*5486feefSafresh1 ok(open($fh, '>', \$x), 'open-write tied scalar'); 259*5486feefSafresh1 $s .= ':O'; 260*5486feefSafresh1 print($fh 'ABC'); 261*5486feefSafresh1 $s .= ':P'; 262*5486feefSafresh1 ok(seek($fh, 0, SEEK_SET)); 263*5486feefSafresh1 $s .= ':SK'; 264*5486feefSafresh1 print($fh 'DEF'); 265*5486feefSafresh1 $s .= ':P'; 266*5486feefSafresh1 ok(close($fh), 'close tied scalar - write'); 267*5486feefSafresh1 is($s, ':F:S():O:F:S(ABC):P:SK:F:S(DEF):P', 'tied actions - write'); 268*5486feefSafresh1 is($x, 'DEF', 'new value preserved'); 269*5486feefSafresh1 270*5486feefSafresh1 $x = 'GHI'; 271*5486feefSafresh1 $s = ''; 272*5486feefSafresh1 ok(open($fh, '+<', \$x), 'open-read tied scalar'); 273*5486feefSafresh1 $s .= ':O'; 274*5486feefSafresh1 my $buf; 275*5486feefSafresh1 is(read($fh,$buf,2), 2, 'read1'); 276*5486feefSafresh1 $s .= ':R'; 277*5486feefSafresh1 is($buf, 'GH', 'buf1'); 278*5486feefSafresh1 is(read($fh,$buf,2), 1, 'read2'); 279*5486feefSafresh1 $s .= ':R'; 280*5486feefSafresh1 is($buf, 'I', 'buf2'); 281*5486feefSafresh1 is(read($fh,$buf,2), 0, 'read3'); 282*5486feefSafresh1 $s .= ':R'; 283*5486feefSafresh1 is($buf, '', 'buf3'); 284*5486feefSafresh1 ok(close($fh), 'close tied scalar - read'); 285*5486feefSafresh1 is($s, ':F:S(GHI):O:F:R:F:R:F:R', 'tied actions - read'); 286*5486feefSafresh1} 287*5486feefSafresh1 288*5486feefSafresh1# [perl #78716] Seeking beyond the end of the string, then reading 289*5486feefSafresh1{ 290*5486feefSafresh1 my $str = '1234567890'; 291*5486feefSafresh1 open my $strIn, '<', \$str; 292*5486feefSafresh1 seek $strIn, 15, 1; 293*5486feefSafresh1 is read($strIn, my $buffer, 5), 0, 294*5486feefSafresh1 'seek beyond end end of string followed by read'; 295*5486feefSafresh1} 296*5486feefSafresh1 297*5486feefSafresh1# Writing to COW scalars and non-PVs 298*5486feefSafresh1{ 299*5486feefSafresh1 my $bovid = __PACKAGE__; 300*5486feefSafresh1 open my $handel, ">", \$bovid; 301*5486feefSafresh1 print $handel "the COW with the crumpled horn"; 302*5486feefSafresh1 is $bovid, "the COW with the crumpled horn", 'writing to COW scalars'; 303*5486feefSafresh1 304*5486feefSafresh1 package lrcg { use overload fallback => 1, '""'=>sub { 'chin' } } 305*5486feefSafresh1 seek $handel, 3, 0; 306*5486feefSafresh1 $bovid = bless [], lrcg::; 307*5486feefSafresh1 print $handel 'mney'; 308*5486feefSafresh1 is $bovid, 'chimney', 'writing to refs'; 309*5486feefSafresh1 310*5486feefSafresh1 seek $handel, 1, 0; 311*5486feefSafresh1 $bovid = 42; # still has a PV 312*5486feefSafresh1 print $handel 5; 313*5486feefSafresh1 is $bovid, 45, 'writing to numeric scalar'; 314*5486feefSafresh1 315*5486feefSafresh1 seek $handel, 1, 0; 316*5486feefSafresh1 undef $bovid; 317*5486feefSafresh1 $bovid = 42; # just IOK 318*5486feefSafresh1 print $handel 5; 319*5486feefSafresh1 is $bovid, 45, 'writing to numeric scalar'; 320*5486feefSafresh1} 321*5486feefSafresh1 322*5486feefSafresh1# [perl #92706] 323*5486feefSafresh1{ 324*5486feefSafresh1 open my $fh, "<", \(my $f=*f); seek $fh, 2,1; 325*5486feefSafresh1 pass 'seeking on a glob copy'; 326*5486feefSafresh1 open my $fh, "<", \(my $f=*f); seek $fh, -2,2; 327*5486feefSafresh1 pass 'seeking on a glob copy from the end'; 328*5486feefSafresh1} 329*5486feefSafresh1 330*5486feefSafresh1# [perl #108398] 331*5486feefSafresh1sub has_trailing_nul(\$) { 332*5486feefSafresh1 my ($ref) = @_; 333*5486feefSafresh1 my $sv = B::svref_2object($ref); 334*5486feefSafresh1 return undef if !$sv->isa('B::PV'); 335*5486feefSafresh1 336*5486feefSafresh1 my $cur = $sv->CUR; 337*5486feefSafresh1 my $len = $sv->LEN; 338*5486feefSafresh1 return 0 if $cur >= $len; 339*5486feefSafresh1 340*5486feefSafresh1 my $ptrlen = length(pack('P', '')); 341*5486feefSafresh1 my $ptrfmt 342*5486feefSafresh1 = $ptrlen == length(pack('J', 0)) ? 'J' 343*5486feefSafresh1 : $ptrlen == length(pack('I', 0)) ? 'I' 344*5486feefSafresh1 : die "Can't determine pointer format"; 345*5486feefSafresh1 346*5486feefSafresh1 my $pv_addr = unpack $ptrfmt, pack 'P', $$ref; 347*5486feefSafresh1 my $trailing = unpack 'P', pack $ptrfmt, $pv_addr+$cur; 348*5486feefSafresh1 return $trailing eq "\0"; 349*5486feefSafresh1} 350*5486feefSafresh1SKIP: { 351*5486feefSafresh1 if ($Config::Config{'extensions'} !~ m!\bB\b!) { 352*5486feefSafresh1 skip "no B", 4; 353*5486feefSafresh1 } 354*5486feefSafresh1 require B; 355*5486feefSafresh1 356*5486feefSafresh1 open my $fh, ">", \my $memfile or die $!; 357*5486feefSafresh1 358*5486feefSafresh1 print $fh "abc"; 359*5486feefSafresh1 ok has_trailing_nul $memfile, 360*5486feefSafresh1 'write appends trailing null when growing string'; 361*5486feefSafresh1 362*5486feefSafresh1 seek $fh, 0,SEEK_SET; 363*5486feefSafresh1 print $fh "abc"; 364*5486feefSafresh1 ok has_trailing_nul $memfile, 365*5486feefSafresh1 'write appends trailing null when not growing string'; 366*5486feefSafresh1 367*5486feefSafresh1 seek $fh, 200, SEEK_SET; 368*5486feefSafresh1 print $fh "abc"; 369*5486feefSafresh1 ok has_trailing_nul $memfile, 370*5486feefSafresh1 'write appends null when growing string after seek past end'; 371*5486feefSafresh1 372*5486feefSafresh1 open $fh, ">", \($memfile = "hello"); 373*5486feefSafresh1 ok has_trailing_nul $memfile, 374*5486feefSafresh1 'initial truncation in ">" mode provides trailing null'; 375*5486feefSafresh1} 376*5486feefSafresh1 377*5486feefSafresh1# [perl #112780] Cloning of in-memory handles 378*5486feefSafresh1SKIP: { 379*5486feefSafresh1 skip "no threads", 2 if !$Config::Config{useithreads}; 380*5486feefSafresh1 require threads; 381*5486feefSafresh1 my $str = ''; 382*5486feefSafresh1 open my $fh, ">", \$str; 383*5486feefSafresh1 $str = 'a'; 384*5486feefSafresh1 is scalar threads::async(sub { my $foo = $str; $foo })->join, "a", 385*5486feefSafresh1 'scalars behind in-memory handles are cloned properly'; 386*5486feefSafresh1 print $fh "a"; 387*5486feefSafresh1 is scalar threads::async(sub { print $fh "b"; $str })->join, "ab", 388*5486feefSafresh1 'printing to a cloned in-memory handle works'; 389*5486feefSafresh1} 390*5486feefSafresh1 391*5486feefSafresh1# [perl #113764] Duping via >&= (broken by the fix for #112870) 392*5486feefSafresh1{ 393*5486feefSafresh1 open FILE, '>', \my $content or die "Couldn't open scalar filehandle"; 394*5486feefSafresh1 open my $fh, ">&=FILE" or die "Couldn't open: $!"; 395*5486feefSafresh1 print $fh "Foo-Bar\n"; 396*5486feefSafresh1 close $fh; 397*5486feefSafresh1 close FILE; 398*5486feefSafresh1 is $content, "Foo-Bar\n", 'duping via >&='; 399*5486feefSafresh1} 400*5486feefSafresh1 401*5486feefSafresh1# [perl #109828] PerlIO::scalar does not handle UTF-8 402*5486feefSafresh1my $byte_warning = "Strings with code points over 0xFF may not be mapped into in-memory file handles\n"; 403*5486feefSafresh1{ 404*5486feefSafresh1 use Errno qw(EINVAL); 405*5486feefSafresh1 my @warnings; 406*5486feefSafresh1 local $SIG{__WARN__} = sub { push @warnings, "@_" }; 407*5486feefSafresh1 my $content = "12\x{101}"; 408*5486feefSafresh1 $! = 0; 409*5486feefSafresh1 ok(!open(my $fh, "<", \$content), "non-byte open should fail"); 410*5486feefSafresh1 is(0+$!, EINVAL, "check \$! is updated"); 411*5486feefSafresh1 is(@warnings, 0, "should be no warnings (yet)"); 412*5486feefSafresh1 use warnings "utf8"; 413*5486feefSafresh1 $! = 0; 414*5486feefSafresh1 ok(!open(my $fh, "<", \$content), "non byte open should fail (and warn)"); 415*5486feefSafresh1 is(0+$!, EINVAL, "check \$! is updated even when we warn"); 416*5486feefSafresh1 is(@warnings, 1, "should have warned"); 417*5486feefSafresh1 is($warnings[0], $byte_warning, "should have warned"); 418*5486feefSafresh1 419*5486feefSafresh1 @warnings = (); 420*5486feefSafresh1 $content = "12\xA1"; 421*5486feefSafresh1 utf8::upgrade($content); 422*5486feefSafresh1 ok(open(my $fh, "<", \$content), "open upgraded scalar"); 423*5486feefSafresh1 binmode $fh; 424*5486feefSafresh1 my $tmp; 425*5486feefSafresh1 is(read($fh, $tmp, 4), 3, "read should get the downgraded bytes"); 426*5486feefSafresh1 is($tmp, "12\xA1", "check we got the expected bytes"); 427*5486feefSafresh1 close $fh; 428*5486feefSafresh1 is(@warnings, 0, "should be no more warnings"); 429*5486feefSafresh1} 430*5486feefSafresh1{ # changes after open 431*5486feefSafresh1 my $content = "abc"; 432*5486feefSafresh1 ok(open(my $fh, "+<", \$content), "open a scalar"); 433*5486feefSafresh1 binmode $fh; 434*5486feefSafresh1 my $tmp; 435*5486feefSafresh1 is(read($fh, $tmp, 1), 1, "basic read"); 436*5486feefSafresh1 seek($fh, 1, SEEK_SET); 437*5486feefSafresh1 $content = "\xA1\xA2\xA3"; 438*5486feefSafresh1 utf8::upgrade($content); 439*5486feefSafresh1 is(read($fh, $tmp, 1), 1, "read from post-open upgraded scalar"); 440*5486feefSafresh1 is($tmp, "\xA2", "check we read the correct value"); 441*5486feefSafresh1 seek($fh, 1, SEEK_SET); 442*5486feefSafresh1 $content = "\x{101}\x{102}\x{103}"; 443*5486feefSafresh1 444*5486feefSafresh1 my @warnings; 445*5486feefSafresh1 local $SIG{__WARN__} = sub { push @warnings, "@_" }; 446*5486feefSafresh1 447*5486feefSafresh1 $! = 0; 448*5486feefSafresh1 is(read($fh, $tmp, 1), undef, "read from scalar with >0xff chars"); 449*5486feefSafresh1 is(0+$!, EINVAL, "check errno set correctly"); 450*5486feefSafresh1 is(@warnings, 0, "should be no warnings (yet)"); 451*5486feefSafresh1 use warnings "utf8"; 452*5486feefSafresh1 seek($fh, 1, SEEK_SET); 453*5486feefSafresh1 is(read($fh, $tmp, 1), undef, "read from scalar with >0xff chars"); 454*5486feefSafresh1 is(@warnings, 1, "check warnings"); 455*5486feefSafresh1 is($warnings[0], $byte_warning, "check warnings"); 456*5486feefSafresh1 457*5486feefSafresh1 select $fh; # make sure print fails rather tha buffers 458*5486feefSafresh1 $| = 1; 459*5486feefSafresh1 select STDERR; 460*5486feefSafresh1 no warnings "utf8"; 461*5486feefSafresh1 @warnings = (); 462*5486feefSafresh1 $content = "\xA1\xA2\xA3"; 463*5486feefSafresh1 utf8::upgrade($content); 464*5486feefSafresh1 seek($fh, 1, SEEK_SET); 465*5486feefSafresh1 ok((print $fh "A"), "print to an upgraded byte string"); 466*5486feefSafresh1 seek($fh, 1, SEEK_SET); 467*5486feefSafresh1 is($content, "\xA1A\xA3", "check result"); 468*5486feefSafresh1 469*5486feefSafresh1 $content = "\x{101}\x{102}\x{103}"; 470*5486feefSafresh1 $! = 0; 471*5486feefSafresh1 ok(!(print $fh "B"), "write to an non-downgradable SV"); 472*5486feefSafresh1 is(0+$!, EINVAL, "check errno set"); 473*5486feefSafresh1 474*5486feefSafresh1 is(@warnings, 0, "should be no warning"); 475*5486feefSafresh1 476*5486feefSafresh1 use warnings "utf8"; 477*5486feefSafresh1 ok(!(print $fh "B"), "write to an non-downgradable SV (and warn)"); 478*5486feefSafresh1 is(@warnings, 1, "check warnings"); 479*5486feefSafresh1 is($warnings[0], $byte_warning, "check warnings"); 480*5486feefSafresh1} 481*5486feefSafresh1 482*5486feefSafresh1# RT #119529: Reading refs should not loop 483*5486feefSafresh1 484*5486feefSafresh1{ 485*5486feefSafresh1 my $x = \42; 486*5486feefSafresh1 open my $fh, "<", \$x; 487*5486feefSafresh1 my $got = <$fh>; # this used to loop 488*5486feefSafresh1 like($got, qr/^SCALAR\(0x[0-9a-f]+\)$/, "ref to a ref"); 489*5486feefSafresh1 is ref $x, "SCALAR", "target scalar is still a reference"; 490*5486feefSafresh1} 491*5486feefSafresh1 492*5486feefSafresh1# Appending to refs 493*5486feefSafresh1{ 494*5486feefSafresh1 my $x = \42; 495*5486feefSafresh1 my $as_string = "$x"; 496*5486feefSafresh1 open my $refh, ">>", \$x; 497*5486feefSafresh1 is ref $x, "SCALAR", 'still a ref after opening for appending'; 498*5486feefSafresh1 print $refh "boo\n"; 499*5486feefSafresh1 is $x, $as_string."boo\n", 'string gets appended to ref'; 500*5486feefSafresh1} 501*5486feefSafresh1 502*5486feefSafresh1SKIP: 503*5486feefSafresh1{ # [perl #123443] 504*5486feefSafresh1 skip "Can't seek over 4GB with a small off_t", 4 505*5486feefSafresh1 if $Config::Config{lseeksize} < 8; 506*5486feefSafresh1 my $buf0 = "hello"; 507*5486feefSafresh1 open my $fh, "<", \$buf0 or die $!; 508*5486feefSafresh1 ok(seek($fh, 2**32, SEEK_SET), "seek to a large position"); 509*5486feefSafresh1 is(read($fh, my $tmp, 1), 0, "read from a large offset"); 510*5486feefSafresh1 is($tmp, "", "should have read nothing"); 511*5486feefSafresh1 ok(eof($fh), "fh should be eof"); 512*5486feefSafresh1} 513*5486feefSafresh1 514*5486feefSafresh1{ 515*5486feefSafresh1 my $buf0 = "hello"; 516*5486feefSafresh1 open my $fh, "<", \$buf0 or die $!; 517*5486feefSafresh1 ok(!seek($fh, -10, SEEK_CUR), "seek to negative position"); 518*5486feefSafresh1 is(tell($fh), 0, "shouldn't change the position"); 519*5486feefSafresh1} 520*5486feefSafresh1 521*5486feefSafresh1SKIP: 522*5486feefSafresh1{ # write() beyond SSize_t limit 523*5486feefSafresh1 skip "Can't overflow SSize_t with Off_t", 2 524*5486feefSafresh1 if $Config::Config{lseeksize} <= $Config::Config{sizesize}; 525*5486feefSafresh1 my $buf0 = "hello"; 526*5486feefSafresh1 open my $fh, "+<", \$buf0 or die $!; 527*5486feefSafresh1 ok(seek($fh, 2**32, SEEK_SET), "seek to a large position"); 528*5486feefSafresh1 select((select($fh), ++$|)[0]); 529*5486feefSafresh1 ok(!(print $fh "x"), "write to a large offset"); 530*5486feefSafresh1} 531