On Sun, 9 Jul 2023 13:29:58 -0700 Andrew Hewus Fresh <and...@afresh1.com> wrote:
> + case SYS_truncate: > + { > + const char * path = va_arg(args, const char *); > + off_t length = va_arg(args, off_t); > + ret = truncate(path, length); > + } > + break; I prefer braces like this, case SYS_truncate: { ... break; } In my opinion, all va_arg()s should look like off_t length = (off_t)va_arg(args, long); because perl passes every argument as long (from pp_syscall in pp_sys.c). I worry that va_arg(args, off_t) would act strangely on platforms with 32-bit long and 64-bit off_t. Only a few syscalls have off_t arguments, and these few calls are almost useless in Perl, so this might not affect real programs. How to pread($fd, $buf, 4, 16)? 1. syscall(169, $fd, $buf, 4, 0, 16) 2. syscall(169, $fd, $buf, 4, 0, 0, 16) 3. syscall(169, $fd, $buf, 4, 16, 0) 4. syscall(169, $fd, $buf, 4, 0, 16, 0) 5. syscall(169, $fd, $buf, 4, 16) If va_args(args, off_t) takes 2 longs, then pick line 1 if big-endian, or line 3 if little-endian. If it skips a 3rd long for alignment, then pick line 2 or 4. If it takes 1 long, then pick line 5. If we (off_t)va_args(args, long), then it always takes 1 long, so every platform picks line 5, but the offset must fit in a long. The syscalls with off_t are void *mmap(void *, size_t, int, int, int, off_t); void *mquery(void *, size_t, int, int, int, off_t); off_t lseek(int, off_t, int); int truncate(const char *, off_t); int ftruncate(int, off_t); ssize_t pread(int, void *, size_t, off_t); ssize_t pwrite(int, const void *, size_t, off_t); ssize_t preadv(int, const struct iovec *, int, off_t); ssize_t pwritev(int, const struct iovec *, int, off_t); syscall(SYS_lseek, @args) would truncate its return from off_t to long, but that is fine, because everyone should use Perl's sysseek. POSIX::2008 in CPAN looks like a better way to call pread.