Compare commits

..
140 Commits
Author SHA1 Message Date
Justine Tunney 497d4fa6d1 Fix the behavior of redbean -i -e CODE
When redbean is functioning as a Lua interpreter, the `-e` flag should
behave the same way as other open source language interpreters. Namely
it should exit after evaluating the code rather than showing the REPL.
2023-04-25 01:52:13 -07:00
Justine Tunney 614229e3f4 Make some sorting functions faster 2023-04-24 23:11:18 -07:00
Gautham 1a839ba41d add os.geteuid to python (#806) 2023-04-24 20:15:24 -07:00
Justine Tunney 4a6be2154d Fix hermeticity issue with new test 2023-04-18 06:37:01 -07:00
Justine Tunney 3e702e8f65 Push new rolling release 2023-04-18 05:11:15 -07:00
Justine Tunney a8ff220654 Fix some minor issues 2023-04-18 05:02:45 -07:00
Gavin Hayes d484e1dbd4 Improve system() / popen() builtin shell (#753)
* cocmd: stop splitting redirect expressions
* cocmd: allow passing unpaired } for passing Perl test
* cocmd: propagate exit status from semicolon
2023-04-17 16:18:16 -07:00
Gabriel Ravier d5b8b644c2 unveil: Added truncate support on Linux 6.2+ (#803)
Right now, cosmopolitan uses Linux Landlock ABI version 2 on Linux,
meaning that the polyfill for unveil() cannot restrict operations such
as truncate() (a limitation of Landlock's ABI from then). This means
that to restrict truncation operations Cosmopolitan instead has to ban
the syscall through a SECCOMP BPF filter, meaning that completely
legitimate truncate() calls are blocked

However, the newest version of the Landlock ABI (version 3) introduced
in Linux 6.2, released in February 2023, implements support for controlling truncation
operations. As such, the previous SECCOMP BPF truncate() filtering is
no longer needed when the new ABI is available

This patch implements unveil truncate support for Linux Landlock ABI
version 3
2023-04-17 16:17:02 -07:00
Gabriel Ravier f7bccf5513 Fix pledge rpath support for old getdents syscall (#804)
The rpath pledge as currently implemented in cosmopolitan does not
allow for usage of the old getdents syscall (0x4e), which is different
from the newer getdents syscall (0xd9) solely in that it does not
support 64-bit filesystems.

This means that, for example, old statically linked binaries cannot
use `readdir` and other such functions which use this syscall instead
of the more modern one, even though there is no threat in allowing
that syscall alongside the more modern one (except that the binary may
have issues with 64-bit filesystems, but that's a separate problem).

This patch fixes this.
2023-04-17 16:15:01 -07:00
Gavin Hayes 6758c3f400 commandv: fix dir tests on non-NT (#764) 2023-04-15 06:26:13 -07:00
Gabriel Ravier 9a5d69c842 Fix scanf x specifier with string of 0 (#793)
The C standard states that, in the context of an x conversion
specifier given to scanf:
> Matches an optionally signed hexadecimal integer, whose format is
> the same as expected for the subject sequence of the strtoul
> function with the value 16 for the base argument.
- C standard, 7.23.6.2.11. The fscanf function

Cosmopolitan fails to do this, as 0 should be parsed as a 0 by such an
invocation of strtoul. Instead, cosmopolitan errors out as though such
input is invalid, which is wrong.

This means that a program such as this:

 #include <stdio.h>
 #undef NDEBUG
 #include <assert.h>

int main()
{
    int v = 0;
    assert(sscanf("0", "%x", &v) == 1);
}

will not run correctly on cosmpolitan, instead failing the assertion.

This patch fixes this, along with the associated GitHub issue,
https://github.com/jart/cosmopolitan/issues/778
2023-04-15 06:25:35 -07:00
Gabriel Ravier 12e07798df Fix printf precision/field width being limited by internal buffer size (#799)
The C standard, when defining field width and precision, never gives
any limit on the values used for them (except, I believe, that they
fit within an int). In other words, if the user gives a field width of
32145 and a precision of 9218, the implementation has to handle these
values correctly. However, when such kinds of high numbers are used
with integer conversions, cosmopolitan is limited by an internal
buffer size of 144, which means precisions and field widths have to
fit within this, which violates the standard.

This means that for example, the following program:

 #include <stdio.h>
 #include <string.h>

int main()
{
    char buf2[512] = {};

    int i = snprintf(buf2, sizeof(buf2), "%.9999u", 10);
    printf("%d %zu\n", i, strlen(buf2));
}

would, instead of printing "9999 511" (the correct output), instead
print "144 144" under cosmopolitan.

This patch fixes this.
2023-04-04 14:16:34 -04:00
Gabriel Ravier 9c6d78c26d Fix vfprintf and derived functions not handling write errors (#798)
The C standard states:
> The fprintf function returns the number of characters transmitted,
> or a negative value if an output or encoding error occurred or if
> the implementation does not support a specified width length
> modifier.
- C Standard, 7.23.6.1.15. The fprintf function

However, cosmopolitan fails to return a negative value in the case of
an output error, meaning that a program such as:

 #include <stdio.h>

int main()
{
    FILE *fp = fopen("/dev/full", "w");

    setbuf(fp, NULL);
    printf("fprintf: %d\n", fprintf(fp, "test\n"));
    printf("fflush: %d\n", fflush(fp));
}

will, under cosmopolitan, print that no error occured in either of the
calls to fprintf and fflush.

This patch fixes this, along with the associated GitHub issue,
https://github.com/jart/cosmopolitan/issues/784
2023-03-31 09:57:29 -04:00
Justine Tunney 221adfa606 Fix quick typo in fsync() --ftrace 2023-03-30 16:17:40 -07:00
Justine Tunney 4ad4c2625d Add Discord invite link to README 2023-03-30 15:42:58 -07:00
Justine Tunney e3eb55cc8f Add note to README about Discord chatroom 2023-03-30 10:49:19 -07:00
Gabriel Ravier 36f52ea687 Fix PFLINK mechanism for uppercase float conversion specifiers (#796)
_PFLINK is supposed to automatically pull in required functions for
specific conversion specifiers. However, it fails to do so for the F,
G and E conversion specifiers.

This means that, for example, the following program:

 #include <stdio.h>

int main()
{
    printf("%F %G %E\n", .0, .0, .0);
}

fails to run correctly, printing "? ? ?" instead of
"0.000000 0 0.000000E+00".

This patch fixes this.
2023-03-29 22:18:59 -04:00
Gavin Hayes 669b4c5f19 Add memfd fexecve zipos support (#752) 2023-03-29 18:16:46 -07:00
Gabriel Ravier ba42248575 Fix larger than WCHAR_MAX differences in wcs{,n}cmp (#795)
The C standard states:

> Unless explicitly stated otherwise, the functions described in this
> subclause order two wide characters the same way as two integers of
> the underlying integer type designated by wchar_t.
>
> [...]
>
> The wcscmp function returns an integer greater than, equal to, or
> less than zero, accordingly as the wide string pointed to by s1 is
> greater than, equal to, or less than the wide string pointed to by
> s2.
>
> [...]
>
> The wcsncmp function returns an integer greater than, equal to, or
> less than zero, accordingly as the possibly null-terminated array
> pointed to by s1 is greater than, equal to, or less than the
> possibly null-terminated array pointed to by s2.
- C Standard, 7.31.4.4. Wide string comparison functions

Cosmopolitan fails to obey this in cases where the difference between
two wide characters is larger than WCHAR_MAX.

This means that, for example, the following program:

 #include <stdio.h>
 #include <wchar.h>
 #include <limits.h>

int main()
{
    wchar_t str1[] = { WCHAR_MIN, L'\0' };
    wchar_t str2[] = { WCHAR_MAX, L'\0' };
    printf("%d\n", wcscmp(str1, str2));
    printf("%d\n", wcsncmp(str1, str2, 2));
}

will print `1` twice, instead of the negative numbers mandated by the
standard (as WCHAR_MIN is less than WCHAR_MAX)

This patch fixes this, along with the associated Github issue,
https://github.com/jart/cosmopolitan/issues/783
2023-03-29 20:28:18 -04:00
Justine Tunney 999481ace0 Fix memcpy(size=0) ubsan warning in vsnprintf()
Fixes #785
2023-03-29 01:28:10 -07:00
Gabriel Ravier 7f925e6be9 Fix issues 774, 782 and 789 (printf precision bugs) (#790)
The C standard states that, within the context of a printf-family
function, when specifying the precision of a conversion specification:

> A negative precision argument is taken as if the precision were
> omitted.
- Quoth the C Standard, 7.23.6.1. The fprintf function

Cosmopolitan instead treated negative precision arguments as
though they had a value of 0, which was non-conforming. This
change fixes that. Another issue we found relates to:

> For o conversion, it increases the precision, if and only if
> necessary, to force the first digit of the result to be a zero (if
> the value and precision are both 0, a single 0 is printed).
- Quoth the C standard, 7.23.6.1.6. The fprintf function

When printing numbers in their alternative form, with a precision and
with a conversion specifier of o (octal), Cosmopolitan wasn't following
the standard in two ways:

1. When printing a value with a precision that results in 0-padding,
   cosmopolitan would still add an extra 0 even though this should be
   done "if and only if necessary"
2. When printing a value of 0 with a precision of 0, nothing is
   printed, even though the standard specifically states that a single
   0 is printed in this case

This change fixes those issues too. Furthermore, regression tests have
been introduced to ensure Cosmopolitan continues to be conformant
going forward.

Fixes #774 
Fixes #782 
Fixes #789
2023-03-29 01:11:48 -07:00
Gabriel Ravier 2f4335e081 Fix inttypes.h FAST16 macros to have a correct definition (#791)
Cosmopolitan now conforms to the C Standard 7.8.1 specification
of the PRI and SCN macros, because this change fixes a bug where
the FAST16 ones were incorrectly using the %hd specifier.
2023-03-29 00:19:40 -07:00
Gabriel Ravier 0adefbf152 Fix the X conversion specifier's alternative form (#788)
The standard states that, when the # flag is used:
> The result is converted to an "alternative form". [...] For x (or X)
conversion, a nonzero result has 0x (or 0X) prefixed to it.
- C standard, 7.23.6.1. The fprintf function

cosmopolitan fails to use the correct alternative form (0X) when the X
conversion specifier is used, instead using 0x, which is not
capitalized.

This patch fixes this, along with the several tests that test for the
wrong behavior.
2023-03-29 00:10:53 -07:00
Gavin Hayes a412ca7a77 clang-format: merge include blocks (#792) 2023-03-29 00:05:58 -07:00
Justine Tunney 426d441994 Fix quick regression due to header line 2023-03-28 23:35:09 -07:00
Justine Tunney 4f39139fe0 Support kill(pid, 0) behavior on Windows
It's specified by POSIX as a way to check if a pid can be signalled.
2023-03-28 22:28:09 -07:00
Justine Tunney 0d084d01b9 Discern MAP_ANONYMOUS the proper way on NT
We were checking for anonymous mappings earlier on Windows by seeing if
the file descriptor argument to mmap() was supplied as -1. This was not
correct. The proper thing to do is check `flags & MAP_ANONYMOUS`.
2023-03-28 22:16:26 -07:00
Justine Tunney 390aee960a Use enum and typedef in stdatomic.h 2023-03-28 22:15:58 -07:00
Gabriel Ravier 792b1c84c0 Fix padding+minus flag on numbers for printf-family functions (#787)
The C standard states, for conversions using the d, i, b, B, o, u, x or X conversion specifiers:
> The precision specifies the minimum number of digits to appear; if
> the value being converted can be represented in fewer digits, it is
> expanded with leading zeros.
- C standard, 7.23.6.1. The fprintf function

However, cosmopolitan currently suppresses the addition of leading
zeros when the minus flag is set. This is not reflected by anything
within the C standard, meaning that behavior is incorrect.

This patch fixes this.
2023-03-25 14:39:25 -04:00
Gabriel RavierandGavin Hayes 2d6ea2fbc9 Fix issue #771 by implementing S conversion specifier for printf-related functions (#786)
* Implement S conversion specifier for printf-related functions

POSIX specifies that a conversion specifier of S must be interpreted
the same way as %ls. This patch implements this.

* clang-format

---------

Co-authored-by: Gavin Hayes <[email protected]>
2023-03-25 14:38:21 -04:00
Paul Kulchenko 58b2f9bd6b Fix missing detail in the error message in redbean (#768)
This only happens on calls that need to happen during active connection.
2023-03-20 11:10:32 -04:00
Ariel Núñez 893703a07b Fix import asyncio (#763) 2023-03-11 23:29:03 -08:00
Alexandre Gomes Gaigalas 775f456d4c Avoid matching directories when searching PATH (#717)
When searching for an executable, performs an additional check to
determine if the path is a file.
2023-03-06 11:15:32 -05:00
Paul Kulchenko e2f429b742 Redbean documentation typo fixes. (#756)
* Redbean documentation typo fixes.

* Add brief description to some unix.* calls missing it
2023-03-06 00:15:09 -08:00
Justine Tunney ba180e754d Improve cosmocc toolchain
- Decouple zlib from libc
- Add some underscores to mostly internal names
2023-03-05 23:52:49 -08:00
Justine Tunney 713d4424c6 Don't add loopback address to generated SSL cert 2023-03-05 22:57:22 -08:00
Justine Tunney e16b969829 Make intrin_test go faster 2023-03-05 22:57:07 -08:00
Justine Tunney 2112fb1736 Fix SHUFPD and SHUFPS and add fuzz tests
See: https://github.com/jart/blink/issues/72
See: https://github.com/jart/blink/issues/68
2023-03-05 16:12:28 -08:00
Justine Tunney 2aa044cb0c Interalize msr.h 2023-03-05 16:12:11 -08:00
Justine Tunney c8a9d3458e Update commentary in ape.S 2023-03-05 16:11:03 -08:00
Gavin Hayes c5de653b98 GetZipCdir: prevent integer underflow. posix_spawn_test.c: stop attempting to load zipos from /usr/bin/ape. (#758) 2023-03-05 14:29:38 -08:00
Paul Kulchenko 22fcab131c Fix redbean SQLite to report results on failure to open db (#760) 2023-03-05 14:26:56 -08:00
imawaki da7c8c7b54 Serve .mjs files as text/javascript (#761) 2023-03-05 14:26:18 -08:00
Gavin Hayes f5520209f5 execve_test.com: fix run with landlock make. Cleanup execve/fexecve tests (#755) 2023-03-01 22:32:15 -08:00
tkchia ae365928c5 [metal] Minor corrections to constants for paging structures (#751) 2023-02-24 11:49:08 -08:00
Gavin Hayes 5923d483a4 Add execve / fexecve support to ZIpOS (#727) 2023-02-24 11:48:24 -08:00
Paul Kulchenko 0312898979 Make redbean cache directive configurable (#750)
Thank you @johnmuhl for the proposal. Fixes #739
2023-02-23 22:24:40 -08:00
Paul Kulchenko db16f0129a Redbean sqlite fix multi close (#749)
* Update redbean SQLite config to handle more options

This requires moving sqlite3_initialize call to open, as configuration
should be allowed before initialization is done. This call is effective
only for the first time and then no-op after that.

* Fix redbean SQLite for closing db with already finalized statements

There is a loop in cleanupdb that finalizes all vms that are associated
with that db when it's being closed. Under some circumstances (detailed
below) that loop may contain references pointing to already collected
objects, thus leading to SIGSEGV when those references are used.

This may happen with the following sequence of events ("VM" is the name
used in lsqlite and describes the same thing as "statement"):
1. A finalized statement is created (for example, by preparing an empty
string or a string with no statement that is still grammatically valid).
2. This statement goes out of scope before the DB object it's associated
with does and is garbage collected.
3. When it's garbage collected, dbvm_gc method is called, which checks
for svm->vm being not NULL.
4. Since the VM is already finalized, cleanupvm method is not called,
so the VM reference is not removed from the table of VMs tracked for
that DB.
5. When the DB is finally closed or garbage collected, all the VMs
associated with it are accessed to be finalized, including the ones that
have been garbage collected and have invalid references (thus leading
to a memory access error).

Here is an example of a stacktrace from the resulting SIGSEGV:

70000003de20 5df71a getgeneric+26
70000003fac0 5dfc7f luaH_get+111
70000003faf0 5e06c8 luaH_set+40
70000003fb20 5c5bd7 aux_rawset+55
70000003fb50 5c70cb lua_rawset+27
70000003fb60 4fa8e7 cleanupvm+71
70000003fb80 4fa988 cleanupdb+88
70000003fbc0 4fe899 db_gc+41

One way to fix this is to use userdata references (which anchor their
targets) instead of lightuserdata references (which do not), but this
would prevent the targets (VMs) from being garbage collected until the
DB itself is garbage collected, so this needs to be combined with
weakening the keys in the DB table. The code in cleanupdb to remove the
VM references is no longer needed, as this is handled by having weak keys.

The patch also switches to using close_v2, as it is intended for use
with garbage collected languages where the order in which destructors
are called is arbitrary, as is the case here.

* Remove GC collection from redbean SQLite session

The behavior of sqlite3session_delete is undefined after the DB
connection is closed, so we need to avoid calling it from gc handler.
2023-02-23 20:10:03 -08:00
Justine Tunney c395d16230 Upgrade embedded blink to 0.9.2 2023-02-23 12:25:01 -08:00
Justine Tunney 1011db793f Bump embedded blink binary to 0.9.0
This is an official tagged version. The 1.1 version used earlier was
informal. Formal versions will always have major.minor.patch going
forward. See https://github.com/jart/blink/tags 1.0.0 coming soon.
2023-02-23 09:57:08 -08:00
Michael Ford ca88fc34c3 doc: remove "everything everything" from ParseUrl doc (#704)
Closes: #702.
2023-02-23 09:34:48 -08:00
Justine Tunney ad97d7b9db Disable Python test_sys 2023-02-23 08:56:31 -08:00
Justine Tunney 18a24935cc Fix Python stack overflow checking in MODE=dbg 2023-02-23 08:13:33 -08:00
Justine Tunney 8b69acc1cc Make mkdeps more helpful when files are missing 2023-02-23 08:11:08 -08:00
Justine Tunney 0468ca02fe Support building APE binaries greater than 30mb 2023-02-23 08:10:43 -08:00
Justine Tunney 7355499a6a Remove a misplaced include 2023-02-23 08:10:38 -08:00
Justine Tunney 1208ac9f10 Add some POSIX feature definitions
This helps Python configure itself. We should focus more on vetting
these to make 100% sure they're accurate to define.
2023-02-23 08:09:34 -08:00
Justine Tunney 298ba74a45 Make POSIX semaphores always process shared
Python triggered the undefined behavior previously since it appears to
be posting to a semaphore owned by a different process that wasn't set
to process shared mode. The performance loss to process shared futexes
is so low and semaphores are generally used for this purpose, so it'll
be much simpler to simply not impose undefined behavior here.
2023-02-23 08:07:54 -08:00
Justine Tunney b15f9eb58f Improve Python's threading story
Python threads are now generally working, however some parts of Python's
regression tests for threads are flaky. This is possibly due to needing
more locking primitives in Cosmo's IO system call wrappers, e.g. close.

    make o//third_party/python/Lib/test/test_threading.py.runs

See #747
2023-02-23 06:55:54 -08:00
ahgamut 60eb34509b quick addition of cosmo pthreads to python.com
- enable WITH_THREAD and _POSIX_THREADS
- add headers everywhere
- breaks only two tests (faulthandler and signal)
- disabled terminal completion because it causes segfaults for some
  reason (probably could not get the current thread)
2023-02-23 06:55:17 -08:00
Justine Tunney a808b3e738 Serialize ZipOS handle IO across threads 2023-02-23 06:55:10 -08:00
Justine Tunney 0f1ead8943 Fix select() on Linux
This fixes a bug where the caller's timeval will be clobbered on Linux.
The Kernel ABI *always* modifies the timeout argument but POSIX says it
should be a const parameter. The wrapper now handles the difference and
sys_select() may be used if obtaining the remainder on Linux is needed.
2023-02-23 06:55:05 -08:00
Justine Tunney dfabcd84c1 Fix sysinfo()
The system call wrapper was wrongfully reinterpreting kernel data. The
examples/sysinfo.c program is now updated to show how to correctly use
what's returned.
2023-02-23 06:54:58 -08:00
Justine Tunney 71d955be1d Add blog link for access() impl inspiration 2023-02-23 06:54:53 -08:00
James Hulce e4ee1da652 Fix filenames in help.txt (#722)
Many functions incorrectly direct users to see a .c file, when they should be .S
2023-02-22 19:00:49 -08:00
Gavin Hayes ff9c15f48a Add APE fexecve() support (#733) 2023-02-22 18:58:23 -08:00
Gavin Hayes b275e664ec Make ZipOS mmap safer (#735)
- It now runs entirely under __mmi_lock
- Hide implementation strace
2023-02-22 18:57:36 -08:00
Paul Kulchenko e323527ffa Remove slowloris handling from Redbean (#737)
It's been superseded by token bucket processing, does not take time
into considerations (only the number of fragments), and affects file
uploads that may require a large number of reads.
2023-02-22 18:56:02 -08:00
Joshua Wierenga 08fef9b277 Fix nt path format check (#744) 2023-02-22 18:42:13 -08:00
Gavin Hayes 94dcf81954 Add glob to cocmd (#740) 2023-02-21 10:31:04 -08:00
Justine Tunney 2b6261a52d Make some system call fixes
- Fix minor ABI issue with SIOCGIFCONF
- Fix ABI translation issues with statfs() on BSDs
- Fix SQLite angled header line
2023-02-12 22:16:34 -08:00
Justine Tunney 0eb621f75e Remove non-JIT'd blink builds for now 2023-02-12 22:14:16 -08:00
Justine Tunney 9634227181 Polyfill Linux unlink() EISDIR on POSIX platforms 2023-02-05 16:50:11 -08:00
Justine Tunney 9fce2751c8 Remove problematic test 2023-02-05 16:50:04 -08:00
Justine Tunney 49c1dea03b Add msync_test 2023-02-05 16:49:52 -08:00
Justine Tunney 4b8874ceb9 Make some simple fixes 2023-02-03 02:09:15 -08:00
Justine Tunney cf19e3e46a Fix SO_LINGER on Apple 2023-02-02 20:05:37 -08:00
Justine Tunney 1429a7b3ef Fix bug in ASAN reporting 2023-02-02 02:28:58 -08:00
Justine Tunney 7486a2cd51 Perform minor cleanups 2023-02-02 02:28:58 -08:00
Gavin Hayes fd0da9c0df Implement zipos mmap (#725) 2023-02-02 02:28:50 -08:00
Paul Kulchenko 6d36584ff2 Redbean lsqlite config addition (#724)
* Fix mislabeled constant in redbean SQLite code
* Simplify callback handling in redbean SQLite
* Add config options to redbean SQLite
* Update redbean SQLite API to return current error callback
2023-01-29 19:37:19 -08:00
James Hulce f422edaf15 FIx link in gensvg demo (#723)
Code link in the gensvg demo is broken, fix that
2023-01-28 09:12:13 -08:00
Justine Tunney 1473eafd1a Fix the build and introduce some APIs
The tcgetwinsize() and tcsetwinsize() APIs are now available. The
printargs.com example also now displays the baud rate.
2023-01-20 09:25:45 -08:00
Justine Tunney cac86197cb Add fix for Blink detection 2023-01-19 09:12:49 -08:00
Justine Tunney 006c44ff5d Update tests and CPU detection for Blink 2023-01-18 00:56:09 -08:00
Justine Tunney be3e109309 Fix build break 2023-01-08 15:35:08 -08:00
Justine Tunney 2bad436abf Return error on fopen(NULL)
https://sqlite.org/forum/forumpost/d1c96a9032e564f8
2023-01-08 15:17:44 -08:00
Justine Tunney 7ab4630cc9 Fix MODE=asan build regression 2023-01-08 05:47:18 -08:00
Justine Tunney 5dab97b6d4 Implement program for finding start of zip content 2023-01-06 19:55:00 -08:00
Justine Tunney b38a442386 Add ppc64le support and improve platform detection 2023-01-06 09:14:27 -08:00
Justine Tunney 0708310041 Update the blink binaries 2023-01-05 22:50:20 -08:00
Justine Tunney cd27a53345 Support aarch64, silicon, arm, i486, riscv64, mipsel, ppc and s390x
Your APE binaries will now run on eight hardware architectures. The
tradeoff is this change adds about 800kb of bloat to the executable
which to be fair is still more than half as small as Go hello world

Your APE shell script extracts an embedded build of Blink, based on
`$(uname -m)`. The Blink binaries are statically-linked (manylinux)
which means, they'll run on every distro's stock install, including
Apple M1's that haven't enabled Rosetta. Blink's emulation has been
designed to be nearly as fast as Rosetta, using a JIT technique for
faster startup time. Blink has also been tested more thoroughly, w/
emulating Cosmopolitan software, since we're the ones who wrote it.
2023-01-05 14:29:21 -08:00
Justine Tunney 416e173448 Improve the cosmocc toolchain
These changes were necessary to help Blink become buildable using
Cosmopolitan Libc.
2023-01-05 12:20:52 -08:00
Justine Tunney d73523864a Fix bugs with Redbean Fetch() uploading
This change makes Fetch() work correctly when large bodies are supplied,
or bodies containing NUL characters are supplied.

Fixes #573
2023-01-05 09:52:36 -08:00
Justine Tunney eb69a42863 Fix --strace crashing on MacOS and Windows 2023-01-04 06:46:37 -08:00
Justine Tunney 651826b660 Update assimilate to work with modern APE format 2023-01-04 06:34:48 -08:00
Justine Tunney 6dcdf91458 Add a turfwar hilbert decoration 2023-01-03 18:28:35 -08:00
Justine Tunney a6586cafb2 Retry SQLITE_BUSY when stepping in TurfWar 2023-01-03 06:10:39 -08:00
Justine Tunney e496ee7a80 Be less pushy about redbean ddos protection 2023-01-03 05:14:34 -08:00
Justine Tunney a4b6803556 Fix recursive locks when tid is huge
It turns out Linux may assign thread ids that are much larger than
previously thought. We now have fewer bits of depth so we can have
bigger tids.
2023-01-03 05:01:00 -08:00
Justine Tunney 9c72fef086 Remove affinity tuning from IPv4 Games 2023-01-03 04:48:01 -08:00
Justine Tunney 10d1c6da18 Support argv[0] munging on Windows 2023-01-03 03:22:40 -08:00
ahgamut 5ed84e04f8 remove libc/sock/if.h
libc/sock/if.h is removed because:

- it contained only IFNAMSIZ, which was also defined in
  libc/sock/struct/ifreq.h
- it was not included in any file EXCEPT libc/isystem/net/if.h, which
  also included the libc/sock/struct/ifreq.h

hence we remove this file, and move the IFNAMSIZ definition to
libc/sock/struct/ifreq.h which is included in isystem.
2023-01-01 16:51:00 -08:00
ahgamut 25fa6acc4d check existence of IFNAMSIZ
IFNAMSIZ is defined in:

- libc/sock/if.h
- libc/sock/struct/ifreq.h

we add a check in the latter to avoid a complaint when using the
amalgamated header.
2023-01-01 16:51:00 -08:00
Ronsor 9a46c5afc4 Add a new example showing how to use hiredis. 2023-01-01 16:30:10 -08:00
Ronsor 97ae5f7b1e Fix hiredis build 2023-01-01 16:30:10 -08:00
Ronsor 1c7c277432 Include a port of the hiredis library.
SSL support is not yet included; however, everything else works
perfectly fine.
2023-01-01 16:30:10 -08:00
Danny Robinson 70ca8c4016 Update redbean lsqlite definitions (#709) 2023-01-01 16:28:34 -08:00
tkchiaandtkchia 73507d5f4e Add some definitions for Linux frame buffer/console ioctl APIs (#712)
Co-authored-by: tkchia <[email protected]>
2023-01-01 16:28:03 -08:00
Ronsor d2f811eff3 Add support for the -i (include headers) and -d (POST data) options in curl.com (#708)
This commit also paves the way for initial IPv6 support in `curl.com` by specifying
`AF_UNSPEC` for the address family in the hints passed to `getaddrinfo()`.
2022-12-23 17:06:48 -08:00
Justine Tunney 2e5181666f Fix the build 2022-12-21 23:06:55 -08:00
Gavin Hayes 5c0ce6b83e Add note about APE loader and noexec mounts (#707) 2022-12-21 23:00:51 -08:00
Ronsor f6b3019796 Make curl example into a complete tool (#706)
You can now handily use `curl` with popen()/system() by
placing `STATIC_YOINK("_curl")` in your main source file.
2022-12-21 16:12:02 -08:00
Justine Tunney dd04aeba1c Increase stack size to 128k and guard size to 16k
This improves our compatibility with Apple M1.
2022-12-18 22:58:29 -08:00
Justine Tunney 57c0dcdc29 Decrease TurfWar background query intervals
The database is much larger than it was when we started, so these
background reporting queries have become much more expensive than
before. We also had someone make 750k claims in one day, and even
hundreds of thousands per hour, which broke our assumptions about
hourly / daily reports being cheap.
2022-12-18 02:23:12 -08:00
Justine Tunney 6d39c6f646 Have redbean avoid gzip when emulated without jit 2022-12-18 02:22:58 -08:00
Justine Tunney 5a3c646307 Fix sysinfo() totalram on XNU
HW_MEMSIZE is the 64-bit version of HW_PHYSMEM, which is inaccurate on
systems having more than 4gb of RAM.
2022-12-18 02:22:46 -08:00
tkchiaandtkchia 0da47c51de [metal] Allow programs larger than 440 KiB to run in bare metal mode (#685)
* [metal] Copy program pages to extended memory at startup
* [metal] Reclaim base memory pages for later app use
* [metal] Load program pages beyond 1st 440 KiB to extended memory

o//examples/hellolua.com now runs correctly under QEMU (in
legacy BIOS mode).

* [metal] Place GDT in read/write segment

The CPU absolutely needs to alter the GDT when loading the
task register (via ltr).  To account for this, I move the
GDT into a read/write data section.  There is still a "rump"
read-only GDT in the text section that is used by the real
mode bootloader.

We also delay the loading of the task register (ltr) until
after the IDT and TSS are finally set up.

* [metal] Get examples/vga2.c serial output working for UEFI boot
* [metal] Get examples/vga2.c VGA output working for UEFI boot
* [metal] Allow munmap() to reclaim dynamically allocated pages
* Place TLS sections right after .text, not after embedded zip file

Co-authored-by: tkchia <[email protected]>
2022-12-17 17:51:20 -08:00
Justine Tunney 120079b0a6 Remove evil constants from cosmopolitan.h
- `I` a.k.a. `_Complex_I` (fixes #705)
- `B0`, `B50`, etc. (fixes #403)
2022-12-17 00:42:45 -08:00
Justine Tunney 3da887c58f Introduce CPUID detection for Blink 2022-12-17 00:38:07 -08:00
Justine Tunney 4922bc4890 Fix SQLite3 build for Landlock Make 2022-12-11 14:49:53 -08:00
Justine Tunney ed161b240e Clean up some code 2022-12-11 14:30:59 -08:00
Justine Tunney 531bfbd61f Fix DNS resolution w/ commas in Windows Registry 2022-12-11 14:30:59 -08:00
Paul Kulchenko cd0b12ed1a Add diff and iterator to SQLite session (#700) 2022-11-28 13:40:04 -08:00
Paul Kulchenko 0dc0758574 Upgrade SQLite to 3.40 (#699) 2022-11-28 12:54:48 -08:00
Paul Kulchenko bcae817215 Update SQLite deserialize to allow resizing restored DB (#701)
Using either option (FREEONCLOSE or RESIZEABLE) requires using
sqlite3_malloc. Ref. #436
2022-11-28 12:53:20 -08:00
Justine Tunney b850b14300 Improve cosmocc / cosmoc++ toolchains
They'll now automatically create empty static archives for system
libraries that are provided by Cosmopolitan Libc. This helps make
configure scripts less confused. Musl does the same thing.
2022-11-14 13:45:57 -08:00
Justine Tunney a277170c9a Make kprintf_test resistant to limbo 2022-11-13 14:26:19 -08:00
Justine Tunney 711bd095db Import exuberant ctags 2022-11-13 13:26:28 -08:00
Justine Tunney d55b019284 Fix the build 2022-11-11 11:13:21 -08:00
Justine Tunney f2af97711b Make improvements
- Improve compatibility with Blink virtual machine
- Add non-POSIX APIs for joining threads and signal masks
- Never ever use anything except 32-bit integers for atomics
- Add some `#undef` statements to workaround `ctags` problems
2022-11-10 21:52:47 -08:00
Justine Tunney b46ac13504 Introduce new jartsr=' ape prefix
Files beginning with "MZqFpD" are Actually Portable Executables,
which have a printf statement in the first 4096 bytes with octal
codes that specify the ELF header. APE also specifies `jartsr='`
as an alternative prefix, intended for binaries that do not want
to be identified as Windows executables. Like the \177ELF magic,
all these prefixes decode as x86 jump instructions that could be
used for 16-bit bootloaders or 32-bit / 64-bit flat executables.
Most importantly they provide a fallback path for Thompson shell
copmatible command interpreters, which do not require a shebang,
e.g. bash, zsh, fish, bourne, almquist, etc. Please note that in
order to meet the requirements of POSIX.1, the single quote must
be followed by a newline character, before any null bytes occur.
See also: https://www.austingroupbugs.net/view.php?id=1250
2022-11-10 21:18:32 -08:00
Justine Tunney cee6871710 Make detached threads work better
This change adds a double linked list of threads, so that pthread_exit()
will know when it should call exit() from an orphaned child. This change
also improves ftrace and strace logging.
2022-11-09 03:58:57 -08:00
Justine Tunney b74d8c1acd Remove unnecessary STRACE() statement 2022-11-08 15:33:16 -08:00
Justine Tunney fc595a7111 Fix build
libc/integral changes aren't checked in the build dependency, due to
being explicitly listed in .UNVEIL, which is how this breakage ended
up accidentally slipping through the cracks.
2022-11-08 15:24:17 -08:00
Justine Tunney bf7843833f Rename hidden keyword to _Hide 2022-11-08 12:55:28 -08:00
Paul Kulchenko 251dcb07eb Add redbean sqlite session support (#680) 2022-11-08 12:53:37 -08:00
Justine Tunney b407327972 Make fixes and improvements
- clock_nanosleep() is now much faster on OpenBSD and NetBSD
- Thread joining is now much faster on NetBSD
- FreeBSD timestamps are now more accurate
- Thread spawning now goes faster on XNU
- Clean up the clone() code
2022-11-08 10:11:46 -08:00
Justine Tunney aee50b1327 Fix test breakage 2022-11-07 06:31:30 -08:00
Justine Tunney 4de2cf34e6 Allow HTTP range past EOF
Fixes #683
2022-11-07 05:52:24 -08:00
838 changed files with 79868 additions and 28628 deletions

No files matched your search

+1
View File
@@ -8,6 +8,7 @@ AlwaysBreakBeforeMultilineStrings: false
AllowShortFunctionsOnASingleLine: false
KeepEmptyLinesAtTheStartOfBlocks: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
IncludeBlocks: Merge
---
Language: Cpp
AllowShortFunctionsOnASingleLine: false
+19 -17
View File
@@ -60,7 +60,7 @@
# build/config.mk
SHELL = build/bootstrap/cocmd.com
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10 win10:31336
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10
MAKEFLAGS += --no-builtin-rules
.SUFFIXES:
@@ -121,6 +121,7 @@ include libc/tinymath/tinymath.mk # │ You can issue raw system calls
include third_party/compiler_rt/compiler_rt.mk # │
include libc/str/str.mk # │
include third_party/xed/xed.mk # │
include third_party/puff/puff.mk # │
include third_party/zlib/zlib.mk # │
include third_party/double-conversion/dc.mk # │
include libc/elf/elf.mk # │
@@ -134,11 +135,11 @@ include libc/crt/crt.mk # │ You can issue system calls
include third_party/nsync/nsync.mk # │
include third_party/dlmalloc/dlmalloc.mk #─┘
include libc/mem/mem.mk #─┐
include libc/zipos/zipos.mk # ├──DYNAMIC RUNTIME
include third_party/gdtoa/gdtoa.mk # │ You can now use stdio
include libc/time/time.mk # │ You can finally call malloc()
include third_party/nsync/mem/mem.mk # │
include libc/thread/thread.mk # │
include third_party/gdtoa/gdtoa.mk # ├──DYNAMIC RUNTIME
include third_party/nsync/mem/mem.mk # │ You can now use stdio
include libc/thread/thread.mk # │ You can finally call malloc()
include libc/zipos/zipos.mk # │
include libc/time/time.mk # │
include libc/stdio/stdio.mk # │
include third_party/libcxx/libcxx.mk # │
include net/net.mk # │
@@ -175,7 +176,9 @@ include third_party/lua/lua.mk
include third_party/tr/tr.mk
include third_party/sed/sed.mk
include third_party/awk/awk.mk
include third_party/hiredis/hiredis.mk
include third_party/make/make.mk
include third_party/ctags/ctags.mk
include third_party/finger/finger.mk
include third_party/argon2/argon2.mk
include third_party/smallz4/smallz4.mk
@@ -192,6 +195,7 @@ include third_party/python/python.mk
include tool/build/emucrt/emucrt.mk
include tool/build/emubin/emubin.mk
include tool/build/build.mk
include tool/curl/curl.mk
include examples/examples.mk
include examples/pyapp/pyapp.mk
include examples/pylife/pylife.mk
@@ -278,14 +282,14 @@ o/$(MODE)/hdrs-old.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
TAGS: private .UNSANDBOXED = 1
TAGS: o/$(MODE)/srcs-old.txt $(SRCS)
TAGS: o/$(MODE)/srcs-old.txt $(SRCS) o/$(MODE)/third_party/ctags/ctags.com
@$(RM) $@
@$(TAGS) $(TAGSFLAGS) -L $< -o $@
@o/$(MODE)/third_party/ctags/ctags.com $(TAGSFLAGS) -L $< -o $@
HTAGS: private .UNSANDBOXED = 1
HTAGS: o/$(MODE)/hdrs-old.txt $(HDRS)
HTAGS: o/$(MODE)/hdrs-old.txt $(HDRS) o/$(MODE)/third_party/ctags/ctags.com
@$(RM) $@
@build/htags -L $< -o $@
@build/htags o/$(MODE)/third_party/ctags/ctags.com -L $< -o $@
loc: private .UNSANDBOXED = 1
loc: o/$(MODE)/tool/build/summy.com
@@ -306,7 +310,6 @@ COSMOPOLITAN_OBJECTS = \
LIBC_LOG \
LIBC_TIME \
LIBC_ZIPOS \
THIRD_PARTY_ZLIB \
THIRD_PARTY_MUSL \
LIBC_STDIO \
THIRD_PARTY_GDTOA \
@@ -332,6 +335,7 @@ COSMOPOLITAN_OBJECTS = \
LIBC_NT_ADVAPI32 \
LIBC_NT_SYNCHRONIZATION \
LIBC_FMT \
THIRD_PARTY_PUFF \
THIRD_PARTY_COMPILER_RT \
LIBC_TINYMATH \
THIRD_PARTY_XED \
@@ -371,11 +375,9 @@ COSMOPOLITAN_HEADERS = \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
THIRD_PARTY_MUSL \
THIRD_PARTY_ZLIB \
THIRD_PARTY_ZLIB_GZ \
THIRD_PARTY_REGEX
o/$(MODE)/cosmopolitan.a: \
o/$(MODE)/cosmopolitan.a: \
$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_A_OBJS))
o/cosmopolitan.h: \
@@ -438,9 +440,9 @@ $(SRCS):
$(HDRS):
$(INCS):
.DEFAULT:
@$(ECHO) >&2
@$(ECHO) NOTE: deleting o/$(MODE)/depend because of an unspecified prerequisite: $@ >&2
@$(ECHO) >&2
@$(ECHO)
@$(ECHO) NOTE: deleting o/$(MODE)/depend because of an unspecified prerequisite: $@
@$(ECHO)
$(RM) o/$(MODE)/depend
-include o/$(MODE)/depend
+12 -3
View File
@@ -57,9 +57,13 @@ sudo sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/status'
Since we used the `ape-no-modify-self.o` bootloader (rather than
`ape.o`) your executable will not modify itself when it's run. What
it'll instead do, is extract a 4kb program to `${TMPDIR:-${HOME:-.}}`
that maps your program into memory without needing to copy it. It's
possible to install the APE loader systemwide as follows.
it'll instead do, is extract a 4kb program (the [APE loader](https://justine.lol/apeloader/))
to `${TMPDIR:-${HOME:-.}}` that maps your program into memory without
needing to copy it. The APE loader must be in an executable location
(e.g. not stored on a `noexec` mount) for it to run. See below for
alternatives:
It's possible to install the APE loader systemwide as follows.
```sh
# System-Wide APE Install
@@ -239,6 +243,11 @@ You normally run the `.com.dbg` file under gdb. If you need to debug the
gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000'
```
## Discord Chatroom
The Cosmopolitan development team collaborates on the Redbean Discord
server. You're welcome to join us! <https://discord.gg/FwAVVu7eJ4>
## Support Vector
| Platform | Min Version | Circa |
+305 -68
View File
@@ -116,11 +116,29 @@ cstr: .endobj cstr,globl,hidden # ←for gdb readability
ape_mz:
#if SupportsWindows() || SupportsMetal()
.asciz "MZqFpD='\n" # Mark 'Zibo' Joseph Zbikowski
// # in real mode
// dec %bp
// pop %dx
// jno 0x4a
// jo 0x4a
//
// # in legacy mode
// push %ebp
// pop %edx
// jno 0x4a
// jo 0x4a
//
// # 64-bit mode
// rex.WRB
// pop %r10
// jno 0x4a
// jo 0x4a
#else
// Avoid virus scanner reputation damage when targeting System Five.
// WARNING: This prefix is experimental; it may be removed sometime.
// TODO(jart): Find another prefix that will work with BIOS loading.
.asciz "JTqFpD='\n" # Mark 'Zibo' Joseph Zbikowski
.asciz "jartsr='\n" # Justine Alexandra Roberts Tunney
// push $0x61
// jb 0x78
// jae 0x78
#endif
.short 0x1000 # MZ: lowers upper bound load / 16
.short 0xf800 # MZ: roll greed on bss
@@ -140,6 +158,9 @@ ape_mz:
.long RVA(ape_pe) # PE: the new technology
#else
.long 0
.org 0x78
pop %rax
jmp _start
#endif
.endfn ape_mz,globl,hidden
@@ -261,6 +282,9 @@ pc: cld
xor %dh,%dh # current head
mov $v_ape_realsectors,%di # total sectors
3: call pcread
mov %es,%si # addr += 512
add $512>>4,%si
mov %si,%es
dec %di
jnz 3b
6: ljmp $0,$REAL(realmodeloader)
@@ -349,6 +373,7 @@ dsknfo: push %bx
pop %ds
xchg %bx,%ax
stosw #→ pc_drive_type, pc_drive_last_sector
scasb
xchg %cx,%ax
stosw #→ pc_drive_last_cylinder
xchg %dx,%ax
@@ -387,9 +412,6 @@ pcread: push %ax
pop %cx
pop %ax
jc 9f
mov %es,%si # addr += 512
add $512>>4,%si
mov %si,%es
inc %al # ++sector
cmp mm+"struct mman::pc_drive_last_sector",%al
jbe 2f
@@ -559,6 +581,9 @@ ape_disk:
#if SupportsWindows() || SupportsMetal() || SupportsXnu()
apesh: .ascii "\n@\n#'\"\n" # sixth edition shebang
.ascii "m=\"$(uname -m)\"\n"
.ascii "if [ \"$m\" = x86_64 ] || [ \"$m\" = amd64 ]; then\n"
// Until all operating systems can be updated to support APE,
// we have a beautiful, yet imperfect workaround, which is to
// modify the binary to follow the local system's convention.
@@ -660,17 +685,99 @@ apesh: .ascii "\n@\n#'\"\n" # sixth edition shebang
.ascii "o=\"$t\"\n"
.ascii "exec \"$o\" \"$@\"\n"
#endif /* APE_NO_MODIFY_SELF */
.ascii "R=$?\n"
.ascii "if [ \"$(uname -m)\" != x86_64 ]; then\n"
.ascii "Q=\"$(command -v qemu-x86_64)\" &&\n"
.ascii "exec \"$Q\" \"$o\" \"$@\"\n"
#ifndef APE_NO_MODIFY_SELF
.ascii "else\n" # means argv[0] was wrong
.ascii " exec \"$o\" \"$@\"\n" # so do a path resolution
#endif /* APE_NO_MODIFY_SELF */
.ascii "exit $?\n"
.ascii "fi\n"
.ascii "exit $R\n"
.ascii "PHDRS='' <<'@'\n"
.endobj apesh
// elf program headers get inserted here
// because they need to be in the first 4096 bytes
.section .emush,"a",@progbits
emush: .ascii "\n@\n#'\"\n"
.ascii "s=\"$(uname -s)\"\n"
// our script is running on a non-x86_64 architecture
// 1. `dd` out the appropriate blink vm blob
// 2. gunzip the blink virtual machine executable
// 3. relaunch this program inside the blink vm
.ascii "o=\"$(command -v \"$0\")\"\n"
.ascii "e=\"${TMPDIR:-${HOME:-.}}/.ape-blink-0.9.2\"\n"
// Blink for Apple Silicon, e.g. M1 Macbook
.ascii "if [ \"$s\" = Darwin ] && [ \"$m\" = arm64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-darwin-arm64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_darwin_arm64_b9
.byte blink_darwin_arm64_b8
.byte blink_darwin_arm64_b7
.byte blink_darwin_arm64_b6
.byte blink_darwin_arm64_b5
.byte blink_darwin_arm64_b4
.byte blink_darwin_arm64_b3
.byte blink_darwin_arm64_b2
.byte blink_darwin_arm64_b1
.byte blink_darwin_arm64_b0
.ascii ")) count=$(("
.byte blink_darwin_arm64_size_b9
.byte blink_darwin_arm64_size_b8
.byte blink_darwin_arm64_size_b7
.byte blink_darwin_arm64_size_b6
.byte blink_darwin_arm64_size_b5
.byte blink_darwin_arm64_size_b4
.byte blink_darwin_arm64_size_b3
.byte blink_darwin_arm64_size_b2
.byte blink_darwin_arm64_size_b1
.byte blink_darwin_arm64_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
// Blink for Aarch64 Linux, e.g. Raspberry Pi
.ascii "if [ \"$s\" = Linux ]; then\n"
.ascii "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-aarch64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_aarch64_b9
.byte blink_aarch64_b8
.byte blink_aarch64_b7
.byte blink_aarch64_b6
.byte blink_aarch64_b5
.byte blink_aarch64_b4
.byte blink_aarch64_b3
.byte blink_aarch64_b2
.byte blink_aarch64_b1
.byte blink_aarch64_b0
.ascii ")) count=$(("
.byte blink_aarch64_size_b9
.byte blink_aarch64_size_b8
.byte blink_aarch64_size_b7
.byte blink_aarch64_size_b6
.byte blink_aarch64_size_b5
.byte blink_aarch64_size_b4
.byte blink_aarch64_size_b3
.byte blink_aarch64_size_b2
.byte blink_aarch64_size_b1
.byte blink_aarch64_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
.ascii "fi\n"
.ascii "echo unsupported architecture >&2\n"
.rept 16
.ascii "exit 127\n"
.endr
.ascii "exit 1\n"
.endobj emush
#ifdef APE_LOADER
.section .ape.loader,"a",@progbits
.align 64
@@ -1090,6 +1197,42 @@ ape_idata_idt:
ape_idata_idtend:
.previous
.section .piro.data.sort.metal_gdt,"aw",@progbits
.align 8
_gdt:
// ┌G:granularity (1 → limit *= 0x1000)
// │┌D/B:default operation size (0 = 16|64bit, 1 = 32-bit)
// ││┌L:long mode
// │││┌AVL:this bit is thine (1<<52)
// ││││ ┌P:present
// ││││ │┌DPL:privilege
// ││││ ││ ┌─────────data/code(1)
// ││││ ││ │┌────data(0)──────code(1)
// ││││ ││ ││┌───conforming───expand-down
// ││││ ││ │││┌──writeable────readable
// ││││ ││ ││││┌─accessed─────accessed
// ││││ ││ │││││
// ││││ ┌──││─│││││───────────────────────────────┐
// ┌───││││─│──││─│││││───────────┐ │
// ┌───┴──┐││││┌┴─┐│├┐│││││┌──────────┴───────────┐┌──────┴───────┐
// │ ││││││ ││││││││││ base address││ segment limit│
// │ ││││││ ││││││││││ 32 bits││ 20 bits│
// │ ││││││ ││││││││││ ││ │
// 6666555555555544444444443333333333222222222211111111110000000000
// 3210987654321098765432109876543210987654321098765432109876543210
// │ ││││││ ││││││││││ ││ │
.quad 0b0000000000000000000000000000000000000000000000000000000000000000 # 0
.quad 0b0000000000001111100110100000000000000000000000001111111111111111 # 8
.quad 0b0000000000001111100100100000000000000000000000001111111111111111 #16
.quad 0b0000000011001111100110100000000000000000000000001111111111111111 #24
.quad 0b0000000011001111100100100000000000000000000000001111111111111111 #32
.quad 0b0000000010101111100110110000000000000000000000001111111111111111 #40
.quad 0b0000000010101111100100110000000000000000000000001111111111111111 #48
.tssdescstub _tss #56,64
_gdt_end:
.endobj _gdt,global,hidden
.previous
.section .piro.data.sort.iat.1,"aw",@progbits
.type ape_idata_iatend,@object
.type ape_idata_iat,@object
@@ -1147,48 +1290,21 @@ sconf: .short 1843200/*hz*/ / 16/*wut*/ / 9600/*baud*/
// Global Descriptor Table
.align 8
_gdtrphy:
.short 2f-1f-1 # table byte length
.long REAL(1f) # table address (physical space)
.endobj _gdtrphy,global,hidden
_gdtrlo:
.short 2f-_gdtlo-1 # table byte length
.long REAL(_gdtlo) # table address (base memory space)
.endobj _gdtrlo,global,hidden
_gdtr:
.short 2f-1f-1 # table byte length
.quad 1f # table address (final virtual space)
.short _gdt_end-_gdt-1 # table byte length
.quad _gdt # table address (final virtual space)
.endobj _gdtr,global,hidden
.align 8
_gdt:
1:
// ┌G:granularity (1 → limit *= 0x1000)
// │┌D/B:default operation size (0 = 16|64bit, 1 = 32-bit)
// ││┌L:long mode
// │││┌AVL:this bit is thine (1<<52)
// ││││ ┌P:present
// ││││ │┌DPL:privilege
// ││││ ││ ┌─────────data/code(1)
// ││││ ││ │┌────data(0)──────code(1)
// ││││ ││ ││┌───conforming───expand-down
// ││││ ││ │││┌──writeable────readable
// ││││ ││ ││││┌─accessed─────accessed
// ││││ ││ │││││
// ││││ ┌──││─│││││───────────────────────────────┐
// ┌───││││─│──││─│││││───────────┐ │
// ┌───┴──┐││││┌┴─┐│├┐│││││┌──────────┴───────────┐┌──────┴───────┐
// │ ││││││ ││││││││││ base address││ segment limit│
// │ ││││││ ││││││││││ 32 bits││ 20 bits│
// │ ││││││ ││││││││││ ││ │
// 6666555555555544444444443333333333222222222211111111110000000000
// 3210987654321098765432109876543210987654321098765432109876543210
// │ ││││││ ││││││││││ ││ │
.quad 0b0000000000000000000000000000000000000000000000000000000000000000 # 0
.quad 0b0000000000001111100110100000000000000000000000001111111111111111 # 8
.quad 0b0000000000001111100100100000000000000000000000001111111111111111 #16
.quad 0b0000000011001111100110100000000000000000000000001111111111111111 #24
// Partial GDT with descriptors for switching to unreal mode or long mode.
_gdtlo = .-GDT_LEGACY_DATA
.quad 0b0000000011001111100100100000000000000000000000001111111111111111 #32
.quad 0b0000000010101111100110110000000000000000000000001111111111111111 #40
.quad 0b0000000010101111100100110000000000000000000000001111111111111111 #48
.tssdescstub _tss #56,64
2:
.endobj _gdt,global,hidden
/*─────────────────────────────────────────────────────────────────────────────╗
│ αcτµαlly pδrταblε εxεcµταblε § real mode │
@@ -1196,6 +1312,7 @@ _gdt:
the default mode of operation on modern cpus */
realmodeloader:
call lhinit
call rlinit
call sinit4
.optfn _start16
@@ -1203,6 +1320,25 @@ realmodeloader:
call longmodeloader
.endfn realmodeloader
// Prepares to later load parts of the program that are not loaded yet.
//
// @param al next sector number
// @param cx next cylinder number
// @param dh next head number
// @param dl drive number
// @clob ax, cx, es, di
lhinit: cmp $0x40,%dl
je 9f
pushpop 0,%es
mov $mm+"struct mman::pc_drive_next_sector",%di
cld
stosb #→ pc_drive_next_sector
xchg %ax,%cx
stosw #→ pc_drive_next_cylinder
mov %dh,%al
stosb #→ pc_drive_next_head
9: ret
.section .sort.text.real.init.1,"ax",@progbits
.type rlinit,@function
rlinit: .previous/*
@@ -1263,17 +1399,19 @@ longmodeloader:
call lcheck
call a20
call e820
call cpyhi
call loadhi
call pinit
call golong
.endfn longmodeloader
// Long Mode Hardware Check
lcheck: pushf # check for i8086 / i8088 / i80186
pop %ax
test $0x80,%ah # see intel manual volume 1 20.1.2
jnz 10f # we now assume 32bit is supported
pushfl # now check for i386 or early i486
pop %eax # test ability to change cpuid bit
lcheck: pushf # checks for i8086 / i8088 / i80186
pop %ax # see intel manual volume 1 §20.1.2
test $0x80,%ah
jnz 10f # we now assume 32 bit is supported
pushfl # now check for i386, or early i486
pop %eax # tests ability to change cpuid bit
mov %eax,%ecx
mov $1<<21,%ebx
xor %ebx,%eax
@@ -1286,16 +1424,16 @@ lcheck: pushf # check for i8086 / i8088 / i80186
or %ebx,%eax # puts cpuid bit in the on position
push %eax
popfl
mov $0x80000000,%edi # get amd ext cpuid thingy length
mov $0x80000000,%edi # get amd64 ext cpuid thingy length
mov %edi,%eax
inc %edi
cpuid # clobbers eax, ebx, ecx, and edx
cpuid # leaf 0x80000000, clob ax/bx/cx/dx
cmp %edi,%eax
jl 10f
mov %edi,%eax
cpuid
mov $1<<29|1<<20,%edi # need nexgen32e long mode support
and %edi,%edx # & nx support
cpuid # leaf 0x80000001, clob ax/bx/cx/dx
mov $1<<29|1<<20,%edi # 29 = LM (long), 20 = NX (no exec)
and %edi,%edx # we need to both, or we won't work
cmp %edi,%edx
jne 10f
xor %ax,%ax
@@ -1405,10 +1543,88 @@ a20: cli
5: ret
.endfn a20
// Copies program pages loaded into base memory, to extended memory.
//
// @clob esi, edi
cpyhi: push %es
movpp %ds,%es
call unreal
mov $IMAGE_BASE_REAL,%esi
mov $IMAGE_BASE_PHYSICAL,%edi
mov $v_ape_realdwords,%ecx
cld
rep movsl %ds:(%esi),%es:(%edi)
sti
pop %es
ret
.endfn cpyhi
// Disables interrupts and switches to "unreal mode".
//
// @return ds, es have same base addresses as before but can access
// 4 GiB of memory
// @clob eax
unreal: push %ds
push %es
cli
lgdt REAL(_gdtrlo)
mov %cr0,%eax
or $CR0_PE,%al
mov %eax,%cr0
jmp 0f
0: pushpop GDT_LEGACY_DATA,%ds
movpp %ds,%es
and $~CR0_PE,%al
mov %eax,%cr0
jmp 1f
1: pop %es
pop %ds
ret
// Reads any remaining program pages into memory which have not yet
// been read by the boot sector.
//
// @clob eax, ecx, dx, esi, edi, bp
loadhi: mov $v_ape_highsectors,%bp
test %bp,%bp
jz 9f
mov $mm+"struct mman::pc_drive",%si
cld
lodsb #← pc_drive
xchg %ax,%dx
lodsw
lodsb #← pc_drive_next_sector
test %al,%al
jz 9f
xchg %ax,%cx
lodsw #← pc_drive_next_cylinder
xchg %ax,%cx
mov (%si),%dh #← pc_drive_next_head
push %es
#define SEG 0x79000
mov $IMAGE_BASE_PHYSICAL+v_ape_realbytes-SEG,%edi
push $SEG>>4
pop %es
0: call pcread
push %ax
call unreal
pop %ax
push %cx
xor %esi,%esi
xor %ecx,%ecx
mov $512/4,%cl
cld
rep movsl %es:(%esi),%es:(%edi)
sti
pop %cx
dec %bp
jnz 0b
pop %es
9: ret
// Initializes long mode paging.
pinit: push %ds
push %es
#define SEG 0x79000
mov $SEG>>4,%ax
mov %ax,%ds
mov %ax,%es
@@ -1449,7 +1665,7 @@ golong: cli
rdmsr
or $EFER_LME|EFER_SCE|EFER_NXE,%eax
wrmsr
lgdt REAL(_gdtrphy)
lgdt REAL(_gdtrlo)
mov %cr0,%eax
or $CR0_PE|CR0_PG|CR0_MP,%eax
and $~CR0_EM,%eax
@@ -1459,7 +1675,9 @@ golong: cli
// Long mode is long.
.code64
long: xor %eax,%eax
long: movabs $BANE+PHYSICAL(0f),%rax
jmp *%rax
0: xor %eax,%eax
mov $GDT_LONG_DATA,%al
mov %eax,%ds
mov %eax,%ss
@@ -1467,18 +1685,16 @@ long: xor %eax,%eax
mov %eax,%fs
mov %eax,%gs
mov $0x80000,%esp
mov $GDT_LONG_TSS,%al
ltr %ax
xor %r12d,%r12d
xor %r13d,%r13d
xor %r14d,%r14d
xor %r15d,%r15d
xor %ebx,%ebx
xor %ebp,%ebp
push %rbp
mov $mm,%rdi
mov %cr3,%rsi
mov $IMAGE_BASE_REAL,%edx
mov $IMAGE_BASE_PHYSICAL,%edx
lea v_ape_allbytes(%rdx),%ecx
call __map_phdrs
push $0x037f
fldcw (%rsp)
@@ -1564,6 +1780,10 @@ kernel: movabs $ape_stack_vaddr,%rsp
.byte 0x0f,0x1f,0207 # nop rdi binbase
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
#endif
movabs $BANE+mm,%rdi
mov $0x79000,%esi
mov $0x7f000,%edx
call __reclaim_boot_pages
push $_HOSTMETAL # sets __hostos in crt.S
pop %rcx
pushq .Lenv0(%rip) # envp[0][0]
@@ -1609,6 +1829,7 @@ kernel: movabs $ape_stack_vaddr,%rsp
.ldsvar _end
.ldsvar _etext
.ldsvar v_ape_realsectors
.ldsvar v_ape_realbytes
.ldsvar v_ape_highsectors
.ldsvar ape_idata_ro
.ldsvar ape_pad_rodata
@@ -1702,5 +1923,21 @@ __bss_start:
__bss_end:
.previous
.section .blink,"a",@progbits
.globl blink_aarch64_size
blink_aarch64:
.incbin "ape/blink-aarch64.gz"
.endobj blink_aarch64,globl
blink_aarch64_size = . - blink_aarch64
.previous
.section .blink,"a",@progbits
.globl blink_darwin_arm64_size
blink_darwin_arm64:
.incbin "ape/blink-darwin-arm64.gz"
.endobj blink_darwin_arm64,globl
blink_darwin_arm64_size = . - blink_darwin_arm64
.previous
.end

+82 -32
View File
@@ -216,6 +216,8 @@ SECTIONS {
KEEP(*(.elf.phdrs))
HIDDEN(ape_phdrs_end = .);
KEEP(*(.emush))
/* OpenBSD */
. = ALIGN(__SIZEOF_POINTER__);
HIDDEN(ape_note = .);
@@ -273,6 +275,7 @@ SECTIONS {
KEEP(*(.textwindowsprologue))
*(.text.windows)
KEEP(*(.textwindowsepilogue))
KEEP(*(.blink))
*(SORT_BY_ALIGNMENT(.text.modernity))
*(SORT_BY_ALIGNMENT(.text.modernity.*))
*(SORT_BY_ALIGNMENT(.text.hot))
@@ -349,9 +352,30 @@ SECTIONS {
HIDDEN(_etext = .);
PROVIDE_HIDDEN(etext = .);
/*END: Read Only Data (only needed for initialization) */
/*END: Read Only Data */
} :Rom
/* initialization image for thread-local storage, this is copied */
/* out to actual TLS areas at runtime, so just make it read-only */
.tdata . : {
_tdata_start = .;
*(SORT_BY_ALIGNMENT(.tdata))
*(SORT_BY_ALIGNMENT(.tdata.*))
_tdata_end = .;
. = ALIGN(PAGESIZE);
} :Tls :Rom
/*END: Read Only Data */
/* this only tells the linker about the layout of uninitialized */
/* TLS data, and does not advance the linker's location counter */
.tbss . : {
_tbss_start = .;
*(SORT_BY_ALIGNMENT(.tbss))
*(SORT_BY_ALIGNMENT(.tbss.*))
. = ALIGN(TLS_ALIGNMENT);
/* the %fs register is based on this location */
_tbss_end = .;
} :Tls
.data ALIGN(PAGESIZE) : {
/*BEGIN: Read/Write Data */
KEEP(*(SORT_BY_NAME(.piro.data.sort.iat.*)))
@@ -385,26 +409,7 @@ SECTIONS {
. = ALIGN(PAGESIZE);
} :Ram
.tdata . : {
_tdata_start = .;
*(SORT_BY_ALIGNMENT(.tdata))
*(SORT_BY_ALIGNMENT(.tdata.*))
_tdata_end = .;
. = ALIGN(PAGESIZE);
} :Tls :Ram
/*END: file content that's loaded by o/s */
/*BEGIN: bss memory void */
.tbss . : {
_tbss_start = .;
*(SORT_BY_ALIGNMENT(.tbss))
*(SORT_BY_ALIGNMENT(.tbss.*))
. = ALIGN(TLS_ALIGNMENT);
/* the %fs register is based on this location */
_tbss_end = .;
} :Tls
/*END: file content */
/*BEGIN: bss memory that's addressable */
@@ -509,7 +514,7 @@ HIDDEN(ape_rom_rva = RVA(ape_rom_vaddr));
HIDDEN(ape_ram_offset = ape_rom_offset + ape_rom_filesz);
HIDDEN(ape_ram_vaddr = ADDR(.data));
HIDDEN(ape_ram_paddr = LOADADDR(.data));
HIDDEN(ape_ram_filesz = SIZEOF(.data) + SIZEOF(.tdata));
HIDDEN(ape_ram_filesz = SIZEOF(.data));
HIDDEN(ape_ram_memsz = ADDR(.bss) + SIZEOF(.bss) - ape_ram_vaddr);
HIDDEN(ape_ram_align = PAGESIZE);
HIDDEN(ape_ram_rva = RVA(ape_ram_vaddr));
@@ -533,16 +538,16 @@ HIDDEN(ape_note_align = __SIZEOF_POINTER__);
HIDDEN(ape_text_offset = ape_rom_offset + LOADADDR(.text) - ape_rom_paddr);
HIDDEN(ape_text_paddr = LOADADDR(.text));
HIDDEN(ape_text_vaddr = ADDR(.text));
HIDDEN(ape_text_filesz = SIZEOF(.text));
HIDDEN(ape_text_memsz = SIZEOF(.text));
HIDDEN(ape_text_filesz = SIZEOF(.text) + SIZEOF(.tdata));
HIDDEN(ape_text_memsz = SIZEOF(.text) + SIZEOF(.tdata));
HIDDEN(ape_text_align = PAGESIZE);
HIDDEN(ape_text_rva = RVA(ape_text_vaddr));
HIDDEN(ape_data_offset = ape_ram_offset + LOADADDR(.data) - ape_ram_paddr);
HIDDEN(ape_data_paddr = LOADADDR(.data));
HIDDEN(ape_data_vaddr = ADDR(.data));
HIDDEN(ape_data_filesz = SIZEOF(.data) + SIZEOF(.tdata));
HIDDEN(ape_data_memsz = SIZEOF(.data) + SIZEOF(.tdata));
HIDDEN(ape_data_filesz = SIZEOF(.data));
HIDDEN(ape_data_memsz = SIZEOF(.data));
HIDDEN(ape_data_align = PAGESIZE);
HIDDEN(ape_data_rva = RVA(ape_data_vaddr));
@@ -562,13 +567,58 @@ SHSTUB2(ape_loader_dd_count,
? ROUNDUP(ape_loader_end - ape_loader, PAGESIZE) / 64
: 0);
HIDDEN(blink_aarch64_b0 = RVA(blink_aarch64) % 10 + 48);
HIDDEN(blink_aarch64_b1 = RVA(blink_aarch64) < 10 ? 32 : RVA(blink_aarch64) / 10 % 10 + 48);
HIDDEN(blink_aarch64_b2 = RVA(blink_aarch64) < 100 ? 32 : RVA(blink_aarch64) / 100 % 10 + 48);
HIDDEN(blink_aarch64_b3 = RVA(blink_aarch64) < 1000 ? 32 : RVA(blink_aarch64) / 1000 % 10 + 48);
HIDDEN(blink_aarch64_b4 = RVA(blink_aarch64) < 10000 ? 32 : RVA(blink_aarch64) / 10000 % 10 + 48);
HIDDEN(blink_aarch64_b5 = RVA(blink_aarch64) < 100000 ? 32 : RVA(blink_aarch64) / 100000 % 10 + 48);
HIDDEN(blink_aarch64_b6 = RVA(blink_aarch64) < 1000000 ? 32 : RVA(blink_aarch64) / 1000000 % 10 + 48);
HIDDEN(blink_aarch64_b7 = RVA(blink_aarch64) < 10000000 ? 32 : RVA(blink_aarch64) / 10000000 % 10 + 48);
HIDDEN(blink_aarch64_b8 = RVA(blink_aarch64) < 100000000 ? 32 : RVA(blink_aarch64) / 100000000 % 10 + 48);
HIDDEN(blink_aarch64_b9 = RVA(blink_aarch64) < 1000000000 ? 32 : RVA(blink_aarch64) / 1000000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b0 = blink_aarch64_size % 10 + 48);
HIDDEN(blink_aarch64_size_b1 = blink_aarch64_size < 10 ? 32 : blink_aarch64_size / 10 % 10 + 48);
HIDDEN(blink_aarch64_size_b2 = blink_aarch64_size < 100 ? 32 : blink_aarch64_size / 100 % 10 + 48);
HIDDEN(blink_aarch64_size_b3 = blink_aarch64_size < 1000 ? 32 : blink_aarch64_size / 1000 % 10 + 48);
HIDDEN(blink_aarch64_size_b4 = blink_aarch64_size < 10000 ? 32 : blink_aarch64_size / 10000 % 10 + 48);
HIDDEN(blink_aarch64_size_b5 = blink_aarch64_size < 100000 ? 32 : blink_aarch64_size / 100000 % 10 + 48);
HIDDEN(blink_aarch64_size_b6 = blink_aarch64_size < 1000000 ? 32 : blink_aarch64_size / 1000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b7 = blink_aarch64_size < 10000000 ? 32 : blink_aarch64_size / 10000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b8 = blink_aarch64_size < 100000000 ? 32 : blink_aarch64_size / 100000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b9 = blink_aarch64_size < 1000000000 ? 32 : blink_aarch64_size / 1000000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b0 = RVA(blink_darwin_arm64) % 10 + 48);
HIDDEN(blink_darwin_arm64_b1 = RVA(blink_darwin_arm64) < 10 ? 32 : RVA(blink_darwin_arm64) / 10 % 10 + 48);
HIDDEN(blink_darwin_arm64_b2 = RVA(blink_darwin_arm64) < 100 ? 32 : RVA(blink_darwin_arm64) / 100 % 10 + 48);
HIDDEN(blink_darwin_arm64_b3 = RVA(blink_darwin_arm64) < 1000 ? 32 : RVA(blink_darwin_arm64) / 1000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b4 = RVA(blink_darwin_arm64) < 10000 ? 32 : RVA(blink_darwin_arm64) / 10000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b5 = RVA(blink_darwin_arm64) < 100000 ? 32 : RVA(blink_darwin_arm64) / 100000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b6 = RVA(blink_darwin_arm64) < 1000000 ? 32 : RVA(blink_darwin_arm64) / 1000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b7 = RVA(blink_darwin_arm64) < 10000000 ? 32 : RVA(blink_darwin_arm64) / 10000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b8 = RVA(blink_darwin_arm64) < 100000000 ? 32 : RVA(blink_darwin_arm64) / 100000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b9 = RVA(blink_darwin_arm64) < 1000000000 ? 32 : RVA(blink_darwin_arm64) / 1000000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b0 = blink_darwin_arm64_size % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b1 = blink_darwin_arm64_size < 10 ? 32 : blink_darwin_arm64_size / 10 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b2 = blink_darwin_arm64_size < 100 ? 32 : blink_darwin_arm64_size / 100 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b3 = blink_darwin_arm64_size < 1000 ? 32 : blink_darwin_arm64_size / 1000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b4 = blink_darwin_arm64_size < 10000 ? 32 : blink_darwin_arm64_size / 10000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b5 = blink_darwin_arm64_size < 100000 ? 32 : blink_darwin_arm64_size / 100000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b6 = blink_darwin_arm64_size < 1000000 ? 32 : blink_darwin_arm64_size / 1000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b7 = blink_darwin_arm64_size < 10000000 ? 32 : blink_darwin_arm64_size / 10000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b8 = blink_darwin_arm64_size < 100000000 ? 32 : blink_darwin_arm64_size / 100000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b9 = blink_darwin_arm64_size < 1000000000 ? 32 : blink_darwin_arm64_size / 1000000000 % 10 + 48);
#if SupportsMetal()
HIDDEN(v_ape_realsectors =
MIN(0x70000 - IMAGE_BASE_REAL,
ROUNDUP(RVA(_tdata_end), 512)) / 512);
HIDDEN(v_ape_realpages = v_ape_realsectors / (4096 / 512));
HIDDEN(v_ape_highsectors =
(ROUNDUP(RVA(_tdata_end), 512) / 512) - v_ape_realsectors);
MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512);
HIDDEN(v_ape_realbytes = v_ape_realsectors * 512);
HIDDEN(v_ape_realdwords = v_ape_realsectors * (512 / 4));
HIDDEN(v_ape_allsectors = ROUNDUP(RVA(_ezip), 512) / 512);
HIDDEN(v_ape_allbytes = v_ape_allsectors * 512);
HIDDEN(v_ape_highsectors = MIN(0xffff, v_ape_allsectors - v_ape_realsectors));
TSSDESCSTUB2(_tss, _tss, _tss_end ? _tss_end - _tss - 1 : 0);
#endif
@@ -651,7 +701,7 @@ CHURN(ADDR(.bss));
CHURN(_start);
CHURN(ape_phdrs);
#if SupportsMetal()
CHURN(v_ape_realsectors);
CHURN(v_ape_allsectors);
#endif
#if SupportsXnu()
CHURN(ape_macho);
@@ -715,7 +765,7 @@ ASSERT(IS2POW(ape_stack_memsz),
"ape_stack_memsz must be a two power");
ASSERT(ape_stack_vaddr % ape_stack_memsz == 0,
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 - ape_stack_memsz);");
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 & -ape_stack_memsz);");
ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT,
"_Thread_local _Alignof can't exceed TLS_ALIGNMENT");
+9 -1
View File
@@ -96,6 +96,10 @@ o/ape/idata.inc: \
ape/idata.internal.h \
ape/relocations.h
o/$(MODE)/ape/ape.o: \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz
o/$(MODE)/ape/ape-no-modify-self.o: \
ape/ape.S \
ape/macros.internal.h \
@@ -115,6 +119,8 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
libc/runtime/pc.internal.h \
libc/runtime/symbolic.h \
libc/sysv/consts/prot.h \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz \
o/$(MODE)/ape/ape.elf
@$(COMPILE) \
-AOBJECTIFY.S \
@@ -141,7 +147,9 @@ o/$(MODE)/ape/ape-copy-self.o: \
libc/runtime/mman.internal.h \
libc/runtime/pc.internal.h \
libc/runtime/symbolic.h \
libc/sysv/consts/prot.h
libc/sysv/consts/prot.h \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz
@$(COMPILE) \
-AOBJECTIFY.S \
$(OBJECTIFY.S) \
+2 -2
View File
@@ -97,8 +97,8 @@ if [ x"$(uname -s)" = xLinux ]; then
echo you may need to edit configs to persist across reboot >&2
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo '$SUDO sh -c "echo '"'"':APE-sysv:M::JTqFpD::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE-sysv:M::JTqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo '$SUDO sh -c "echo '"'"':APE-jart:M::jartsr::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo done >&2
if [ x"$(cat /proc/sys/fs/binfmt_misc/status)" = xdisabled ]; then
+8 -10
View File
@@ -8,21 +8,19 @@ fi
{
echo
echo "APE Uninstaller intends to run"
echo "APE Uninstaller intends to run (in pseudo-shell)"
echo
echo " $SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE'"
echo " $SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE-sysv'"
echo " $SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape /tmp/.ape"
echo " sudo echo -1 into /proc/sys/fs/binfmt_misc/APE*"
echo " sudo rm -f /usr/bin/ape ~/.ape o/tmp/.ape /tmp/.ape"
echo
echo "You may then use ape/apeinstall.sh to reinstall it"
echo
} >&2
set -ex
if [ -f /proc/sys/fs/binfmt_misc/APE ]; then
$SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE' || exit
fi
if [ -f /proc/sys/fs/binfmt_misc/APE-sysv ]; then
$SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE-sysv' || exit
fi
for f in /proc/sys/fs/binfmt_misc/APE*; do
if [ -f $f ]; then
$SUDO sh -c "echo -1 >$f" || exit
fi
done
$SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape o/tmp/ape /tmp/.ape /tmp/ape || exit
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
-1
View File
@@ -45,7 +45,6 @@
LC_ALL = C
SOURCE_DATE_EPOCH = 0
TAGS ?= /usr/bin/ctags # emacs source builds or something breaks it
ARFLAGS = rcsD
ZFLAGS ?=
XARGS ?= xargs -P4 -rs8000
+4 -1
View File
@@ -43,6 +43,9 @@
# '(progn
# (add-hook 'c-mode-common-hook 'jart-c-mode-common-hook)))
TAGS="$1"
shift
# ctags doesn't understand atomics, e.g.
# extern char **environ;
set -- --regex-c='/_Atomic(\([^)]*\))/\1/b' "$@"
@@ -63,7 +66,7 @@ set -- --regex-c='/^extern [^(]*(\*const \([^)]*\))(/\1/b' "$@"
# struct WorstSoftwareEver;
set -- --regex-c='/^struct.*;$/uehocruehcroue/b' "$@"
exec ${TAGS:-ctags} \
exec $TAGS \
-e \
--langmap=c:.c.h \
--exclude=libc/nt/struct/imagefileheader.internal.h \
+2
View File
@@ -38,10 +38,12 @@ int main(int argc, char *argv[]) {
show(CLOCK_REALTIME);
show(CLOCK_REALTIME_FAST);
show(CLOCK_REALTIME_PRECISE);
show(CLOCK_REALTIME_COARSE);
show(CLOCK_MONOTONIC);
show(CLOCK_MONOTONIC_RAW);
show(CLOCK_MONOTONIC_FAST);
show(CLOCK_MONOTONIC_PRECISE);
show(CLOCK_MONOTONIC_COARSE);
show(CLOCK_PROCESS_CPUTIME_ID);
show(CLOCK_THREAD_CPUTIME_ID);
show(CLOCK_PROF);
+1
View File
@@ -80,6 +80,7 @@ EXAMPLES_DIRECTDEPS = \
THIRD_PARTY_LIBCXX \
THIRD_PARTY_LINENOISE \
THIRD_PARTY_LUA \
THIRD_PARTY_HIREDIS \
THIRD_PARTY_MBEDTLS \
THIRD_PARTY_MUSL \
THIRD_PARTY_NSYNC \
+21
View File
@@ -0,0 +1,21 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/stdio/stdio.h"
int main(int argc, char *argv[]) {
char buf[256];
if (!getdomainname(buf, sizeof(buf))) {
printf("%s\n", buf);
return 0;
} else {
return 1;
}
}
+55
View File
@@ -0,0 +1,55 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/runtime/runtime.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "third_party/hiredis/hiredis.h"
/**
* @fileoverview Demo of using hiredis to connect to a Redis server
*/
int main(int argc, char *argv[]) {
if (argc < 3 || argc > 5) {
fprintf(stderr, "Usage: %s HOST PORT [KEY] [VALUE]\n", argv[0]);
exit(1);
}
bool setValue = (argc == 5), getValue = (argc == 4);
redisContext *c = redisConnect(argv[1], atoi(argv[2]));
if (c == NULL || c->err) {
if (c) {
fprintf(stderr, "Connection error: %s\n", c->errstr);
redisFree(c);
} else {
fputs("Failed to allocate redis context\n", stderr);
}
exit(1);
}
redisReply *reply;
if (!setValue && !getValue) {
reply = redisCommand(c, "PING");
printf("PING: %s\n", reply->str);
} else if (setValue) {
reply = redisCommand(c, "SET %s %s", argv[3], argv[4]);
printf("SET: %s\n", reply->str);
} else {
reply = redisCommand(c, "GET %s", argv[3]);
printf("GET: %s\n", reply->str);
}
freeReplyObject(reply);
redisFree(c);
return 0;
}
File renamed without changes.
+43
View File
@@ -0,0 +1,43 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/assert.h"
#include "libc/calls/struct/timespec.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/clock.h"
/**
* @fileoverview shows how accurate clock_nanosleep() is
*/
int main(int argc, char *argv[]) {
long i, ns;
struct timespec x, y, w;
timespec_sleep(timespec_fromnanos(0)); // warmup
printf("\nrelative sleep\n");
for (i = 0; i < 28; ++i) {
ns = 1l << i;
x = timespec_real();
timespec_sleep(timespec_fromnanos(ns));
y = timespec_real();
printf("%,11ld ns sleep took %,ld ns\n", ns,
timespec_tonanos(timespec_sub(y, x)));
}
printf("\nabsolute sleep\n");
for (i = 0; i < 28; ++i) {
ns = 1l << i;
x = timespec_real();
timespec_sleep_until(timespec_add(x, timespec_fromnanos(ns)));
y = timespec_real();
printf("%,11ld ns sleep took %,ld ns\n", ns,
timespec_tonanos(timespec_sub(y, x)));
}
}
+3 -3
View File
@@ -27,13 +27,13 @@ dontinline void ShowIt(const char *path) {
"optimal transfer block size");
sizefmt(ibuf, sf.f_frsize, 1024);
printf("f_frsize = %,zu (%sb %s)\n", sf.f_frsize, ibuf, "fragment size");
sizefmt(ibuf, sf.f_blocks * sf.f_bsize, 1024);
sizefmt(ibuf, sf.f_blocks * sf.f_frsize, 1024);
printf("f_blocks = %,zu (%sb %s)\n", sf.f_blocks, ibuf,
"total data blocks in filesystem");
sizefmt(ibuf, sf.f_bfree * sf.f_bsize, 1024);
sizefmt(ibuf, sf.f_bfree * sf.f_frsize, 1024);
printf("f_bfree = %,zu (%sb %s)\n", sf.f_bfree, ibuf,
"free blocks in filesystem");
sizefmt(ibuf, sf.f_bavail * sf.f_bsize, 1024);
sizefmt(ibuf, sf.f_bavail * sf.f_frsize, 1024);
printf("f_bavail = %,zu (%sb %s)\n", sf.f_bavail, ibuf,
"free blocks available to use");
printf("f_files = %,zu (%s)\n", sf.f_files,
+16 -16
View File
@@ -46,31 +46,31 @@ int main(int argc, char *argv[]) {
1. / 65536 * si.loads[1], //
1. / 65536 * si.loads[2]); //
sizefmt(ibuf, si.totalram, 1024);
printf("%-16s %s\n", "totalram", ibuf);
sizefmt(ibuf, si.totalram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "totalram", si.totalram, ibuf);
sizefmt(ibuf, si.freeram, 1024);
printf("%-16s %s\n", "freeram", ibuf);
sizefmt(ibuf, si.freeram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "freeram", si.freeram, ibuf);
sizefmt(ibuf, si.sharedram, 1024);
printf("%-16s %s\n", "sharedram", ibuf);
sizefmt(ibuf, si.sharedram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "sharedram", si.sharedram, ibuf);
sizefmt(ibuf, si.bufferram, 1024);
printf("%-16s %s\n", "bufferram", ibuf);
sizefmt(ibuf, si.bufferram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "bufferram", si.bufferram, ibuf);
sizefmt(ibuf, si.totalswap, 1024);
printf("%-16s %s\n", "totalswap", ibuf);
sizefmt(ibuf, si.totalswap * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "totalswap", si.totalswap, ibuf);
sizefmt(ibuf, si.freeswap, 1024);
printf("%-16s %s\n", "freeswap", ibuf);
sizefmt(ibuf, si.freeswap * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "freeswap", si.freeswap, ibuf);
printf("%-16s %lu\n", "processes", si.procs);
sizefmt(ibuf, si.totalhigh, 1024);
printf("%-16s %s\n", "totalhigh", ibuf);
sizefmt(ibuf, si.totalhigh * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "totalhigh", si.totalhigh, ibuf);
sizefmt(ibuf, si.freehigh, 1024);
printf("%-16s %s\n", "freehigh", ibuf);
sizefmt(ibuf, si.freehigh * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "freehigh", si.freehigh, ibuf);
sizefmt(ibuf, si.mem_unit, 1024);
printf("%-16s %s\n", "mem_unit", ibuf);
+6
View File
@@ -24,10 +24,16 @@
STATIC_YOINK("vga_console");
STATIC_YOINK("_idt");
STATIC_YOINK("EfiMain");
int main(int argc, char *argv[]) {
int i;
volatile int x = 1;
volatile int y = 2;
printf("argc = %d\n", argc);
for (i = 0; i < argc; ++i) {
printf("argv[%d] = \"%s\"\n", i, argv[i]);
}
printf("\e[92;44mHello World!\e[0m %d\n", 1 / (x + y - 3));
for (;;);
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef COSMOPOLITAN_LIBC_AR_H_
#define COSMOPOLITAN_LIBC_AR_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define ARMAG "!<arch>\n"
#define SARMAG 8
#define ARFMAG "`\n"
struct ar_hdr {
char ar_name[16];
char ar_date[12];
char ar_uid[6], ar_gid[6];
char ar_mode[8];
char ar_size[10];
char ar_fmag[2];
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_AR_H_ */
+1 -1
View File
@@ -4,7 +4,7 @@
COSMOPOLITAN_C_START_
extern bool __assert_disable;
void __assert_fail(const char *, const char *, int) hidden relegated;
void __assert_fail(const char *, const char *, int) _Hide relegated;
#ifdef NDEBUG
#define assert(x) ((void)0)
+23 -5
View File
@@ -5,6 +5,25 @@
#define _POSIX2_VERSION _POSIX_VERSION
#define _XOPEN_VERSION 700
#define _POSIX_MAPPED_FILES _POSIX_VERSION
#define _POSIX_FSYNC _POSIX_VERSION
#define _POSIX_IPV6 _POSIX_VERSION
#define _POSIX_THREADS _POSIX_VERSION
#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION
#define _POSIX_THREAD_CPUTIME _POSIX_VERSION
#define _POSIX_TIMEOUTS _POSIX_VERSION
#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION
#define _POSIX_CPUTIME _POSIX_VERSION
#define _POSIX_BARRIERS _POSIX_VERSION
#define _POSIX_SPIN_LOCKS _POSIX_VERSION
#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION
#define _POSIX_SEMAPHORES _POSIX_VERSION
#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION
#define EOF -1 /* end of file */
#define WEOF -1u /* end of file (multibyte) */
#define _IOFBF 0 /* fully buffered */
@@ -35,11 +54,10 @@
#define WIFCONTINUED(s) ((s) == 0xffff)
#define WIFEXITED(s) (!WTERMSIG(s))
#define WIFSIGNALED(s) ((0xffff & (s)) - 1u < 0xffu)
#define WIFSTOPPED(s) \
((short)(((0xffff & (unsigned)(s)) * 0x10001) >> 8) > 0x7f00)
#define WSTOPSIG(s) WEXITSTATUS(s)
#define WTERMSIG(s) (127 & (s))
#define W_STOPCODE(s) ((s) << 8 | 0177)
#define WIFSTOPPED(s) ((255 & (s)) == 127)
#define WSTOPSIG(s) WEXITSTATUS(s)
#define WTERMSIG(s) (127 & (s))
#define W_STOPCODE(s) ((s) << 8 | 0177)
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
+1 -10
View File
@@ -121,21 +121,12 @@ o/$(MODE)/libc/calls/execlp.o \
o/$(MODE)/libc/calls/statfs.o \
o/$(MODE)/libc/calls/fstatfs.o \
o/$(MODE)/libc/calls/execve-sysv.o \
o/$(MODE)/libc/calls/readlinkat-nt.o \
o/$(MODE)/libc/calls/execve-nt.greg.o \
o/$(MODE)/libc/calls/mkntenvblock.o: private \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
# we must disable static stack safety because:
# PATH_MAX*sizeof(char16_t)*2 exceeds 4096 byte frame limit
o/$(MODE)/libc/calls/copyfile.o \
o/$(MODE)/libc/calls/symlinkat-nt.o \
o/$(MODE)/libc/calls/readlinkat-nt.o \
o/$(MODE)/libc/calls/linkat-nt.o \
o/$(MODE)/libc/calls/renameat-nt.o: private \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
# we must segregate codegen because:
# file contains multiple independently linkable apis
o/$(MODE)/libc/calls/ioctl-siocgifconf.o \
+18 -15
View File
@@ -50,20 +50,23 @@
* sys_clock_gettime l: 220𝑐 71𝑛𝑠
*
* @param clock can be one of:
* - `CLOCK_REALTIME`: universally supported
* - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd
* - `CLOCK_MONOTONIC`: universally supported
* - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd
* - `CLOCK_MONOTONIC_RAW`: nearly universally supported
* - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd
* - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd
* - `CLOCK_REALTIME_COARSE`: : linux and openbsd
* - `CLOCK_MONOTONIC_COARSE`: linux
* - `CLOCK_PROF`: linux and netbsd
* - `CLOCK_BOOTTIME`: linux and openbsd
* - `CLOCK_REALTIME_ALARM`: linux-only
* - `CLOCK_BOOTTIME_ALARM`: linux-only
* - `CLOCK_TAI`: linux-only
* - `CLOCK_REALTIME`: universally supported
* - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd
* - `CLOCK_REALTIME_PRECISE`: ditto but better on freebsd
* - `CLOCK_REALTIME_COARSE`: : like `CLOCK_REALTIME_FAST` w/ Linux 2.6.32+
* - `CLOCK_MONOTONIC`: universally supported
* - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd
* - `CLOCK_MONOTONIC_PRECISE`: ditto but better on freebsd
* - `CLOCK_MONOTONIC_COARSE`: : like `CLOCK_MONOTONIC_FAST` w/ Linux 2.6.32+
* - `CLOCK_MONOTONIC_RAW`: is actually monotonic but needs Linux 2.6.28+
* - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd
* - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd
* - `CLOCK_MONOTONIC_COARSE`: linux, freebsd
* - `CLOCK_PROF`: linux and netbsd
* - `CLOCK_BOOTTIME`: linux and openbsd
* - `CLOCK_REALTIME_ALARM`: linux-only
* - `CLOCK_BOOTTIME_ALARM`: linux-only
* - `CLOCK_TAI`: linux-only
* @param ts is where the result is stored
* @return 0 on success, or -1 w/ errno
* @error EPERM if pledge() is in play without stdio promise
@@ -116,7 +119,7 @@ clock_gettime_f *__clock_gettime_get(bool *opt_out_isfast) {
return res;
}
hidden int __clock_gettime_init(int clockid, struct timespec *ts) {
_Hide int __clock_gettime_init(int clockid, struct timespec *ts) {
clock_gettime_f *gettime;
__clock_gettime = gettime = __clock_gettime_get(0);
return gettime(clockid, ts);
+3 -3
View File
@@ -7,9 +7,9 @@ COSMOPOLITAN_C_START_
typedef int clock_gettime_f(int, struct timespec *);
extern clock_gettime_f *__clock_gettime;
clock_gettime_f *__clock_gettime_get(bool *) hidden;
int __clock_gettime_init(int, struct timespec *) hidden;
int sys_clock_gettime_mono(struct timespec *) hidden;
clock_gettime_f *__clock_gettime_get(bool *) _Hide;
int __clock_gettime_init(int, struct timespec *) _Hide;
int sys_clock_gettime_mono(struct timespec *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+165 -27
View File
@@ -16,7 +16,11 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/asan.internal.h"
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/clock_gettime.internal.h"
#include "libc/calls/cp.internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/timespec.h"
@@ -27,11 +31,158 @@
#include "libc/errno.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/macros.internal.h"
#include "libc/nt/ntdll.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/timer.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
static int64_t g_nanosleep_latency;
static errno_t sys_clock_nanosleep(int clock, int flags,
const struct timespec *req,
struct timespec *rem) {
int e, rc;
BEGIN_CANCELLATION_POINT;
e = errno;
if (IsLinux() || IsFreebsd() || IsNetbsd()) {
rc = __sys_clock_nanosleep(clock, flags, req, rem);
} else if (IsXnu()) {
rc = sys_clock_nanosleep_xnu(clock, flags, req, rem);
} else if (IsOpenbsd()) {
rc = sys_clock_nanosleep_openbsd(clock, flags, req, rem);
} else {
rc = sys_clock_nanosleep_nt(clock, flags, req, rem);
}
if (rc == -1) {
rc = errno;
errno = e;
}
END_CANCELLATION_POINT;
return rc;
}
// determine sched_yield() vs. clock_nanosleep() threshold
// 1ns sys_clock_nanosleep() on Windows takes milliseconds :'(
// 1ns sys_clock_nanosleep() on Linux/FreeBSD takes tens of microseconds
// 1ns sys_clock_nanosleep() on OpenBSD/NetBSD takes tens of milliseconds D:
static struct timespec GetNanosleepLatency(void) {
errno_t rc;
int64_t nanos;
clock_gettime_f *cgt;
struct timespec x, y, w = {0, 1};
if (!(nanos = g_nanosleep_latency)) {
BLOCK_CANCELLATIONS;
for (cgt = __clock_gettime_get(0);;) {
_npassert(!cgt(CLOCK_REALTIME_PRECISE, &x));
rc = sys_clock_nanosleep(CLOCK_REALTIME, 0, &w, 0);
_npassert(!rc || rc == EINTR);
if (!rc) {
_npassert(!cgt(CLOCK_REALTIME_PRECISE, &y));
nanos = timespec_tonanos(timespec_sub(y, x));
g_nanosleep_latency = nanos;
break;
}
}
ALLOW_CANCELLATIONS;
}
return timespec_fromnanos(nanos);
}
static errno_t CheckCancel(void) {
if (_weaken(pthread_testcancel_np)) {
return _weaken(pthread_testcancel_np)();
} else {
return 0;
}
}
static errno_t SpinNanosleep(int clock, int flags, const struct timespec *req,
struct timespec *rem) {
errno_t rc;
clock_gettime_f *cgt;
struct timespec now, start, elapsed;
if ((rc = CheckCancel())) {
if (rc == EINTR && !flags && rem) {
*rem = *req;
}
return rc;
}
cgt = __clock_gettime_get(0);
_npassert(!cgt(CLOCK_REALTIME, &start));
for (;;) {
sched_yield();
_npassert(!cgt(CLOCK_REALTIME, &now));
if (flags & TIMER_ABSTIME) {
if (timespec_cmp(now, *req) >= 0) {
return 0;
}
if ((rc = CheckCancel())) {
return rc;
}
} else {
if (timespec_cmp(now, start) < 0) continue;
elapsed = timespec_sub(now, start);
if ((rc = CheckCancel())) {
if (rc == EINTR && rem) {
if (timespec_cmp(elapsed, *req) >= 0) {
bzero(rem, sizeof(*rem));
} else {
*rem = elapsed;
}
}
return rc;
}
if (timespec_cmp(elapsed, *req) >= 0) {
return 0;
}
}
}
}
static bool ShouldUseSpinNanosleep(int clock, int flags,
const struct timespec *req) {
errno_t e;
struct timespec now;
if (IsWindows()) {
// Our spin technique here is intended to take advantage of the fact
// that sched_yield() takes about a hundred nanoseconds. But Windows
// SleepEx(0, 0) a.k.a. NtYieldExecution() takes a whole millisecond
// and it matters not whether our intent is to yielding or sleeping,
// since we use the SleepEx() function to implement both. Therefore,
// there's no reason to use SpinNanosleep() on Windows.
return false;
}
if (clock != CLOCK_REALTIME && //
clock != CLOCK_REALTIME_PRECISE && //
clock != CLOCK_MONOTONIC && //
clock != CLOCK_MONOTONIC_RAW && //
clock != CLOCK_MONOTONIC_PRECISE) {
return false;
}
if (!flags) {
return timespec_cmp(*req, GetNanosleepLatency()) < 0;
}
// We need a clock_gettime() system call to perform this check if the
// sleep request is an absolute timestamp. So we avoid doing that on
// systems where sleep latency isn't too outrageous.
if (timespec_cmp(GetNanosleepLatency(), timespec_fromnanos(50 * 1000)) < 0) {
return false;
}
e = errno;
if (__clock_gettime_get(0)(clock, &now)) {
// punt to the nanosleep system call
errno = e;
return false;
}
return timespec_cmp(*req, now) < 0 ||
timespec_cmp(timespec_sub(*req, now), GetNanosleepLatency()) < 0;
}
/**
* Sleeps for particular amount of time.
*
@@ -61,7 +212,7 @@
* while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &abs, 0));
*
* will accurately spin on `EINTR` errors. That way you're not impeding
* signal delivery and you're not losing precision on your wait timeout.
* signal delivery and you're not loosing precision on the wait timeout.
* This function has first-class support on Linux, FreeBSD, and NetBSD;
* on OpenBSD it's good; on XNU it's bad; and on Windows it's ugly.
*
@@ -88,43 +239,30 @@
*/
errno_t clock_nanosleep(int clock, int flags, const struct timespec *req,
struct timespec *rem) {
int rc, e = errno;
BEGIN_CANCELLATION_POINT;
if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) ||
(rem && !__asan_is_valid_timespec(rem))))) {
rc = efault();
int rc;
LOCKTRACE("clock_nanosleep(%s, %s, %s) → ...", DescribeClockName(clock),
DescribeSleepFlags(flags), DescribeTimespec(0, req));
if (IsMetal()) {
rc = ENOSYS;
} else if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) ||
(rem && !__asan_is_valid_timespec(rem))))) {
rc = EFAULT;
} else if (clock == 127 || //
(flags & ~TIMER_ABSTIME) || //
req->tv_sec < 0 || //
!(0 <= req->tv_nsec && req->tv_nsec <= 999999999)) {
rc = einval();
} else if (IsLinux() || IsFreebsd() || IsNetbsd()) {
rc = sys_clock_nanosleep(clock, flags, req, rem);
} else if (IsXnu()) {
rc = sys_clock_nanosleep_xnu(clock, flags, req, rem);
} else if (IsOpenbsd()) {
rc = sys_clock_nanosleep_openbsd(clock, flags, req, rem);
} else if (IsMetal()) {
rc = enosys();
rc = EINVAL;
} else if (ShouldUseSpinNanosleep(clock, flags, req)) {
rc = SpinNanosleep(clock, flags, req, rem);
} else {
rc = sys_clock_nanosleep_nt(clock, flags, req, rem);
rc = sys_clock_nanosleep(clock, flags, req, rem);
}
if (rc == -1) {
rc = errno;
errno = e;
}
END_CANCELLATION_POINT;
#if SYSDEBUG
if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
STRACE("clock_nanosleep(%s, %s, %s, [%s]) → %s", DescribeClockName(clock),
DescribeSleepFlags(flags), DescribeTimespec(0, req),
DescribeTimespec(rc, rem), DescribeErrnoResult(rc));
DescribeTimespec(rc, rem), DescribeErrno(rc));
}
#endif
return rc;
}
+1 -1
View File
@@ -24,7 +24,7 @@
#include "libc/nt/runtime.h"
#include "libc/sysv/consts/o.h"
void sys_fcntl_nt_lock_cleanup(int) hidden;
void sys_fcntl_nt_lock_cleanup(int) _Hide;
textwindows int sys_close_nt(struct Fd *fd, int fildes) {
int e;
+18 -4
View File
@@ -16,16 +16,18 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/bits.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/struct/stat.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/log/libfatal.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ok.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h"
static bool IsExePath(const char *s, size_t n) {
@@ -48,6 +50,9 @@ static bool AccessCommand(const char *name, char *path, size_t pathsz,
size_t pathlen) {
size_t suffixlen;
suffixlen = strlen(suffix);
if (IsWindows() && suffixlen == 0 && !IsExePath(name, namelen) &&
!IsComPath(name, namelen))
return false;
if (pathlen + 1 + namelen + suffixlen + 1 > pathsz) return false;
if (pathlen && (path[pathlen - 1] != '/' && path[pathlen - 1] != '\\')) {
path[pathlen] = !IsWindows() ? '/'
@@ -57,7 +62,16 @@ static bool AccessCommand(const char *name, char *path, size_t pathsz,
}
memcpy(path + pathlen, name, namelen);
memcpy(path + pathlen + namelen, suffix, suffixlen + 1);
if (!access(path, X_OK)) return true;
if (!access(path, X_OK)) {
struct stat st;
if (!stat(path, &st)) {
if (S_ISREG(st.st_mode)) {
return true;
} else {
errno = EACCES;
}
}
}
if (errno == EACCES || *err != EACCES) *err = errno;
return false;
}
+7 -5
View File
@@ -19,6 +19,7 @@
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/blocksigs.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/execve-sysv.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
@@ -37,6 +38,11 @@ static bool CanExecute(const char *path) {
return !sys_faccessat(AT_FDCWD, path, X_OK, 0);
}
bool IsAPEMagic(char buf[8]) {
return READ64LE(buf) == READ64LE("MZqFpD='") ||
READ64LE(buf) == READ64LE("JTqFpD='");
}
static bool IsApeBinary(const char *path) {
int fd;
char buf[8];
@@ -44,11 +50,7 @@ static bool IsApeBinary(const char *path) {
// TODO(jart): Should we block signals too?
BLOCK_CANCELLATIONS;
if ((fd = sys_open(path, O_RDONLY, 0)) != -1) {
if (sys_read(fd, buf, 8) == 8 && //
(READ64LE(buf) == READ64LE("MZqFpD='") ||
READ64LE(buf) == READ64LE("JTqFpD='"))) {
res = true;
}
res = sys_read(fd, buf, 8) == 8 && IsAPEMagic(buf);
sys_close(fd);
}
ALLOW_CANCELLATIONS;
+10
View File
@@ -0,0 +1,10 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_
#define COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
bool IsAPEMagic(char[8]) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_ */
+20 -8
View File
@@ -32,6 +32,7 @@
#include "libc/log/libfatal.internal.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
/**
* Replaces current process with program.
@@ -51,6 +52,7 @@
* @vforksafe
*/
int execve(const char *prog, char *const argv[], char *const envp[]) {
struct ZiposUri uri;
int rc;
size_t i;
if (!prog || !argv || !envp ||
@@ -61,16 +63,26 @@ int execve(const char *prog, char *const argv[], char *const envp[]) {
} else {
STRACE("execve(%#s, %s, %s) → ...", prog, DescribeStringList(argv),
DescribeStringList(envp));
if (!IsWindows()) {
rc = 0;
if (IsLinux() && __execpromises && _weaken(sys_pledge_linux)) {
rc = _weaken(sys_pledge_linux)(__execpromises, __pledge_mode);
}
if (!rc) {
rc = 0;
if (IsLinux() && __execpromises && _weaken(sys_pledge_linux)) {
rc = _weaken(sys_pledge_linux)(__execpromises, __pledge_mode);
}
if (!rc) {
if (_weaken(__zipos_parseuri) &&
(_weaken(__zipos_parseuri)(prog, &uri) != -1)) {
rc = _weaken(__zipos_open)(&uri, O_RDONLY | O_CLOEXEC, 0);
if (rc != -1) {
const int zipFD = rc;
strace_enabled(-1);
rc = fexecve(zipFD, argv, envp);
close(zipFD);
strace_enabled(+1);
}
} else if (!IsWindows()) {
rc = sys_execve(prog, argv, envp);
} else {
rc = sys_execve_nt(prog, argv, envp);
}
} else {
rc = sys_execve_nt(prog, argv, envp);
}
}
STRACE("execve(%#s) failed %d% m", prog, rc);
+1 -1
View File
@@ -98,7 +98,7 @@ static textwindows bool EqualsFileLock(struct FileLock *fl, int64_t off,
return fl->off == off && off + len == fl->off + fl->len;
}
hidden textwindows void sys_fcntl_nt_lock_cleanup(int fd) {
_Hide textwindows void sys_fcntl_nt_lock_cleanup(int fd) {
struct FileLock *fl, *ft, **flp;
pthread_mutex_lock(&g_locks.mu);
for (flp = &g_locks.list, fl = *flp; fl;) {
+208 -13
View File
@@ -16,23 +16,167 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/blocksigs.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/cp.internal.h"
#include "libc/calls/execve-sysv.internal.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/stat.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/fd.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/mfd.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/shm.h"
#include "libc/sysv/errfuns.h"
int sys_fexecve(int, char *const[], char *const[]);
static bool IsAPEFd(const int fd) {
char buf[8];
bool res;
return (sys_pread(fd, buf, 8, 0, 0) == 8) && IsAPEMagic(buf);
}
static int fexecve_impl(const int fd, char *const argv[], char *const envp[]) {
int rc;
if (IsLinux()) {
char path[14 + 12];
FormatInt32(stpcpy(path, "/proc/self/fd/"), fd);
rc = __sys_execve(path, argv, envp);
} else if (IsFreebsd()) {
rc = sys_fexecve(fd, argv, envp);
} else {
rc = enosys();
}
return rc;
}
typedef enum {
PTF_NUM = 1 << 0,
PTF_NUM2 = 1 << 1,
PTF_NUM3 = 1 << 2,
PTF_ANY = 1 << 3
} PTF_PARSE;
static bool ape_to_elf(void *ape, const size_t apesize) {
static const char printftok[] = "printf '";
static const size_t printftoklen = sizeof(printftok) - 1;
const char *tok = memmem(ape, apesize, printftok, printftoklen);
if (tok) {
tok += printftoklen;
uint8_t *dest = ape;
PTF_PARSE state = PTF_ANY;
uint8_t value = 0;
for (; tok < (const char *)(dest + apesize); tok++) {
if ((state & (PTF_NUM | PTF_NUM2 | PTF_NUM3)) &&
(*tok >= '0' && *tok <= '7')) {
value = (value << 3) | (*tok - '0');
state <<= 1;
if (state & PTF_ANY) {
*dest++ = value;
}
} else if (state & PTF_NUM) {
break;
} else {
if (state & (PTF_NUM2 | PTF_NUM3)) {
*dest++ = value;
}
if (*tok == '\\') {
state = PTF_NUM;
value = 0;
} else if (*tok == '\'') {
return true;
} else {
*dest++ = *tok;
state = PTF_ANY;
}
}
}
}
errno = ENOEXEC;
return false;
}
/**
* Creates a memfd and copies fd to it.
*
* This does an inplace conversion of APE to ELF when detected!!!!
*/
static int fd_to_mem_fd(const int infd, char *path) {
if (!IsLinux() && !IsFreebsd() || !_weaken(mmap) || !_weaken(munmap)) {
return enosys();
}
struct stat st;
if (fstat(infd, &st) == -1) {
return -1;
}
int fd;
if (IsLinux()) {
fd = sys_memfd_create(__func__, MFD_CLOEXEC);
} else if (IsFreebsd()) {
fd = sys_shm_open(SHM_ANON, O_CREAT | O_RDWR, 0);
} else {
return enosys();
}
if (fd == -1) {
return -1;
}
void *space;
if ((sys_ftruncate(fd, st.st_size, st.st_size) != -1) &&
((space = _weaken(mmap)(0, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, 0)) != MAP_FAILED)) {
ssize_t readRc;
readRc = pread(infd, space, st.st_size, 0);
bool success = readRc != -1;
if (success && (st.st_size > 8) && IsAPEMagic(space)) {
int flags = fcntl(fd, F_GETFD);
if (success = (flags != -1) &&
(fcntl(fd, F_SETFD, flags & (~FD_CLOEXEC)) != -1) &&
ape_to_elf(space, st.st_size)) {
const int newfd = fcntl(fd, F_DUPFD, 9001);
if (newfd != -1) {
close(fd);
fd = newfd;
}
}
}
const int e = errno;
if ((_weaken(munmap)(space, st.st_size) != -1) && success) {
if (path) {
FormatInt32(stpcpy(path, "COSMOPOLITAN_INIT_ZIPOS="), fd);
}
_unassert(readRc == st.st_size);
return fd;
} else if (!success) {
errno = e;
}
}
const int e = errno;
close(fd);
errno = e;
return -1;
}
/**
* Executes binary executable at file descriptor.
*
* This is only supported on Linux and FreeBSD. APE binaries currently
* aren't supported.
* This is only supported on Linux and FreeBSD. APE binaries are
* supported. Zipos is supported. Zipos fds or FD_CLOEXEC APE fds or
* fds that fail fexecve with ENOEXEC are copied to a new memfd (with
* in-memory APE to ELF conversion) and fexecve is (re)attempted.
*
* @param fd is opened executable and current file position is ignored
* @return doesn't return on success, otherwise -1 w/ errno
@@ -40,8 +184,7 @@ int sys_fexecve(int, char *const[], char *const[]);
* @raise ENOSYS on Windows, XNU, OpenBSD, NetBSD, and Metal
*/
int fexecve(int fd, char *const argv[], char *const envp[]) {
int rc;
size_t i;
int rc = 0;
if (!argv || !envp ||
(IsAsan() &&
(!__asan_is_valid_strlist(argv) || !__asan_is_valid_strlist(envp)))) {
@@ -49,15 +192,67 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
} else {
STRACE("fexecve(%d, %s, %s) → ...", fd, DescribeStringList(argv),
DescribeStringList(envp));
if (IsLinux()) {
char path[14 + 12];
FormatInt32(stpcpy(path, "/proc/self/fd/"), fd);
rc = __sys_execve(path, argv, envp);
} else if (IsFreebsd()) {
rc = sys_fexecve(fd, argv, envp);
} else {
rc = enosys();
int savedErr = 0;
do {
if (!IsLinux() && !IsFreebsd()) {
rc = enosys();
break;
}
if (!__isfdkind(fd, kFdZip)) {
bool memfdReq;
BEGIN_CANCELLATION_POINT;
BLOCK_SIGNALS;
strace_enabled(-1);
memfdReq = ((rc = fcntl(fd, F_GETFD)) != -1) && (rc & FD_CLOEXEC) &&
IsAPEFd(fd);
strace_enabled(+1);
ALLOW_SIGNALS;
END_CANCELLATION_POINT;
if (rc == -1) {
break;
} else if (!memfdReq) {
fexecve_impl(fd, argv, envp);
if (errno != ENOEXEC) {
break;
}
savedErr = ENOEXEC;
}
}
int newfd;
char *path = alloca(PATH_MAX);
BEGIN_CANCELLATION_POINT;
BLOCK_SIGNALS;
strace_enabled(-1);
newfd = fd_to_mem_fd(fd, path);
strace_enabled(+1);
ALLOW_SIGNALS;
END_CANCELLATION_POINT;
if (newfd == -1) {
break;
}
size_t numenvs;
for (numenvs = 0; envp[numenvs];) ++numenvs;
const size_t desenvs = min(500, max(numenvs + 1, 2));
static _Thread_local char *envs[500];
memcpy(envs, envp, numenvs * sizeof(char *));
envs[numenvs] = path;
envs[numenvs + 1] = NULL;
fexecve_impl(newfd, argv, envs);
if (!savedErr) {
savedErr = errno;
}
BEGIN_CANCELLATION_POINT;
BLOCK_SIGNALS;
strace_enabled(-1);
close(newfd);
strace_enabled(+1);
ALLOW_SIGNALS;
END_CANCELLATION_POINT;
} while (0);
if (savedErr) {
errno = savedErr;
}
rc = -1;
}
STRACE("fexecve(%d) failed %d% m", fd, rc);
return rc;
+1 -1
View File
@@ -47,7 +47,7 @@ int fsync(int fd) {
rc = sys_fdatasync_nt(fd);
}
END_CANCELLATION_POINT;
STRACE("fysnc(%d) → %d% m", fd, rc);
STRACE("fsync(%d) → %d% m", fd, rc);
} else {
rc = fstat(fd, &st);
STRACE("fsync_fake(%d) → %d% m", fd, rc);
-21
View File
@@ -1,21 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_
#define COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_
#include "libc/nt/enum/ctrlevent.h"
#include "libc/sysv/consts/sig.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
static inline int GetConsoleCtrlEvent(int sig) {
switch (sig) {
case SIGINT:
return kNtCtrlCEvent;
case SIGQUIT:
return kNtCtrlBreakEvent;
default:
return -1;
}
}
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_GETCONSOLECTRLEVENT_H_ */
+3 -1
View File
@@ -17,12 +17,14 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
/**
* Returns process group id of calling process.
*
* This function is equivalent to `getpgid(0)`.
*/
int getpgrp(void) {
int rc;
+1 -1
View File
@@ -97,7 +97,7 @@ gettimeofday_f *__gettimeofday_get(bool *opt_out_isfast) {
return res;
}
hidden int __gettimeofday_init(struct timeval *tv, struct timezone *tz) {
_Hide int __gettimeofday_init(struct timeval *tv, struct timezone *tz) {
gettimeofday_f *gettime;
__gettimeofday = gettime = __gettimeofday_get(0);
return gettime(tv, tz, 0).ax;
+10 -10
View File
@@ -12,15 +12,15 @@ COSMOPOLITAN_C_START_
#define kIoMotion ((const int8_t[3]){1, 0, 0})
hidden extern struct Fds g_fds;
hidden extern const struct Fd kEmptyFd;
_Hide extern struct Fds g_fds;
_Hide extern const struct Fd kEmptyFd;
int __reservefd(int) hidden;
int __reservefd_unlocked(int) hidden;
void __releasefd(int) hidden;
int __ensurefds(int) hidden;
int __ensurefds_unlocked(int) hidden;
void __printfds(void) hidden;
int __reservefd(int) _Hide;
int __reservefd_unlocked(int) _Hide;
void __releasefd(int) _Hide;
int __ensurefds(int) _Hide;
int __ensurefds_unlocked(int) _Hide;
void __printfds(void) _Hide;
forceinline int64_t __getfdhandleactual(int fd) {
return g_fds.p[fd].handle;
@@ -42,8 +42,8 @@ forceinline size_t _clampio(size_t size) {
}
}
int sys_close_nt(struct Fd *, int) hidden;
int _check_interrupts(bool, struct Fd *) hidden;
int sys_close_nt(struct Fd *, int) _Hide;
int _check_interrupts(bool, struct Fd *) _Hide;
int sys_openat_metal(int, const char *, int, unsigned);
COSMOPOLITAN_C_END_
+5 -5
View File
@@ -43,11 +43,11 @@
* The ifc_len is an input/output parameter: set it to the total size of
* the ifcu_buf (ifcu_req) buffer on input.
*/
int ioctl_siocgifconf_nt(int, struct ifconf *) hidden;
int ioctl_siocgifaddr_nt(int, struct ifreq *) hidden;
int ioctl_siocgifflags_nt(int, struct ifreq *) hidden;
int ioctl_siocgifnetmask_nt(int, struct ifreq *) hidden;
int ioctl_siocgifbrdaddr_nt(int, struct ifreq *) hidden;
int ioctl_siocgifconf_nt(int, struct ifconf *) _Hide;
int ioctl_siocgifaddr_nt(int, struct ifreq *) _Hide;
int ioctl_siocgifflags_nt(int, struct ifreq *) _Hide;
int ioctl_siocgifnetmask_nt(int, struct ifreq *) _Hide;
int ioctl_siocgifbrdaddr_nt(int, struct ifreq *) _Hide;
static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
/*
+2 -2
View File
@@ -18,18 +18,18 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/internal.h"
#include "libc/calls/ioctl.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/struct/metatermios.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/termios.internal.h"
#include "libc/calls/ttydefaults.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
int ioctl_tcgets_nt(int, struct termios *) hidden;
int ioctl_tcgets_nt(int, struct termios *) _Hide;
static int ioctl_tcgets_metal(int fd, struct termios *tio) {
bzero(tio, sizeof(*tio));
+2
View File
@@ -18,11 +18,13 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/pr.h"
privileged bool __is_linux_2_6_23(void) {
int rc;
if (!IsLinux()) return false;
if (IsGenuineBlink()) return true;
asm volatile("syscall"
: "=a"(rc)
: "0"(157), "D"(PR_GET_SECCOMP)
+1 -1
View File
@@ -19,4 +19,4 @@
#include "libc/calls/internal.h"
#include "libc/calls/struct/fd.internal.h"
hidden const struct Fd kEmptyFd;
_Hide const struct Fd kEmptyFd;
+19 -4
View File
@@ -17,7 +17,6 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/getconsolectrlevent.internal.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/macros.internal.h"
@@ -29,8 +28,20 @@
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/processentry32.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
static inline int GetConsoleCtrlEvent(int sig) {
switch (sig) {
case SIGINT:
return kNtCtrlCEvent;
case SIGQUIT:
return kNtCtrlBreakEvent;
default:
return -1;
}
}
textwindows int sys_kill_nt(int pid, int sig) {
bool32 ok;
int64_t h;
@@ -46,6 +57,7 @@ textwindows int sys_kill_nt(int pid, int sig) {
// If we're targeting current process group then just call raise().
if (!pid || pid == getpid()) {
if (!sig) return 0; // ability check passes
return raise(sig);
}
@@ -72,6 +84,7 @@ textwindows int sys_kill_nt(int pid, int sig) {
// is this a cosmo pid that was returned by fork?
if (__isfdkind(pid, kFdProcess)) {
if (!sig) return 0; // ability check passes
// since windows can't execve we need to kill the grandchildren
// TODO(jart): should we just kill the whole tree too? there's
// no obvious way to tell if it's the execve shell
@@ -96,9 +109,11 @@ textwindows int sys_kill_nt(int pid, int sig) {
// XXX: Is this a raw new technology pid? Because that's messy.
if ((h = OpenProcess(kNtProcessTerminate, false, pid))) {
ok = TerminateProcess(h, 128 + sig);
if (!ok && GetLastError() == kNtErrorAccessDenied) {
ok = true; // cargo culting other codebases here
if (sig) {
ok = TerminateProcess(h, 128 + sig);
if (!ok && GetLastError() == kNtErrorAccessDenied) {
ok = true; // cargo culting other codebases here
}
}
CloseHandle(h);
return 0;
+9
View File
@@ -26,6 +26,15 @@
*/
#define LANDLOCK_ACCESS_FS_REFER 0x2000ul
/**
* Control file truncation.
*
* @see https://lore.kernel.org/all/[email protected]/
* @see https://docs.kernel.org/userspace-api/landlock.html
* @note ABI 3+
*/
#define LANDLOCK_ACCESS_FS_TRUNCATE 0x4000ul
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
+2 -2
View File
@@ -61,14 +61,14 @@ textstartup noasan void InitializeMetalFile(void) {
* The zipos code will automatically arrange to do this. Alternatively,
* user code can STATIC_YOINK this symbol.
*/
size_t size = ROUNDUP(_tdata_end - _base, 4096);
size_t size = ROUNDUP(_ezip - _base, 4096);
void *copied_base;
struct DirectMap dm;
dm = sys_mmap_metal(NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED_linux | MAP_ANONYMOUS_linux, -1, 0);
copied_base = dm.addr;
_npassert(copied_base != (void *)-1);
memcpy(copied_base, (void *)(BANE + IMAGE_BASE_REAL), size);
memcpy(copied_base, (void *)(BANE + IMAGE_BASE_PHYSICAL), size);
__ape_com_base = copied_base;
__ape_com_size = size;
}
+7 -10
View File
@@ -61,15 +61,12 @@ static inline int IsAlpha(int c) {
// TODO(jart): this needs fuzzing and security review
//
// @param cmdline is output buffer
// @param prog is frontloaded as argv[0]
// @param argv is an a NULL-terminated array of UTF-8 strings
// @return 0 on success, or -1 w/ errno
// @raise E2BIG if everything is too huge
// @see "Everyone quotes command line arguments the wrong way" MSDN
// @see libc/runtime/getdosargv.c
textwindows int mkntcmdline(char16_t cmdline[ARG_MAX / 2], const char *prog,
char *const argv[]) {
char *arg;
textwindows int mkntcmdline(char16_t cmdline[ARG_MAX / 2], char *const argv[]) {
uint64_t w;
wint_t x, y;
int slashes, n;
@@ -81,16 +78,16 @@ textwindows int mkntcmdline(char16_t cmdline[ARG_MAX / 2], const char *prog,
bzero(ansiargv, sizeof(ansiargv));
argv = ansiargv;
}
for (arg = prog, k = i = 0; arg; arg = argv[++i]) {
for (k = i = 0; argv[i]; ++i) {
if (i) APPEND(u' ');
if ((needsquote = NeedsQuotes(arg))) APPEND(u'"');
if ((needsquote = NeedsQuotes(argv[i]))) APPEND(u'"');
for (slashes = j = 0;;) {
x = arg[j++] & 255;
x = argv[i][j++] & 255;
if (x >= 0300) {
n = ThomPikeLen(x);
x = ThomPikeByte(x);
while (--n) {
if ((y = arg[j++] & 255)) {
if ((y = argv[i][j++] & 255)) {
x = ThomPikeMerge(x, y);
} else {
x = 0;
@@ -101,9 +98,9 @@ textwindows int mkntcmdline(char16_t cmdline[ARG_MAX / 2], const char *prog,
if (!x) break;
if (x == '/' || x == '\\') {
if (!i) {
// turn / into \ for first arg
// turn / into \ for first argv[i]
x = '\\';
// turn \c\... into c:\ for first arg
// turn \c\... into c:\ for first argv[i]
if (k == 2 && IsAlpha(cmdline[1]) && cmdline[0] == '\\') {
cmdline[0] = cmdline[1];
cmdline[1] = ':';
+2 -2
View File
@@ -79,7 +79,7 @@ textwindows int __mkntpath2(const char *path,
* 1. Need +1 for NUL-terminator
* 2. Need +1 for UTF-16 overflow
* 3. Need ≥2 for SetCurrentDirectory trailing slash requirement
* 5. Need ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
* 4. Need ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
* which is an "8.3 filename" from the DOS days
*/
const char *q;
@@ -119,7 +119,7 @@ textwindows int __mkntpath2(const char *path,
q += 2;
z -= 7;
x = 7;
} else if (IsSlash(q[0]) && IsAlpha(q[1]) && IsSlash(q[2])) {
} else if (IsAlpha(q[0]) && q[1] == ':' && IsSlash(q[2])) {
z = MIN(32767, PATH_MAX);
// turn "c:\foo" into "\\?\c:\foo"
p[0] = '\\';
+9 -4
View File
@@ -21,13 +21,18 @@
noasan int sys_munmap_metal(void *addr, size_t size) {
size_t i;
uint64_t *e;
uint64_t *e, paddr;
struct mman *mm;
uint64_t *pml4t = __get_pml4t();
mm = (struct mman *)(BANE + 0x0500);
for (i = 0; i < size; i += 4096) {
e = __get_virtual(mm, __get_pml4t(), (uint64_t)addr + i, false);
if (e) *e = ~(PAGE_V | PAGE_RSRV);
invlpg((uint64_t)addr + i);
e = __get_virtual(mm, pml4t, (uint64_t)addr + i, false);
if (e) {
paddr = *e & PAGE_TA;
*e &= ~(PAGE_V | PAGE_RSRV);
invlpg((uint64_t)addr + i);
__unref_page(mm, pml4t, paddr);
}
}
return 0;
}
+5 -5
View File
@@ -45,10 +45,10 @@ static long double GetTimeSample(void) {
uint64_t tick1, tick2;
long double time1, time2;
sched_yield();
time1 = dtime(CLOCK_REALTIME_FAST);
time1 = dtime(CLOCK_REALTIME_PRECISE);
tick1 = rdtsc();
nanosleep(&(struct timespec){0, 1000000}, NULL);
time2 = dtime(CLOCK_REALTIME_FAST);
time2 = dtime(CLOCK_REALTIME_PRECISE);
tick2 = rdtsc();
return (time2 - time1) * 1e9 / MAX(1, tick2 - tick1);
}
@@ -74,13 +74,13 @@ static long double MeasureNanosPerCycle(void) {
void RefreshTime(void) {
struct Now now;
now.cpn = MeasureNanosPerCycle();
now.r0 = dtime(CLOCK_REALTIME_FAST);
now.r0 = dtime(CLOCK_REALTIME_PRECISE);
now.k0 = rdtsc();
memcpy(&g_now, &now, sizeof(now));
}
static long double nowl_sys(void) {
return dtime(CLOCK_REALTIME_FAST);
return dtime(CLOCK_REALTIME_PRECISE);
}
static long double nowl_art(void) {
@@ -92,7 +92,7 @@ static long double nowl_vdso(void) {
long double secs;
struct timespec tv;
_unassert(__gettime);
__gettime(CLOCK_REALTIME_FAST, &tv);
__gettime(CLOCK_REALTIME_PRECISE, &tv);
secs = tv.tv_nsec;
secs *= 1 / 1e9L;
secs += tv.tv_sec;
+1 -1
View File
@@ -48,7 +48,7 @@
*
* @param flags can have R_OK, W_OK, X_OK, etc.
* @return 0 if authorized, or -1 w/ errno
* @kudos Aaron Ballman for teaching this
* @see https://blog.aaronballman.com/2011/08/how-to-check-access-rights/
* @see libc/sysv/consts.sh
*/
textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
+1 -1
View File
@@ -18,7 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/ntmagicpaths.internal.h"
hidden const struct NtMagicPaths kNtMagicPaths = {
_Hide const struct NtMagicPaths kNtMagicPaths = {
#define TAB(NAME, STRING) STRING,
#include "libc/calls/ntmagicpaths.inc"
#undef TAB
+1 -1
View File
@@ -9,7 +9,7 @@ struct NtMagicPaths {
#undef TAB
};
hidden extern const struct NtMagicPaths kNtMagicPaths;
_Hide extern const struct NtMagicPaths kNtMagicPaths;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+1 -1
View File
@@ -84,7 +84,7 @@ textwindows int ntspawn(
sizeof(*block), 0)) &&
(block = MapViewOfFileEx(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0,
sizeof(*block), 0)) &&
mkntcmdline(block->cmdline, prog, argv) != -1 &&
mkntcmdline(block->cmdline, argv) != -1 &&
mkntenvblock(block->envvars, envp, extravar, block->buf) != -1 &&
CreateProcess(prog16, block->cmdline, opt_lpProcessAttributes,
opt_lpThreadAttributes, bInheritHandles,
+3 -3
View File
@@ -6,13 +6,13 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int mkntcmdline(char16_t[ARG_MAX / 2], const char *, char *const[]) hidden;
int mkntcmdline(char16_t[ARG_MAX / 2], char *const[]) _Hide;
int mkntenvblock(char16_t[ARG_MAX / 2], char *const[], const char *,
char[ARG_MAX]) hidden;
char[ARG_MAX]) _Hide;
int ntspawn(const char *, char *const[], char *const[], const char *,
struct NtSecurityAttributes *, struct NtSecurityAttributes *,
bool32, uint32_t, const char16_t *, const struct NtStartupInfo *,
struct NtProcessInformation *) hidden;
struct NtProcessInformation *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+4 -2
View File
@@ -292,6 +292,7 @@ static const struct thatispacked SyscallName {
{__NR_linux_epoll_wait, "epoll_wait"}, //
{__NR_linux_epoll_ctl, "epoll_ctl"}, //
{__NR_linux_getdents, "getdents"}, //
{__NR_linux_oldgetdents, "oldgetdents"}, //
{__NR_linux_set_tid_address, "set_tid_address"}, //
{__NR_linux_restart_syscall, "restart_syscall"}, //
{__NR_linux_semtimedop, "semtimedop"}, //
@@ -582,6 +583,7 @@ static const uint16_t kPledgeRpath[] = {
__NR_linux_statfs, //
__NR_linux_fstatfs, //
__NR_linux_getdents, //
__NR_linux_oldgetdents, //
};
static const uint16_t kPledgeWpath[] = {
@@ -975,13 +977,13 @@ static privileged void OnSigSys(int sig, siginfo_t *si, void *vctx) {
if (HasSyscall(kPledge + i, si->si_syscall)) {
Log("error: pledge ", kPledge[i].name, " for ",
GetSyscallName(si->si_syscall), " (ord=", ord, " rip=", rip, ")\n",
0);
NULL);
found = true;
}
}
if (!found) {
Log("error: bad syscall (", GetSyscallName(si->si_syscall), " ord=", ord,
" rip=", rip, ")\n", 0);
" rip=", rip, ")\n", NULL);
}
switch (mode & PLEDGE_PENALTY_MASK) {
case PLEDGE_PENALTY_KILL_PROCESS:
+5 -2
View File
@@ -24,6 +24,7 @@
#include "libc/errno.h"
#include "libc/intrin/promises.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/nexgen32e/vendor.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/errfuns.h"
@@ -238,8 +239,10 @@
int pledge(const char *promises, const char *execpromises) {
int e, rc;
unsigned long ipromises, iexecpromises;
if (!ParsePromises(promises, &ipromises) &&
!ParsePromises(execpromises, &iexecpromises)) {
if (IsGenuineBlink()) {
rc = 0; // blink doesn't support seccomp
} else if (!ParsePromises(promises, &ipromises) &&
!ParsePromises(execpromises, &iexecpromises)) {
if (IsLinux()) {
// copy exec and execnative from promises to execpromises
iexecpromises = ~(~iexecpromises | (~ipromises & (1ul << PROMISE_EXEC)));
+3 -3
View File
@@ -11,10 +11,10 @@ struct Pledges {
const size_t len;
};
hidden extern const struct Pledges kPledge[PROMISE_LEN_];
_Hide extern const struct Pledges kPledge[PROMISE_LEN_];
int sys_pledge_linux(unsigned long, int) hidden;
int ParsePromises(const char *, unsigned long *) hidden;
int sys_pledge_linux(unsigned long, int) _Hide;
int ParsePromises(const char *, unsigned long *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+2 -1
View File
@@ -28,6 +28,7 @@
#include "libc/nt/files.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/reparsedatabuffer.h"
#include "libc/runtime/stack.h"
#include "libc/str/str.h"
#include "libc/str/utf16.h"
#include "libc/sysv/errfuns.h"
@@ -45,7 +46,7 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
mem = 16384;
memory = alloca(mem);
for (i = 0; i < mem; i += PAGESIZE) memory[i] = 0;
CheckLargeStackAllocation(memory, mem);
rdb = (struct NtReparseDataBuffer *)memory;
if ((h = CreateFile(path16, 0, 0, 0, kNtOpenExisting,
kNtFileFlagOpenReparsePoint | kNtFileFlagBackupSemantics,
+3 -3
View File
@@ -18,11 +18,11 @@ int sys_sched_get_priority_max(int);
int sys_sched_get_priority_min(int);
int sys_sched_getparam(int, struct sched_param *);
int sys_sched_getscheduler(int);
int sys_sched_setaffinity(int, uint64_t, const void *) hidden;
int sys_sched_setaffinity(int, uint64_t, const void *) _Hide;
int sys_sched_setparam(int, const struct sched_param *);
int sys_sched_setscheduler(int, int, const struct sched_param *);
int sys_sched_yield(void) hidden;
int64_t sys_sched_getaffinity(int, uint64_t, void *) hidden;
int sys_sched_yield(void) _Hide;
int64_t sys_sched_getaffinity(int, uint64_t, void *) _Hide;
int sys_sched_getscheduler_netbsd(int, struct sched_param *);
int sys_sched_setparam_netbsd(int, int, int, const struct sched_param *) //
+2 -2
View File
@@ -17,11 +17,11 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/struct/timespec.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
int sys_sched_rr_get_interval(int, struct timespec *) hidden;
int sys_sched_rr_get_interval(int, struct timespec *) _Hide;
/**
* Returns round-robin `SCHED_RR` quantum for `pid`.
File diff suppressed because it is too large. Load diff
+8 -8
View File
@@ -28,14 +28,14 @@ struct Signals {
extern struct Signals __sig;
extern atomic_long __sig_count;
bool __sig_check(bool) hidden;
bool __sig_handle(bool, int, int, ucontext_t *) hidden;
int __sig_add(int, int, int) hidden;
int __sig_mask(int, const sigset_t *, sigset_t *) hidden;
int __sig_raise(int, int) hidden;
void __sig_check_ignore(const int, const unsigned) hidden;
void __sig_pending(sigset_t *) hidden;
int __sig_is_applicable(struct Signal *) hidden;
bool __sig_check(bool) _Hide;
bool __sig_handle(bool, int, int, ucontext_t *) _Hide;
int __sig_add(int, int, int) _Hide;
int __sig_mask(int, const sigset_t *, sigset_t *) _Hide;
int __sig_raise(int, int) _Hide;
void __sig_check_ignore(const int, const unsigned) _Hide;
void __sig_pending(sigset_t *) _Hide;
int __sig_is_applicable(struct Signal *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+1 -1
View File
@@ -7,7 +7,7 @@
COSMOPOLITAN_C_START_
int sys_sigtimedwait(const sigset_t *, union siginfo_meta *,
const struct timespec *, size_t) hidden;
const struct timespec *, size_t) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+7 -7
View File
@@ -6,13 +6,13 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
hidden extern int __vforked;
hidden extern bool __time_critical;
hidden extern unsigned __sighandrvas[NSIG];
hidden extern unsigned __sighandflags[NSIG];
hidden extern pthread_mutex_t __fds_lock_obj;
hidden extern pthread_mutex_t __sig_lock_obj;
hidden extern const struct NtSecurityAttributes kNtIsInheritable;
_Hide extern int __vforked;
_Hide extern bool __time_critical;
_Hide extern unsigned __sighandrvas[NSIG];
_Hide extern unsigned __sighandflags[NSIG];
_Hide extern pthread_mutex_t __fds_lock_obj;
_Hide extern pthread_mutex_t __sig_lock_obj;
_Hide extern const struct NtSecurityAttributes kNtIsInheritable;
void __fds_lock(void);
void __fds_unlock(void);
+9 -5
View File
@@ -184,6 +184,10 @@ static const char *DescribeStatfsTypeLinux(int64_t x) {
return "xfs";
case 0x012fd16d:
return "_xiafs";
case 0x2fc12fc1:
return "zfs";
case 0x4253584e:
return "apfs";
default:
return "unknown";
}
@@ -222,7 +226,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
} else if (IsFreebsd()) {
f_type = m->freebsd.f_type;
f_bsize = m->freebsd.f_bsize;
f_bsize = m->freebsd.f_iosize;
f_blocks = m->freebsd.f_blocks;
f_bfree = m->freebsd.f_bfree;
f_bavail = m->freebsd.f_bavail;
@@ -237,14 +241,14 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
} else if (IsXnu()) {
f_type = m->xnu.f_type;
f_bsize = m->xnu.f_bsize;
f_bsize = m->xnu.f_iosize;
f_blocks = m->xnu.f_blocks;
f_bfree = m->xnu.f_bfree;
f_bavail = m->xnu.f_bavail;
f_files = m->xnu.f_files;
f_ffree = m->xnu.f_ffree;
f_fsid = m->xnu.f_fsid;
f_namelen = 4096;
f_namelen = 255;
f_frsize = m->xnu.f_bsize;
f_flags = m->xnu.f_flags;
f_owner = m->xnu.f_owner;
@@ -252,7 +256,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
} else if (IsOpenbsd()) {
f_type = f->f_type;
f_bsize = m->openbsd.f_bsize;
f_bsize = m->openbsd.f_iosize;
f_blocks = m->openbsd.f_blocks;
f_bfree = m->openbsd.f_bfree;
f_bavail = m->openbsd.f_bavail;
@@ -267,7 +271,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
} else if (IsNetbsd()) {
f_type = m->netbsd.f_type;
f_bsize = m->netbsd.f_bsize;
f_bsize = m->netbsd.f_iosize;
f_blocks = m->netbsd.f_blocks;
f_bfree = m->netbsd.f_bfree;
f_bavail = m->netbsd.f_bavail;
+15
View File
@@ -0,0 +1,15 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERCOLORMAP_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERCOLORMAP_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
struct FrameBufferColorMap {
uint32_t start;
uint32_t len;
uint16_t *red;
uint16_t *green;
uint16_t *blue;
uint16_t *transp;
};
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_FRAMEBUFFERCOLORMAP_H_ */
+16 -16
View File
@@ -6,24 +6,24 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int64_t sys_preadv(int, struct iovec *, int, int64_t, int64_t) hidden;
int64_t sys_pwritev(int, const struct iovec *, int, int64_t, int64_t) hidden;
int64_t sys_readv(int32_t, const struct iovec *, int32_t) hidden;
int64_t sys_vmsplice(int, const struct iovec *, int64_t, uint32_t) hidden;
int64_t sys_writev(int32_t, const struct iovec *, int32_t) hidden;
size_t __iovec_size(const struct iovec *, size_t) hidden;
int64_t sys_preadv(int, struct iovec *, int, int64_t, int64_t) _Hide;
int64_t sys_pwritev(int, const struct iovec *, int, int64_t, int64_t) _Hide;
int64_t sys_readv(int32_t, const struct iovec *, int32_t) _Hide;
int64_t sys_vmsplice(int, const struct iovec *, int64_t, uint32_t) _Hide;
int64_t sys_writev(int32_t, const struct iovec *, int32_t) _Hide;
size_t __iovec_size(const struct iovec *, size_t) _Hide;
ssize_t WritevUninterruptible(int, struct iovec *, int);
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
ssize_t sys_readv_metal(struct Fd *, const struct iovec *, int) hidden;
ssize_t sys_readv_nt(struct Fd *, const struct iovec *, int) hidden;
ssize_t sys_readv_serial(struct Fd *, const struct iovec *, int) hidden;
ssize_t sys_write_nt(int, const struct iovec *, size_t, ssize_t) hidden;
ssize_t sys_writev_metal(struct Fd *, const struct iovec *, int) hidden;
ssize_t sys_writev_nt(int, const struct iovec *, int) hidden;
ssize_t sys_writev_serial(struct Fd *, const struct iovec *, int) hidden;
ssize_t sys_send_nt(int, const struct iovec *, size_t, uint32_t) hidden;
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) _Hide;
ssize_t sys_readv_metal(struct Fd *, const struct iovec *, int) _Hide;
ssize_t sys_readv_nt(struct Fd *, const struct iovec *, int) _Hide;
ssize_t sys_readv_serial(struct Fd *, const struct iovec *, int) _Hide;
ssize_t sys_write_nt(int, const struct iovec *, size_t, ssize_t) _Hide;
ssize_t sys_writev_metal(struct Fd *, const struct iovec *, int) _Hide;
ssize_t sys_writev_nt(int, const struct iovec *, int) _Hide;
ssize_t sys_writev_serial(struct Fd *, const struct iovec *, int) _Hide;
ssize_t sys_send_nt(int, const struct iovec *, size_t, uint32_t) _Hide;
ssize_t sys_sendto_nt(int, const struct iovec *, size_t, uint32_t, void *,
uint32_t) hidden;
uint32_t) _Hide;
const char *DescribeIovec(char[300], ssize_t, const struct iovec *, int);
#define DescribeIovec(x, y, z) DescribeIovec(alloca(300), x, y, z)
+3 -3
View File
@@ -5,9 +5,9 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int sys_getitimer(int, struct itimerval *) hidden;
int sys_setitimer(int, const struct itimerval *, struct itimerval *) hidden;
int sys_setitimer_nt(int, const struct itimerval *, struct itimerval *) hidden;
int sys_getitimer(int, struct itimerval *) _Hide;
int sys_setitimer(int, const struct itimerval *, struct itimerval *) _Hide;
int sys_setitimer_nt(int, const struct itimerval *, struct itimerval *) _Hide;
const char *DescribeTimeval(char[45], int, const struct timeval *);
#define DescribeTimeval(rc, ts) DescribeTimeval(alloca(45), rc, ts)
+1 -1
View File
@@ -94,7 +94,7 @@ union metastat {
struct stat_netbsd netbsd;
};
void __stat2cosmo(struct stat *restrict, const union metastat *) hidden;
void __stat2cosmo(struct stat *restrict, const union metastat *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+3 -3
View File
@@ -5,9 +5,9 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int sys_getrlimit(int, struct rlimit *) hidden;
int sys_setrlimit(int, const struct rlimit *) hidden;
int sys_setrlimit_nt(int, const struct rlimit *) hidden;
int sys_getrlimit(int, struct rlimit *) _Hide;
int sys_setrlimit(int, const struct rlimit *) _Hide;
int sys_setrlimit_nt(int, const struct rlimit *) _Hide;
const char *DescribeRlimit(char[64], int, const struct rlimit *);
#define DescribeRlimit(rc, rl) DescribeRlimit(alloca(64), rc, rl)
+6 -6
View File
@@ -4,12 +4,12 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int __sys_getrusage(int, struct rusage *) hidden;
int __sys_wait4(int, int *, int, struct rusage *) hidden;
int sys_getrusage(int, struct rusage *) hidden;
int sys_wait4(int, int *, int, struct rusage *) hidden;
void __rusage2linux(struct rusage *) hidden;
int sys_getrusage_nt(int, struct rusage *) hidden;
int __sys_getrusage(int, struct rusage *) _Hide;
int __sys_wait4(int, int *, int, struct rusage *) _Hide;
int sys_getrusage(int, struct rusage *) _Hide;
int sys_wait4(int, int *, int, struct rusage *) _Hide;
void __rusage2linux(struct rusage *) _Hide;
int sys_getrusage_nt(int, struct rusage *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+5 -5
View File
@@ -54,11 +54,11 @@ union metasigaction {
struct sigaction_xnu_out xnu_out;
};
void __sigenter_xnu(int, struct siginfo *, void *) hidden;
void __sigenter_wsl(int, struct siginfo *, void *) hidden;
void __sigenter_netbsd(int, struct siginfo *, void *) hidden;
void __sigenter_freebsd(int, struct siginfo *, void *) hidden;
void __sigenter_openbsd(int, struct siginfo *, void *) hidden;
void __sigenter_xnu(int, struct siginfo *, void *) _Hide;
void __sigenter_wsl(int, struct siginfo *, void *) _Hide;
void __sigenter_netbsd(int, struct siginfo *, void *) _Hide;
void __sigenter_freebsd(int, struct siginfo *, void *) _Hide;
void __sigenter_openbsd(int, struct siginfo *, void *) _Hide;
const char *DescribeSigaction(char[256], int, const struct sigaction *);
#define DescribeSigaction(rc, sa) DescribeSigaction(alloca(256), rc, sa)
+1 -1
View File
@@ -16,7 +16,7 @@ union siginfo_meta {
struct siginfo_netbsd netbsd;
};
void __siginfo2cosmo(struct siginfo *, const union siginfo_meta *) hidden;
void __siginfo2cosmo(struct siginfo *, const union siginfo_meta *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+1 -1
View File
@@ -5,7 +5,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int sys_sigqueueinfo(int, const siginfo_t *) hidden;
int sys_sigqueueinfo(int, const siginfo_t *) _Hide;
const char *DescribeSiginfo(char[300], int, const siginfo_t *);
#define DescribeSiginfo(x, y) DescribeSiginfo(alloca(300), x, y)
+4 -4
View File
@@ -6,10 +6,10 @@
COSMOPOLITAN_C_START_
int __sys_sigprocmask(int, const struct sigset *, struct sigset *,
uint64_t) hidden;
int sys_sigprocmask(int, const struct sigset *, struct sigset *) hidden;
int sys_sigsuspend(const struct sigset *, uint64_t) hidden;
int sys_sigpending(struct sigset *, size_t) hidden;
uint64_t) _Hide;
int sys_sigprocmask(int, const struct sigset *, struct sigset *) _Hide;
int sys_sigsuspend(const struct sigset *, uint64_t) _Hide;
int sys_sigpending(struct sigset *, size_t) _Hide;
const char *DescribeSigset(char[128], int, const sigset_t *);
#define DescribeSigset(rc, ss) DescribeSigset(alloca(128), rc, ss)
+1 -1
View File
@@ -4,7 +4,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int sys_sigqueue(int, int, const union sigval) hidden;
int sys_sigqueue(int, int, const union sigval) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+5 -5
View File
@@ -5,11 +5,11 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int sys_fstat(int, struct stat *) hidden;
int sys_fstatat(int, const char *, struct stat *, int) hidden;
int sys_fstat_nt(int64_t, struct stat *) hidden;
int sys_fstatat_nt(int, const char *, struct stat *, int) hidden;
int sys_lstat_nt(const char *, struct stat *) hidden;
int sys_fstat(int, struct stat *) _Hide;
int sys_fstatat(int, const char *, struct stat *, int) _Hide;
int sys_fstat_nt(int64_t, struct stat *) _Hide;
int sys_fstatat_nt(int, const char *, struct stat *, int) _Hide;
int sys_lstat_nt(const char *, struct stat *) _Hide;
int sys_fstat_metal(int, struct stat *);
const char *DescribeStat(char[300], int, const struct stat *);
+1 -1
View File
@@ -9,7 +9,7 @@ struct statfs_linux {
int64_t f_bsize; /* optimal transfer block size */
int64_t f_blocks; /* total data blocks in filesystem */
int64_t f_bfree; /* free blocks in filesystem */
int64_t f_bavail; /* free blocks available to */
int64_t f_bavail; /* free blocks available to unprivileged user */
int64_t f_files; /* total file nodes in filesystem */
int64_t f_ffree; /* free file nodes in filesystem */
fsid_t f_fsid; /* filesystem id */
+1 -1
View File
@@ -17,7 +17,7 @@ union statfs_meta {
struct statfs_netbsd netbsd;
};
void statfs2cosmo(struct statfs *, const union statfs_meta *) hidden;
void statfs2cosmo(struct statfs *, const union statfs_meta *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+2 -1
View File
@@ -13,7 +13,8 @@ struct sysinfo {
uint64_t totalswap; /* size of emergency memory */
uint64_t freeswap; /* hopefully equal to totalswap */
int16_t procs; /* number of processes */
int16_t __ignore; /* padding */
int16_t __ignore1; /* padding */
int32_t __ignore2; /* padding */
uint64_t totalhigh; /* wut */
uint64_t freehigh; /* wut */
uint32_t mem_unit; /* ram stuff above is multiples of this */
+2 -2
View File
@@ -4,8 +4,8 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int sys_sysinfo(struct sysinfo *) hidden;
int sys_sysinfo_nt(struct sysinfo *) hidden;
int sys_sysinfo(struct sysinfo *) _Hide;
int sys_sysinfo_nt(struct sysinfo *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+18 -18
View File
@@ -6,24 +6,24 @@
COSMOPOLITAN_C_START_
/* clang-format off */
int __sys_utimensat(int, const char *, const struct timespec[2], int) hidden;
int __utimens(int, const char *, const struct timespec[2], int) hidden;
int sys_clock_getres(int, struct timespec *) hidden;
int sys_clock_gettime(int, struct timespec *) hidden;
int sys_clock_gettime_nt(int, struct timespec *) hidden;
int sys_clock_gettime_xnu(int, struct timespec *) hidden;
int sys_clock_nanosleep(int, int, const struct timespec *, struct timespec *) hidden;
int sys_clock_nanosleep_nt(int, int, const struct timespec *, struct timespec *) hidden;
int sys_clock_nanosleep_openbsd(int, int, const struct timespec *, struct timespec *) hidden;
int sys_clock_nanosleep_xnu(int, int, const struct timespec *, struct timespec *) hidden;
int sys_futimens(int, const struct timespec[2]) hidden;
int sys_nanosleep(const struct timespec *, struct timespec *) hidden;
int sys_nanosleep_nt(const struct timespec *, struct timespec *) hidden;
int sys_nanosleep_xnu(const struct timespec *, struct timespec *) hidden;
int sys_sem_timedwait(int64_t, const struct timespec *) hidden;
int sys_utimensat(int, const char *, const struct timespec[2], int) hidden;
int sys_utimensat_nt(int, const char *, const struct timespec[2], int) hidden;
int sys_utimensat_xnu(int, const char *, const struct timespec[2], int) hidden;
int __sys_clock_nanosleep(int, int, const struct timespec *, struct timespec *) _Hide;
int __sys_utimensat(int, const char *, const struct timespec[2], int) _Hide;
int __utimens(int, const char *, const struct timespec[2], int) _Hide;
int sys_clock_getres(int, struct timespec *) _Hide;
int sys_clock_gettime(int, struct timespec *) _Hide;
int sys_clock_gettime_nt(int, struct timespec *) _Hide;
int sys_clock_gettime_xnu(int, struct timespec *) _Hide;
int sys_clock_nanosleep_nt(int, int, const struct timespec *, struct timespec *) _Hide;
int sys_clock_nanosleep_openbsd(int, int, const struct timespec *, struct timespec *) _Hide;
int sys_clock_nanosleep_xnu(int, int, const struct timespec *, struct timespec *) _Hide;
int sys_futimens(int, const struct timespec[2]) _Hide;
int sys_nanosleep(const struct timespec *, struct timespec *) _Hide;
int sys_nanosleep_nt(const struct timespec *, struct timespec *) _Hide;
int sys_nanosleep_xnu(const struct timespec *, struct timespec *) _Hide;
int sys_sem_timedwait(int64_t, const struct timespec *) _Hide;
int sys_utimensat(int, const char *, const struct timespec[2], int) _Hide;
int sys_utimensat_nt(int, const char *, const struct timespec[2], int) _Hide;
int sys_utimensat_xnu(int, const char *, const struct timespec[2], int) _Hide;
const char *DescribeTimespec(char[45], int, const struct timespec *);
#define DescribeTimespec(rc, ts) DescribeTimespec(alloca(45), rc, ts)
+8 -8
View File
@@ -5,14 +5,14 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
axdx_t sys_gettimeofday(struct timeval *, struct timezone *, void *) hidden;
int sys_futimes(int, const struct timeval *) hidden;
int sys_futimesat(int, const char *, const struct timeval *) hidden;
int sys_lutimes(const char *, const struct timeval *) hidden;
int sys_utimes(const char *, const struct timeval *) hidden;
axdx_t sys_gettimeofday_xnu(struct timeval *, struct timezone *, void *) hidden;
axdx_t sys_gettimeofday_nt(struct timeval *, struct timezone *, void *) hidden;
int sys_utimes_nt(const char *, const struct timeval[2]) hidden;
axdx_t sys_gettimeofday(struct timeval *, struct timezone *, void *) _Hide;
int sys_futimes(int, const struct timeval *) _Hide;
int sys_futimesat(int, const char *, const struct timeval *) _Hide;
int sys_lutimes(const char *, const struct timeval *) _Hide;
int sys_utimes(const char *, const struct timeval *) _Hide;
axdx_t sys_gettimeofday_xnu(struct timeval *, struct timezone *, void *) _Hide;
axdx_t sys_gettimeofday_nt(struct timeval *, struct timezone *, void *) _Hide;
int sys_utimes_nt(const char *, const struct timeval[2]) _Hide;
axdx_t sys_gettimeofday_metal(struct timeval *, struct timezone *, void *);
COSMOPOLITAN_C_END_
+2 -2
View File
@@ -5,8 +5,8 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
void _ntcontext2linux(struct ucontext *, const struct NtContext *) hidden;
void _ntlinux2context(struct NtContext *, const ucontext_t *) hidden;
void _ntcontext2linux(struct ucontext *, const struct NtContext *) _Hide;
void _ntlinux2context(struct NtContext *, const ucontext_t *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
Whitespace-only changes.
+1 -1
View File
@@ -5,7 +5,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden;
int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+34 -34
View File
@@ -3,40 +3,40 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
bool32 sys_isatty_nt(int) hidden;
char *sys_getcwd_nt(char *, size_t) hidden;
int sys_chdir_nt(const char *) hidden;
int sys_close_epoll_nt(int) hidden;
int sys_dup_nt(int, int, int, int) hidden;
int sys_execve_nt(const char *, char *const[], char *const[]) hidden;
int sys_faccessat_nt(int, const char *, int, uint32_t) hidden;
int sys_fadvise_nt(int, uint64_t, uint64_t, int) hidden;
int sys_fchdir_nt(int) hidden;
int sys_fchmodat_nt(int, const char *, uint32_t, int) hidden;
int sys_fcntl_nt(int, int, uintptr_t) hidden;
int sys_fdatasync_nt(int) hidden;
int sys_flock_nt(int, int) hidden;
int sys_fork_nt(uint32_t) hidden;
int sys_ftruncate_nt(int64_t, uint64_t) hidden;
int sys_getloadavg_nt(double *, int) hidden;
int sys_getppid_nt(void) hidden;
int sys_getpriority_nt(int, unsigned) hidden;
int sys_kill_nt(int, int) hidden;
int sys_linkat_nt(int, const char *, int, const char *) hidden;
int sys_madvise_nt(void *, size_t, int) hidden;
int sys_mkdirat_nt(int, const char *, uint32_t) hidden;
int sys_msync_nt(char *, size_t, int) hidden;
int sys_open_nt(int, const char *, uint32_t, int32_t) dontdiscard hidden;
int sys_pipe_nt(int[hasatleast 2], unsigned) hidden;
int sys_renameat_nt(int, const char *, int, const char *) hidden;
int sys_sched_yield_nt(void) hidden;
int sys_setpriority_nt(int, unsigned, int) hidden;
int sys_symlinkat_nt(const char *, int, const char *) hidden;
int sys_sync_nt(void) hidden;
int sys_truncate_nt(const char *, uint64_t) hidden;
int sys_unlinkat_nt(int, const char *, int) hidden;
int64_t sys_lseek_nt(int, int64_t, int) hidden;
ssize_t sys_readlinkat_nt(int, const char *, char *, size_t) hidden;
bool32 sys_isatty_nt(int) _Hide;
char *sys_getcwd_nt(char *, size_t) _Hide;
int sys_chdir_nt(const char *) _Hide;
int sys_close_epoll_nt(int) _Hide;
int sys_dup_nt(int, int, int, int) _Hide;
int sys_execve_nt(const char *, char *const[], char *const[]) _Hide;
int sys_faccessat_nt(int, const char *, int, uint32_t) _Hide;
int sys_fadvise_nt(int, uint64_t, uint64_t, int) _Hide;
int sys_fchdir_nt(int) _Hide;
int sys_fchmodat_nt(int, const char *, uint32_t, int) _Hide;
int sys_fcntl_nt(int, int, uintptr_t) _Hide;
int sys_fdatasync_nt(int) _Hide;
int sys_flock_nt(int, int) _Hide;
int sys_fork_nt(uint32_t) _Hide;
int sys_ftruncate_nt(int64_t, uint64_t) _Hide;
int sys_getloadavg_nt(double *, int) _Hide;
int sys_getppid_nt(void) _Hide;
int sys_getpriority_nt(int, unsigned) _Hide;
int sys_kill_nt(int, int) _Hide;
int sys_linkat_nt(int, const char *, int, const char *) _Hide;
int sys_madvise_nt(void *, size_t, int) _Hide;
int sys_mkdirat_nt(int, const char *, uint32_t) _Hide;
int sys_msync_nt(char *, size_t, int) _Hide;
int sys_open_nt(int, const char *, uint32_t, int32_t) dontdiscard _Hide;
int sys_pipe_nt(int[hasatleast 2], unsigned) _Hide;
int sys_renameat_nt(int, const char *, int, const char *) _Hide;
int sys_sched_yield_nt(void) _Hide;
int sys_setpriority_nt(int, unsigned, int) _Hide;
int sys_symlinkat_nt(const char *, int, const char *) _Hide;
int sys_sync_nt(void) _Hide;
int sys_truncate_nt(const char *, uint64_t) _Hide;
int sys_unlinkat_nt(int, const char *, int) _Hide;
int64_t sys_lseek_nt(int, int64_t, int) _Hide;
ssize_t sys_readlinkat_nt(int, const char *, char *, size_t) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+130 -127
View File
@@ -10,133 +10,136 @@ COSMOPOLITAN_C_START_
│ cosmopolitan § syscalls » system five » structless synthetic jump slots ─╬─│┼
╚────────────────────────────────────────────────────────────────────────────│*/
axdx_t __sys_fork(void) hidden;
axdx_t __sys_pipe(i32[hasatleast 2], i32) hidden;
axdx_t sys_getpid(void) hidden;
char *sys_getcwd(char *, u64) hidden;
char *sys_getcwd_xnu(char *, u64) hidden;
i32 __sys_dup3(i32, i32, i32) hidden;
i32 __sys_execve(const char *, char *const[], char *const[]) hidden;
i32 __sys_fcntl(i32, i32, ...) hidden;
i32 __sys_fcntl_cp(i32, i32, ...) hidden;
i32 __sys_fstat(i32, void *) hidden;
i32 __sys_fstatat(i32, const char *, void *, i32) hidden;
i32 __sys_gettid(i64 *) hidden;
i32 __sys_munmap(void *, u64) hidden;
i32 __sys_openat(i32, const char *, i32, u32) hidden;
i32 __sys_openat_nc(i32, const char *, i32, u32) hidden;
i32 __sys_pipe2(i32[hasatleast 2], u32) hidden;
i32 sys_arch_prctl(i32, i64) hidden;
i32 sys_chdir(const char *) hidden;
i32 sys_chroot(const char *) hidden;
i32 sys_close(i32) hidden;
i32 sys_close_range(u32, u32, u32) hidden;
i32 sys_closefrom(i32) hidden;
i32 sys_creat(const char *, u32) hidden;
i32 sys_dup(i32) hidden;
i32 sys_dup2(i32, i32) hidden;
i32 sys_dup3(i32, i32, i32) hidden;
i32 sys_execve(const char *, char *const[], char *const[]) hidden;
i32 sys_faccessat(i32, const char *, i32, u32) hidden;
i32 sys_faccessat2(i32, const char *, i32, u32) hidden;
i32 sys_fadvise(i32, i64, i64, i32) hidden;
i32 sys_fchdir(i32) hidden;
i32 sys_fchmod(i32, u32) hidden;
i32 sys_fchmodat(i32, const char *, u32, u32) hidden;
i32 sys_fchown(i64, u32, u32) hidden;
i32 sys_fchownat(i32, const char *, u32, u32, u32) hidden;
i32 sys_fcntl(i32, i32, u64, i32 (*)(i32, i32, ...)) hidden;
i32 sys_fdatasync(i32) hidden;
i32 sys_flock(i32, i32) hidden;
i32 sys_fork(void) hidden;
i32 sys_fsync(i32) hidden;
i32 sys_ftruncate(i32, i64, i64) hidden;
i32 sys_getcontext(void *) hidden;
i32 sys_getpgid(i32) hidden;
i32 sys_getpgrp(void) hidden;
i32 sys_getppid(void) hidden;
i32 sys_getpriority(i32, u32) hidden;
i32 sys_getresgid(u32 *, u32 *, u32 *) hidden;
i32 sys_getresuid(u32 *, u32 *, u32 *) hidden;
i32 sys_getsid(i32) hidden;
i32 sys_gettid(void) hidden;
i32 sys_ioctl(i32, u64, ...) hidden;
i32 sys_ioctl_cp(i32, u64, ...) hidden;
i32 sys_issetugid(void) hidden;
i32 sys_kill(i32, i32, i32) hidden;
i32 sys_linkat(i32, const char *, i32, const char *, i32) hidden;
i32 sys_madvise(void *, size_t, i32) hidden;
i32 sys_memfd_create(const char *, u32) hidden;
i32 sys_mincore(void *, u64, unsigned char *) hidden;
i32 sys_mkdirat(i32, const char *, u32) hidden;
i32 sys_mkfifo(const char *, u32) hidden;
i32 sys_mknod(const char *, u32, u64) hidden;
i32 sys_mprotect(void *, u64, i32) hidden;
i32 sys_msync(void *, u64, i32) hidden;
i32 sys_munmap(void *, u64) hidden;
i32 sys_open(const char *, i32, u32) hidden;
i32 sys_openat(i32, const char *, i32, u32) hidden;
i32 sys_pause(void) hidden;
i32 sys_pipe(i32[hasatleast 2]) hidden;
i32 sys_pipe2(i32[hasatleast 2], u32) hidden;
i32 sys_pivot_root(const char *, const char *) hidden;
i32 sys_pledge(const char *, const char *) hidden;
i32 sys_posix_openpt(i32) hidden;
i32 sys_renameat(i32, const char *, i32, const char *) hidden;
i32 sys_sem_close(i64) hidden;
i32 sys_sem_destroy(i64) hidden;
i32 sys_sem_getvalue(i64, u32 *) hidden;
i32 sys_sem_init(u32, i64 *) hidden;
i32 sys_sem_open(const char *, int, u32, i64 *) hidden;
i32 sys_sem_post(i64) hidden;
i32 sys_sem_trywait(i64) hidden;
i32 sys_sem_unlink(const char *) hidden;
i32 sys_sem_wait(i64) hidden;
i32 sys_setfsgid(i32) hidden;
i32 sys_setfsuid(i32) hidden;
i32 sys_setgid(i32) hidden;
i32 sys_setpgid(i32, i32) hidden;
i32 sys_setpriority(i32, u32, i32) hidden;
i32 sys_setregid(u32, u32) hidden;
i32 sys_setresgid(u32, u32, u32) hidden;
i32 sys_setresuid(u32, u32, u32) hidden;
i32 sys_setreuid(u32, u32) hidden;
i32 sys_setsid(void) hidden;
i32 sys_setuid(i32) hidden;
i32 sys_sigaction(i32, const void *, void *, i64, i64) hidden;
i32 sys_sigaltstack(const void *, void *) hidden;
i32 sys_symlinkat(const char *, i32, const char *) hidden;
i32 sys_sync(void) hidden;
i32 sys_sync_file_range(i32, i64, i64, u32) hidden;
i32 sys_syslog(i32, char *, i32) hidden;
i32 sys_tgkill(i32, i32, i32) hidden;
i32 sys_tkill(i32, i32, void *) hidden;
i32 sys_truncate(const char *, u64, u64) hidden;
i32 sys_uname(void *) hidden;
i32 sys_unlink(const char *) hidden;
i32 sys_unlinkat(i32, const char *, i32) hidden;
i32 sys_unmount(const char *, i32) hidden;
i32 sys_unveil(const char *, const char *) hidden;
i64 __sys_ptrace(i32, i32, i64, long *) hidden;
i64 sys_copy_file_range(i32, long *, i32, long *, u64, u32) hidden;
i64 sys_getrandom(void *, u64, u32) hidden;
i64 sys_lseek(i32, i64, i64, i64) hidden;
i64 sys_pread(i32, void *, u64, i64, i64) hidden;
i64 sys_pwrite(i32, const void *, u64, i64, i64) hidden;
i64 sys_read(i32, void *, u64) hidden;
i64 sys_readlink(const char *, char *, u64) hidden;
i64 sys_readlinkat(i32, const char *, char *, u64) hidden;
i64 sys_sendfile(i32, i32, i64 *, u64) hidden;
i64 sys_splice(i32, i64 *, i32, i64 *, u64, u32) hidden;
i64 sys_write(i32, const void *, u64) hidden;
u32 sys_getegid(void) hidden;
u32 sys_geteuid(void) hidden;
u32 sys_getgid(void) hidden;
u32 sys_getuid(void) hidden;
u32 sys_umask(u32) hidden;
void *__sys_mmap(void *, u64, u32, u32, i64, i64, i64) hidden;
void *sys_mremap(void *, u64, u64, i32, void *) hidden;
void sys_exit(i32) hidden;
axdx_t __sys_fork(void) _Hide;
axdx_t __sys_pipe(i32[hasatleast 2], i32) _Hide;
axdx_t sys_getpid(void) _Hide;
char *sys_getcwd(char *, u64) _Hide;
char *sys_getcwd_xnu(char *, u64) _Hide;
i32 __sys_dup3(i32, i32, i32) _Hide;
i32 __sys_execve(const char *, char *const[], char *const[]) _Hide;
i32 __sys_fcntl(i32, i32, ...) _Hide;
i32 __sys_fcntl_cp(i32, i32, ...) _Hide;
i32 __sys_fstat(i32, void *) _Hide;
i32 __sys_fstatat(i32, const char *, void *, i32) _Hide;
i32 __sys_gettid(i64 *) _Hide;
i32 __sys_munmap(void *, u64) _Hide;
i32 __sys_openat(i32, const char *, i32, u32) _Hide;
i32 __sys_openat_nc(i32, const char *, i32, u32) _Hide;
i32 __sys_pipe2(i32[hasatleast 2], u32) _Hide;
i32 sys_arch_prctl(i32, i64) _Hide;
i32 sys_chdir(const char *) _Hide;
i32 sys_chroot(const char *) _Hide;
i32 sys_close(i32) _Hide;
i32 sys_close_range(u32, u32, u32) _Hide;
i32 sys_closefrom(i32) _Hide;
i32 sys_creat(const char *, u32) _Hide;
i32 sys_dup(i32) _Hide;
i32 sys_dup2(i32, i32) _Hide;
i32 sys_dup3(i32, i32, i32) _Hide;
i32 sys_execve(const char *, char *const[], char *const[]) _Hide;
i32 sys_execveat(i32, const char *, char *const[], char *const[], i32) _Hide;
i32 sys_faccessat(i32, const char *, i32, u32) _Hide;
i32 sys_faccessat2(i32, const char *, i32, u32) _Hide;
i32 sys_fadvise(i32, i64, i64, i32) _Hide;
i32 sys_fchdir(i32) _Hide;
i32 sys_fchmod(i32, u32) _Hide;
i32 sys_fchmodat(i32, const char *, u32, u32) _Hide;
i32 sys_fchown(i64, u32, u32) _Hide;
i32 sys_fchownat(i32, const char *, u32, u32, u32) _Hide;
i32 sys_fcntl(i32, i32, u64, i32 (*)(i32, i32, ...)) _Hide;
i32 sys_fdatasync(i32) _Hide;
i32 sys_fexecve(i32, char *const[], char *const[]) _Hide;
i32 sys_flock(i32, i32) _Hide;
i32 sys_fork(void) _Hide;
i32 sys_fsync(i32) _Hide;
i32 sys_ftruncate(i32, i64, i64) _Hide;
i32 sys_getcontext(void *) _Hide;
i32 sys_getpgid(i32) _Hide;
i32 sys_getpgrp(void) _Hide;
i32 sys_getppid(void) _Hide;
i32 sys_getpriority(i32, u32) _Hide;
i32 sys_getresgid(u32 *, u32 *, u32 *) _Hide;
i32 sys_getresuid(u32 *, u32 *, u32 *) _Hide;
i32 sys_getsid(i32) _Hide;
i32 sys_gettid(void) _Hide;
i32 sys_ioctl(i32, u64, ...) _Hide;
i32 sys_ioctl_cp(i32, u64, ...) _Hide;
i32 sys_issetugid(void) _Hide;
i32 sys_kill(i32, i32, i32) _Hide;
i32 sys_linkat(i32, const char *, i32, const char *, i32) _Hide;
i32 sys_madvise(void *, size_t, i32) _Hide;
i32 sys_memfd_create(const char *, u32) _Hide;
i32 sys_mincore(void *, u64, unsigned char *) _Hide;
i32 sys_mkdirat(i32, const char *, u32) _Hide;
i32 sys_mkfifo(const char *, u32) _Hide;
i32 sys_mknod(const char *, u32, u64) _Hide;
i32 sys_mprotect(void *, u64, i32) _Hide;
i32 sys_msync(void *, u64, i32) _Hide;
i32 sys_munmap(void *, u64) _Hide;
i32 sys_open(const char *, i32, u32) _Hide;
i32 sys_openat(i32, const char *, i32, u32) _Hide;
i32 sys_pause(void) _Hide;
i32 sys_pipe(i32[hasatleast 2]) _Hide;
i32 sys_pipe2(i32[hasatleast 2], u32) _Hide;
i32 sys_pivot_root(const char *, const char *) _Hide;
i32 sys_pledge(const char *, const char *) _Hide;
i32 sys_posix_openpt(i32) _Hide;
i32 sys_renameat(i32, const char *, i32, const char *) _Hide;
i32 sys_sem_close(i64) _Hide;
i32 sys_sem_destroy(i64) _Hide;
i32 sys_sem_getvalue(i64, u32 *) _Hide;
i32 sys_sem_init(u32, i64 *) _Hide;
i32 sys_sem_open(const char *, int, u32, i64 *) _Hide;
i32 sys_sem_post(i64) _Hide;
i32 sys_sem_trywait(i64) _Hide;
i32 sys_sem_unlink(const char *) _Hide;
i32 sys_sem_wait(i64) _Hide;
i32 sys_setfsgid(i32) _Hide;
i32 sys_setfsuid(i32) _Hide;
i32 sys_setgid(i32) _Hide;
i32 sys_setpgid(i32, i32) _Hide;
i32 sys_setpriority(i32, u32, i32) _Hide;
i32 sys_setregid(u32, u32) _Hide;
i32 sys_setresgid(u32, u32, u32) _Hide;
i32 sys_setresuid(u32, u32, u32) _Hide;
i32 sys_setreuid(u32, u32) _Hide;
i32 sys_setsid(void) _Hide;
i32 sys_setuid(i32) _Hide;
i32 sys_shm_open(const char *, i32, u32) _Hide;
i32 sys_sigaction(i32, const void *, void *, i64, i64) _Hide;
i32 sys_sigaltstack(const void *, void *) _Hide;
i32 sys_symlinkat(const char *, i32, const char *) _Hide;
i32 sys_sync(void) _Hide;
i32 sys_sync_file_range(i32, i64, i64, u32) _Hide;
i32 sys_syslog(i32, char *, i32) _Hide;
i32 sys_tgkill(i32, i32, i32) _Hide;
i32 sys_tkill(i32, i32, void *) _Hide;
i32 sys_truncate(const char *, u64, u64) _Hide;
i32 sys_uname(void *) _Hide;
i32 sys_unlink(const char *) _Hide;
i32 sys_unlinkat(i32, const char *, i32) _Hide;
i32 sys_unmount(const char *, i32) _Hide;
i32 sys_unveil(const char *, const char *) _Hide;
i64 __sys_ptrace(i32, i32, i64, long *) _Hide;
i64 sys_copy_file_range(i32, long *, i32, long *, u64, u32) _Hide;
i64 sys_getrandom(void *, u64, u32) _Hide;
i64 sys_lseek(i32, i64, i64, i64) _Hide;
i64 sys_pread(i32, void *, u64, i64, i64) _Hide;
i64 sys_pwrite(i32, const void *, u64, i64, i64) _Hide;
i64 sys_read(i32, void *, u64) _Hide;
i64 sys_readlink(const char *, char *, u64) _Hide;
i64 sys_readlinkat(i32, const char *, char *, u64) _Hide;
i64 sys_sendfile(i32, i32, i64 *, u64) _Hide;
i64 sys_splice(i32, i64 *, i32, i64 *, u64, u32) _Hide;
i64 sys_write(i32, const void *, u64) _Hide;
u32 sys_getegid(void) _Hide;
u32 sys_geteuid(void) _Hide;
u32 sys_getgid(void) _Hide;
u32 sys_getuid(void) _Hide;
u32 sys_umask(u32) _Hide;
void *__sys_mmap(void *, u64, u32, u32, i64, i64, i64) _Hide;
void *sys_mremap(void *, u64, u64, i32, void *) _Hide;
void sys_exit(i32) _Hide;
#undef i32
#undef i64
+17 -17
View File
@@ -3,25 +3,25 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
bool isdirectory_nt(const char *) hidden;
bool isregularfile_nt(const char *) hidden;
bool issymlink_nt(const char *) hidden;
bool32 ntsetprivilege(int64_t, const char16_t *, uint32_t) hidden;
char16_t *CreatePipeName(char16_t *) hidden;
int __mkntpath(const char *, char16_t[hasatleast PATH_MAX]) hidden;
int __mkntpath2(const char *, char16_t[hasatleast PATH_MAX], int) hidden;
int __mkntpathat(int, const char *, int, char16_t[hasatleast PATH_MAX]) hidden;
int __sample_pids(int[hasatleast 64], int64_t[hasatleast 64], bool) hidden;
int ntaccesscheck(const char16_t *, uint32_t) paramsnonnull() hidden;
int sys_pause_nt(void) hidden;
int64_t __fix_enotdir(int64_t, char16_t *) hidden;
int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *) hidden;
bool isdirectory_nt(const char *) _Hide;
bool isregularfile_nt(const char *) _Hide;
bool issymlink_nt(const char *) _Hide;
bool32 ntsetprivilege(int64_t, const char16_t *, uint32_t) _Hide;
char16_t *CreatePipeName(char16_t *) _Hide;
int __mkntpath(const char *, char16_t[hasatleast PATH_MAX]) _Hide;
int __mkntpath2(const char *, char16_t[hasatleast PATH_MAX], int) _Hide;
int __mkntpathat(int, const char *, int, char16_t[hasatleast PATH_MAX]) _Hide;
int __sample_pids(int[hasatleast 64], int64_t[hasatleast 64], bool) _Hide;
int ntaccesscheck(const char16_t *, uint32_t) paramsnonnull() _Hide;
int sys_pause_nt(void) _Hide;
int64_t __fix_enotdir(int64_t, char16_t *) _Hide;
int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *) _Hide;
int64_t __winerr(void) nocallback privileged;
int64_t ntreturn(uint32_t);
void *GetProcAddressModule(const char *, const char *) hidden;
void WinMainForked(void) hidden;
void _check_sigalrm(void) hidden;
void _check_sigchld(void) hidden;
void *GetProcAddressModule(const char *, const char *) _Hide;
void WinMainForked(void) _Hide;
void _check_sigalrm(void) _Hide;
void _check_sigchld(void) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+17 -17
View File
@@ -6,27 +6,27 @@ COSMOPOLITAN_C_START_
│ cosmopolitan § syscalls » system five » structless support ─╬─│┼
╚────────────────────────────────────────────────────────────────────────────│*/
bool __is_linux_2_6_23(void) hidden;
bool __is_linux_2_6_23(void) _Hide;
bool32 sys_isatty_metal(int);
int __fixupnewfd(int, int) hidden;
int __fixupnewfd(int, int) _Hide;
int __notziposat(int, const char *);
int __tkill(int, int, void *) hidden;
int _fork(uint32_t) hidden;
int _isptmaster(int) hidden;
int _ptsname(int, char *, size_t) hidden;
int getdomainname_linux(char *, size_t) hidden;
int gethostname_bsd(char *, size_t, int) hidden;
int gethostname_linux(char *, size_t) hidden;
int gethostname_nt(char *, size_t, int) hidden;
int __tkill(int, int, void *) _Hide;
int _fork(uint32_t) _Hide;
int _isptmaster(int) _Hide;
int _ptsname(int, char *, size_t) _Hide;
int getdomainname_linux(char *, size_t) _Hide;
int gethostname_bsd(char *, size_t, int) _Hide;
int gethostname_linux(char *, size_t) _Hide;
int gethostname_nt(char *, size_t, int) _Hide;
int sys_msyscall(void *, size_t);
long sys_bogus(void);
ssize_t __getrandom(void *, size_t, unsigned) hidden;
void *__vdsosym(const char *, const char *) hidden;
void __onfork(void) hidden;
void __restore_rt() hidden;
void __restore_rt_netbsd(void) hidden;
void cosmo2flock(uintptr_t) hidden;
void flock2cosmo(uintptr_t) hidden;
ssize_t __getrandom(void *, size_t, unsigned) _Hide;
void *__vdsosym(const char *, const char *) _Hide;
void __onfork(void) _Hide;
void __restore_rt() _Hide;
void __restore_rt_netbsd(void) _Hide;
void cosmo2flock(uintptr_t) _Hide;
void flock2cosmo(uintptr_t) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+2 -6
View File
@@ -21,7 +21,6 @@
#include "libc/calls/struct/sysinfo.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timeval.h"
#include "libc/calls/struct/vmmeter-meta.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/strace.internal.h"
@@ -32,7 +31,7 @@
#define CTL_KERN 1
#define CTL_HW 6
#define KERN_BOOTTIME 21
#define HW_PHYSMEM 5
#define HW_PHYSMEM (IsXnu() ? 24 : 5)
static int64_t GetUptime(void) {
if (IsNetbsd()) return 0; // TODO(jart): Why?
@@ -44,7 +43,7 @@ static int64_t GetUptime(void) {
}
static int64_t GetPhysmem(void) {
uint64_t x;
uint64_t x = 0;
size_t n = sizeof(x);
int mib[] = {CTL_HW, HW_PHYSMEM};
if (sys_sysctl(mib, ARRAYLEN(mib), &x, &n, 0, 0) == -1) return 0;
@@ -82,9 +81,6 @@ int sysinfo(struct sysinfo *info) {
rc = sys_sysinfo_nt(&x);
}
if (rc != -1) {
x.procs = MAX(1, x.procs);
x.mem_unit = MAX(1, x.mem_unit);
x.totalram = MAX((8 * 1024 * 1024) / x.mem_unit, x.totalram);
memcpy(info, &x, sizeof(x));
}
STRACE("sysinfo(%p) → %d% m", info, rc);
+28
View File
@@ -0,0 +1,28 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2023 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or 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. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/struct/winsize.h"
/**
* Gets terminal window size.
*/
int tcgetwinsize(int fd, struct winsize *ws) {
return ioctl_tiocgwinsz(fd, ws);
}
+28
View File
@@ -0,0 +1,28 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2023 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or 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. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/struct/winsize.h"
/**
* Sets terminal window size attributes.
*/
int tcsetwinsize(int fd, const struct winsize *ws) {
return ioctl_tiocswinsz(fd, ws);
}
+2
View File
@@ -35,6 +35,8 @@ int cfsetospeed(struct termios *, unsigned);
int cfsetispeed(struct termios *, unsigned);
uint32_t cfgetospeed(const struct termios *);
uint32_t cfgetispeed(const struct termios *);
int tcsetwinsize(int, const struct winsize *);
int tcgetwinsize(int, struct winsize *);
/*───────────────────────────────────────────────────────────────────────────│─╗
│ cosmopolitan § teletypewriter » undiamonding ─╬─│┼
+1 -1
View File
@@ -29,6 +29,6 @@
*/
struct timespec timespec_mono(void) {
struct timespec ts;
_npassert(!clock_gettime(CLOCK_MONOTONIC_FAST, &ts));
_npassert(!clock_gettime(CLOCK_MONOTONIC, &ts));
return ts;
}
+1 -1
View File
@@ -31,6 +31,6 @@
*/
struct timespec timespec_real(void) {
struct timespec ts;
_npassert(!clock_gettime(CLOCK_REALTIME_FAST, &ts));
_npassert(!clock_gettime(CLOCK_REALTIME, &ts));
return ts;
}
Loaded 100 of 838 files, more files were not shown because too many files have changed in this diff. Show more