xref: /openbsd-src/gnu/usr.bin/perl/ext/POSIX/t/sysconf.t (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1#!perl -T
2
3BEGIN {
4    use Config;
5    use Test::More;
6    plan skip_all => "POSIX is unavailable" if $Config{'extensions'} !~ m!\bPOSIX\b!;
7}
8
9use strict;
10use File::Spec;
11use POSIX;
12
13sub check(@) {
14    grep { eval "&$_;1" or $@!~/vendor has not defined POSIX macro/ } @_
15}
16
17my @path_consts = check qw(
18    _PC_CHOWN_RESTRICTED _PC_LINK_MAX _PC_NAME_MAX
19    _PC_NO_TRUNC _PC_PATH_MAX
20);
21
22my @path_consts_terminal = check qw(
23    _PC_MAX_CANON _PC_MAX_INPUT _PC_VDISABLE
24);
25
26my @path_consts_fifo = check qw(
27    _PC_PIPE_BUF
28);
29
30my @sys_consts = check qw(
31    _SC_ARG_MAX _SC_CHILD_MAX _SC_CLK_TCK _SC_JOB_CONTROL
32    _SC_NGROUPS_MAX _SC_OPEN_MAX _SC_PAGESIZE _SC_SAVED_IDS
33    _SC_STREAM_MAX _SC_VERSION _SC_TZNAME_MAX
34);
35
36my $tests = 2 * 2 * @path_consts +
37            2 * 2 * @path_consts_terminal +
38            2 * 2 * @path_consts_fifo +
39                1 * @sys_consts;
40plan $tests
41     ? (tests => $tests)
42     : (skip_all => "No tests to run on this OS")
43;
44
45# Don't test on "." as it can be networked storage which returns EINVAL
46# Testing on "/" may not be portable to non-Unix as it may not be readable
47# "/tmp" should be readable and likely also local.
48my $testdir = File::Spec->tmpdir;
49$testdir = VMS::Filespec::fileify($testdir) if $^O eq 'VMS';
50
51my $r;
52
53my $TTY = "/dev/tty";
54
55sub _check_and_report {
56    my ($sub, $constant, $description) = @_;
57    $! = 0;
58    my $return_val = eval {$sub->(eval "$constant()")};
59    my $errno = $!; # Grab this before anything else changes it.
60    is($@, '', $description);
61
62    # We can't test sysconf further without investigating the type of argument
63    # provided
64    return if $description =~ /sysconf/;
65
66    if (defined $return_val) {
67	like($return_val, qr/\A(?:-?[1-9][0-9]*|0 but true)\z/,
68	     'the returned value should be a signed integer');
69    } else {
70      SKIP:
71	{
72	    # POSIX specifies EINVAL is returned if the f?pathconf()
73	    # isn't implemented for the specific path
74	    skip "$description not implemented for this path", 1
75		if $errno == EINVAL && $description =~ /pathconf/;
76	    cmp_ok($errno, '==', 0, 'errno should be 0 as before the call')
77		or diag("\$!: $errno");
78	}
79    }
80}
81
82# testing fpathconf() on a non-terminal file
83SKIP: {
84    my $fd = POSIX::open($testdir, O_RDONLY)
85        or skip "could not open test directory '$testdir' ($!)",
86	  2 * @path_consts;
87
88    for my $constant (@path_consts) {
89	_check_and_report(sub { fpathconf($fd, shift) }, $constant,
90			  "calling fpathconf($fd, $constant)");
91    }
92
93    POSIX::close($fd);
94}
95
96# testing pathconf() on a non-terminal file
97for my $constant (@path_consts) {
98    _check_and_report(sub { pathconf($testdir, shift) }, $constant,
99		      "calling pathconf('$testdir', $constant)");
100}
101
102SKIP: {
103    my $n = 2 * 2 * @path_consts_terminal;
104
105    -c $TTY
106	or skip("$TTY not a character file", $n);
107    open(TTY, $TTY)
108	or skip("failed to open $TTY: $!", $n);
109    -t TTY
110	or skip("TTY ($TTY) not a terminal file", $n);
111
112    my $fd = fileno(TTY);
113
114    # testing fpathconf() on a terminal file
115    for my $constant (@path_consts_terminal) {
116	_check_and_report(sub { fpathconf($fd, shift) }, $constant,
117			  "calling fpathconf($fd, $constant) ($TTY)");
118    }
119
120    close($fd);
121    # testing pathconf() on a terminal file
122    for my $constant (@path_consts_terminal) {
123	_check_and_report(sub { pathconf($TTY, shift) }, $constant,
124			  "calling pathconf($TTY, $constant)");
125    }
126}
127
128my $fifo = "fifo$$";
129
130SKIP: {
131    eval { mkfifo($fifo, 0666) }
132	or skip("could not create fifo $fifo ($!)", 2 * 2 * @path_consts_fifo);
133
134  SKIP: {
135      my $fd = POSIX::open($fifo, O_RDONLY | O_NONBLOCK)
136	  or skip("could not open $fifo ($!)", 2 * @path_consts_fifo);
137
138      for my $constant (@path_consts_fifo) {
139	  _check_and_report(sub { fpathconf($fd, shift) }, $constant,
140			    "calling fpathconf($fd, $constant) ($fifo)");
141      }
142
143      POSIX::close($fd);
144  }
145
146  # testing pathconf() on a fifo file
147  for my $constant (@path_consts_fifo) {
148      _check_and_report(sub { pathconf($fifo, shift) }, $constant,
149			"calling pathconf($fifo, $constant");
150  }
151}
152
153END {
154    1 while unlink($fifo);
155}
156
157SKIP: {
158    if($^O eq 'cygwin') {
159        pop @sys_consts;
160        skip("No _SC_TZNAME_MAX on Cygwin", 1);
161    }
162
163}
164# testing sysconf()
165for my $constant (@sys_consts) {
166    _check_and_report(sub {sysconf(shift)}, $constant,
167		      "calling sysconf($constant)");
168}
169