1*0Sstevel@tonic-gate#!./perl 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gateBEGIN { 4*0Sstevel@tonic-gate chdir 't' if -d 't'; 5*0Sstevel@tonic-gate @INC = '../lib'; 6*0Sstevel@tonic-gate require Config; import Config; 7*0Sstevel@tonic-gate if ($^O ne 'VMS' and $Config{'extensions'} !~ /\bPOSIX\b/) { 8*0Sstevel@tonic-gate print "1..0\n"; 9*0Sstevel@tonic-gate exit 0; 10*0Sstevel@tonic-gate } 11*0Sstevel@tonic-gate} 12*0Sstevel@tonic-gate 13*0Sstevel@tonic-gaterequire "./test.pl"; 14*0Sstevel@tonic-gateplan(tests => 65); 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gateuse POSIX qw(fcntl_h signal_h limits_h _exit getcwd open read strftime write 17*0Sstevel@tonic-gate errno); 18*0Sstevel@tonic-gateuse strict 'subs'; 19*0Sstevel@tonic-gate 20*0Sstevel@tonic-gate$| = 1; 21*0Sstevel@tonic-gate 22*0Sstevel@tonic-gate$Is_W32 = $^O eq 'MSWin32'; 23*0Sstevel@tonic-gate$Is_Dos = $^O eq 'dos'; 24*0Sstevel@tonic-gate$Is_MPE = $^O eq 'mpeix'; 25*0Sstevel@tonic-gate$Is_MacOS = $^O eq 'MacOS'; 26*0Sstevel@tonic-gate$Is_VMS = $^O eq 'VMS'; 27*0Sstevel@tonic-gate$Is_OS2 = $^O eq 'os2'; 28*0Sstevel@tonic-gate$Is_UWin = $^O eq 'uwin'; 29*0Sstevel@tonic-gate$Is_OS390 = $^O eq 'os390'; 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gateok( $testfd = open("TEST", O_RDONLY, 0), 'O_RDONLY with open' ); 32*0Sstevel@tonic-gateread($testfd, $buffer, 4) if $testfd > 2; 33*0Sstevel@tonic-gateis( $buffer, "#!./", ' with read' ); 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gateTODO: 36*0Sstevel@tonic-gate{ 37*0Sstevel@tonic-gate local $TODO = "read to array element not working"; 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate read($testfd, $buffer[1], 5) if $testfd > 2; 40*0Sstevel@tonic-gate is( $buffer[1], "perl\n", ' read to array element' ); 41*0Sstevel@tonic-gate} 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gatewrite(1,"ok 4\nnot ok 4\n", 5); 44*0Sstevel@tonic-gatenext_test(); 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gateSKIP: { 47*0Sstevel@tonic-gate skip("no pipe() support on DOS", 2) if $Is_Dos; 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate @fds = POSIX::pipe(); 50*0Sstevel@tonic-gate ok( $fds[0] > $testfd, 'POSIX::pipe' ); 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate CORE::open($reader = \*READER, "<&=".$fds[0]); 53*0Sstevel@tonic-gate CORE::open($writer = \*WRITER, ">&=".$fds[1]); 54*0Sstevel@tonic-gate print $writer "ok 6\n"; 55*0Sstevel@tonic-gate close $writer; 56*0Sstevel@tonic-gate print <$reader>; 57*0Sstevel@tonic-gate close $reader; 58*0Sstevel@tonic-gate next_test(); 59*0Sstevel@tonic-gate} 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gateSKIP: { 62*0Sstevel@tonic-gate skip("no sigaction support on win32/dos", 6) if $Is_W32 || $Is_Dos; 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate my $sigset = new POSIX::SigSet 1, 3; 65*0Sstevel@tonic-gate $sigset->delset(1); 66*0Sstevel@tonic-gate ok(! $sigset->ismember(1), 'POSIX::SigSet->delset' ); 67*0Sstevel@tonic-gate ok( $sigset->ismember(3), 'POSIX::SigSet->ismember' ); 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate SKIP: { 70*0Sstevel@tonic-gate skip("no kill() support on Mac OS", 4) if $Is_MacOS; 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate my $sigint_called = 0; 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate my $mask = new POSIX::SigSet &SIGINT; 75*0Sstevel@tonic-gate my $action = new POSIX::SigAction 'main::SigHUP', $mask, 0; 76*0Sstevel@tonic-gate sigaction(&SIGHUP, $action); 77*0Sstevel@tonic-gate $SIG{'INT'} = 'SigINT'; 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate # At least OpenBSD/i386 3.3 is okay, as is NetBSD 1.5. 80*0Sstevel@tonic-gate # But not NetBSD 1.6 & 1.6.1: the test makes perl crash. 81*0Sstevel@tonic-gate # So the kill() must not be done with this config in order to 82*0Sstevel@tonic-gate # finish the test. 83*0Sstevel@tonic-gate # For others (darwin & freebsd), let the test fail without crashing. 84*0Sstevel@tonic-gate my $todo = $^O eq 'netbsd' && $Config{osvers}=~/^1\.6/; 85*0Sstevel@tonic-gate my $why_todo = "# TODO $^O $Config{osvers} seems to loose blocked signals"; 86*0Sstevel@tonic-gate if (!$todo) { 87*0Sstevel@tonic-gate kill 'HUP', $$; 88*0Sstevel@tonic-gate } else { 89*0Sstevel@tonic-gate print "not ok 9 - sigaction SIGHUP ",$why_todo,"\n"; 90*0Sstevel@tonic-gate print "not ok 10 - sig mask delayed SIGINT ",$why_todo,"\n"; 91*0Sstevel@tonic-gate } 92*0Sstevel@tonic-gate sleep 1; 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate $todo = 1 if ($^O eq 'freebsd') 95*0Sstevel@tonic-gate || ($^O eq 'darwin' && $Config{osvers} lt '6.6'); 96*0Sstevel@tonic-gate printf "%s 11 - masked SIGINT received %s\n", 97*0Sstevel@tonic-gate $sigint_called ? "ok" : "not ok", 98*0Sstevel@tonic-gate $todo ? $why_todo : ''; 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate print "ok 12 - signal masks successful\n"; 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate sub SigHUP { 103*0Sstevel@tonic-gate print "ok 9 - sigaction SIGHUP\n"; 104*0Sstevel@tonic-gate kill 'INT', $$; 105*0Sstevel@tonic-gate sleep 2; 106*0Sstevel@tonic-gate print "ok 10 - sig mask delayed SIGINT\n"; 107*0Sstevel@tonic-gate } 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate sub SigINT { 110*0Sstevel@tonic-gate $sigint_called++; 111*0Sstevel@tonic-gate } 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate # The order of the above tests is very important, so 114*0Sstevel@tonic-gate # we use literal prints and hard coded numbers. 115*0Sstevel@tonic-gate next_test() for 1..4; 116*0Sstevel@tonic-gate } 117*0Sstevel@tonic-gate} 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gateSKIP: { 120*0Sstevel@tonic-gate skip("_POSIX_OPEN_MAX is inaccurate on MPE", 1) if $Is_MPE; 121*0Sstevel@tonic-gate skip("_POSIX_OPEN_MAX undefined ($fds[1])", 1) unless &_POSIX_OPEN_MAX; 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate ok( &_POSIX_OPEN_MAX >= 16, "The minimum allowed values according to susv2" ); 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate} 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gatemy $pat; 128*0Sstevel@tonic-gateif ($Is_MacOS) { 129*0Sstevel@tonic-gate $pat = qr/:t:$/; 130*0Sstevel@tonic-gate} 131*0Sstevel@tonic-gateelsif ( $Is_VMS ) { 132*0Sstevel@tonic-gate $pat = qr/\.T]/i; 133*0Sstevel@tonic-gate} 134*0Sstevel@tonic-gateelse { 135*0Sstevel@tonic-gate $pat = qr#[\\/]t$#i; 136*0Sstevel@tonic-gate} 137*0Sstevel@tonic-gatelike( getcwd(), qr/$pat/, 'getcwd' ); 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate# Check string conversion functions. 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gateSKIP: { 142*0Sstevel@tonic-gate skip("strtod() not present", 1) unless $Config{d_strtod}; 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate $lc = &POSIX::setlocale(&POSIX::LC_NUMERIC, 'C') if $Config{d_setlocale}; 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate # we're just checking that strtod works, not how accurate it is 147*0Sstevel@tonic-gate ($n, $x) = &POSIX::strtod('3.14159_OR_SO'); 148*0Sstevel@tonic-gate ok((abs("3.14159" - $n) < 1e-6) && ($x == 6), 'strtod works'); 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate &POSIX::setlocale(&POSIX::LC_NUMERIC, $lc) if $Config{d_setlocale}; 151*0Sstevel@tonic-gate} 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gateSKIP: { 154*0Sstevel@tonic-gate skip("strtol() not present", 2) unless $Config{d_strtol}; 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gate ($n, $x) = &POSIX::strtol('21_PENGUINS'); 157*0Sstevel@tonic-gate is($n, 21, 'strtol() number'); 158*0Sstevel@tonic-gate is($x, 9, ' unparsed chars'); 159*0Sstevel@tonic-gate} 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gateSKIP: { 162*0Sstevel@tonic-gate skip("strtoul() not present", 2) unless $Config{d_strtoul}; 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate ($n, $x) = &POSIX::strtoul('88_TEARS'); 165*0Sstevel@tonic-gate is($n, 88, 'strtoul() number'); 166*0Sstevel@tonic-gate is($x, 6, ' unparsed chars'); 167*0Sstevel@tonic-gate} 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate# Pick up whether we're really able to dynamically load everything. 170*0Sstevel@tonic-gateok( &POSIX::acos(1.0) == 0.0, 'dynamic loading' ); 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate# This can coredump if struct tm has a timezone field and we 173*0Sstevel@tonic-gate# didn't detect it. If this fails, try adding 174*0Sstevel@tonic-gate# -DSTRUCT_TM_HASZONE to your cflags when compiling ext/POSIX/POSIX.c. 175*0Sstevel@tonic-gate# See ext/POSIX/hints/sunos_4.pl and ext/POSIX/hints/linux.pl 176*0Sstevel@tonic-gateprint POSIX::strftime("ok 21 # %H:%M, on %D\n", localtime()); 177*0Sstevel@tonic-gatenext_test(); 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate# If that worked, validate the mini_mktime() routine's normalisation of 180*0Sstevel@tonic-gate# input fields to strftime(). 181*0Sstevel@tonic-gatesub try_strftime { 182*0Sstevel@tonic-gate my $expect = shift; 183*0Sstevel@tonic-gate my $got = POSIX::strftime("%a %b %d %H:%M:%S %Y %j", @_); 184*0Sstevel@tonic-gate is($got, $expect, "validating mini_mktime() and strftime(): $expect"); 185*0Sstevel@tonic-gate} 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate$lc = &POSIX::setlocale(&POSIX::LC_TIME, 'C') if $Config{d_setlocale}; 188*0Sstevel@tonic-gatetry_strftime("Wed Feb 28 00:00:00 1996 059", 0,0,0, 28,1,96); 189*0Sstevel@tonic-gatetry_strftime("Thu Feb 29 00:00:60 1996 060", 60,0,-24, 30,1,96); 190*0Sstevel@tonic-gatetry_strftime("Fri Mar 01 00:00:00 1996 061", 0,0,-24, 31,1,96); 191*0Sstevel@tonic-gatetry_strftime("Sun Feb 28 00:00:00 1999 059", 0,0,0, 28,1,99); 192*0Sstevel@tonic-gatetry_strftime("Mon Mar 01 00:00:00 1999 060", 0,0,24, 28,1,99); 193*0Sstevel@tonic-gatetry_strftime("Mon Feb 28 00:00:00 2000 059", 0,0,0, 28,1,100); 194*0Sstevel@tonic-gatetry_strftime("Tue Feb 29 00:00:00 2000 060", 0,0,0, 0,2,100); 195*0Sstevel@tonic-gatetry_strftime("Wed Mar 01 00:00:00 2000 061", 0,0,0, 1,2,100); 196*0Sstevel@tonic-gatetry_strftime("Fri Mar 31 00:00:00 2000 091", 0,0,0, 31,2,100); 197*0Sstevel@tonic-gate&POSIX::setlocale(&POSIX::LC_TIME, $lc) if $Config{d_setlocale}; 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gate{ 200*0Sstevel@tonic-gate for my $test (0, 1) { 201*0Sstevel@tonic-gate $! = 0; 202*0Sstevel@tonic-gate # POSIX::errno is autoloaded. 203*0Sstevel@tonic-gate # Autoloading requires many system calls. 204*0Sstevel@tonic-gate # errno() looks at $! to generate its result. 205*0Sstevel@tonic-gate # Autoloading should not munge the value. 206*0Sstevel@tonic-gate my $foo = $!; 207*0Sstevel@tonic-gate my $errno = POSIX::errno(); 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate # Force numeric context. 210*0Sstevel@tonic-gate is( $errno + 0, $foo + 0, 'autoloading and errno() mix' ); 211*0Sstevel@tonic-gate } 212*0Sstevel@tonic-gate} 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gateSKIP: { 215*0Sstevel@tonic-gate skip("no kill() support on Mac OS", 1) if $Is_MacOS; 216*0Sstevel@tonic-gate is (eval "kill 0", 0, "check we have CORE::kill") 217*0Sstevel@tonic-gate or print "\$\@ is " . _qq($@) . "\n"; 218*0Sstevel@tonic-gate} 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate# Check that we can import the POSIX kill routine 221*0Sstevel@tonic-gatePOSIX->import ('kill'); 222*0Sstevel@tonic-gatemy $result = eval "kill 0"; 223*0Sstevel@tonic-gateis ($result, undef, "we should now have POSIX::kill"); 224*0Sstevel@tonic-gate# Check usage. 225*0Sstevel@tonic-gatelike ($@, qr/^Usage: POSIX::kill\(pid, sig\)/, "check its usage message"); 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate# Check unimplemented. 228*0Sstevel@tonic-gate$result = eval {POSIX::offsetof}; 229*0Sstevel@tonic-gateis ($result, undef, "offsetof should fail"); 230*0Sstevel@tonic-gatelike ($@, qr/^Unimplemented: POSIX::offsetof\(\) is C-specific/, 231*0Sstevel@tonic-gate "check its unimplemented message"); 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate# Check reimplemented. 234*0Sstevel@tonic-gate$result = eval {POSIX::fgets}; 235*0Sstevel@tonic-gateis ($result, undef, "fgets should fail"); 236*0Sstevel@tonic-gatelike ($@, qr/^Use method IO::Handle::gets\(\) instead/, 237*0Sstevel@tonic-gate "check its redef message"); 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate# Simplistic tests for the isXXX() functions (bug #16799) 240*0Sstevel@tonic-gateok( POSIX::isalnum('1'), 'isalnum' ); 241*0Sstevel@tonic-gateok(!POSIX::isalnum('*'), 'isalnum' ); 242*0Sstevel@tonic-gateok( POSIX::isalpha('f'), 'isalpha' ); 243*0Sstevel@tonic-gateok(!POSIX::isalpha('7'), 'isalpha' ); 244*0Sstevel@tonic-gateok( POSIX::iscntrl("\cA"),'iscntrl' ); 245*0Sstevel@tonic-gateok(!POSIX::iscntrl("A"), 'iscntrl' ); 246*0Sstevel@tonic-gateok( POSIX::isdigit('1'), 'isdigit' ); 247*0Sstevel@tonic-gateok(!POSIX::isdigit('z'), 'isdigit' ); 248*0Sstevel@tonic-gateok( POSIX::isgraph('@'), 'isgraph' ); 249*0Sstevel@tonic-gateok(!POSIX::isgraph(' '), 'isgraph' ); 250*0Sstevel@tonic-gateok( POSIX::islower('l'), 'islower' ); 251*0Sstevel@tonic-gateok(!POSIX::islower('L'), 'islower' ); 252*0Sstevel@tonic-gateok( POSIX::isupper('U'), 'isupper' ); 253*0Sstevel@tonic-gateok(!POSIX::isupper('u'), 'isupper' ); 254*0Sstevel@tonic-gateok( POSIX::isprint('$'), 'isprint' ); 255*0Sstevel@tonic-gateok(!POSIX::isprint("\n"), 'isprint' ); 256*0Sstevel@tonic-gateok( POSIX::ispunct('%'), 'ispunct' ); 257*0Sstevel@tonic-gateok(!POSIX::ispunct('u'), 'ispunct' ); 258*0Sstevel@tonic-gateok( POSIX::isspace("\t"), 'isspace' ); 259*0Sstevel@tonic-gateok(!POSIX::isspace('_'), 'isspace' ); 260*0Sstevel@tonic-gateok( POSIX::isxdigit('f'), 'isxdigit' ); 261*0Sstevel@tonic-gateok(!POSIX::isxdigit('g'), 'isxdigit' ); 262*0Sstevel@tonic-gate# metaphysical question : what should be returned for an empty string ? 263*0Sstevel@tonic-gate# anyway this shouldn't segfault (bug #24554) 264*0Sstevel@tonic-gateok( POSIX::isalnum(''), 'isalnum empty string' ); 265*0Sstevel@tonic-gateok( POSIX::isalnum(undef),'isalnum undef' ); 266*0Sstevel@tonic-gate# those functions should stringify their arguments 267*0Sstevel@tonic-gateok(!POSIX::isalpha([]), 'isalpha []' ); 268*0Sstevel@tonic-gateok( POSIX::isprint([]), 'isprint []' ); 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate# Check that output is not flushed by _exit. This test should be last 271*0Sstevel@tonic-gate# in the file, and is not counted in the total number of tests. 272*0Sstevel@tonic-gateif ($^O eq 'vos') { 273*0Sstevel@tonic-gate print "# TODO - hit VOS bug posix-885 - _exit flushes output buffers.\n"; 274*0Sstevel@tonic-gate} else { 275*0Sstevel@tonic-gate $| = 0; 276*0Sstevel@tonic-gate # The following line assumes buffered output, which may be not true: 277*0Sstevel@tonic-gate print '@#!*$@(!@#$' unless ($Is_MacOS || $Is_OS2 || $Is_UWin || $Is_OS390 || 278*0Sstevel@tonic-gate $Is_VMS || 279*0Sstevel@tonic-gate (defined $ENV{PERLIO} && 280*0Sstevel@tonic-gate $ENV{PERLIO} eq 'unix' && 281*0Sstevel@tonic-gate $Config::Config{useperlio})); 282*0Sstevel@tonic-gate _exit(0); 283*0Sstevel@tonic-gate} 284