1850e2753Smillert#!perl -T 2850e2753Smillert 3850e2753SmillertBEGIN { 4850e2753Smillert use Config; 5850e2753Smillert use Test::More; 6850e2753Smillert plan skip_all => "POSIX is unavailable" if $Config{'extensions'} !~ m!\bPOSIX\b!; 7850e2753Smillert} 8850e2753Smillert 9850e2753Smillertuse strict; 10*256a93a4Safresh1use warnings; 11850e2753Smillertuse File::Spec; 12850e2753Smillertuse POSIX; 13850e2753Smillert 14850e2753Smillertsub check(@) { 15850e2753Smillert grep { eval "&$_;1" or $@!~/vendor has not defined POSIX macro/ } @_ 16850e2753Smillert} 17850e2753Smillert 18850e2753Smillertmy @path_consts = check qw( 19850e2753Smillert _PC_CHOWN_RESTRICTED _PC_LINK_MAX _PC_NAME_MAX 20850e2753Smillert _PC_NO_TRUNC _PC_PATH_MAX 21850e2753Smillert); 22850e2753Smillert 23850e2753Smillertmy @path_consts_terminal = check qw( 24850e2753Smillert _PC_MAX_CANON _PC_MAX_INPUT _PC_VDISABLE 25850e2753Smillert); 26850e2753Smillert 27850e2753Smillertmy @path_consts_fifo = check qw( 28850e2753Smillert _PC_PIPE_BUF 29850e2753Smillert); 30850e2753Smillert 31850e2753Smillertmy @sys_consts = check qw( 32850e2753Smillert _SC_ARG_MAX _SC_CHILD_MAX _SC_CLK_TCK _SC_JOB_CONTROL 33850e2753Smillert _SC_NGROUPS_MAX _SC_OPEN_MAX _SC_PAGESIZE _SC_SAVED_IDS 34850e2753Smillert _SC_STREAM_MAX _SC_VERSION _SC_TZNAME_MAX 35850e2753Smillert); 36850e2753Smillert 37898184e3Ssthenmy $tests = 2 * 2 * @path_consts + 38898184e3Ssthen 2 * 2 * @path_consts_terminal + 39898184e3Ssthen 2 * 2 * @path_consts_fifo + 40898184e3Ssthen 1 * @sys_consts; 41850e2753Smillertplan $tests 42850e2753Smillert ? (tests => $tests) 43850e2753Smillert : (skip_all => "No tests to run on this OS") 44850e2753Smillert; 45850e2753Smillert 4643003dfeSmillert# Don't test on "." as it can be networked storage which returns EINVAL 4743003dfeSmillert# Testing on "/" may not be portable to non-Unix as it may not be readable 4843003dfeSmillert# "/tmp" should be readable and likely also local. 4943003dfeSmillertmy $testdir = File::Spec->tmpdir; 5043003dfeSmillert$testdir = VMS::Filespec::fileify($testdir) if $^O eq 'VMS'; 51850e2753Smillert 52850e2753Smillertmy $r; 53850e2753Smillert 54850e2753Smillertmy $TTY = "/dev/tty"; 55850e2753Smillert 56850e2753Smillertsub _check_and_report { 57898184e3Ssthen my ($sub, $constant, $description) = @_; 58898184e3Ssthen $! = 0; 59898184e3Ssthen my $return_val = eval {$sub->(eval "$constant()")}; 60898184e3Ssthen my $errno = $!; # Grab this before anything else changes it. 61898184e3Ssthen is($@, '', $description); 62898184e3Ssthen 63898184e3Ssthen # We can't test sysconf further without investigating the type of argument 64898184e3Ssthen # provided 65898184e3Ssthen return if $description =~ /sysconf/; 66898184e3Ssthen 67898184e3Ssthen if (defined $return_val) { 68898184e3Ssthen like($return_val, qr/\A(?:-?[1-9][0-9]*|0 but true)\z/, 69898184e3Ssthen 'the returned value should be a signed integer'); 70898184e3Ssthen } else { 7191f110e0Safresh1 SKIP: 7291f110e0Safresh1 { 7391f110e0Safresh1 # POSIX specifies EINVAL is returned if the f?pathconf() 7491f110e0Safresh1 # isn't implemented for the specific path 7591f110e0Safresh1 skip "$description not implemented for this path", 1 7691f110e0Safresh1 if $errno == EINVAL && $description =~ /pathconf/; 77898184e3Ssthen cmp_ok($errno, '==', 0, 'errno should be 0 as before the call') 78898184e3Ssthen or diag("\$!: $errno"); 79850e2753Smillert } 80850e2753Smillert } 8191f110e0Safresh1} 82850e2753Smillert 83850e2753Smillert# testing fpathconf() on a non-terminal file 84850e2753SmillertSKIP: { 8543003dfeSmillert my $fd = POSIX::open($testdir, O_RDONLY) 8643003dfeSmillert or skip "could not open test directory '$testdir' ($!)", 87898184e3Ssthen 2 * @path_consts; 88850e2753Smillert 89850e2753Smillert for my $constant (@path_consts) { 906fb12b70Safresh1 SKIP: { 916fb12b70Safresh1 skip "pathconf($constant) hangs on Android", 2 if $constant eq '_PC_LINK_MAX' && $^O =~ /android/; 92898184e3Ssthen _check_and_report(sub { fpathconf($fd, shift) }, $constant, 93898184e3Ssthen "calling fpathconf($fd, $constant)"); 94850e2753Smillert } 956fb12b70Safresh1 } 96850e2753Smillert 97850e2753Smillert POSIX::close($fd); 98850e2753Smillert} 99850e2753Smillert 100850e2753Smillert# testing pathconf() on a non-terminal file 101850e2753Smillertfor my $constant (@path_consts) { 1026fb12b70Safresh1 SKIP: { 1036fb12b70Safresh1 skip "pathconf($constant) hangs on Android", 2 if $constant eq '_PC_LINK_MAX' && $^O =~ /android/; 104898184e3Ssthen _check_and_report(sub { pathconf($testdir, shift) }, $constant, 105898184e3Ssthen "calling pathconf('$testdir', $constant)"); 106850e2753Smillert } 1076fb12b70Safresh1} 108850e2753Smillert 109850e2753SmillertSKIP: { 110898184e3Ssthen my $n = 2 * 2 * @path_consts_terminal; 111850e2753Smillert 112850e2753Smillert -c $TTY 113850e2753Smillert or skip("$TTY not a character file", $n); 114*256a93a4Safresh1 open(my $LEXTTY, '<', $TTY) 115850e2753Smillert or skip("failed to open $TTY: $!", $n); 116*256a93a4Safresh1 -t $LEXTTY 117*256a93a4Safresh1 or skip("$LEXTTY ($TTY) not a terminal file", $n); 118850e2753Smillert 119*256a93a4Safresh1 my $fd = fileno($LEXTTY); 120850e2753Smillert 121850e2753Smillert # testing fpathconf() on a terminal file 122850e2753Smillert for my $constant (@path_consts_terminal) { 123898184e3Ssthen _check_and_report(sub { fpathconf($fd, shift) }, $constant, 124898184e3Ssthen "calling fpathconf($fd, $constant) ($TTY)"); 125850e2753Smillert } 126850e2753Smillert 127*256a93a4Safresh1 close($LEXTTY); 128850e2753Smillert # testing pathconf() on a terminal file 129850e2753Smillert for my $constant (@path_consts_terminal) { 130898184e3Ssthen _check_and_report(sub { pathconf($TTY, shift) }, $constant, 131898184e3Ssthen "calling pathconf($TTY, $constant)"); 132850e2753Smillert } 133850e2753Smillert} 134850e2753Smillert 135850e2753Smillertmy $fifo = "fifo$$"; 136850e2753Smillert 137850e2753SmillertSKIP: { 138850e2753Smillert eval { mkfifo($fifo, 0666) } 139898184e3Ssthen or skip("could not create fifo $fifo ($!)", 2 * 2 * @path_consts_fifo); 140850e2753Smillert 141850e2753Smillert SKIP: { 142898184e3Ssthen my $fd = POSIX::open($fifo, O_RDONLY | O_NONBLOCK) 143898184e3Ssthen or skip("could not open $fifo ($!)", 2 * @path_consts_fifo); 144850e2753Smillert 145850e2753Smillert for my $constant (@path_consts_fifo) { 146898184e3Ssthen _check_and_report(sub { fpathconf($fd, shift) }, $constant, 147898184e3Ssthen "calling fpathconf($fd, $constant) ($fifo)"); 148850e2753Smillert } 149850e2753Smillert 150850e2753Smillert POSIX::close($fd); 151850e2753Smillert } 152850e2753Smillert 153850e2753Smillert # testing pathconf() on a fifo file 154850e2753Smillert for my $constant (@path_consts_fifo) { 155898184e3Ssthen _check_and_report(sub { pathconf($fifo, shift) }, $constant, 156898184e3Ssthen "calling pathconf($fifo, $constant"); 157850e2753Smillert } 158850e2753Smillert} 159850e2753Smillert 160850e2753SmillertEND { 161*256a93a4Safresh1 if ($fifo) { 162850e2753Smillert 1 while unlink($fifo); 163850e2753Smillert } 164*256a93a4Safresh1} 165850e2753Smillert 166850e2753SmillertSKIP: { 167850e2753Smillert if($^O eq 'cygwin') { 168850e2753Smillert pop @sys_consts; 169898184e3Ssthen skip("No _SC_TZNAME_MAX on Cygwin", 1); 170850e2753Smillert } 171850e2753Smillert 172850e2753Smillert} 173850e2753Smillert# testing sysconf() 174850e2753Smillertfor my $constant (@sys_consts) { 175898184e3Ssthen _check_and_report(sub {sysconf(shift)}, $constant, 176898184e3Ssthen "calling sysconf($constant)"); 177850e2753Smillert} 178