rubycc 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +56 -0
- data/LICENSE.txt +21 -0
- data/NOTICE +52 -0
- data/README.md +208 -0
- data/data/README.md +117 -0
- data/data/r10_corpus_scan.json +4082 -0
- data/data/r10_manual_classification.json +5342 -0
- data/data/r10_verification_m4a.json +1531 -0
- data/data/r10_verification_m4b.json +1818 -0
- data/data/r10_verification_m4c.json +1489 -0
- data/data/r10_verification_m4d.json +318 -0
- data/data/r10_verification_rbs.json +192 -0
- data/data/verified_gems.json +397 -0
- data/exe/rmake +16 -0
- data/exe/rubycc +9 -0
- data/exe/rubycc-ar +114 -0
- data/exe/rubycc-doctor +14 -0
- data/exe/rubycc-pkgconf +8 -0
- data/include/float.h +87 -0
- data/include/iso646.h +18 -0
- data/include/libc/alloca.h +18 -0
- data/include/libc/arpa/inet.h +61 -0
- data/include/libc/assert.h +43 -0
- data/include/libc/dirent.h +72 -0
- data/include/libc/dlfcn.h +58 -0
- data/include/libc/features.h +205 -0
- data/include/libc/glibc/aarch64/ctype.h +108 -0
- data/include/libc/glibc/aarch64/endian.h +54 -0
- data/include/libc/glibc/aarch64/errno.h +154 -0
- data/include/libc/glibc/aarch64/fcntl.h +144 -0
- data/include/libc/glibc/aarch64/inttypes.h +182 -0
- data/include/libc/glibc/aarch64/limits.h +63 -0
- data/include/libc/glibc/aarch64/pthread.h +131 -0
- data/include/libc/glibc/aarch64/setjmp.h +84 -0
- data/include/libc/glibc/aarch64/stdint.h +174 -0
- data/include/libc/glibc/aarch64/sys/epoll.h +88 -0
- data/include/libc/glibc/aarch64/sys/fcntl.h +19 -0
- data/include/libc/glibc/aarch64/sys/select.h +75 -0
- data/include/libc/glibc/aarch64/sys/stat.h +136 -0
- data/include/libc/glibc/aarch64/sys/syscall.h +167 -0
- data/include/libc/glibc/aarch64/sys/time.h +74 -0
- data/include/libc/glibc/aarch64/sys/types.h +127 -0
- data/include/libc/glibc/aarch64/time.h +113 -0
- data/include/libc/glibc/x86_64/ctype.h +108 -0
- data/include/libc/glibc/x86_64/endian.h +54 -0
- data/include/libc/glibc/x86_64/errno.h +154 -0
- data/include/libc/glibc/x86_64/fcntl.h +134 -0
- data/include/libc/glibc/x86_64/inttypes.h +182 -0
- data/include/libc/glibc/x86_64/limits.h +61 -0
- data/include/libc/glibc/x86_64/pthread.h +111 -0
- data/include/libc/glibc/x86_64/setjmp.h +82 -0
- data/include/libc/glibc/x86_64/stdint.h +163 -0
- data/include/libc/glibc/x86_64/sys/epoll.h +91 -0
- data/include/libc/glibc/x86_64/sys/fcntl.h +19 -0
- data/include/libc/glibc/x86_64/sys/select.h +75 -0
- data/include/libc/glibc/x86_64/sys/stat.h +130 -0
- data/include/libc/glibc/x86_64/sys/syscall.h +188 -0
- data/include/libc/glibc/x86_64/sys/time.h +74 -0
- data/include/libc/glibc/x86_64/sys/types.h +123 -0
- data/include/libc/glibc/x86_64/time.h +113 -0
- data/include/libc/grp.h +50 -0
- data/include/libc/langinfo.h +126 -0
- data/include/libc/link.h +18 -0
- data/include/libc/locale.h +83 -0
- data/include/libc/math.h +191 -0
- data/include/libc/netinet/in.h +126 -0
- data/include/libc/netinet/tcp.h +44 -0
- data/include/libc/poll.h +46 -0
- data/include/libc/pwd.h +58 -0
- data/include/libc/regex.h +53 -0
- data/include/libc/sched.h +35 -0
- data/include/libc/signal.h +204 -0
- data/include/libc/stdio.h +157 -0
- data/include/libc/stdlib.h +92 -0
- data/include/libc/string.h +74 -0
- data/include/libc/strings.h +25 -0
- data/include/libc/sys/cdefs.h +126 -0
- data/include/libc/sys/inotify.h +111 -0
- data/include/libc/sys/ioctl.h +36 -0
- data/include/libc/sys/mman.h +65 -0
- data/include/libc/sys/param.h +41 -0
- data/include/libc/sys/resource.h +109 -0
- data/include/libc/sys/socket.h +167 -0
- data/include/libc/sys/statfs.h +82 -0
- data/include/libc/sys/timerfd.h +55 -0
- data/include/libc/sys/uio.h +40 -0
- data/include/libc/sys/un.h +25 -0
- data/include/libc/sys/utsname.h +35 -0
- data/include/libc/sys/wait.h +135 -0
- data/include/libc/termios.h +179 -0
- data/include/libc/unistd.h +194 -0
- data/include/stdalign.h +16 -0
- data/include/stdarg.h +31 -0
- data/include/stdatomic.h +158 -0
- data/include/stdbool.h +15 -0
- data/include/stdckdint.h +28 -0
- data/include/stddef.h +60 -0
- data/include/stdnoreturn.h +18 -0
- data/include/x86intrin.h +16 -0
- data/lib/rubycc/backend/aarch64.rb +1724 -0
- data/lib/rubycc/backend/x86_64.rb +1369 -0
- data/lib/rubycc/compile_error.rb +36 -0
- data/lib/rubycc/compiler.rb +305 -0
- data/lib/rubycc/doctor/builder.rb +151 -0
- data/lib/rubycc/doctor/cli.rb +190 -0
- data/lib/rubycc/doctor/fetcher.rb +84 -0
- data/lib/rubycc/doctor/gemfile.rb +115 -0
- data/lib/rubycc/doctor/verified_gems.rb +114 -0
- data/lib/rubycc/doctor.rb +16 -0
- data/lib/rubycc/driver.rb +463 -0
- data/lib/rubycc/front/ast.rb +528 -0
- data/lib/rubycc/front/constant_evaluator.rb +631 -0
- data/lib/rubycc/front/initializer_resolver.rb +592 -0
- data/lib/rubycc/front/lexeme_reader.rb +460 -0
- data/lib/rubycc/front/lexer.rb +232 -0
- data/lib/rubycc/front/parser.rb +4122 -0
- data/lib/rubycc/front/token.rb +49 -0
- data/lib/rubycc/ir/call_convention.rb +486 -0
- data/lib/rubycc/ir/generator.rb +6036 -0
- data/lib/rubycc/ir/ir.rb +417 -0
- data/lib/rubycc/link/compat_runtime.rb +89 -0
- data/lib/rubycc/link/errors.rb +13 -0
- data/lib/rubycc/link/executable_linker.rb +405 -0
- data/lib/rubycc/link/library_resolver.rb +437 -0
- data/lib/rubycc/link/partial_linker.rb +546 -0
- data/lib/rubycc/link/shared_linker.rb +1732 -0
- data/lib/rubycc/mkmf_shim.rb +83 -0
- data/lib/rubycc/objfile/ar_archive.rb +437 -0
- data/lib/rubycc/objfile/elf_reader.rb +646 -0
- data/lib/rubycc/objfile/elf_writer.rb +891 -0
- data/lib/rubycc/objfile/relocatable_writer.rb +376 -0
- data/lib/rubycc/pkgconf/cli.rb +139 -0
- data/lib/rubycc/pkgconf/errors.rb +39 -0
- data/lib/rubycc/pkgconf/model.rb +28 -0
- data/lib/rubycc/pkgconf/parser.rb +109 -0
- data/lib/rubycc/pkgconf/pkgconf.rb +15 -0
- data/lib/rubycc/pkgconf/resolver.rb +70 -0
- data/lib/rubycc/pkgconf/search_path.rb +38 -0
- data/lib/rubycc/pkgconf/system_path_filter.rb +131 -0
- data/lib/rubycc/preprocess/constant_expression.rb +219 -0
- data/lib/rubycc/preprocess/glibc_version.rb +124 -0
- data/lib/rubycc/preprocess/pp_token.rb +62 -0
- data/lib/rubycc/preprocess/preprocessor.rb +2020 -0
- data/lib/rubycc/preprocess/scanner.rb +290 -0
- data/lib/rubycc/preprocess/token_converter.rb +157 -0
- data/lib/rubycc/rmake/cli.rb +143 -0
- data/lib/rubycc/rmake/errors.rb +71 -0
- data/lib/rubycc/rmake/executor.rb +818 -0
- data/lib/rubycc/rmake/expander.rb +251 -0
- data/lib/rubycc/rmake/makefile.rb +352 -0
- data/lib/rubycc/rmake/model.rb +137 -0
- data/lib/rubycc/rmake/parser.rb +226 -0
- data/lib/rubycc/rmake/rmake.rb +15 -0
- data/lib/rubycc/type.rb +1236 -0
- data/lib/rubycc/version.rb +5 -0
- data/lib/rubycc.rb +36 -0
- data/lib/rubygems_plugin.rb +102 -0
- metadata +219 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/* rubycc bundled <sys/inotify.h>: the Linux inotify(7) filesystem-change
|
|
2
|
+
notification interface. Provenance: clean room against the Linux kernel
|
|
3
|
+
UAPI (linux/inotify.h) and the glibc call surface, not derived from musl or
|
|
4
|
+
glibc source. The event-mask bits, the two init flags and struct
|
|
5
|
+
inotify_event's layout are that ABI reproduced as measured integer
|
|
6
|
+
constants and measured field offsets (an ABI fact, not copied text -- see
|
|
7
|
+
docs/HEADER-LICENSING.md sec. 4), the same treatment as poll.h and
|
|
8
|
+
sys/epoll.h.
|
|
9
|
+
|
|
10
|
+
Common layer, and that was measured rather than assumed. struct
|
|
11
|
+
inotify_event ends in a flexible array member, which is exactly the shape
|
|
12
|
+
where a wrong tail assumption would be invisible in a member-by-member
|
|
13
|
+
read, so its size and every offset were printed from the glibc oracle on
|
|
14
|
+
both targets and came back identical:
|
|
15
|
+
|
|
16
|
+
sizeof 16, _Alignof 4, wd @ 0, mask @ 4, cookie @ 8, len @ 12,
|
|
17
|
+
name @ 16 (the flexible member contributes nothing to sizeof, so the
|
|
18
|
+
16-byte size is the header alone -- which is what makes libev's
|
|
19
|
+
`ofs += sizeof (struct inotify_event) + ev->len` walk correct)
|
|
20
|
+
|
|
21
|
+
The member widths and signedness were measured too: wd is a signed 4-byte
|
|
22
|
+
int (it is a watch descriptor, and -1 is the error return of
|
|
23
|
+
inotify_add_watch), while mask, cookie and len are unsigned 4-byte. Since
|
|
24
|
+
nothing here differs between the targets, the header is arch neutral,
|
|
25
|
+
unlike sys/epoll.h whose struct packing does differ.
|
|
26
|
+
|
|
27
|
+
IN_CLOEXEC and IN_NONBLOCK share bits with the open(2) flags, and some O_*
|
|
28
|
+
names do differ between the targets (that is why fcntl.h is an arch-layer
|
|
29
|
+
header), so those two were measured on both as well: 0x80000 and 0x800 on
|
|
30
|
+
each.
|
|
31
|
+
|
|
32
|
+
inotify_init/inotify_init1/inotify_add_watch/inotify_rm_watch are
|
|
33
|
+
Linux/glibc declarations whose bodies resolve from the host libc at link
|
|
34
|
+
time.
|
|
35
|
+
|
|
36
|
+
Not included: the IN_ALL_EVENTS convenience mask is provided, but glibc's
|
|
37
|
+
internal aliases beyond it are not, and NAME_MAX (which callers sizing a
|
|
38
|
+
read buffer want next to this header) is left to <limits.h>, which already
|
|
39
|
+
provides it. nio4r, the gem that put this header on the list, reaches
|
|
40
|
+
inotify_init1 / inotify_add_watch / inotify_rm_watch and the mask bits
|
|
41
|
+
through libev's ev_stat backend. */
|
|
42
|
+
|
|
43
|
+
#ifndef _RUBYCC_SYS_INOTIFY_H
|
|
44
|
+
#define _RUBYCC_SYS_INOTIFY_H
|
|
45
|
+
|
|
46
|
+
#include <stdint.h>
|
|
47
|
+
|
|
48
|
+
/* Flags for inotify_init1; they share O_CLOEXEC's and O_NONBLOCK's bits
|
|
49
|
+
(measured, both arches). */
|
|
50
|
+
#define IN_CLOEXEC 0x80000
|
|
51
|
+
#define IN_NONBLOCK 0x800
|
|
52
|
+
|
|
53
|
+
/* The events a watch can ask for (measured, both arches). */
|
|
54
|
+
#define IN_ACCESS 0x00000001 /* file was read */
|
|
55
|
+
#define IN_MODIFY 0x00000002 /* file was written */
|
|
56
|
+
#define IN_ATTRIB 0x00000004 /* metadata changed */
|
|
57
|
+
#define IN_CLOSE_WRITE 0x00000008 /* writable descriptor closed */
|
|
58
|
+
#define IN_CLOSE_NOWRITE 0x00000010 /* read-only descriptor closed */
|
|
59
|
+
#define IN_OPEN 0x00000020 /* file was opened */
|
|
60
|
+
#define IN_MOVED_FROM 0x00000040 /* renamed out of the watched directory */
|
|
61
|
+
#define IN_MOVED_TO 0x00000080 /* renamed into the watched directory */
|
|
62
|
+
#define IN_CREATE 0x00000100 /* entry created in the directory */
|
|
63
|
+
#define IN_DELETE 0x00000200 /* entry deleted from the directory */
|
|
64
|
+
#define IN_DELETE_SELF 0x00000400 /* the watched file itself was deleted */
|
|
65
|
+
#define IN_MOVE_SELF 0x00000800 /* the watched file itself was renamed */
|
|
66
|
+
|
|
67
|
+
/* The two pairs above that callers usually want together. */
|
|
68
|
+
#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
|
|
69
|
+
#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO)
|
|
70
|
+
|
|
71
|
+
/* Everything a watch may be asked for, i.e. the twelve bits above
|
|
72
|
+
(measured: 0xfff on both arches). */
|
|
73
|
+
#define IN_ALL_EVENTS 0x00000fff
|
|
74
|
+
|
|
75
|
+
/* Events the kernel reports without being asked (measured, both arches). */
|
|
76
|
+
#define IN_UNMOUNT 0x00002000 /* the backing filesystem was unmounted */
|
|
77
|
+
#define IN_Q_OVERFLOW 0x00004000 /* the event queue overflowed */
|
|
78
|
+
#define IN_IGNORED 0x00008000 /* the watch was removed */
|
|
79
|
+
|
|
80
|
+
/* Bits that modify how inotify_add_watch installs the watch (measured, both
|
|
81
|
+
arches). IN_ISDIR is not one of these: it is set by the kernel on a
|
|
82
|
+
reported event whose subject is a directory. */
|
|
83
|
+
#define IN_ONLYDIR 0x01000000 /* fail unless the path is a directory */
|
|
84
|
+
#define IN_DONT_FOLLOW 0x02000000 /* do not dereference a symbolic link */
|
|
85
|
+
#define IN_EXCL_UNLINK 0x04000000 /* stop reporting unlinked children */
|
|
86
|
+
#define IN_MASK_CREATE 0x10000000 /* fail if a watch already exists */
|
|
87
|
+
#define IN_MASK_ADD 0x20000000 /* add to, not replace, the existing mask */
|
|
88
|
+
#define IN_ISDIR 0x40000000 /* reported: the subject is a directory */
|
|
89
|
+
#define IN_ONESHOT 0x80000000 /* remove the watch after one event */
|
|
90
|
+
|
|
91
|
+
/* One queued event, as read(2) hands it over. Measured: 16 bytes, 4-byte
|
|
92
|
+
aligned, with the four fixed members packed end to end and the name
|
|
93
|
+
starting immediately after them. `name` is a flexible array member: when
|
|
94
|
+
`len` is non-zero the kernel writes `len` bytes there (a NUL-terminated
|
|
95
|
+
name plus enough NUL padding to keep the next event 4-byte aligned), so
|
|
96
|
+
consecutive events in a read buffer are `sizeof(struct inotify_event) +
|
|
97
|
+
len` bytes apart. */
|
|
98
|
+
struct inotify_event {
|
|
99
|
+
int wd; /* offset 0: the watch this event belongs to */
|
|
100
|
+
uint32_t mask; /* offset 4: the IN_ bits that fired */
|
|
101
|
+
uint32_t cookie; /* offset 8: pairs a MOVED_FROM with its MOVED_TO */
|
|
102
|
+
uint32_t len; /* offset 12: bytes of `name`, including padding */
|
|
103
|
+
char name[]; /* offset 16: present only when len is non-zero */
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
int inotify_init(void);
|
|
107
|
+
int inotify_init1(int __flags);
|
|
108
|
+
int inotify_add_watch(int __fd, const char *__pathname, uint32_t __mask);
|
|
109
|
+
int inotify_rm_watch(int __fd, int __wd);
|
|
110
|
+
|
|
111
|
+
#endif /* _RUBYCC_SYS_INOTIFY_H */
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* rubycc bundled <sys/ioctl.h>: the ioctl(2) declaration and terminal window
|
|
2
|
+
size query (POSIX does not standardize ioctl at all; this is a Linux/glibc
|
|
3
|
+
ABI surface). Provenance: clean room against the glibc/Linux ABI (glibc's
|
|
4
|
+
bits/ioctl-types.h plus the kernel UAPI's asm-generic/ioctls.h request
|
|
5
|
+
numbers), not derived from musl. Narrowed to the surface io-console's
|
|
6
|
+
corpus sample actually reaches (Step 124, M5 H2): on the HAVE_TERMIOS_H
|
|
7
|
+
path (see termios.h's provenance note) the only ioctl requests it issues
|
|
8
|
+
are TIOCGWINSZ/TIOCSWINSZ against a `struct winsize`; the TCGETA/TCSETAF/
|
|
9
|
+
TIOCGETP/TIOCSETP requests belong to the termio.h/sgtty.h fallback paths
|
|
10
|
+
that HAVE_TERMIOS_H skips on Linux, so they are not reproduced here (the
|
|
11
|
+
same "corpus-reached surface only" scoping sched.h and poll.h used).
|
|
12
|
+
struct winsize is a struct callers read/write members of directly, so it
|
|
13
|
+
cannot be an opaque byte blob; its size (8) and every member's offset, and
|
|
14
|
+
the TIOCGWINSZ/TIOCSWINSZ request numbers, were measured against the glibc
|
|
15
|
+
oracle on both x86-64 and aarch64 (see test/test_header_abi.rb's IOCTL
|
|
16
|
+
case) and the two agreed exactly, so this header lives in the common
|
|
17
|
+
layer. */
|
|
18
|
+
|
|
19
|
+
#ifndef _RUBYCC_SYS_IOCTL_H
|
|
20
|
+
#define _RUBYCC_SYS_IOCTL_H
|
|
21
|
+
|
|
22
|
+
/* struct winsize: 8 bytes, 2-byte aligned (measured, both arches). */
|
|
23
|
+
struct winsize {
|
|
24
|
+
unsigned short ws_row; /* offset 0: rows, in characters */
|
|
25
|
+
unsigned short ws_col; /* offset 2: columns, in characters */
|
|
26
|
+
unsigned short ws_xpixel; /* offset 4: horizontal size, pixels */
|
|
27
|
+
unsigned short ws_ypixel; /* offset 6: vertical size, pixels */
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/* Terminal window size ioctl requests (measured, both arches agree). */
|
|
31
|
+
#define TIOCGWINSZ 0x5413
|
|
32
|
+
#define TIOCSWINSZ 0x5414
|
|
33
|
+
|
|
34
|
+
int ioctl(int __fd, unsigned long __request, ...);
|
|
35
|
+
|
|
36
|
+
#endif /* _RUBYCC_SYS_IOCTL_H */
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/* rubycc bundled <sys/mman.h>: the memory-mapping calls and the PROT_/MAP_/MS_/
|
|
2
|
+
MADV_ flag macros (POSIX plus Linux extensions). Provenance: clean room
|
|
3
|
+
against the Linux kernel UAPI (asm-generic/mman-common.h and mman.h), not
|
|
4
|
+
derived from musl. The flag values and MAP_FAILED are that ABI reproduced as
|
|
5
|
+
measured integer constants (an ABI fact, not copied text -- see
|
|
6
|
+
docs/HEADER-LICENSING.md), the same treatment as errno.h and fcntl.h. mmap,
|
|
7
|
+
munmap and kin are POSIX declarations. Common layer: every flag value is
|
|
8
|
+
identical on x86-64 and aarch64 (both use the asm-generic assignments). */
|
|
9
|
+
|
|
10
|
+
#ifndef _RUBYCC_SYS_MMAN_H
|
|
11
|
+
#define _RUBYCC_SYS_MMAN_H
|
|
12
|
+
|
|
13
|
+
#ifndef _RUBYCC_SIZE_T
|
|
14
|
+
#define _RUBYCC_SIZE_T
|
|
15
|
+
typedef unsigned long size_t;
|
|
16
|
+
#endif
|
|
17
|
+
#ifndef _RUBYCC_OFF_T
|
|
18
|
+
#define _RUBYCC_OFF_T
|
|
19
|
+
typedef long off_t;
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
/* Memory protection bits (for mmap/mprotect). */
|
|
23
|
+
#define PROT_NONE 0x0
|
|
24
|
+
#define PROT_READ 0x1
|
|
25
|
+
#define PROT_WRITE 0x2
|
|
26
|
+
#define PROT_EXEC 0x4
|
|
27
|
+
|
|
28
|
+
/* mmap flags. MAP_SHARED/MAP_PRIVATE are the required sharing mode; the rest
|
|
29
|
+
are Linux extensions. */
|
|
30
|
+
#define MAP_SHARED 0x00001
|
|
31
|
+
#define MAP_PRIVATE 0x00002
|
|
32
|
+
#define MAP_FIXED 0x00010
|
|
33
|
+
#define MAP_ANONYMOUS 0x00020
|
|
34
|
+
#define MAP_ANON MAP_ANONYMOUS
|
|
35
|
+
#define MAP_GROWSDOWN 0x00100
|
|
36
|
+
#define MAP_LOCKED 0x02000
|
|
37
|
+
#define MAP_NORESERVE 0x04000
|
|
38
|
+
#define MAP_POPULATE 0x08000
|
|
39
|
+
#define MAP_STACK 0x20000
|
|
40
|
+
|
|
41
|
+
/* mmap failure sentinel: the return value on error. */
|
|
42
|
+
#define MAP_FAILED ((void *) -1)
|
|
43
|
+
|
|
44
|
+
/* msync flags. */
|
|
45
|
+
#define MS_ASYNC 0x1
|
|
46
|
+
#define MS_INVALIDATE 0x2
|
|
47
|
+
#define MS_SYNC 0x4
|
|
48
|
+
|
|
49
|
+
/* madvise advice values. */
|
|
50
|
+
#define MADV_NORMAL 0
|
|
51
|
+
#define MADV_RANDOM 1
|
|
52
|
+
#define MADV_SEQUENTIAL 2
|
|
53
|
+
#define MADV_WILLNEED 3
|
|
54
|
+
#define MADV_DONTNEED 4
|
|
55
|
+
#define MADV_FREE 8
|
|
56
|
+
|
|
57
|
+
void *mmap(void *__addr, size_t __len, int __prot, int __flags, int __fd, off_t __offset);
|
|
58
|
+
int munmap(void *__addr, size_t __len);
|
|
59
|
+
int mprotect(void *__addr, size_t __len, int __prot);
|
|
60
|
+
int msync(void *__addr, size_t __len, int __flags);
|
|
61
|
+
int madvise(void *__addr, size_t __len, int __advice);
|
|
62
|
+
int mlock(const void *__addr, size_t __len);
|
|
63
|
+
int munlock(const void *__addr, size_t __len);
|
|
64
|
+
|
|
65
|
+
#endif /* _RUBYCC_SYS_MMAN_H */
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* rubycc bundled <sys/param.h>: BSD-heritage traditional Unix parameter
|
|
2
|
+
macros. Provenance: clean room. glibc's own <sys/param.h> is itself only a
|
|
3
|
+
compatibility shim (its own comment header calls it "Compatibility header
|
|
4
|
+
for old-style Unix parameters and limits") that pulls in sys/types.h,
|
|
5
|
+
limits.h, endian.h and signal.h to synthesize BSD-named aliases
|
|
6
|
+
(MAXPATHLEN, NOFILE, ...) and a handful of bit-twiddling macros
|
|
7
|
+
(setbit/isset/howmany/roundup/MIN/MAX); it was inspected on the host
|
|
8
|
+
(x86-64 and aarch64 glibc, both agree) to confirm what it actually emits,
|
|
9
|
+
but no macro *body* is copied from it -- MIN/MAX/howmany/roundup below are
|
|
10
|
+
rubycc's own phrasing of the same well-known formulas (an ABI/behavioral
|
|
11
|
+
fact -- the value MIN(a,b)/roundup(x,y) etc. must produce -- not a
|
|
12
|
+
creative expression; see docs/HEADER-LICENSING.md Sec 4). Narrowed to the
|
|
13
|
+
surface digest's corpus sample actually reaches (Step 124, M5 H2): sha1.c's
|
|
14
|
+
`#include <sys/param.h>` is itself gated behind `defined(_KERNEL) ||
|
|
15
|
+
defined(_STANDALONE)`, neither of which a userspace Ruby extension build
|
|
16
|
+
ever defines, so the include is unreachable dead code for this gem in
|
|
17
|
+
practice -- and no digest source references MIN/MAX/howmany/roundup or any
|
|
18
|
+
other sys/param.h name either. This header ships only the traditional
|
|
19
|
+
four macros a "sys/param.h" compatibility shim is expected to carry
|
|
20
|
+
(matching the header's own docs above); the BSD name aliases (MAXPATHLEN,
|
|
21
|
+
NOFILE, ...), the setbit/isset bitmap macros and the endian.h/signal.h
|
|
22
|
+
pull-ins are not reproduced (no corpus sample needs them, and re-adding
|
|
23
|
+
them would just re-derive limits.h/endian.h under new names). */
|
|
24
|
+
|
|
25
|
+
#ifndef _RUBYCC_SYS_PARAM_H
|
|
26
|
+
#define _RUBYCC_SYS_PARAM_H
|
|
27
|
+
|
|
28
|
+
#ifndef MIN
|
|
29
|
+
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
30
|
+
#endif
|
|
31
|
+
#ifndef MAX
|
|
32
|
+
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
33
|
+
#endif
|
|
34
|
+
#ifndef howmany
|
|
35
|
+
#define howmany(x, y) (((x) + ((y) - 1)) / (y))
|
|
36
|
+
#endif
|
|
37
|
+
#ifndef roundup
|
|
38
|
+
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
|
|
39
|
+
#endif
|
|
40
|
+
|
|
41
|
+
#endif /* _RUBYCC_SYS_PARAM_H */
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* rubycc bundled <sys/resource.h>: resource limits and usage (POSIX.1).
|
|
2
|
+
Provenance: clean room against the POSIX public interface and the Linux
|
|
3
|
+
kernel UAPI (asm-generic/resource.h); struct rlimit's and struct rusage's
|
|
4
|
+
member names, types and order are that ABI's own public contract, not
|
|
5
|
+
glibc implementation detail. Every member is used directly by callers, so
|
|
6
|
+
neither struct can be an opaque byte blob; both structs' sizes and every
|
|
7
|
+
member's offset were measured against the glibc oracle on both x86-64 and
|
|
8
|
+
aarch64 (see test/test_header_abi.rb's RESOURCE case) and the two agreed
|
|
9
|
+
exactly (rlim_t is `unsigned long` and struct timeval's members are both
|
|
10
|
+
`long` on either LP64 target, so neither struct has an arch-dependent
|
|
11
|
+
field width), so this header lives in the common layer. The C libraries do
|
|
12
|
+
differ, though: struct rusage is larger on musl, which is carried below
|
|
13
|
+
under __RUBYCC_LIBC_MUSL__ (see the preprocessor's LIBCS). struct timeval
|
|
14
|
+
reuses the __timeval_defined guard sys/time.h also defines it under, so the
|
|
15
|
+
two headers agree rather than redefine when both are included.
|
|
16
|
+
The RLIMIT_* enumerators and RUSAGE_* constants are the standard Linux/
|
|
17
|
+
glibc values (measured, both arches agree). getrlimit/setrlimit/getrusage
|
|
18
|
+
are POSIX declarations whose bodies resolve from the host libc at link time
|
|
19
|
+
(Step 123, M5 H2). */
|
|
20
|
+
|
|
21
|
+
#ifndef _RUBYCC_SYS_RESOURCE_H
|
|
22
|
+
#define _RUBYCC_SYS_RESOURCE_H
|
|
23
|
+
|
|
24
|
+
#ifndef _RUBYCC_TIME_T
|
|
25
|
+
#define _RUBYCC_TIME_T
|
|
26
|
+
typedef long time_t;
|
|
27
|
+
#endif
|
|
28
|
+
#ifndef _RUBYCC_SUSECONDS_T
|
|
29
|
+
#define _RUBYCC_SUSECONDS_T
|
|
30
|
+
typedef long suseconds_t;
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
#ifndef __timeval_defined
|
|
34
|
+
#define __timeval_defined 1
|
|
35
|
+
struct timeval {
|
|
36
|
+
time_t tv_sec;
|
|
37
|
+
suseconds_t tv_usec;
|
|
38
|
+
};
|
|
39
|
+
#endif
|
|
40
|
+
|
|
41
|
+
typedef unsigned long rlim_t;
|
|
42
|
+
|
|
43
|
+
/* struct rlimit: 16 bytes, 8-byte aligned (measured, both arches). */
|
|
44
|
+
struct rlimit {
|
|
45
|
+
rlim_t rlim_cur; /* Soft limit. offset 0 */
|
|
46
|
+
rlim_t rlim_max; /* Hard limit. offset 8 */
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/* struct rusage: 144 bytes, 8-byte aligned on glibc and 272 bytes, 8-byte
|
|
50
|
+
aligned on musl (both sizeof/_Alignof pairs measured with the ABI harness,
|
|
51
|
+
glibc's on this host and musl's on the CI musl run, docs/STEPS.md Step 193).
|
|
52
|
+
Every member offset below was probed on both and agreed, so the two libraries
|
|
53
|
+
differ only in what follows the last member: musl reserves a further 128
|
|
54
|
+
bytes there. Those bytes are reproduced as one opaque trailing array rather
|
|
55
|
+
than as named fields, because only their extent was measured -- the same
|
|
56
|
+
treatment sys/stat.h gives struct stat's reserved slots. The
|
|
57
|
+
ru_ixrss/ru_idrss/ru_isrss/ru_nswap fields are unused by Linux but kept for
|
|
58
|
+
the standard layout. */
|
|
59
|
+
struct rusage {
|
|
60
|
+
struct timeval ru_utime; /* offset 0: user CPU time used */
|
|
61
|
+
struct timeval ru_stime; /* offset 16: system CPU time used */
|
|
62
|
+
long ru_maxrss; /* offset 32: maximum resident set size */
|
|
63
|
+
long ru_ixrss; /* offset 40: integral shared memory size */
|
|
64
|
+
long ru_idrss; /* offset 48: integral unshared data size */
|
|
65
|
+
long ru_isrss; /* offset 56: integral unshared stack size */
|
|
66
|
+
long ru_minflt; /* offset 64: page reclaims */
|
|
67
|
+
long ru_majflt; /* offset 72: page faults */
|
|
68
|
+
long ru_nswap; /* offset 80: swaps */
|
|
69
|
+
long ru_inblock; /* offset 88: block input operations */
|
|
70
|
+
long ru_oublock; /* offset 96: block output operations */
|
|
71
|
+
long ru_msgsnd; /* offset 104: messages sent */
|
|
72
|
+
long ru_msgrcv; /* offset 112: messages received */
|
|
73
|
+
long ru_nsignals; /* offset 120: signals received */
|
|
74
|
+
long ru_nvcsw; /* offset 128: voluntary context switches */
|
|
75
|
+
long ru_nivcsw; /* offset 136: involuntary context switches */
|
|
76
|
+
#if defined(__RUBYCC_LIBC_MUSL__)
|
|
77
|
+
long __reserved[16]; /* offset 144: musl's trailing 128 bytes (measured) */
|
|
78
|
+
#endif
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
#define RLIMIT_CPU 0
|
|
82
|
+
#define RLIMIT_FSIZE 1
|
|
83
|
+
#define RLIMIT_DATA 2
|
|
84
|
+
#define RLIMIT_STACK 3
|
|
85
|
+
#define RLIMIT_CORE 4
|
|
86
|
+
#define RLIMIT_RSS 5
|
|
87
|
+
#define RLIMIT_NPROC 6
|
|
88
|
+
#define RLIMIT_NOFILE 7
|
|
89
|
+
#define RLIMIT_MEMLOCK 8
|
|
90
|
+
#define RLIMIT_AS 9
|
|
91
|
+
#define RLIMIT_LOCKS 10
|
|
92
|
+
#define RLIMIT_SIGPENDING 11
|
|
93
|
+
#define RLIMIT_MSGQUEUE 12
|
|
94
|
+
#define RLIMIT_NICE 13
|
|
95
|
+
#define RLIMIT_RTPRIO 14
|
|
96
|
+
#define RLIMIT_RTTIME 15
|
|
97
|
+
#define RLIMIT_NLIMITS 16
|
|
98
|
+
|
|
99
|
+
#define RLIM_INFINITY ((rlim_t)-1)
|
|
100
|
+
|
|
101
|
+
#define RUSAGE_SELF 0
|
|
102
|
+
#define RUSAGE_CHILDREN (-1)
|
|
103
|
+
#define RUSAGE_THREAD 1
|
|
104
|
+
|
|
105
|
+
int getrlimit(int __resource, struct rlimit *__rlimits);
|
|
106
|
+
int setrlimit(int __resource, const struct rlimit *__rlimits);
|
|
107
|
+
int getrusage(int __who, struct rusage *__usage);
|
|
108
|
+
|
|
109
|
+
#endif /* _RUBYCC_SYS_RESOURCE_H */
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/* rubycc bundled <sys/socket.h>: the socket address family / type / option
|
|
2
|
+
macros, the socket address structs (sockaddr, sockaddr_storage, msghdr,
|
|
3
|
+
iovec, cmsghdr, linger) and the POSIX socket calls. Provenance: clean room
|
|
4
|
+
against the Linux kernel UAPI (linux/socket.h, asm-generic/socket.h,
|
|
5
|
+
linux/uio.h) and the glibc socket ABI, not derived from musl. The AF_/PF_/
|
|
6
|
+
SOCK_/SOL_/SO_/MSG_/SHUT_ values and the struct layouts are that ABI
|
|
7
|
+
reproduced as measured integer constants and measured field offsets (an ABI
|
|
8
|
+
fact, not copied text -- see docs/HEADER-LICENSING.md), the same treatment
|
|
9
|
+
as errno.h and fcntl.h. socket, bind, connect and kin are POSIX declarations
|
|
10
|
+
whose bodies resolve from the host libc at link time. Common layer: every
|
|
11
|
+
macro value and every struct layout below (struct sockaddr, sockaddr_storage,
|
|
12
|
+
msghdr, iovec, cmsghdr and linger all included) is identical on x86-64 and
|
|
13
|
+
aarch64. */
|
|
14
|
+
|
|
15
|
+
#ifndef _RUBYCC_SYS_SOCKET_H
|
|
16
|
+
#define _RUBYCC_SYS_SOCKET_H
|
|
17
|
+
|
|
18
|
+
#ifndef _RUBYCC_SIZE_T
|
|
19
|
+
#define _RUBYCC_SIZE_T
|
|
20
|
+
typedef unsigned long size_t;
|
|
21
|
+
#endif
|
|
22
|
+
#ifndef _RUBYCC_SSIZE_T
|
|
23
|
+
#define _RUBYCC_SSIZE_T
|
|
24
|
+
typedef long ssize_t;
|
|
25
|
+
#endif
|
|
26
|
+
#ifndef _RUBYCC_SOCKLEN_T
|
|
27
|
+
#define _RUBYCC_SOCKLEN_T
|
|
28
|
+
typedef unsigned int socklen_t;
|
|
29
|
+
#endif
|
|
30
|
+
#ifndef _RUBYCC_SA_FAMILY_T
|
|
31
|
+
#define _RUBYCC_SA_FAMILY_T
|
|
32
|
+
typedef unsigned short sa_family_t;
|
|
33
|
+
#endif
|
|
34
|
+
|
|
35
|
+
/* struct iovec: 16 bytes, 8-byte aligned (measured, both arches). */
|
|
36
|
+
#ifndef _RUBYCC_STRUCT_IOVEC
|
|
37
|
+
#define _RUBYCC_STRUCT_IOVEC
|
|
38
|
+
struct iovec {
|
|
39
|
+
void *iov_base; /* offset 0 */
|
|
40
|
+
size_t iov_len; /* offset 8 */
|
|
41
|
+
};
|
|
42
|
+
#endif
|
|
43
|
+
|
|
44
|
+
/* struct sockaddr: 16 bytes, the generic socket address (POSIX/glibc). */
|
|
45
|
+
struct sockaddr {
|
|
46
|
+
sa_family_t sa_family; /* offset 0 */
|
|
47
|
+
char sa_data[14]; /* offset 2 */
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/* struct sockaddr_storage: 128 bytes, 8-byte aligned (measured, both arches),
|
|
51
|
+
large and aligned enough to hold any of the protocol-specific sockaddr_*
|
|
52
|
+
structs. __ss_align forces the 8-byte alignment and pads the struct out to
|
|
53
|
+
the full 128 bytes. */
|
|
54
|
+
struct sockaddr_storage {
|
|
55
|
+
sa_family_t ss_family; /* offset 0 */
|
|
56
|
+
char __ss_padding[118]; /* offset 2 */
|
|
57
|
+
unsigned long __ss_align; /* offset 120 */
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/* struct msghdr: 56 bytes (measured, both arches), the sendmsg/recvmsg
|
|
61
|
+
scatter-gather message descriptor. */
|
|
62
|
+
struct msghdr {
|
|
63
|
+
void *msg_name; /* offset 0 */
|
|
64
|
+
socklen_t msg_namelen; /* offset 8 */
|
|
65
|
+
struct iovec *msg_iov; /* offset 16 */
|
|
66
|
+
size_t msg_iovlen; /* offset 24 */
|
|
67
|
+
void *msg_control; /* offset 32 */
|
|
68
|
+
size_t msg_controllen; /* offset 40 */
|
|
69
|
+
int msg_flags; /* offset 48 */
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/* struct cmsghdr: 16 bytes, one ancillary-data record header. */
|
|
73
|
+
struct cmsghdr {
|
|
74
|
+
size_t cmsg_len; /* offset 0 */
|
|
75
|
+
int cmsg_level; /* offset 8 */
|
|
76
|
+
int cmsg_type; /* offset 12 */
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/* struct linger: 8 bytes, the SO_LINGER option payload. */
|
|
80
|
+
struct linger {
|
|
81
|
+
int l_onoff;
|
|
82
|
+
int l_linger;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/* Address / protocol families (Linux kernel UAPI). */
|
|
86
|
+
#define AF_UNSPEC 0
|
|
87
|
+
#define AF_UNIX 1
|
|
88
|
+
#define AF_LOCAL AF_UNIX
|
|
89
|
+
#define AF_INET 2
|
|
90
|
+
#define AF_INET6 10
|
|
91
|
+
/* AF_NETLINK is the kernel-configuration socket family. It is here because a
|
|
92
|
+
corpus gem asked for it by name (raindrops' linux_inet_diag.c opens one to
|
|
93
|
+
read TCP listen queues) and for no other reason: the families are a numbered
|
|
94
|
+
space with dozens of members, and adding the ones nobody has reached for
|
|
95
|
+
would be values nobody has measured. */
|
|
96
|
+
#define AF_NETLINK 16
|
|
97
|
+
|
|
98
|
+
#define PF_UNSPEC AF_UNSPEC
|
|
99
|
+
#define PF_UNIX AF_UNIX
|
|
100
|
+
#define PF_LOCAL AF_UNIX
|
|
101
|
+
#define PF_INET AF_INET
|
|
102
|
+
#define PF_INET6 AF_INET6
|
|
103
|
+
#define PF_NETLINK AF_NETLINK
|
|
104
|
+
|
|
105
|
+
/* Socket types. SOCK_CLOEXEC/SOCK_NONBLOCK are Linux extensions that may be
|
|
106
|
+
OR'd into the type argument of socket()/socketpair(). */
|
|
107
|
+
#define SOCK_STREAM 1
|
|
108
|
+
#define SOCK_DGRAM 2
|
|
109
|
+
#define SOCK_RAW 3
|
|
110
|
+
#define SOCK_SEQPACKET 5
|
|
111
|
+
#define SOCK_NONBLOCK 0x800
|
|
112
|
+
#define SOCK_CLOEXEC 0x80000
|
|
113
|
+
|
|
114
|
+
/* getsockopt/setsockopt level and SO_* option names (asm-generic/socket.h). */
|
|
115
|
+
#define SOL_SOCKET 1
|
|
116
|
+
|
|
117
|
+
#define SO_REUSEADDR 2
|
|
118
|
+
#define SO_TYPE 3
|
|
119
|
+
#define SO_ERROR 4
|
|
120
|
+
#define SO_BROADCAST 6
|
|
121
|
+
#define SO_SNDBUF 7
|
|
122
|
+
#define SO_RCVBUF 8
|
|
123
|
+
#define SO_KEEPALIVE 9
|
|
124
|
+
#define SO_LINGER 13
|
|
125
|
+
#define SO_REUSEPORT 15
|
|
126
|
+
|
|
127
|
+
/* send/recv message flags. */
|
|
128
|
+
#define MSG_OOB 1
|
|
129
|
+
#define MSG_PEEK 2
|
|
130
|
+
#define MSG_TRUNC 0x20
|
|
131
|
+
#define MSG_DONTWAIT 0x40
|
|
132
|
+
#define MSG_WAITALL 0x100
|
|
133
|
+
#define MSG_NOSIGNAL 0x4000
|
|
134
|
+
|
|
135
|
+
/* shutdown() how. */
|
|
136
|
+
#define SHUT_RD 0
|
|
137
|
+
#define SHUT_WR 1
|
|
138
|
+
#define SHUT_RDWR 2
|
|
139
|
+
|
|
140
|
+
int socket(int __domain, int __type, int __protocol);
|
|
141
|
+
int socketpair(int __domain, int __type, int __protocol, int __fds[2]);
|
|
142
|
+
int bind(int __fd, const struct sockaddr *__addr, socklen_t __len);
|
|
143
|
+
int getsockname(int __fd, struct sockaddr *__addr, socklen_t *__len);
|
|
144
|
+
int connect(int __fd, const struct sockaddr *__addr, socklen_t __len);
|
|
145
|
+
int getpeername(int __fd, struct sockaddr *__addr, socklen_t *__len);
|
|
146
|
+
ssize_t send(int __fd, const void *__buf, size_t __n, int __flags);
|
|
147
|
+
ssize_t recv(int __fd, void *__buf, size_t __n, int __flags);
|
|
148
|
+
ssize_t sendto(int __fd, const void *__buf, size_t __n, int __flags,
|
|
149
|
+
const struct sockaddr *__addr, socklen_t __addr_len);
|
|
150
|
+
ssize_t recvfrom(int __fd, void *__buf, size_t __n, int __flags,
|
|
151
|
+
struct sockaddr *__addr, socklen_t *__addr_len);
|
|
152
|
+
ssize_t sendmsg(int __fd, const struct msghdr *__message, int __flags);
|
|
153
|
+
ssize_t recvmsg(int __fd, struct msghdr *__message, int __flags);
|
|
154
|
+
int getsockopt(int __fd, int __level, int __optname, void *__optval, socklen_t *__optlen);
|
|
155
|
+
int setsockopt(int __fd, int __level, int __optname, const void *__optval, socklen_t __optlen);
|
|
156
|
+
int listen(int __fd, int __n);
|
|
157
|
+
int accept(int __fd, struct sockaddr *__addr, socklen_t *__addr_len);
|
|
158
|
+
/* accept4 is the Linux extension that folds SOCK_CLOEXEC / SOCK_NONBLOCK into
|
|
159
|
+
the accept itself, closing the race a separate fcntl leaves open. glibc gates
|
|
160
|
+
it behind _GNU_SOURCE; this header exposes SOCK_CLOEXEC unconditionally
|
|
161
|
+
already (see the socket types above), so the declaration follows the same
|
|
162
|
+
rule rather than growing a feature-test macro of its own. kgio's accept.c
|
|
163
|
+
calls it whenever its extconf found it. */
|
|
164
|
+
int accept4(int __fd, struct sockaddr *__addr, socklen_t *__addr_len, int __flags);
|
|
165
|
+
int shutdown(int __fd, int __how);
|
|
166
|
+
|
|
167
|
+
#endif /* _RUBYCC_SYS_SOCKET_H */
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* rubycc bundled <sys/statfs.h>: the Linux statfs(2) filesystem-statistics
|
|
2
|
+
interface. Provenance: clean room against the Linux kernel UAPI
|
|
3
|
+
(the statfs(2) argument layout) and the glibc call surface, not derived
|
|
4
|
+
from musl or glibc source. struct statfs's size, member widths, signedness
|
|
5
|
+
and offsets are that ABI reproduced from measurement (an ABI fact, not
|
|
6
|
+
copied text -- see docs/HEADER-LICENSING.md sec. 4), the same treatment as
|
|
7
|
+
sys/stat.h and dirent.h.
|
|
8
|
+
|
|
9
|
+
Common layer, and this one is worth spelling out because the naive guess
|
|
10
|
+
is the other way. The kernel has two statfs layouts -- a legacy one whose
|
|
11
|
+
counters are 32-bit and a 64-bit one -- and glibc's member types are
|
|
12
|
+
written in terms of word-sized typedefs, so it would be reasonable to
|
|
13
|
+
expect the two targets to disagree the way sys/stat.h's struct stat does.
|
|
14
|
+
Measured with the glibc oracle, they do not: both x86-64 and aarch64
|
|
15
|
+
report
|
|
16
|
+
|
|
17
|
+
sizeof 120, _Alignof 8, and every member 8 bytes wide at
|
|
18
|
+
f_type 0, f_bsize 8, f_blocks 16, f_bfree 24, f_bavail 32,
|
|
19
|
+
f_files 40, f_ffree 48, f_fsid 56, f_namelen 64, f_frsize 72,
|
|
20
|
+
f_flags 80, f_spare 88 (4 x 8 = 32 bytes, running to 120)
|
|
21
|
+
|
|
22
|
+
i.e. both LP64 targets land on the all-64-bit layout with no padding
|
|
23
|
+
anywhere, so one arch-neutral definition serves. The signedness was
|
|
24
|
+
measured member by member as well, and is not uniform: f_type, f_bsize,
|
|
25
|
+
f_namelen, f_frsize, f_flags and f_spare are signed, while the six
|
|
26
|
+
counters f_blocks / f_bfree / f_bavail / f_files / f_ffree are unsigned.
|
|
27
|
+
That asymmetry is why signedness was probed rather than assumed -- libev
|
|
28
|
+
compares f_type against magic numbers as large as 0x9123683e, which only
|
|
29
|
+
behaves as intended because the field is a signed 64-bit word rather than
|
|
30
|
+
a 32-bit one.
|
|
31
|
+
|
|
32
|
+
f_fsid's type: glibc gets __fsid_t from its bits/types.h layer and spells
|
|
33
|
+
the fsid_t alias in <sys/types.h> under __USE_MISC; measured, <sys/statfs.h>
|
|
34
|
+
alone gives only the __fsid_t spelling. rubycc has no split types layer to
|
|
35
|
+
reach for and its bundled <sys/types.h> does not carry the type, so both
|
|
36
|
+
names are defined here under one guard. The type itself measured 8 bytes
|
|
37
|
+
with 4-byte alignment -- two 4-byte ints, not one 8-byte word, which is
|
|
38
|
+
why f_fsid cannot simply be written as a long.
|
|
39
|
+
|
|
40
|
+
Not included: struct statfs64 / statfs64 / fstatfs64 (measured, statfs64
|
|
41
|
+
is byte-for-byte the same 120-byte layout on both LP64 targets, so the
|
|
42
|
+
plain names already are the 64-bit interface here), and the ST_* mount
|
|
43
|
+
flag names, which measurement confirms <sys/statfs.h> does not define at
|
|
44
|
+
all -- they belong to <sys/statvfs.h>, which rubycc does not bundle. nio4r,
|
|
45
|
+
the gem that put this header on the list, reaches statfs and f_type only,
|
|
46
|
+
from libev's ev_stat backend deciding whether a filesystem is local enough
|
|
47
|
+
for inotify to be trusted. */
|
|
48
|
+
|
|
49
|
+
#ifndef _RUBYCC_SYS_STATFS_H
|
|
50
|
+
#define _RUBYCC_SYS_STATFS_H
|
|
51
|
+
|
|
52
|
+
/* The filesystem identifier statfs reports. Measured: 8 bytes, 4-byte
|
|
53
|
+
aligned, i.e. a pair of 4-byte ints rather than one 8-byte word. */
|
|
54
|
+
#ifndef _RUBYCC_FSID_T
|
|
55
|
+
#define _RUBYCC_FSID_T
|
|
56
|
+
typedef struct {
|
|
57
|
+
int __val[2];
|
|
58
|
+
} __fsid_t;
|
|
59
|
+
typedef __fsid_t fsid_t;
|
|
60
|
+
#endif
|
|
61
|
+
|
|
62
|
+
/* Measured: 120 bytes, 8-byte aligned, every member one 8-byte word and no
|
|
63
|
+
padding. Signedness is per member -- see the header note. */
|
|
64
|
+
struct statfs {
|
|
65
|
+
long f_type; /* offset 0: filesystem magic number */
|
|
66
|
+
long f_bsize; /* offset 8: optimal transfer block size */
|
|
67
|
+
unsigned long f_blocks; /* offset 16: total blocks, in f_frsize units */
|
|
68
|
+
unsigned long f_bfree; /* offset 24: free blocks */
|
|
69
|
+
unsigned long f_bavail; /* offset 32: free blocks available to non-root */
|
|
70
|
+
unsigned long f_files; /* offset 40: total file nodes */
|
|
71
|
+
unsigned long f_ffree; /* offset 48: free file nodes */
|
|
72
|
+
__fsid_t f_fsid; /* offset 56: filesystem id */
|
|
73
|
+
long f_namelen; /* offset 64: maximum filename length */
|
|
74
|
+
long f_frsize; /* offset 72: fragment size */
|
|
75
|
+
long f_flags; /* offset 80: mount flags */
|
|
76
|
+
long f_spare[4];/* offset 88: reserved, runs to 120 */
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
int statfs(const char *__path, struct statfs *__buf);
|
|
80
|
+
int fstatfs(int __fd, struct statfs *__buf);
|
|
81
|
+
|
|
82
|
+
#endif /* _RUBYCC_SYS_STATFS_H */
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* rubycc bundled <sys/timerfd.h>: the Linux timerfd(2) family, which delivers
|
|
2
|
+
POSIX timer expirations as readable events on a file descriptor.
|
|
3
|
+
Provenance: clean room against the Linux kernel UAPI
|
|
4
|
+
(linux/timerfd.h) and the glibc call surface, not derived from musl or
|
|
5
|
+
glibc source. The four TFD_* values are that ABI reproduced as measured
|
|
6
|
+
integer constants (an ABI fact, not copied text -- see
|
|
7
|
+
docs/HEADER-LICENSING.md sec. 4), printed from the glibc oracle on x86-64
|
|
8
|
+
and on aarch64 (cross gcc + qemu).
|
|
9
|
+
|
|
10
|
+
Common layer. Both TFD_CLOEXEC and TFD_NONBLOCK share bits with the
|
|
11
|
+
open(2) flags, which do differ between the two targets for some O_* names
|
|
12
|
+
(that is why fcntl.h is an arch-layer header), so this was measured rather
|
|
13
|
+
than assumed. It measured identical on both:
|
|
14
|
+
|
|
15
|
+
TFD_CLOEXEC 0x80000, TFD_NONBLOCK 0x800,
|
|
16
|
+
TFD_TIMER_ABSTIME 1, TFD_TIMER_CANCEL_ON_SET 2
|
|
17
|
+
|
|
18
|
+
and so did everything the interface's types rest on -- struct itimerspec
|
|
19
|
+
is 32 bytes with it_interval at 0 and it_value at 16, struct timespec is
|
|
20
|
+
16 bytes, clockid_t is 4 -- so no arch split is needed here.
|
|
21
|
+
|
|
22
|
+
struct itimerspec is NOT duplicated below: the bundled <time.h> already
|
|
23
|
+
defines it (next to struct timespec, which it is built from), so this
|
|
24
|
+
header includes <time.h> and lets the one definition serve, the same
|
|
25
|
+
judgement <sys/wait.h> makes about siginfo_t. That include also supplies
|
|
26
|
+
the CLOCK_* ids timerfd_create's first argument takes.
|
|
27
|
+
|
|
28
|
+
Not included: timerfd_settime64/timerfd_gettime64 (the 32-bit-time_t
|
|
29
|
+
compatibility entry points; on LP64 targets glibc resolves the plain names
|
|
30
|
+
to the 64-bit implementation already). nio4r, the gem that put this header
|
|
31
|
+
on the list, reaches timerfd_create and timerfd_settime through libev's
|
|
32
|
+
periodic-timer backend. */
|
|
33
|
+
|
|
34
|
+
#ifndef _RUBYCC_SYS_TIMERFD_H
|
|
35
|
+
#define _RUBYCC_SYS_TIMERFD_H
|
|
36
|
+
|
|
37
|
+
#include <time.h>
|
|
38
|
+
|
|
39
|
+
/* timerfd_create flags (measured, both arches). */
|
|
40
|
+
#define TFD_CLOEXEC 0x80000
|
|
41
|
+
#define TFD_NONBLOCK 0x800
|
|
42
|
+
|
|
43
|
+
/* timerfd_settime flags (measured, both arches). ABSTIME reads the value as
|
|
44
|
+
an absolute time on the chosen clock; CANCEL_ON_SET additionally makes a
|
|
45
|
+
discontinuous change of CLOCK_REALTIME cancel the timer, which is how a
|
|
46
|
+
reader learns the wall clock was stepped. */
|
|
47
|
+
#define TFD_TIMER_ABSTIME 1
|
|
48
|
+
#define TFD_TIMER_CANCEL_ON_SET 2
|
|
49
|
+
|
|
50
|
+
int timerfd_create(int __clock_id, int __flags);
|
|
51
|
+
int timerfd_settime(int __fd, int __flags, const struct itimerspec *__new_value,
|
|
52
|
+
struct itimerspec *__old_value);
|
|
53
|
+
int timerfd_gettime(int __fd, struct itimerspec *__curr_value);
|
|
54
|
+
|
|
55
|
+
#endif /* _RUBYCC_SYS_TIMERFD_H */
|