xref: /openbsd-src/gnu/usr.bin/perl/t/op/syscall_emulator.t (revision 312e26c80be876012ae9792d4323a301329d66ae)
1*312e26c8Safresh1#!/usr/bin/perl
2*312e26c8Safresh1#	$OpenBSD: syscall_emulator.t,v 1.1 2023/09/03 01:43:09 afresh1 Exp $	#
3*312e26c8Safresh1
4*312e26c8Safresh1# Copyright (c) 2023 Andrew Hewus Fresh <afresh1@openbsd.org>
5*312e26c8Safresh1#
6*312e26c8Safresh1# Permission to use, copy, modify, and distribute this software for any
7*312e26c8Safresh1# purpose with or without fee is hereby granted, provided that the above
8*312e26c8Safresh1# copyright notice and this permission notice appear in all copies.
9*312e26c8Safresh1#
10*312e26c8Safresh1# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*312e26c8Safresh1# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*312e26c8Safresh1# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*312e26c8Safresh1# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*312e26c8Safresh1# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15*312e26c8Safresh1# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16*312e26c8Safresh1# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*312e26c8Safresh1
18*312e26c8Safresh1BEGIN {
19*312e26c8Safresh1    chdir 't' if -d 't';
20*312e26c8Safresh1    require "./test.pl";
21*312e26c8Safresh1    set_up_inc( qw(. ../lib lib ../dist/base/lib) );
22*312e26c8Safresh1}
23*312e26c8Safresh1
24*312e26c8Safresh1use v5.36;
25*312e26c8Safresh1
26*312e26c8Safresh1use File::Temp;
27*312e26c8Safresh1use POSIX qw< S_IRUSR S_IWUSR S_IRGRP S_IROTH O_CREAT O_WRONLY O_RDONLY >;
28*312e26c8Safresh1
29*312e26c8Safresh1use constant {
30*312e26c8Safresh1    PROT_READ   => 0x01,
31*312e26c8Safresh1    MAP_PRIVATE => 0x0002,
32*312e26c8Safresh1    MAP_FAILED  => -1,
33*312e26c8Safresh1};
34*312e26c8Safresh1
35*312e26c8Safresh1my $dir = File::Temp->newdir("syscall_emulator-XXXXXXXXX");
36*312e26c8Safresh1{
37*312e26c8Safresh1	local $ENV{PERL5LIB} = join ':', @INC;
38*312e26c8Safresh1	open(my $fh, '-|', $^X, "../utils/h2ph", '-d', $dir,
39*312e26c8Safresh1	    "/usr/include/sys/syscall.h") or die "h2ph: $!";
40*312e26c8Safresh1	note <$fh>;
41*312e26c8Safresh1	close($fh) or die $! ? "h2ph: $!" : "h2ph: $?";
42*312e26c8Safresh1	local @INC = ("$dir/usr/include", "$dir");
43*312e26c8Safresh1	require 'sys/syscall.ph';
44*312e26c8Safresh1}
45*312e26c8Safresh1
46*312e26c8Safresh1my $filename = "test.txt";
47*312e26c8Safresh1my $file = "$dir/$filename";
48*312e26c8Safresh1my $fd;
49*312e26c8Safresh1my $out = "Hello World\n";
50*312e26c8Safresh1my $in = "\0" x 32;
51*312e26c8Safresh1my ($in_p, $in_v);
52*312e26c8Safresh1my $sb = "\0" x 4096;
53*312e26c8Safresh1my $st_mode;
54*312e26c8Safresh1
55*312e26c8Safresh1my $perms = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
56*312e26c8Safresh1
57*312e26c8Safresh1plan tests => 17;
58*312e26c8Safresh1
59*312e26c8Safresh1ok(!
60*312e26c8Safresh1    (($fd = syscall(SYS_open(), $file, O_CREAT|O_WRONLY, $perms)) < 0),
61*312e26c8Safresh1    "Opened $filename for write/create"
62*312e26c8Safresh1);
63*312e26c8Safresh1ok(!
64*312e26c8Safresh1    (syscall(SYS_write(), $fd, $out, length $out) <= 0),
65*312e26c8Safresh1    "Wrote out to $filename"
66*312e26c8Safresh1);
67*312e26c8Safresh1ok(!
68*312e26c8Safresh1    (syscall(SYS_close(), $fd) != 0),
69*312e26c8Safresh1    "closed $filename"
70*312e26c8Safresh1);
71*312e26c8Safresh1
72*312e26c8Safresh1
73*312e26c8Safresh1ok(!
74*312e26c8Safresh1    (syscall(SYS_stat(), $file, $sb) != 0),
75*312e26c8Safresh1    "stat $filename"
76*312e26c8Safresh1);
77*312e26c8Safresh1
78*312e26c8Safresh1# fortunately st_mode is the first unsigned long in stat struct
79*312e26c8Safresh1$st_mode = unpack "L", $sb;
80*312e26c8Safresh1
81*312e26c8Safresh1ok( ($st_mode & 0777) == ($perms & 0777),
82*312e26c8Safresh1    sprintf "new file %s has correct permissions (%o)",
83*312e26c8Safresh1        $filename, $st_mode & 0777
84*312e26c8Safresh1);
85*312e26c8Safresh1
86*312e26c8Safresh1ok(!
87*312e26c8Safresh1    (($fd = syscall(SYS_open(), $file, O_RDONLY)) < 0),
88*312e26c8Safresh1    "Opened $filename for read"
89*312e26c8Safresh1);
90*312e26c8Safresh1ok(!
91*312e26c8Safresh1    (syscall(SYS_read(), $fd, $in, length $in) <= 0),
92*312e26c8Safresh1    "read from $filename"
93*312e26c8Safresh1);
94*312e26c8Safresh1
95*312e26c8Safresh1$in = unpack 'Z*', $in;
96*312e26c8Safresh1
97*312e26c8Safresh1ok( length($in) == length($out) && ($in eq $out),
98*312e26c8Safresh1    "Read written content from $filename"
99*312e26c8Safresh1);
100*312e26c8Safresh1
101*312e26c8Safresh1ok(!
102*312e26c8Safresh1    (syscall(SYS_lseek(), $fd, 0, SEEK_SET) < 0),
103*312e26c8Safresh1    "lseek on fd"
104*312e26c8Safresh1);
105*312e26c8Safresh1
106*312e26c8Safresh1ok(!
107*312e26c8Safresh1    (syscall(SYS_pread(), $fd, $in = "\0" x 32, 5, 3) < 0),
108*312e26c8Safresh1    "pread on fd"
109*312e26c8Safresh1);
110*312e26c8Safresh1
111*312e26c8Safresh1$in = unpack 'Z*', $in;
112*312e26c8Safresh1
113*312e26c8Safresh1ok( length($in) == 5 && ($in eq substr $out, 3, 5),
114*312e26c8Safresh1    "Read written content from $filename ($in)"
115*312e26c8Safresh1);
116*312e26c8Safresh1
117*312e26c8Safresh1ok(!
118*312e26c8Safresh1    (syscall(SYS_lseek(), $fd, 0, SEEK_SET) < 0),
119*312e26c8Safresh1    "lseek on fd"
120*312e26c8Safresh1);
121*312e26c8Safresh1
122*312e26c8Safresh1ok(!
123*312e26c8Safresh1    (syscall(SYS_lseek(), $fd, 0, SEEK_SET) < 0),
124*312e26c8Safresh1    "lseek on fd"
125*312e26c8Safresh1);
126*312e26c8Safresh1
127*312e26c8Safresh1ok(!
128*312e26c8Safresh1    (($in_p = syscall(SYS_mmap(), undef, length($out), PROT_READ, MAP_PRIVATE,
129*312e26c8Safresh1        $fd, 0)) == MAP_FAILED),
130*312e26c8Safresh1    "mmap fd"
131*312e26c8Safresh1);
132*312e26c8Safresh1
133*312e26c8Safresh1# From ingy's Pointer module
134*312e26c8Safresh1$in_v = unpack "p*", pack "L!", $in_p;
135*312e26c8Safresh1
136*312e26c8Safresh1ok( length($in_v) == length($out) && ($in_v eq $out),
137*312e26c8Safresh1    "Read written content from $filename"
138*312e26c8Safresh1);
139*312e26c8Safresh1
140*312e26c8Safresh1ok(!
141*312e26c8Safresh1    (syscall(SYS_munmap(), $in_p, length($out)) != 0),
142*312e26c8Safresh1    "munmap fd"
143*312e26c8Safresh1);
144*312e26c8Safresh1
145*312e26c8Safresh1ok(!
146*312e26c8Safresh1    (syscall(SYS_close(), $fd) != 0),
147*312e26c8Safresh1    "closed $filename"
148*312e26c8Safresh1);
149