| # Copyright all contributors <meta@public-inbox.org> |
| # License: AGPL-3.0+ <http://www.gnu.org/licenses/agpl-3.0.txt> |
| # Dump system-specific constant numbers this is to maintain |
| # PublicInbox::Syscall and any other system-specific pieces. |
| # However, sysconf(3) constants are stable ABI on all safe to dump. |
| eval 'exec perl -S $0 ${1+"$@"}' # no shebang |
| if 0; # running under some shell |
| use v5.12; |
| use File::Temp 0.19; |
| use POSIX qw(uname); |
| use Config; |
| print STDERR '# $machine='.(POSIX::uname())[-1]."\n"; |
| my $cc = $ENV{CC} // $Config{cc} // 'cc'; |
| my @cflags = split(/\s+/, $ENV{CFLAGS} // $Config{ccflags} // '-Wall'); |
| my $str = do { local $/; <DATA> }; |
| $str =~ s/^\s*MAYBE\s*([DX])\((\w+)\)/ |
| #ifdef $2 |
| $1($2); |
| #endif |
| /sgxm; |
| my $tmp = File::Temp->newdir('sysdefs-list-XXXX', TMPDIR => 1); |
| my $f = "$tmp/sysdefs.c"; |
| my $x = "$tmp/sysdefs"; |
| open my $fh, '>', $f or die "open $f $!"; |
| print $fh $str or die "print $f $!"; |
| close $fh or die "close $f $!"; |
| system($cc, '-o', $x, $f, @cflags) == 0 or die "$cc failed \$?=$?"; |
| print STDERR '# %Config', |
| (map { " $_=$Config{$_}" } qw(ptrsize sizesize lseeksize)), "\n"; |
| exit(system($x)); # exit is to ensure File::Temp::Dir->DESTROY fires |
| __DATA__ |
| #ifndef _GNU_SOURCE |
| # define _GNU_SOURCE |
| #endif |
| #include <assert.h> |
| #include <signal.h> |
| #include <stddef.h> |
| #include <sys/socket.h> |
| #include <sys/syscall.h> |
| #include <sys/ioctl.h> |
| #ifdef __linux__ |
| # include <linux/fs.h> |
| # include <sys/epoll.h> |
| # include <sys/inotify.h> |
| # include <sys/vfs.h> |
| #endif |
| #include <sys/types.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <stdio.h> |
| |
| #define STRUCT_BEGIN(t) do { t x; printf("'"#t"' => '%zu bytes\n", sizeof(x)) |
| #define STRUCT_END puts("',"); } while (0) |
| |
| // prints the struct field name, @offset, and signed/unsigned bit size |
| #define PR_NUM(f) do { \ |
| x.f = ~0; \ |
| printf("\t.%s @%zu %c%zu\n", #f, \ |
| offsetof(typeof(x),f), \ |
| x.f > 0 ? 'u' : 's', \ |
| sizeof(x.f) * 8); \ |
| } while (0) |
| |
| #define PR_PTR(f) do { \ |
| assert(sizeof(x.f) == sizeof(void *)); \ |
| printf("\t.%s @%zu ptr\n", #f, offsetof(typeof(x),f)); \ |
| } while (0) |
| |
| #define PR_OFF(f) do { \ |
| printf("\t.%s @%zu\n", #f, offsetof(typeof(x),f)); \ |
| } while (0) |
| |
| #define D(x) printf(#x " => %ld,\n", (long)x) |
| #define X(x) printf(#x " => 0x%lx,\n", (unsigned long)x) |
| |
| int main(void) |
| { |
| // verify Config{(ptr|size|lseek)size} entries match: |
| printf("'sizeof(ptr)' => %zu,\n", sizeof(void *)); |
| printf("'sizeof(size_t)' => %zu,\n", sizeof(size_t)); |
| printf("'sizeof(off_t)' => %zu,\n", sizeof(off_t)); |
| |
| #ifdef __linux__ |
| D(SYS_epoll_create1); |
| D(SYS_epoll_ctl); |
| MAYBE D(SYS_epoll_wait); |
| D(SYS_epoll_pwait); |
| D(SYS_signalfd4); |
| |
| X(IN_CLOEXEC); |
| X(IN_ACCESS); |
| X(IN_ALL_EVENTS); |
| X(IN_ATTRIB); |
| X(IN_CLOSE); |
| X(IN_CLOSE_NOWRITE); |
| X(IN_CLOSE_WRITE); |
| X(IN_CREATE); |
| X(IN_DELETE); |
| X(IN_DELETE_SELF); |
| X(IN_DONT_FOLLOW); |
| X(IN_EXCL_UNLINK); |
| X(IN_IGNORED); |
| X(IN_ISDIR); |
| X(IN_MASK_ADD); |
| X(IN_MODIFY); |
| X(IN_MOVE); |
| X(IN_MOVED_FROM); |
| X(IN_MOVED_TO); |
| X(IN_MOVE_SELF); |
| X(IN_ONESHOT); |
| X(IN_ONLYDIR); |
| X(IN_OPEN); |
| X(IN_Q_OVERFLOW); |
| X(IN_UNMOUNT); |
| |
| D(SYS_inotify_init1); |
| D(SYS_inotify_add_watch); |
| D(SYS_inotify_rm_watch); |
| |
| D(SYS_prctl); |
| D(SYS_fstatfs); |
| |
| MAYBE X(FS_IOC_GETFLAGS); |
| MAYBE X(FS_IOC_SETFLAGS); |
| |
| MAYBE D(SYS_renameat2); |
| |
| STRUCT_BEGIN(struct epoll_event); |
| PR_NUM(events); |
| PR_NUM(data.u64); |
| STRUCT_END; |
| |
| STRUCT_BEGIN(struct inotify_event); |
| PR_NUM(wd); |
| PR_NUM(mask); |
| PR_NUM(cookie); |
| PR_NUM(len); |
| PR_OFF(name); |
| STRUCT_END; |
| |
| STRUCT_BEGIN(struct statfs); |
| PR_NUM(f_type); |
| STRUCT_END; |
| #endif /* Linux, any other OSes with stable syscalls? */ |
| |
| D(SIGWINCH); |
| MAYBE D(SO_ACCEPTFILTER); |
| MAYBE D(_SC_NPROCESSORS_ONLN); |
| MAYBE D(_SC_AVPHYS_PAGES); |
| MAYBE D(_SC_PAGE_SIZE); |
| MAYBE D(_SC_PAGESIZE); |
| |
| D(SYS_sendmsg); |
| D(SYS_recvmsg); |
| D(SYS_writev); |
| |
| STRUCT_BEGIN(struct flock); |
| PR_NUM(l_start); |
| PR_NUM(l_len); |
| PR_NUM(l_pid); |
| PR_NUM(l_type); |
| PR_NUM(l_whence); |
| STRUCT_END; |
| |
| STRUCT_BEGIN(struct msghdr); |
| PR_PTR(msg_name); |
| PR_NUM(msg_namelen); |
| PR_PTR(msg_iov); |
| PR_NUM(msg_iovlen); |
| PR_PTR(msg_control); |
| PR_NUM(msg_controllen); |
| PR_NUM(msg_flags); |
| STRUCT_END; |
| |
| STRUCT_BEGIN(struct cmsghdr); |
| PR_NUM(cmsg_len); |
| PR_NUM(cmsg_level); |
| PR_NUM(cmsg_type); |
| STRUCT_END; |
| |
| { |
| struct cmsghdr cmsg; |
| uintptr_t cmsg_data_off; |
| cmsg_data_off = (uintptr_t)CMSG_DATA(&cmsg) - (uintptr_t)&cmsg; |
| D(cmsg_data_off); |
| } |
| |
| return 0; |
| } |