On Thu, 3 Aug 2023 18:43:21 -0700 Andrew Hewus Fresh <and...@afresh1.com> wrote:
> Here's a new version, I think I addressed all of the feedback I got, > although may have missed something. ok gkoehler@ You sent this new version 2 weeks ago, but I didn't build it until yesterday. syscall_emulator.t passes on macppc and powerpc64. > Index: gnu/usr.bin/perl/MANIFEST > =================================================================== > RCS file: /home/afresh1/OpenBSD-perl/OP/cvs/src/gnu/usr.bin/perl/MANIFEST,v > retrieving revision 1.67 > diff -u -p -a -u -p -r1.67 MANIFEST > --- gnu/usr.bin/perl/MANIFEST 8 Jul 2023 14:18:35 -0000 1.67 > +++ gnu/usr.bin/perl/MANIFEST 3 Aug 2023 04:34:38 -0000 > @@ -6605,6 +6605,7 @@ t/op/svleak.pl Test file for svleak.t > t/op/svleak.t See if stuff leaks SVs > t/op/switch.t See if switches (given/when) work > t/op/symbolcache.t See if undef/delete works on stashes with > functions > +t/op/syscall_emulator.t Tests that syscall works via the > emulator > t/op/sysio.t See if sysread and syswrite work > t/op/taint.t See if tainting works > t/op/threads.t Misc. tests for perl features with > threads > Index: gnu/usr.bin/perl/Makefile.SH > =================================================================== > RCS file: /home/afresh1/OpenBSD-perl/OP/cvs/src/gnu/usr.bin/perl/Makefile.SH,v > retrieving revision 1.60 > diff -u -p -a -u -p -r1.60 Makefile.SH > --- gnu/usr.bin/perl/Makefile.SH 8 Jul 2023 14:18:35 -0000 1.60 > +++ gnu/usr.bin/perl/Makefile.SH 3 Aug 2023 04:34:38 -0000 > @@ -541,7 +541,7 @@ c1 = av.c scope.c op.c doop.c doio.c dum > c2 = perly.c pp.c pp_hot.c pp_ctl.c pp_sys.c regcomp.c regexec.c utf8.c sv.c > c3 = taint.c toke.c util.c deb.c run.c builtin.c universal.c pad.c globals.c > keywords.c > c4 = perlio.c numeric.c mathoms.c locale.c pp_pack.c pp_sort.c caretx.c > dquote.c time64.c > -c5 = $(mallocsrc) > +c5 = $(mallocsrc) syscall_emulator.c > > !NO!SUBS! > > @@ -557,7 +557,7 @@ c = $(c1) $(c2) $(c3) $(c4) $(c5) minipe > > obj1 = $(mallocobj) gv$(OBJ_EXT) toke$(OBJ_EXT) perly$(OBJ_EXT) > pad$(OBJ_EXT) regcomp$(OBJ_EXT) dump$(OBJ_EXT) util$(OBJ_EXT) mg$(OBJ_EXT) > reentr$(OBJ_EXT) mro_core$(OBJ_EXT) keywords$(OBJ_EXT) builtin$(OBJ_EXT) > obj2 = hv$(OBJ_EXT) av$(OBJ_EXT) run$(OBJ_EXT) pp_hot$(OBJ_EXT) sv$(OBJ_EXT) > pp$(OBJ_EXT) scope$(OBJ_EXT) pp_ctl$(OBJ_EXT) pp_sys$(OBJ_EXT) > -obj3 = doop$(OBJ_EXT) doio$(OBJ_EXT) regexec$(OBJ_EXT) utf8$(OBJ_EXT) > taint$(OBJ_EXT) deb$(OBJ_EXT) globals$(OBJ_EXT) perlio$(OBJ_EXT) > numeric$(OBJ_EXT) mathoms$(OBJ_EXT) locale$(OBJ_EXT) pp_pack$(OBJ_EXT) > pp_sort$(OBJ_EXT) caretx$(OBJ_EXT) dquote$(OBJ_EXT) time64$(OBJ_EXT) > +obj3 = doop$(OBJ_EXT) doio$(OBJ_EXT) regexec$(OBJ_EXT) utf8$(OBJ_EXT) > taint$(OBJ_EXT) deb$(OBJ_EXT) globals$(OBJ_EXT) perlio$(OBJ_EXT) > numeric$(OBJ_EXT) mathoms$(OBJ_EXT) locale$(OBJ_EXT) pp_pack$(OBJ_EXT) > pp_sort$(OBJ_EXT) caretx$(OBJ_EXT) dquote$(OBJ_EXT) time64$(OBJ_EXT) > syscall_emulator$(OBJ_EXT) > > # split the objects into 3 exclusive sets: those used by both miniperl and > # perl, and those used by just one or the other. Doesn't include the > Index: gnu/usr.bin/perl/Makefile.bsd-wrapper > =================================================================== > RCS file: > /home/afresh1/OpenBSD-perl/OP/cvs/src/gnu/usr.bin/perl/Makefile.bsd-wrapper,v > retrieving revision 1.113 > diff -u -p -a -u -p -r1.113 Makefile.bsd-wrapper > --- gnu/usr.bin/perl/Makefile.bsd-wrapper 15 Feb 2023 01:38:20 -0000 > 1.113 > +++ gnu/usr.bin/perl/Makefile.bsd-wrapper 3 Aug 2023 04:34:38 -0000 > @@ -39,11 +39,18 @@ cleandir: > fi > cd ${.CURDIR} && ${MAKE} -f Makefile.bsd-wrapper1 cleandir > > -all: config.sh > +all: syscall_emulator.c config.sh > cd ${.CURDIR} && exec ${MAKE} -f Makefile.bsd-wrapper1 perl.build > cd ${.CURDIR} && exec ${MAKE} -f Makefile.bsd-wrapper1 mansrc.build > > install: > cd ${.CURDIR} && exec ${MAKE} -f Makefile.bsd-wrapper1 install > + > + > +syscall_emulator.c: gen_syscall_emulator.pl syscall_emulator.h > /usr/include/sys/syscall.h /usr/include/sys/syscallargs.h > + /usr/bin/perl $(.CURDIR)/gen_syscall_emulator.pl > $@ > + > +syscall_emulator.h: > + ln -sf $(.CURDIR)/$@ $@ > > .include <bsd.obj.mk> > Index: gnu/usr.bin/perl/config.over > =================================================================== > RCS file: /home/afresh1/OpenBSD-perl/OP/cvs/src/gnu/usr.bin/perl/config.over,v > retrieving revision 1.22 > diff -u -p -a -u -p -r1.22 config.over > --- gnu/usr.bin/perl/config.over 5 Feb 2017 00:33:38 -0000 1.22 > +++ gnu/usr.bin/perl/config.over 3 Aug 2023 04:34:38 -0000 > @@ -64,3 +64,9 @@ myuname='openbsd' > > # force to use ranlib > ranlib='ranlib' > + > +# Enable the syscall emulator, > +# enabling syscall even if we don't have it > +d_syscall=define > +d_syscallproto=define > + > Index: gnu/usr.bin/perl/gen_syscall_emulator.pl > =================================================================== > RCS file: gnu/usr.bin/perl/gen_syscall_emulator.pl > diff -N gnu/usr.bin/perl/gen_syscall_emulator.pl > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gnu/usr.bin/perl/gen_syscall_emulator.pl 3 Aug 2023 04:34:41 -0000 > @@ -0,0 +1,360 @@ > +#!/usr/bin/perl > +# $OpenBSD$ # > +use v5.36; > +use autodie; > + > +# Copyright (c) 2023 Andrew Hewus Fresh <afre...@openbsd.org> > +# > +# Permission to use, copy, modify, and distribute this software for any > +# purpose with or without fee is hereby granted, provided that the above > +# copyright notice and this permission notice appear in all copies. > +# > +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + > +my $includes = '/usr/include'; > + > +# Because perl uses a long for every syscall argument, > +# if we are building a syscall_emulator for use by perl, > +# taking that into account make things work more consistently > +# across different OpenBSD architectures. > +# Unfortunately there doesn't appear to be an easy way > +# to make everything work "the way it was". > +use constant PERL_LONG_ARGS => 1; > + > +# See also /usr/src/sys/kern/syscalls.master > +my %syscalls = parse_syscalls( > + "$includes/sys/syscall.h", > + "$includes/sys/syscallargs.h", > +)->%*; > +delete $syscalls{MAXSYSCALL}; # not an actual function > + > +# The ordered list of all the headers we need > +my @headers = qw< > + sys/syscall.h > + stdarg.h > + errno.h > + > + sys/socket.h > + sys/event.h > + sys/futex.h > + sys/ioctl.h > + sys/ktrace.h > + sys/mman.h > + sys/mount.h > + sys/msg.h > + sys/poll.h > + sys/ptrace.h > + sys/resource.h > + sys/select.h > + sys/sem.h > + sys/shm.h > + sys/stat.h > + sys/sysctl.h > + sys/time.h > + sys/uio.h > + sys/wait.h > + > + dirent.h > + fcntl.h > + sched.h > + signal.h > + stdlib.h > + stdio.h > + syslog.h > + tib.h > + time.h > + unistd.h > +>; > + > +foreach my $header (@headers) { > + my $filename = "$includes/$header"; > + open my $fh, '<', $filename; > + my $content = do { local $/; readline $fh }; > + close $fh; > + > + foreach my $name (sort keys %syscalls) { > + my $s = $syscalls{$name}; > + my $func_sig = find_func_sig($content, $name, $s); > + > + if (ref $func_sig) { > + die "Multiple defs for $name <$header> <$s->{header}>" > + if $s->{header}; > + $s->{func} = $func_sig; > + $s->{header} = $header; > + } elsif ($func_sig) { > + $s->{mismatched_sig} = "$func_sig <$header>"; > + } > + } > +} > + > +say "/*\n * Generated from gen_syscall_emulator.pl\n */"; > +say "#include <$_>" for @headers; > +print <<"EOL"; > +#include "syscall_emulator.h" > + > +long > +syscall_emulator(int syscall, ...) > +{ > + long ret = 0; > + va_list args; > + va_start(args, syscall); > + > + switch(syscall) { > +EOL > + > +foreach my $name ( > + sort { $syscalls{$a}{id} <=> $syscalls{$b}{id} } keys %syscalls > + ) { > + my %s = %{ $syscalls{$name} }; > + > + # Some syscalls we can't emulate, so we comment those out. > + $s{skip} //= "Indirect syscalls not supported" > + if !$s{argtypes} && ($s{args}[-1] || '') eq '...'; > + $s{skip} //= "Mismatched func: $s{mismatched_sig}" > + if $s{mismatched_sig} and not $s{func}; > + $s{skip} //= "No signature found in headers" > + unless $s{header}; > + > + my $ret = $s{ret} eq 'void' ? '' : 'ret = '; > + $ret .= '(long)' if $s{ret} eq 'void *'; > + > + my (@args, @defines); > + my $argname = ''; > + if ($s{argtypes}) { > + if (@{ $s{argtypes} } > 1) { > + @defines = map { > + my $t = $_->{type}; > + my $n = $_->{name}; > + $n = "_$n" if $n eq $name; # link :-/ > + push @args, $n; > + PERL_LONG_ARGS > + ? "$t $n = ($t)va_arg(args, long);" > + : "$t $n = va_arg(args, $t);" > + } @{ $s{argtypes} }; > + } else { > + if (@{ $s{argtypes} }) { > + $argname = " // " . join ', ', > + map { $_->{name} } > + @{ $s{argtypes} }; > + } > + @args = map { "va_arg(args, $_->{type})" } > + @{ $s{argtypes} }; > + } > + } else { > + @args = @{ $s{args} }; > + > + # If we didn't find args in syscallargs.h but have args > + # we don't know how to write our function. > + $s{skip} //= "Not found in sys/syscallargs.h" > + if @args; > + } > + > + #my $header = $s{header} ? " <$s{header}>" : ''; > + > + my $indent = "\t"; > + say "$indent/* $s{skip}" if $s{skip}; > + > + $indent .= ' *' if $s{skip}; > + say "${indent} $s{signature} <sys/syscall.h>" > + if $s{skip} && $s{skip} =~ /Mismatch/; > + > + my $brace = @defines ? " {" : ""; > + say "${indent}case $s{define}:$brace"; # // $s{id}"; > + say "${indent}\t$_" for @defines; > + #say "${indent}\t// $s{signature}$header"; > + say "${indent}\t$ret$name(" . join(', ', @args) . ");$argname"; > + say "${indent}\tbreak;"; > + say "${indent}}" if $brace; > + > + say "\t */" if $s{skip}; > +} > + > +print <<"EOL"; > + default: > + ret = -1; > + errno = ENOSYS; > + } > + va_end(args); > + > + return ret; > +} > +EOL > + > + > +sub parse_syscalls($syscall, $args) > +{ > + my %s = parse_syscall_h($syscall)->%*; > + > + my %a = parse_syscallargs_h($args)->%*; > + $s{$_}{argtypes} = $a{$_} for grep { $a{$_} } keys %s; > + > + return \%s; > +} > + > +sub parse_syscall_h($filename) > +{ > + my %s; > + open my $fh, '<', $filename; > + while (readline $fh) { > + if (m{^/\* > + \s+ syscall: \s+ "(?<name>[^"]+)" > + \s+ ret: \s+ "(?<ret> [^"]+)" > + \s+ args: \s+ (?<args>.*?) > + \s* \*/ > + | > + ^\#define \s+ (?<define>SYS_(?<name>\S+)) \s+ (?<id>\d+) > + }x) > + { > + my $name = $+{name}; > + $s{$name}{$_} = $+{$_} for keys %+; > + $s{$name}{args} = [ $+{args} =~ /"(.*?)"/g ] > + if exists $+{args}; > + } > + } > + close $fh; > + > + foreach my $name (keys %s) { > + my %d = %{ $s{$name} }; > + next unless $d{ret}; # the MAXSYSCALL > + > + my $ret = $d{ret}; > + my @args = @{ $d{args} || [] }; > + @args = 'void' unless @args; > + > + if ($args[-1] ne '...') { > + my @a; > + for (@args) { > + push @a, $_; > + last if $_ eq '...'; > + } > + @args = @a; > + } > + > + my $args = join ", ", @args; > + $s{$name}{signature} = "$ret\t$name($args);" =~ s/\s+/ /gr; > + #print " $s{$name}{signature}\n"; > + } > + > + return \%s; > +} > + > +sub parse_syscallargs_h($filename) > +{ > + my %args; > + > + open my $fh, '<', $filename; > + while (readline $fh) { > + if (my ($syscall) = /^struct \s+ sys_(\w+)_args \s+ \{/x) { > + $args{$syscall} = []; > + while (readline $fh) { > + last if /^\s*\};\s*$/; > + if (/syscallarg > + \( (?<type> [^)]+ ) \) > + \s+ (?<name> \w+ ) \s* ; > + /x) { > + push @{$args{$syscall}}, {%+}; > + } > + } > + } > + } > + close $fh; > + > + return \%args; > +} > + > +sub find_func_sig($content, $name, $s) > +{ > + my $re = $s->{re} //= qr{^ > + (?<ret> \S+ (?: [^\S\n]+ \S+)? ) [^\S\n]* \n? > + \b \Q$name\E \( (?<args> [^)]* ) \) > + [^;]*; > + }xms; > + > + $content =~ /$re/ || return !!0; > + my $ret = $+{ret}; > + my $args = $+{args}; > + > + for ($ret, $args) { > + s/^\s+//; > + s/\s+$//; > + s/\s+/ /g; > + } > + > + # The actual functions may have this extra annotation > + $args =~ s/\*\s*__restrict/*/g; > + > + my %func_sig = ( ret => $ret, args => [ split /\s*,\s*/, $args ] ); > + > + return "$ret $name($args);" =~ s/\s+/ /gr > + unless sigs_match($s, \%func_sig); > + > + return \%func_sig; > +} > + > +# Tests whether two types are equivalent. > +# Sometimes there are two ways to represent the same thing > +# and it seems the functions and the syscalls > +# differ a fair amount. > +sub types_match($l, $r) > +{ > + state %m = ( > + caddr_t => 'char *', > + idtype_t => 'int', > + nfds_t => 'u_int', > + __off_t => 'off_t', > + pid_t => 'int', > + __size_t => 'u_long', > + size_t => 'u_long', > + 'unsigned int' => 'u_int', > + 'unsigned long' => 'u_long', > + ); > + > + $l //= '__undef__'; > + $r //= '__undef__'; > + > + s/\b volatile \s+//x for $l, $r; > + s/\b const \s+//x for $l, $r; > + s/\s* \[\d*\] $/ \*/x for $l, $r; > + > + my ($f, $s) = sort { length($a) <=> length($b) } $l, $r; > + if (index($s, $f) == 0) { > + $s =~ s/^\Q$f\E\s*//; > + if ( $s && $s =~ /^\w+$/ ) { > + #warn "prefix ['$f', '$s']\n"; > + s/\s*\Q$s\E$// for $l, $r; > + } > + } > + > + $l = $m{$l} //= $l; > + $r = $m{$r} //= $r; > + > + return $l eq $r; > +} > + > + > +# Tests whether two function signatures match, > +# expected to be left from syscall.h, right from the appopriate header. > +sub sigs_match($l, $r) > +{ > + return !!0 unless types_match( $l->{ret}, $l->{ret} ); > + > + my @l_args = @{ $l->{args} || [] }; > + my @r_args = @{ $r->{args} || [] }; > + > + for (\@l_args, \@r_args) { > + @{$_} = 'void' unless @{$_}; > + } > + > + for my $i ( 0 .. $#l_args ) { > + return !!0 unless types_match($l_args[$i], $r_args[$i]); > + last if $l_args[$i] eq '...'; > + } > + > + return !!1; > +} > Index: gnu/usr.bin/perl/pp_sys.c > =================================================================== > RCS file: /home/afresh1/OpenBSD-perl/OP/cvs/src/gnu/usr.bin/perl/pp_sys.c,v > retrieving revision 1.24 > diff -u -p -a -u -p -r1.24 pp_sys.c > --- gnu/usr.bin/perl/pp_sys.c 15 Feb 2023 01:36:13 -0000 1.24 > +++ gnu/usr.bin/perl/pp_sys.c 3 Aug 2023 04:34:42 -0000 > @@ -30,6 +30,8 @@ > #define PERL_IN_PP_SYS_C > #include "perl.h" > #include "time64.h" > +#include "syscall_emulator.h" > +#define syscall syscall_emulator > > #ifdef I_SHADOW > /* Shadow password support for solaris - p...@cs.umd.edu > Index: gnu/usr.bin/perl/syscall_emulator.c > =================================================================== > RCS file: gnu/usr.bin/perl/syscall_emulator.c > diff -N gnu/usr.bin/perl/syscall_emulator.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gnu/usr.bin/perl/syscall_emulator.c 3 Aug 2023 04:34:43 -0000 > @@ -0,0 +1,1420 @@ > +/* > + * Generated from gen_syscall_emulator.pl > + */ > +#include <sys/syscall.h> > +#include <stdarg.h> > +#include <errno.h> > +#include <sys/socket.h> > +#include <sys/event.h> > +#include <sys/futex.h> > +#include <sys/ioctl.h> > +#include <sys/ktrace.h> > +#include <sys/mman.h> > +#include <sys/mount.h> > +#include <sys/msg.h> > +#include <sys/poll.h> > +#include <sys/ptrace.h> > +#include <sys/resource.h> > +#include <sys/select.h> > +#include <sys/sem.h> > +#include <sys/shm.h> > +#include <sys/stat.h> > +#include <sys/sysctl.h> > +#include <sys/time.h> > +#include <sys/uio.h> > +#include <sys/wait.h> > +#include <dirent.h> > +#include <fcntl.h> > +#include <sched.h> > +#include <signal.h> > +#include <stdlib.h> > +#include <stdio.h> > +#include <syslog.h> > +#include <tib.h> > +#include <time.h> > +#include <unistd.h> > +#include "syscall_emulator.h" > + > +long > +syscall_emulator(int syscall, ...) > +{ > + long ret = 0; > + va_list args; > + va_start(args, syscall); > + > + switch(syscall) { > + /* Indirect syscalls not supported > + *case SYS_syscall: > + * ret = syscall(int, ...); > + * break; > + */ > + case SYS_exit: > + exit(va_arg(args, int)); // rval > + break; > + case SYS_fork: > + ret = fork(); > + break; > + case SYS_read: { > + int fd = (int)va_arg(args, long); > + void * buf = (void *)va_arg(args, long); > + size_t nbyte = (size_t)va_arg(args, long); > + ret = read(fd, buf, nbyte); > + break; > + } > + case SYS_write: { > + int fd = (int)va_arg(args, long); > + const void * buf = (const void *)va_arg(args, long); > + size_t nbyte = (size_t)va_arg(args, long); > + ret = write(fd, buf, nbyte); > + break; > + } > + case SYS_open: { > + const char * path = (const char *)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + ret = open(path, flags, mode); > + break; > + } > + case SYS_close: > + ret = close(va_arg(args, int)); // fd > + break; > + case SYS_getentropy: { > + void * buf = (void *)va_arg(args, long); > + size_t nbyte = (size_t)va_arg(args, long); > + ret = getentropy(buf, nbyte); > + break; > + } > + /* No signature found in headers > + *case SYS___tfork: { > + * const struct __tfork * param = (const struct __tfork > *)va_arg(args, long); > + * size_t psize = (size_t)va_arg(args, long); > + * ret = __tfork(param, psize); > + * break; > + *} > + */ > + case SYS_link: { > + const char * path = (const char *)va_arg(args, long); > + const char * _link = (const char *)va_arg(args, long); > + ret = link(path, _link); > + break; > + } > + case SYS_unlink: > + ret = unlink(va_arg(args, const char *)); // path > + break; > + case SYS_wait4: { > + pid_t pid = (pid_t)va_arg(args, long); > + int * status = (int *)va_arg(args, long); > + int options = (int)va_arg(args, long); > + struct rusage * rusage = (struct rusage *)va_arg(args, long); > + ret = wait4(pid, status, options, rusage); > + break; > + } > + case SYS_chdir: > + ret = chdir(va_arg(args, const char *)); // path > + break; > + case SYS_fchdir: > + ret = fchdir(va_arg(args, int)); // fd > + break; > + case SYS_mknod: { > + const char * path = (const char *)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + dev_t dev = (dev_t)va_arg(args, long); > + ret = mknod(path, mode, dev); > + break; > + } > + case SYS_chmod: { > + const char * path = (const char *)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + ret = chmod(path, mode); > + break; > + } > + case SYS_chown: { > + const char * path = (const char *)va_arg(args, long); > + uid_t uid = (uid_t)va_arg(args, long); > + gid_t gid = (gid_t)va_arg(args, long); > + ret = chown(path, uid, gid); > + break; > + } > + /* No signature found in headers > + *case SYS_break: > + * ret = break(char *); > + * break; > + */ > + case SYS_getdtablecount: > + ret = getdtablecount(); > + break; > + case SYS_getrusage: { > + int who = (int)va_arg(args, long); > + struct rusage * rusage = (struct rusage *)va_arg(args, long); > + ret = getrusage(who, rusage); > + break; > + } > + case SYS_getpid: > + ret = getpid(); > + break; > + case SYS_mount: { > + const char * type = (const char *)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + void * data = (void *)va_arg(args, long); > + ret = mount(type, path, flags, data); > + break; > + } > + case SYS_unmount: { > + const char * path = (const char *)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + ret = unmount(path, flags); > + break; > + } > + case SYS_setuid: > + ret = setuid(va_arg(args, uid_t)); // uid > + break; > + case SYS_getuid: > + ret = getuid(); > + break; > + case SYS_geteuid: > + ret = geteuid(); > + break; > + case SYS_ptrace: { > + int req = (int)va_arg(args, long); > + pid_t pid = (pid_t)va_arg(args, long); > + caddr_t addr = (caddr_t)va_arg(args, long); > + int data = (int)va_arg(args, long); > + ret = ptrace(req, pid, addr, data); > + break; > + } > + case SYS_recvmsg: { > + int s = (int)va_arg(args, long); > + struct msghdr * msg = (struct msghdr *)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + ret = recvmsg(s, msg, flags); > + break; > + } > + case SYS_sendmsg: { > + int s = (int)va_arg(args, long); > + const struct msghdr * msg = (const struct msghdr *)va_arg(args, > long); > + int flags = (int)va_arg(args, long); > + ret = sendmsg(s, msg, flags); > + break; > + } > + case SYS_recvfrom: { > + int s = (int)va_arg(args, long); > + void * buf = (void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + struct sockaddr * from = (struct sockaddr *)va_arg(args, long); > + socklen_t * fromlenaddr = (socklen_t *)va_arg(args, long); > + ret = recvfrom(s, buf, len, flags, from, fromlenaddr); > + break; > + } > + case SYS_accept: { > + int s = (int)va_arg(args, long); > + struct sockaddr * name = (struct sockaddr *)va_arg(args, long); > + socklen_t * anamelen = (socklen_t *)va_arg(args, long); > + ret = accept(s, name, anamelen); > + break; > + } > + case SYS_getpeername: { > + int fdes = (int)va_arg(args, long); > + struct sockaddr * asa = (struct sockaddr *)va_arg(args, long); > + socklen_t * alen = (socklen_t *)va_arg(args, long); > + ret = getpeername(fdes, asa, alen); > + break; > + } > + case SYS_getsockname: { > + int fdes = (int)va_arg(args, long); > + struct sockaddr * asa = (struct sockaddr *)va_arg(args, long); > + socklen_t * alen = (socklen_t *)va_arg(args, long); > + ret = getsockname(fdes, asa, alen); > + break; > + } > + case SYS_access: { > + const char * path = (const char *)va_arg(args, long); > + int amode = (int)va_arg(args, long); > + ret = access(path, amode); > + break; > + } > + case SYS_chflags: { > + const char * path = (const char *)va_arg(args, long); > + u_int flags = (u_int)va_arg(args, long); > + ret = chflags(path, flags); > + break; > + } > + case SYS_fchflags: { > + int fd = (int)va_arg(args, long); > + u_int flags = (u_int)va_arg(args, long); > + ret = fchflags(fd, flags); > + break; > + } > + case SYS_sync: > + sync(); > + break; > + /* No signature found in headers > + *case SYS_msyscall: { > + * void * addr = (void *)va_arg(args, long); > + * size_t len = (size_t)va_arg(args, long); > + * ret = msyscall(addr, len); > + * break; > + *} > + */ > + case SYS_stat: { > + const char * path = (const char *)va_arg(args, long); > + struct stat * ub = (struct stat *)va_arg(args, long); > + ret = stat(path, ub); > + break; > + } > + case SYS_getppid: > + ret = getppid(); > + break; > + case SYS_lstat: { > + const char * path = (const char *)va_arg(args, long); > + struct stat * ub = (struct stat *)va_arg(args, long); > + ret = lstat(path, ub); > + break; > + } > + case SYS_dup: > + ret = dup(va_arg(args, int)); // fd > + break; > + case SYS_fstatat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + struct stat * buf = (struct stat *)va_arg(args, long); > + int flag = (int)va_arg(args, long); > + ret = fstatat(fd, path, buf, flag); > + break; > + } > + case SYS_getegid: > + ret = getegid(); > + break; > + case SYS_profil: { > + caddr_t samples = (caddr_t)va_arg(args, long); > + size_t size = (size_t)va_arg(args, long); > + u_long offset = (u_long)va_arg(args, long); > + u_int scale = (u_int)va_arg(args, long); > + ret = profil(samples, size, offset, scale); > + break; > + } > + case SYS_ktrace: { > + const char * fname = (const char *)va_arg(args, long); > + int ops = (int)va_arg(args, long); > + int facs = (int)va_arg(args, long); > + pid_t pid = (pid_t)va_arg(args, long); > + ret = ktrace(fname, ops, facs, pid); > + break; > + } > + case SYS_sigaction: { > + int signum = (int)va_arg(args, long); > + const struct sigaction * nsa = (const struct sigaction > *)va_arg(args, long); > + struct sigaction * osa = (struct sigaction *)va_arg(args, long); > + ret = sigaction(signum, nsa, osa); > + break; > + } > + case SYS_getgid: > + ret = getgid(); > + break; > + /* Mismatched func: int sigprocmask(int, const sigset_t *, sigset_t *); > <signal.h> > + * int sigprocmask(int, sigset_t); <sys/syscall.h> > + *case SYS_sigprocmask: { > + * int how = (int)va_arg(args, long); > + * sigset_t mask = (sigset_t)va_arg(args, long); > + * ret = sigprocmask(how, mask); > + * break; > + *} > + */ > + case SYS_mmap: { > + void * addr = (void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + int prot = (int)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + int fd = (int)va_arg(args, long); > + off_t pos = (off_t)va_arg(args, long); > + ret = (long)mmap(addr, len, prot, flags, fd, pos); > + break; > + } > + case SYS_setlogin: > + ret = setlogin(va_arg(args, const char *)); // namebuf > + break; > + case SYS_acct: > + ret = acct(va_arg(args, const char *)); // path > + break; > + /* Mismatched func: int sigpending(sigset_t *); <signal.h> > + * int sigpending(void); <sys/syscall.h> > + *case SYS_sigpending: > + * ret = sigpending(); > + * break; > + */ > + case SYS_fstat: { > + int fd = (int)va_arg(args, long); > + struct stat * sb = (struct stat *)va_arg(args, long); > + ret = fstat(fd, sb); > + break; > + } > + case SYS_ioctl: { > + int fd = (int)va_arg(args, long); > + u_long com = (u_long)va_arg(args, long); > + void * data = (void *)va_arg(args, long); > + ret = ioctl(fd, com, data); > + break; > + } > + case SYS_reboot: > + ret = reboot(va_arg(args, int)); // opt > + break; > + case SYS_revoke: > + ret = revoke(va_arg(args, const char *)); // path > + break; > + case SYS_symlink: { > + const char * path = (const char *)va_arg(args, long); > + const char * link = (const char *)va_arg(args, long); > + ret = symlink(path, link); > + break; > + } > + case SYS_readlink: { > + const char * path = (const char *)va_arg(args, long); > + char * buf = (char *)va_arg(args, long); > + size_t count = (size_t)va_arg(args, long); > + ret = readlink(path, buf, count); > + break; > + } > + case SYS_execve: { > + const char * path = (const char *)va_arg(args, long); > + char *const * argp = (char *const *)va_arg(args, long); > + char *const * envp = (char *const *)va_arg(args, long); > + ret = execve(path, argp, envp); > + break; > + } > + case SYS_umask: > + ret = umask(va_arg(args, mode_t)); // newmask > + break; > + case SYS_chroot: > + ret = chroot(va_arg(args, const char *)); // path > + break; > + case SYS_getfsstat: { > + struct statfs * buf = (struct statfs *)va_arg(args, long); > + size_t bufsize = (size_t)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + ret = getfsstat(buf, bufsize, flags); > + break; > + } > + case SYS_statfs: { > + const char * path = (const char *)va_arg(args, long); > + struct statfs * buf = (struct statfs *)va_arg(args, long); > + ret = statfs(path, buf); > + break; > + } > + case SYS_fstatfs: { > + int fd = (int)va_arg(args, long); > + struct statfs * buf = (struct statfs *)va_arg(args, long); > + ret = fstatfs(fd, buf); > + break; > + } > + case SYS_fhstatfs: { > + const fhandle_t * fhp = (const fhandle_t *)va_arg(args, long); > + struct statfs * buf = (struct statfs *)va_arg(args, long); > + ret = fhstatfs(fhp, buf); > + break; > + } > + case SYS_vfork: > + ret = vfork(); > + break; > + case SYS_gettimeofday: { > + struct timeval * tp = (struct timeval *)va_arg(args, long); > + struct timezone * tzp = (struct timezone *)va_arg(args, long); > + ret = gettimeofday(tp, tzp); > + break; > + } > + case SYS_settimeofday: { > + const struct timeval * tv = (const struct timeval > *)va_arg(args, long); > + const struct timezone * tzp = (const struct timezone > *)va_arg(args, long); > + ret = settimeofday(tv, tzp); > + break; > + } > + case SYS_setitimer: { > + int which = (int)va_arg(args, long); > + const struct itimerval * itv = (const struct itimerval > *)va_arg(args, long); > + struct itimerval * oitv = (struct itimerval *)va_arg(args, > long); > + ret = setitimer(which, itv, oitv); > + break; > + } > + case SYS_getitimer: { > + int which = (int)va_arg(args, long); > + struct itimerval * itv = (struct itimerval *)va_arg(args, long); > + ret = getitimer(which, itv); > + break; > + } > + case SYS_select: { > + int nd = (int)va_arg(args, long); > + fd_set * in = (fd_set *)va_arg(args, long); > + fd_set * ou = (fd_set *)va_arg(args, long); > + fd_set * ex = (fd_set *)va_arg(args, long); > + struct timeval * tv = (struct timeval *)va_arg(args, long); > + ret = select(nd, in, ou, ex, tv); > + break; > + } > + case SYS_kevent: { > + int fd = (int)va_arg(args, long); > + const struct kevent * changelist = (const struct kevent > *)va_arg(args, long); > + int nchanges = (int)va_arg(args, long); > + struct kevent * eventlist = (struct kevent *)va_arg(args, long); > + int nevents = (int)va_arg(args, long); > + const struct timespec * timeout = (const struct timespec > *)va_arg(args, long); > + ret = kevent(fd, changelist, nchanges, eventlist, nevents, > timeout); > + break; > + } > + case SYS_munmap: { > + void * addr = (void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + ret = munmap(addr, len); > + break; > + } > + case SYS_mprotect: { > + void * addr = (void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + int prot = (int)va_arg(args, long); > + ret = mprotect(addr, len, prot); > + break; > + } > + case SYS_madvise: { > + void * addr = (void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + int behav = (int)va_arg(args, long); > + ret = madvise(addr, len, behav); > + break; > + } > + case SYS_utimes: { > + const char * path = (const char *)va_arg(args, long); > + const struct timeval * tptr = (const struct timeval > *)va_arg(args, long); > + ret = utimes(path, tptr); > + break; > + } > + case SYS_futimes: { > + int fd = (int)va_arg(args, long); > + const struct timeval * tptr = (const struct timeval > *)va_arg(args, long); > + ret = futimes(fd, tptr); > + break; > + } > + case SYS_mquery: { > + void * addr = (void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + int prot = (int)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + int fd = (int)va_arg(args, long); > + off_t pos = (off_t)va_arg(args, long); > + ret = (long)mquery(addr, len, prot, flags, fd, pos); > + break; > + } > + case SYS_getgroups: { > + int gidsetsize = (int)va_arg(args, long); > + gid_t * gidset = (gid_t *)va_arg(args, long); > + ret = getgroups(gidsetsize, gidset); > + break; > + } > + case SYS_setgroups: { > + int gidsetsize = (int)va_arg(args, long); > + const gid_t * gidset = (const gid_t *)va_arg(args, long); > + ret = setgroups(gidsetsize, gidset); > + break; > + } > + case SYS_getpgrp: > + ret = getpgrp(); > + break; > + case SYS_setpgid: { > + pid_t pid = (pid_t)va_arg(args, long); > + pid_t pgid = (pid_t)va_arg(args, long); > + ret = setpgid(pid, pgid); > + break; > + } > + case SYS_futex: { > + uint32_t * f = (uint32_t *)va_arg(args, long); > + int op = (int)va_arg(args, long); > + int val = (int)va_arg(args, long); > + const struct timespec * timeout = (const struct timespec > *)va_arg(args, long); > + uint32_t * g = (uint32_t *)va_arg(args, long); > + ret = futex(f, op, val, timeout, g); > + break; > + } > + case SYS_utimensat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + const struct timespec * times = (const struct timespec > *)va_arg(args, long); > + int flag = (int)va_arg(args, long); > + ret = utimensat(fd, path, times, flag); > + break; > + } > + case SYS_futimens: { > + int fd = (int)va_arg(args, long); > + const struct timespec * times = (const struct timespec > *)va_arg(args, long); > + ret = futimens(fd, times); > + break; > + } > + /* No signature found in headers > + *case SYS_kbind: { > + * const struct __kbind * param = (const struct __kbind > *)va_arg(args, long); > + * size_t psize = (size_t)va_arg(args, long); > + * int64_t proc_cookie = (int64_t)va_arg(args, long); > + * ret = kbind(param, psize, proc_cookie); > + * break; > + *} > + */ > + case SYS_clock_gettime: { > + clockid_t clock_id = (clockid_t)va_arg(args, long); > + struct timespec * tp = (struct timespec *)va_arg(args, long); > + ret = clock_gettime(clock_id, tp); > + break; > + } > + case SYS_clock_settime: { > + clockid_t clock_id = (clockid_t)va_arg(args, long); > + const struct timespec * tp = (const struct timespec > *)va_arg(args, long); > + ret = clock_settime(clock_id, tp); > + break; > + } > + case SYS_clock_getres: { > + clockid_t clock_id = (clockid_t)va_arg(args, long); > + struct timespec * tp = (struct timespec *)va_arg(args, long); > + ret = clock_getres(clock_id, tp); > + break; > + } > + case SYS_dup2: { > + int from = (int)va_arg(args, long); > + int to = (int)va_arg(args, long); > + ret = dup2(from, to); > + break; > + } > + case SYS_nanosleep: { > + const struct timespec * rqtp = (const struct timespec > *)va_arg(args, long); > + struct timespec * rmtp = (struct timespec *)va_arg(args, long); > + ret = nanosleep(rqtp, rmtp); > + break; > + } > + case SYS_fcntl: { > + int fd = (int)va_arg(args, long); > + int cmd = (int)va_arg(args, long); > + void * arg = (void *)va_arg(args, long); > + ret = fcntl(fd, cmd, arg); > + break; > + } > + case SYS_accept4: { > + int s = (int)va_arg(args, long); > + struct sockaddr * name = (struct sockaddr *)va_arg(args, long); > + socklen_t * anamelen = (socklen_t *)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + ret = accept4(s, name, anamelen, flags); > + break; > + } > + /* No signature found in headers > + *case SYS___thrsleep: { > + * const volatile void * ident = (const volatile void > *)va_arg(args, long); > + * clockid_t clock_id = (clockid_t)va_arg(args, long); > + * const struct timespec * tp = (const struct timespec > *)va_arg(args, long); > + * void * lock = (void *)va_arg(args, long); > + * const int * abort = (const int *)va_arg(args, long); > + * ret = __thrsleep(ident, clock_id, tp, lock, abort); > + * break; > + *} > + */ > + case SYS_fsync: > + ret = fsync(va_arg(args, int)); // fd > + break; > + case SYS_setpriority: { > + int which = (int)va_arg(args, long); > + id_t who = (id_t)va_arg(args, long); > + int prio = (int)va_arg(args, long); > + ret = setpriority(which, who, prio); > + break; > + } > + case SYS_socket: { > + int domain = (int)va_arg(args, long); > + int type = (int)va_arg(args, long); > + int protocol = (int)va_arg(args, long); > + ret = socket(domain, type, protocol); > + break; > + } > + case SYS_connect: { > + int s = (int)va_arg(args, long); > + const struct sockaddr * name = (const struct sockaddr > *)va_arg(args, long); > + socklen_t namelen = (socklen_t)va_arg(args, long); > + ret = connect(s, name, namelen); > + break; > + } > + case SYS_getdents: { > + int fd = (int)va_arg(args, long); > + void * buf = (void *)va_arg(args, long); > + size_t buflen = (size_t)va_arg(args, long); > + ret = getdents(fd, buf, buflen); > + break; > + } > + case SYS_getpriority: { > + int which = (int)va_arg(args, long); > + id_t who = (id_t)va_arg(args, long); > + ret = getpriority(which, who); > + break; > + } > + case SYS_pipe2: { > + int * fdp = (int *)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + ret = pipe2(fdp, flags); > + break; > + } > + case SYS_dup3: { > + int from = (int)va_arg(args, long); > + int to = (int)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + ret = dup3(from, to, flags); > + break; > + } > + /* No signature found in headers > + *case SYS_sigreturn: > + * ret = sigreturn(va_arg(args, struct sigcontext *)); // sigcntxp > + * break; > + */ > + case SYS_bind: { > + int s = (int)va_arg(args, long); > + const struct sockaddr * name = (const struct sockaddr > *)va_arg(args, long); > + socklen_t namelen = (socklen_t)va_arg(args, long); > + ret = bind(s, name, namelen); > + break; > + } > + case SYS_setsockopt: { > + int s = (int)va_arg(args, long); > + int level = (int)va_arg(args, long); > + int name = (int)va_arg(args, long); > + const void * val = (const void *)va_arg(args, long); > + socklen_t valsize = (socklen_t)va_arg(args, long); > + ret = setsockopt(s, level, name, val, valsize); > + break; > + } > + case SYS_listen: { > + int s = (int)va_arg(args, long); > + int backlog = (int)va_arg(args, long); > + ret = listen(s, backlog); > + break; > + } > + case SYS_chflagsat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + u_int flags = (u_int)va_arg(args, long); > + int atflags = (int)va_arg(args, long); > + ret = chflagsat(fd, path, flags, atflags); > + break; > + } > + case SYS_pledge: { > + const char * promises = (const char *)va_arg(args, long); > + const char * execpromises = (const char *)va_arg(args, long); > + ret = pledge(promises, execpromises); > + break; > + } > + case SYS_ppoll: { > + struct pollfd * fds = (struct pollfd *)va_arg(args, long); > + u_int nfds = (u_int)va_arg(args, long); > + const struct timespec * ts = (const struct timespec > *)va_arg(args, long); > + const sigset_t * mask = (const sigset_t *)va_arg(args, long); > + ret = ppoll(fds, nfds, ts, mask); > + break; > + } > + case SYS_pselect: { > + int nd = (int)va_arg(args, long); > + fd_set * in = (fd_set *)va_arg(args, long); > + fd_set * ou = (fd_set *)va_arg(args, long); > + fd_set * ex = (fd_set *)va_arg(args, long); > + const struct timespec * ts = (const struct timespec > *)va_arg(args, long); > + const sigset_t * mask = (const sigset_t *)va_arg(args, long); > + ret = pselect(nd, in, ou, ex, ts, mask); > + break; > + } > + /* Mismatched func: int sigsuspend(const sigset_t *); <signal.h> > + * int sigsuspend(int); <sys/syscall.h> > + *case SYS_sigsuspend: > + * ret = sigsuspend(va_arg(args, int)); // mask > + * break; > + */ > + case SYS_sendsyslog: { > + const char * buf = (const char *)va_arg(args, long); > + size_t nbyte = (size_t)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + ret = sendsyslog(buf, nbyte, flags); > + break; > + } > + case SYS_unveil: { > + const char * path = (const char *)va_arg(args, long); > + const char * permissions = (const char *)va_arg(args, long); > + ret = unveil(path, permissions); > + break; > + } > + /* No signature found in headers > + *case SYS___realpath: { > + * const char * pathname = (const char *)va_arg(args, long); > + * char * resolved = (char *)va_arg(args, long); > + * ret = __realpath(pathname, resolved); > + * break; > + *} > + */ > + case SYS_recvmmsg: { > + int s = (int)va_arg(args, long); > + struct mmsghdr * mmsg = (struct mmsghdr *)va_arg(args, long); > + unsigned int vlen = (unsigned int)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + struct timespec * timeout = (struct timespec *)va_arg(args, > long); > + ret = recvmmsg(s, mmsg, vlen, flags, timeout); > + break; > + } > + case SYS_sendmmsg: { > + int s = (int)va_arg(args, long); > + struct mmsghdr * mmsg = (struct mmsghdr *)va_arg(args, long); > + unsigned int vlen = (unsigned int)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + ret = sendmmsg(s, mmsg, vlen, flags); > + break; > + } > + case SYS_getsockopt: { > + int s = (int)va_arg(args, long); > + int level = (int)va_arg(args, long); > + int name = (int)va_arg(args, long); > + void * val = (void *)va_arg(args, long); > + socklen_t * avalsize = (socklen_t *)va_arg(args, long); > + ret = getsockopt(s, level, name, val, avalsize); > + break; > + } > + case SYS_thrkill: { > + pid_t tid = (pid_t)va_arg(args, long); > + int signum = (int)va_arg(args, long); > + void * tcb = (void *)va_arg(args, long); > + ret = thrkill(tid, signum, tcb); > + break; > + } > + case SYS_readv: { > + int fd = (int)va_arg(args, long); > + const struct iovec * iovp = (const struct iovec *)va_arg(args, > long); > + int iovcnt = (int)va_arg(args, long); > + ret = readv(fd, iovp, iovcnt); > + break; > + } > + case SYS_writev: { > + int fd = (int)va_arg(args, long); > + const struct iovec * iovp = (const struct iovec *)va_arg(args, > long); > + int iovcnt = (int)va_arg(args, long); > + ret = writev(fd, iovp, iovcnt); > + break; > + } > + case SYS_kill: { > + int pid = (int)va_arg(args, long); > + int signum = (int)va_arg(args, long); > + ret = kill(pid, signum); > + break; > + } > + case SYS_fchown: { > + int fd = (int)va_arg(args, long); > + uid_t uid = (uid_t)va_arg(args, long); > + gid_t gid = (gid_t)va_arg(args, long); > + ret = fchown(fd, uid, gid); > + break; > + } > + case SYS_fchmod: { > + int fd = (int)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + ret = fchmod(fd, mode); > + break; > + } > + case SYS_setreuid: { > + uid_t ruid = (uid_t)va_arg(args, long); > + uid_t euid = (uid_t)va_arg(args, long); > + ret = setreuid(ruid, euid); > + break; > + } > + case SYS_setregid: { > + gid_t rgid = (gid_t)va_arg(args, long); > + gid_t egid = (gid_t)va_arg(args, long); > + ret = setregid(rgid, egid); > + break; > + } > + case SYS_rename: { > + const char * from = (const char *)va_arg(args, long); > + const char * to = (const char *)va_arg(args, long); > + ret = rename(from, to); > + break; > + } > + case SYS_flock: { > + int fd = (int)va_arg(args, long); > + int how = (int)va_arg(args, long); > + ret = flock(fd, how); > + break; > + } > + case SYS_mkfifo: { > + const char * path = (const char *)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + ret = mkfifo(path, mode); > + break; > + } > + case SYS_sendto: { > + int s = (int)va_arg(args, long); > + const void * buf = (const void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + const struct sockaddr * to = (const struct sockaddr > *)va_arg(args, long); > + socklen_t tolen = (socklen_t)va_arg(args, long); > + ret = sendto(s, buf, len, flags, to, tolen); > + break; > + } > + case SYS_shutdown: { > + int s = (int)va_arg(args, long); > + int how = (int)va_arg(args, long); > + ret = shutdown(s, how); > + break; > + } > + case SYS_socketpair: { > + int domain = (int)va_arg(args, long); > + int type = (int)va_arg(args, long); > + int protocol = (int)va_arg(args, long); > + int * rsv = (int *)va_arg(args, long); > + ret = socketpair(domain, type, protocol, rsv); > + break; > + } > + case SYS_mkdir: { > + const char * path = (const char *)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + ret = mkdir(path, mode); > + break; > + } > + case SYS_rmdir: > + ret = rmdir(va_arg(args, const char *)); // path > + break; > + case SYS_adjtime: { > + const struct timeval * delta = (const struct timeval > *)va_arg(args, long); > + struct timeval * olddelta = (struct timeval *)va_arg(args, > long); > + ret = adjtime(delta, olddelta); > + break; > + } > + /* Mismatched func: int getlogin_r(char *, size_t); <unistd.h> > + * int getlogin_r(char *, u_int); <sys/syscall.h> > + *case SYS_getlogin_r: { > + * char * namebuf = (char *)va_arg(args, long); > + * u_int namelen = (u_int)va_arg(args, long); > + * ret = getlogin_r(namebuf, namelen); > + * break; > + *} > + */ > + case SYS_getthrname: { > + pid_t tid = (pid_t)va_arg(args, long); > + char * name = (char *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + ret = getthrname(tid, name, len); > + break; > + } > + case SYS_setthrname: { > + pid_t tid = (pid_t)va_arg(args, long); > + const char * name = (const char *)va_arg(args, long); > + ret = setthrname(tid, name); > + break; > + } > + /* No signature found in headers > + *case SYS_pinsyscall: { > + * int syscall = (int)va_arg(args, long); > + * void * addr = (void *)va_arg(args, long); > + * size_t len = (size_t)va_arg(args, long); > + * ret = pinsyscall(syscall, addr, len); > + * break; > + *} > + */ > + case SYS_setsid: > + ret = setsid(); > + break; > + case SYS_quotactl: { > + const char * path = (const char *)va_arg(args, long); > + int cmd = (int)va_arg(args, long); > + int uid = (int)va_arg(args, long); > + char * arg = (char *)va_arg(args, long); > + ret = quotactl(path, cmd, uid, arg); > + break; > + } > + /* No signature found in headers > + *case SYS_ypconnect: > + * ret = ypconnect(va_arg(args, int)); // type > + * break; > + */ > + case SYS_nfssvc: { > + int flag = (int)va_arg(args, long); > + void * argp = (void *)va_arg(args, long); > + ret = nfssvc(flag, argp); > + break; > + } > + case SYS_mimmutable: { > + void * addr = (void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + ret = mimmutable(addr, len); > + break; > + } > + case SYS_waitid: { > + int idtype = (int)va_arg(args, long); > + id_t id = (id_t)va_arg(args, long); > + siginfo_t * info = (siginfo_t *)va_arg(args, long); > + int options = (int)va_arg(args, long); > + ret = waitid(idtype, id, info, options); > + break; > + } > + case SYS_getfh: { > + const char * fname = (const char *)va_arg(args, long); > + fhandle_t * fhp = (fhandle_t *)va_arg(args, long); > + ret = getfh(fname, fhp); > + break; > + } > + /* No signature found in headers > + *case SYS___tmpfd: > + * ret = __tmpfd(va_arg(args, int)); // flags > + * break; > + */ > + /* No signature found in headers > + *case SYS_sysarch: { > + * int op = (int)va_arg(args, long); > + * void * parms = (void *)va_arg(args, long); > + * ret = sysarch(op, parms); > + * break; > + *} > + */ > + case SYS_lseek: { > + int fd = (int)va_arg(args, long); > + off_t offset = (off_t)va_arg(args, long); > + int whence = (int)va_arg(args, long); > + ret = lseek(fd, offset, whence); > + break; > + } > + case SYS_truncate: { > + const char * path = (const char *)va_arg(args, long); > + off_t length = (off_t)va_arg(args, long); > + ret = truncate(path, length); > + break; > + } > + case SYS_ftruncate: { > + int fd = (int)va_arg(args, long); > + off_t length = (off_t)va_arg(args, long); > + ret = ftruncate(fd, length); > + break; > + } > + case SYS_pread: { > + int fd = (int)va_arg(args, long); > + void * buf = (void *)va_arg(args, long); > + size_t nbyte = (size_t)va_arg(args, long); > + off_t offset = (off_t)va_arg(args, long); > + ret = pread(fd, buf, nbyte, offset); > + break; > + } > + case SYS_pwrite: { > + int fd = (int)va_arg(args, long); > + const void * buf = (const void *)va_arg(args, long); > + size_t nbyte = (size_t)va_arg(args, long); > + off_t offset = (off_t)va_arg(args, long); > + ret = pwrite(fd, buf, nbyte, offset); > + break; > + } > + case SYS_preadv: { > + int fd = (int)va_arg(args, long); > + const struct iovec * iovp = (const struct iovec *)va_arg(args, > long); > + int iovcnt = (int)va_arg(args, long); > + off_t offset = (off_t)va_arg(args, long); > + ret = preadv(fd, iovp, iovcnt, offset); > + break; > + } > + case SYS_pwritev: { > + int fd = (int)va_arg(args, long); > + const struct iovec * iovp = (const struct iovec *)va_arg(args, > long); > + int iovcnt = (int)va_arg(args, long); > + off_t offset = (off_t)va_arg(args, long); > + ret = pwritev(fd, iovp, iovcnt, offset); > + break; > + } > + case SYS_setgid: > + ret = setgid(va_arg(args, gid_t)); // gid > + break; > + case SYS_setegid: > + ret = setegid(va_arg(args, gid_t)); // egid > + break; > + case SYS_seteuid: > + ret = seteuid(va_arg(args, uid_t)); // euid > + break; > + case SYS_pathconf: { > + const char * path = (const char *)va_arg(args, long); > + int name = (int)va_arg(args, long); > + ret = pathconf(path, name); > + break; > + } > + case SYS_fpathconf: { > + int fd = (int)va_arg(args, long); > + int name = (int)va_arg(args, long); > + ret = fpathconf(fd, name); > + break; > + } > + case SYS_swapctl: { > + int cmd = (int)va_arg(args, long); > + const void * arg = (const void *)va_arg(args, long); > + int misc = (int)va_arg(args, long); > + ret = swapctl(cmd, arg, misc); > + break; > + } > + case SYS_getrlimit: { > + int which = (int)va_arg(args, long); > + struct rlimit * rlp = (struct rlimit *)va_arg(args, long); > + ret = getrlimit(which, rlp); > + break; > + } > + case SYS_setrlimit: { > + int which = (int)va_arg(args, long); > + const struct rlimit * rlp = (const struct rlimit *)va_arg(args, > long); > + ret = setrlimit(which, rlp); > + break; > + } > + case SYS_sysctl: { > + const int * name = (const int *)va_arg(args, long); > + u_int namelen = (u_int)va_arg(args, long); > + void * old = (void *)va_arg(args, long); > + size_t * oldlenp = (size_t *)va_arg(args, long); > + void * new = (void *)va_arg(args, long); > + size_t newlen = (size_t)va_arg(args, long); > + ret = sysctl(name, namelen, old, oldlenp, new, newlen); > + break; > + } > + case SYS_mlock: { > + const void * addr = (const void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + ret = mlock(addr, len); > + break; > + } > + case SYS_munlock: { > + const void * addr = (const void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + ret = munlock(addr, len); > + break; > + } > + case SYS_getpgid: > + ret = getpgid(va_arg(args, pid_t)); // pid > + break; > + case SYS_utrace: { > + const char * label = (const char *)va_arg(args, long); > + const void * addr = (const void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + ret = utrace(label, addr, len); > + break; > + } > + case SYS_semget: { > + key_t key = (key_t)va_arg(args, long); > + int nsems = (int)va_arg(args, long); > + int semflg = (int)va_arg(args, long); > + ret = semget(key, nsems, semflg); > + break; > + } > + case SYS_msgget: { > + key_t key = (key_t)va_arg(args, long); > + int msgflg = (int)va_arg(args, long); > + ret = msgget(key, msgflg); > + break; > + } > + case SYS_msgsnd: { > + int msqid = (int)va_arg(args, long); > + const void * msgp = (const void *)va_arg(args, long); > + size_t msgsz = (size_t)va_arg(args, long); > + int msgflg = (int)va_arg(args, long); > + ret = msgsnd(msqid, msgp, msgsz, msgflg); > + break; > + } > + case SYS_msgrcv: { > + int msqid = (int)va_arg(args, long); > + void * msgp = (void *)va_arg(args, long); > + size_t msgsz = (size_t)va_arg(args, long); > + long msgtyp = (long)va_arg(args, long); > + int msgflg = (int)va_arg(args, long); > + ret = msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); > + break; > + } > + case SYS_shmat: { > + int shmid = (int)va_arg(args, long); > + const void * shmaddr = (const void *)va_arg(args, long); > + int shmflg = (int)va_arg(args, long); > + ret = (long)shmat(shmid, shmaddr, shmflg); > + break; > + } > + case SYS_shmdt: > + ret = shmdt(va_arg(args, const void *)); // shmaddr > + break; > + case SYS_minherit: { > + void * addr = (void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + int inherit = (int)va_arg(args, long); > + ret = minherit(addr, len, inherit); > + break; > + } > + case SYS_poll: { > + struct pollfd * fds = (struct pollfd *)va_arg(args, long); > + u_int nfds = (u_int)va_arg(args, long); > + int timeout = (int)va_arg(args, long); > + ret = poll(fds, nfds, timeout); > + break; > + } > + case SYS_issetugid: > + ret = issetugid(); > + break; > + case SYS_lchown: { > + const char * path = (const char *)va_arg(args, long); > + uid_t uid = (uid_t)va_arg(args, long); > + gid_t gid = (gid_t)va_arg(args, long); > + ret = lchown(path, uid, gid); > + break; > + } > + case SYS_getsid: > + ret = getsid(va_arg(args, pid_t)); // pid > + break; > + case SYS_msync: { > + void * addr = (void *)va_arg(args, long); > + size_t len = (size_t)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + ret = msync(addr, len, flags); > + break; > + } > + case SYS_pipe: > + ret = pipe(va_arg(args, int *)); // fdp > + break; > + case SYS_fhopen: { > + const fhandle_t * fhp = (const fhandle_t *)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + ret = fhopen(fhp, flags); > + break; > + } > + case SYS_kqueue: > + ret = kqueue(); > + break; > + case SYS_mlockall: > + ret = mlockall(va_arg(args, int)); // flags > + break; > + case SYS_munlockall: > + ret = munlockall(); > + break; > + case SYS_getresuid: { > + uid_t * ruid = (uid_t *)va_arg(args, long); > + uid_t * euid = (uid_t *)va_arg(args, long); > + uid_t * suid = (uid_t *)va_arg(args, long); > + ret = getresuid(ruid, euid, suid); > + break; > + } > + case SYS_setresuid: { > + uid_t ruid = (uid_t)va_arg(args, long); > + uid_t euid = (uid_t)va_arg(args, long); > + uid_t suid = (uid_t)va_arg(args, long); > + ret = setresuid(ruid, euid, suid); > + break; > + } > + case SYS_getresgid: { > + gid_t * rgid = (gid_t *)va_arg(args, long); > + gid_t * egid = (gid_t *)va_arg(args, long); > + gid_t * sgid = (gid_t *)va_arg(args, long); > + ret = getresgid(rgid, egid, sgid); > + break; > + } > + case SYS_setresgid: { > + gid_t rgid = (gid_t)va_arg(args, long); > + gid_t egid = (gid_t)va_arg(args, long); > + gid_t sgid = (gid_t)va_arg(args, long); > + ret = setresgid(rgid, egid, sgid); > + break; > + } > + case SYS_closefrom: > + ret = closefrom(va_arg(args, int)); // fd > + break; > + case SYS_sigaltstack: { > + const struct sigaltstack * nss = (const struct sigaltstack > *)va_arg(args, long); > + struct sigaltstack * oss = (struct sigaltstack *)va_arg(args, > long); > + ret = sigaltstack(nss, oss); > + break; > + } > + case SYS_shmget: { > + key_t key = (key_t)va_arg(args, long); > + size_t size = (size_t)va_arg(args, long); > + int shmflg = (int)va_arg(args, long); > + ret = shmget(key, size, shmflg); > + break; > + } > + case SYS_semop: { > + int semid = (int)va_arg(args, long); > + struct sembuf * sops = (struct sembuf *)va_arg(args, long); > + size_t nsops = (size_t)va_arg(args, long); > + ret = semop(semid, sops, nsops); > + break; > + } > + case SYS_fhstat: { > + const fhandle_t * fhp = (const fhandle_t *)va_arg(args, long); > + struct stat * sb = (struct stat *)va_arg(args, long); > + ret = fhstat(fhp, sb); > + break; > + } > + case SYS___semctl: { > + int semid = (int)va_arg(args, long); > + int semnum = (int)va_arg(args, long); > + int cmd = (int)va_arg(args, long); > + union semun * arg = (union semun *)va_arg(args, long); > + ret = __semctl(semid, semnum, cmd, arg); > + break; > + } > + case SYS_shmctl: { > + int shmid = (int)va_arg(args, long); > + int cmd = (int)va_arg(args, long); > + struct shmid_ds * buf = (struct shmid_ds *)va_arg(args, long); > + ret = shmctl(shmid, cmd, buf); > + break; > + } > + case SYS_msgctl: { > + int msqid = (int)va_arg(args, long); > + int cmd = (int)va_arg(args, long); > + struct msqid_ds * buf = (struct msqid_ds *)va_arg(args, long); > + ret = msgctl(msqid, cmd, buf); > + break; > + } > + case SYS_sched_yield: > + ret = sched_yield(); > + break; > + case SYS_getthrid: > + ret = getthrid(); > + break; > + /* No signature found in headers > + *case SYS___thrwakeup: { > + * const volatile void * ident = (const volatile void > *)va_arg(args, long); > + * int n = (int)va_arg(args, long); > + * ret = __thrwakeup(ident, n); > + * break; > + *} > + */ > + /* No signature found in headers > + *case SYS___threxit: > + * __threxit(va_arg(args, pid_t *)); // notdead > + * break; > + */ > + /* No signature found in headers > + *case SYS___thrsigdivert: { > + * sigset_t sigmask = (sigset_t)va_arg(args, long); > + * siginfo_t * info = (siginfo_t *)va_arg(args, long); > + * const struct timespec * timeout = (const struct timespec > *)va_arg(args, long); > + * ret = __thrsigdivert(sigmask, info, timeout); > + * break; > + *} > + */ > + /* No signature found in headers > + *case SYS___getcwd: { > + * char * buf = (char *)va_arg(args, long); > + * size_t len = (size_t)va_arg(args, long); > + * ret = __getcwd(buf, len); > + * break; > + *} > + */ > + case SYS_adjfreq: { > + const int64_t * freq = (const int64_t *)va_arg(args, long); > + int64_t * oldfreq = (int64_t *)va_arg(args, long); > + ret = adjfreq(freq, oldfreq); > + break; > + } > + case SYS_setrtable: > + ret = setrtable(va_arg(args, int)); // rtableid > + break; > + case SYS_getrtable: > + ret = getrtable(); > + break; > + case SYS_faccessat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + int amode = (int)va_arg(args, long); > + int flag = (int)va_arg(args, long); > + ret = faccessat(fd, path, amode, flag); > + break; > + } > + case SYS_fchmodat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + int flag = (int)va_arg(args, long); > + ret = fchmodat(fd, path, mode, flag); > + break; > + } > + case SYS_fchownat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + uid_t uid = (uid_t)va_arg(args, long); > + gid_t gid = (gid_t)va_arg(args, long); > + int flag = (int)va_arg(args, long); > + ret = fchownat(fd, path, uid, gid, flag); > + break; > + } > + case SYS_linkat: { > + int fd1 = (int)va_arg(args, long); > + const char * path1 = (const char *)va_arg(args, long); > + int fd2 = (int)va_arg(args, long); > + const char * path2 = (const char *)va_arg(args, long); > + int flag = (int)va_arg(args, long); > + ret = linkat(fd1, path1, fd2, path2, flag); > + break; > + } > + case SYS_mkdirat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + ret = mkdirat(fd, path, mode); > + break; > + } > + case SYS_mkfifoat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + ret = mkfifoat(fd, path, mode); > + break; > + } > + case SYS_mknodat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + dev_t dev = (dev_t)va_arg(args, long); > + ret = mknodat(fd, path, mode, dev); > + break; > + } > + case SYS_openat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + int flags = (int)va_arg(args, long); > + mode_t mode = (mode_t)va_arg(args, long); > + ret = openat(fd, path, flags, mode); > + break; > + } > + case SYS_readlinkat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + char * buf = (char *)va_arg(args, long); > + size_t count = (size_t)va_arg(args, long); > + ret = readlinkat(fd, path, buf, count); > + break; > + } > + case SYS_renameat: { > + int fromfd = (int)va_arg(args, long); > + const char * from = (const char *)va_arg(args, long); > + int tofd = (int)va_arg(args, long); > + const char * to = (const char *)va_arg(args, long); > + ret = renameat(fromfd, from, tofd, to); > + break; > + } > + case SYS_symlinkat: { > + const char * path = (const char *)va_arg(args, long); > + int fd = (int)va_arg(args, long); > + const char * link = (const char *)va_arg(args, long); > + ret = symlinkat(path, fd, link); > + break; > + } > + case SYS_unlinkat: { > + int fd = (int)va_arg(args, long); > + const char * path = (const char *)va_arg(args, long); > + int flag = (int)va_arg(args, long); > + ret = unlinkat(fd, path, flag); > + break; > + } > + case SYS___set_tcb: > + __set_tcb(va_arg(args, void *)); // tcb > + break; > + case SYS___get_tcb: > + ret = (long)__get_tcb(); > + break; > + default: > + ret = -1; > + errno = ENOSYS; > + } > + va_end(args); > + > + return ret; > +} > Index: gnu/usr.bin/perl/syscall_emulator.h > =================================================================== > RCS file: gnu/usr.bin/perl/syscall_emulator.h > diff -N gnu/usr.bin/perl/syscall_emulator.h > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gnu/usr.bin/perl/syscall_emulator.h 3 Aug 2023 04:34:43 -0000 > @@ -0,0 +1 @@ > +long syscall_emulator(int, ...); > Index: gnu/usr.bin/perl/t/op/syscall_emulator.t > =================================================================== > RCS file: gnu/usr.bin/perl/t/op/syscall_emulator.t > diff -N gnu/usr.bin/perl/t/op/syscall_emulator.t > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gnu/usr.bin/perl/t/op/syscall_emulator.t 3 Aug 2023 04:34:43 -0000 > @@ -0,0 +1,146 @@ > +#!/usr/bin/perl > +# $OpenBSD$ # > + > +# Copyright (c) 2023 Andrew Hewus Fresh <afre...@openbsd.org> > +# > +# Permission to use, copy, modify, and distribute this software for any > +# purpose with or without fee is hereby granted, provided that the above > +# copyright notice and this permission notice appear in all copies. > +# > +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + > +BEGIN { > + chdir 't' if -d 't'; > + require "./test.pl"; > + set_up_inc( qw(. ../lib lib ../dist/base/lib) ); > +} > + > +use v5.36; > + > +use File::Temp; > +use POSIX qw< S_IRUSR S_IWUSR S_IRGRP S_IROTH O_CREAT O_WRONLY O_RDONLY >; > + > +use constant { > + PROT_READ => 0x01, > + MAP_PRIVATE => 0x0002, > + MAP_FAILED => -1, > +}; > + > +my $dir = File::Temp->newdir("syscall_emulator-XXXXXXXXX"); > +{ > + local $ENV{PERL5LIB} = join ':', @INC; > + system($^X, "../utils/h2ph", '-d', $dir, > + "/usr/include/sys/syscall.h"); > + local @INC = ("$dir/usr/include", "$dir"); > + require 'sys/syscall.ph'; > +} > + > +my $filename = "test.txt"; > +my $file = "$dir/$filename"; > +my $fd; > +my $out = "Hello World\n"; > +my $in = "\0" x 32; > +my ($in_p, $in_v); > +my $sb = "\0" x 4096; > +my $st_mode; > + > +my $perms = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; > + > +plan tests => 17; > + > +ok(! > + (($fd = syscall(SYS_open(), $file, O_CREAT|O_WRONLY, $perms)) < 0), > + "Opened $filename for write/create" > +); > +ok(! > + (syscall(SYS_write(), $fd, $out, length $out) <= 0), > + "Wrote out to $filename" > +); > +ok(! > + (syscall(SYS_close(), $fd) != 0), > + "closed $filename" > +); > + > + > +ok(! > + (syscall(SYS_stat(), $file, $sb) != 0), > + "stat $filename" > +); > + > +# fortunately st_mode is the first unsigned long in stat struct > +$st_mode = unpack "L", $sb; > + > +ok( ($st_mode & 0777) == ($perms & 0777), > + sprintf "new file %s has correct permissions (%o)", > + $filename, $st_mode & 0777 > +); > + > +ok(! > + (($fd = syscall(SYS_open(), $file, O_RDONLY)) < 0), > + "Opened $filename for read" > +); > +ok(! > + (syscall(SYS_read(), $fd, $in, length $in) <= 0), > + "read from $filename" > +); > + > +$in = unpack 'Z*', $in; > + > +ok( length($in) == length($out) && ($in eq $out), > + "Read written content from $filename" > +); > + > +ok(! > + (syscall(SYS_lseek(), $fd, 0, SEEK_SET) < 0), > + "lseek on fd" > +); > + > +ok(! > + (syscall(SYS_pread(), $fd, $in = "\0" x 32, 5, 3) < 0), > + "pread on fd" > +); > + > +$in = unpack 'Z*', $in; > + > +ok( length($in) == 5 && ($in eq substr $out, 3, 5), > + "Read written content from $filename ($in)" > +); > + > +ok(! > + (syscall(SYS_lseek(), $fd, 0, SEEK_SET) < 0), > + "lseek on fd" > +); > + > +ok(! > + (syscall(SYS_lseek(), $fd, 0, SEEK_SET) < 0), > + "lseek on fd" > +); > + > +ok(! > + (($in_p = syscall(SYS_mmap(), undef, length($out), PROT_READ, > MAP_PRIVATE, > + $fd, 0)) == MAP_FAILED), > + "mmap fd" > +); > + > +# From ingy's Pointer module > +$in_v = unpack "p*", pack "L!", $in_p; > + > +ok( length($in_v) == length($out) && ($in_v eq $out), > + "Read written content from $filename" > +); > + > +ok(! > + (syscall(SYS_munmap(), $in_p, length($out)) != 0), > + "munmap fd" > +); > + > +ok(! > + (syscall(SYS_close(), $fd) != 0), > + "closed $filename" > +);