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