Compare commits

..
Author SHA1 Message Date
Gautham ace523c79b Tell _frozen_importlib to consider bytecode first (#248) 2021-08-17 22:07:27 -07:00
Justine Tunney c70422586a Support optimize flag 2021-08-17 14:07:59 -07:00
Justine Tunney cabb0a7ede Get Python compiler working
It turns out we needed a file length field.
2021-08-17 12:14:47 -07:00
Justine Tunney 38aece42ba Add Python object dump tool 2021-08-17 12:11:29 -07:00
Justine Tunney f66ef5d58e Change stuff 2021-08-17 10:20:55 -07:00
Justine Tunney 0c6581f912 Attempt to build Python compiler program 2021-08-17 06:28:23 -07:00
Justine Tunney d522a88def Get freeze importlib program working 2021-08-17 01:27:03 -07:00
Justine Tunney 795d6fd6cd Disable zipos trace 2021-08-17 01:26:48 -07:00
Justine Tunney d3a735702b Use real malloc so we can test Python with ASAN 2021-08-17 01:25:04 -07:00
Justine Tunney 214e3a68a9 Let's make imports simple 2021-08-17 00:10:24 -07:00
Justine Tunney 3d0347e26e Improve deltaify.com program
This program deserves its own project page on http://justine.lol since
it's so good at troubleshooting latency, e.g. `make |& deltaify.com`
2021-08-17 00:06:45 -07:00
Justine Tunney bc464a8898 Fix a few more Python tests 2021-08-16 23:47:47 -07:00
Justine Tunney 59e1c245d1 Get more Python tests passing (#141) 2021-08-16 15:26:31 -07:00
Paul Kulchenko 916f19eea1 Add GetRandomBytes to redbean Lua (#244) 2021-08-16 12:12:29 -07:00
Justine Tunney 5029e20bef Improve linenoise and get it working on Windows
Some progress has been made on introducing completion but there's been
difficulties using the Python C API to get local shell variables.
2021-08-15 14:34:05 -07:00
Gautham 968474d291 Fix typo bug in strtoll (#245) 2021-08-15 12:07:33 -07:00
Justine Tunney 228fb7428b Improve isystem includes and magic numbers 2021-08-14 23:36:36 -07:00
Justine Tunney 1e5bd4d23e Ues linenoise in Lua, Python, and SQLite 2021-08-14 11:26:23 -07:00
Justine Tunney fe29710e4e Add linenoise to third party 2021-08-14 11:09:54 -07:00
Justine Tunney 579b597ded Refactor out some duplicated code 2021-08-14 06:17:56 -07:00
Justine Tunney e963d9c8e3 Add cpu / mem / fsz limits to build system
Thanks to all the refactorings we now have the ability to enforce
reasonable limitations on the amount of resources any individual
compile or test can consume. Those limits are currently:

- `-C 8` seconds of 3.1ghz CPU time
- `-M 256mebibytes` of virtual memory
- `-F 100megabyte` limit on file size

Only one file currently needs to exceed these limits:

    o/$(MODE)/third_party/python/Objects/unicodeobject.o: \
        QUOTA += -C16  # overrides cpu limit to 16 seconds

This change introduces a new sizetol() function to LIBC_FMT for parsing
byte or bit size strings with Si unit suffixes. Functions like atoi()
have been rewritten too.
2021-08-13 23:40:53 -07:00
Justine Tunney 9b29358511 Make whitespace changes
Status lines for Emacs and Vim have been added to Python sources so
they'll be easier to edit using Python's preferred coding style.

Some DNS helper functions have been broken up into multiple files. It's
nice to have one function per file whenever possible, since that way we
don't need -ffunction-sections.  Another reason it's good to have small
source files, is because the build will be enforcing resource limits on
compilation and testing soon.
2021-08-13 03:20:45 -07:00
Justine Tunney 71273bc5c9 Revert explicit Lua GC pass (#241) 2021-08-13 03:06:23 -07:00
Gautham 1aa0df696c Test changes to Actually Portable Python (#240)
- Add missing `os.pipe` and `os.getuid`
- Commented out _dummy_thread from Lib/threading.py so tests
  don't simulate multi-threading and waste time/error out
- Revert test_hashlib to avoid blake2
2021-08-13 02:24:43 -07:00
Paul Kulchenko a22f0736d8 Improve Redbean Lua memory (#241)
- Update redbean Lua to check there is enough stack to use
- Add explicit Lua gc pass after each message is processed
- Add Lua memory reporting to redbean
2021-08-13 02:11:49 -07:00
Justine Tunney b420ed8248 Undiamond Python headers
This change gets the Python codebase into a state where it conforms to
the conventions of this codebase. It's now possible to include headers
from Python, without worrying about ordering. Python has traditionally
solved that problem by "diamonding" everything in Python.h, but that's
problematic since it means any change to any Python header invalidates
all the build artifacts. Lastly it makes tooling not work. Since it is
hard to explain to Emacs when I press C-c C-h to add an import line it
shouldn't add the header that actually defines the symbol, and instead
do follow the nonstandard Python convention.

Progress has been made on letting Python load source code from the zip
executable structure via the standard C library APIs. System calss now
recognizes zip!FILENAME alternative URIs as equivalent to zip:FILENAME
since Python uses colon as its delimiter.

Some progress has been made on embedding the notice license terms into
the Python object code. This is easier said than done since Python has
an extremely complicated ownership story.

- Some termios APIs have been added
- Implement rewinddir() dirstream API
- GetCpuCount() API added to Cosmopolitan Libc
- More bugs in Cosmopolitan Libc have been fixed
- zipobj.com now has flags for mangling the path
- Fixed bug a priori with sendfile() on certain BSDs
- Polyfill F_DUPFD and F_DUPFD_CLOEXEC across platforms
- FIOCLEX / FIONCLEX now polyfilled for fast O_CLOEXEC changes
- APE now supports a hybrid solution to no-self-modify for builds
- Many BSD-only magnums added, e.g. O_SEARCH, O_SHLOCK, SF_NODISKIO
2021-08-12 14:07:40 -07:00
Paul Kulchenko 20bb8db9f8 Fix type signature of new Lua hooks (#239) 2021-08-12 00:15:39 -07:00
Paul Kulchenko a2e443edd7 Update redbean to show Lua stack traces (#237)
- Update redbean to include stack trace in Lua errors
- Extend Lua in redbean to include stack trace in all logged errors
- Update default error page in redbean with error details (when allowed)
- Prepend `@` to Lua paths in redbean to recognize them as paths in error messages
- Replace GetClientAddr with GetRemoteAddr to avoid backtrace leak in proxy scenarios
- Fix typo in GetRemoteAddr documentation
2021-08-11 23:27:39 -07:00
Gautham 9454788223 Fix sysconfig check for build vars (#238) 2021-08-11 23:21:54 -07:00
Justine Tunney 31a37aeb1a Fix some example code 2021-08-10 13:38:27 -07:00
Justine Tunney 79ba5233db Fix regression caused by state assertions change 2021-08-10 11:36:17 -07:00
Justine Tunney d26d7ae0e4 Perform build and magnum tuning
Building o//third_party/python now takes 5 seconds on my PC

This change works towards modifying Python to use runtime dispatching
when appropriate. For example, when loading the magnums in the socket
module, it's a good idea to check if the magnum is zero, because that
means the local system platform doesn't support it.
2021-08-10 10:26:13 -07:00
Justine Tunney ee7e296339 Add state assertions to redbean Lua APIs
Many of the API functions provided by redbean are only appropriate to
call in certain contexts, such as request handling or .init.lua, etc.
For example, Fetch can't be called from the global scope of .init.lua
because SSL hasn't been configured yet. Earlier if this happened then
redbean would crash, which was confusing. What we'll do now is show a
friendly error message. See #97

This change also undocuments redbean ssl compression support since it
seems to be causing a flake in the testing infrastructure.
2021-08-09 15:35:38 -07:00
Justine Tunney 3bfb7580c5 Add Lua compiler
Redbean Lua Server Pages may now be stored in the zip as byte code. This
can improve performance, since redbean currently doesn't cache byte code
but it might be more useful for anyone wanting to create a closed source
redbean. The .lua extension should be used for byte code files. Lua will
tell them apart based on a magic number at the start of the file.

This change also improves some Lua error reporting conditions. See #97
2021-08-09 13:09:14 -07:00
Justine Tunney b703eee96e Fix obvious Python performance suboptimality 2021-08-09 10:41:06 -07:00
Justine Tunney 5a441ea57f Remove Python gitignore 2021-08-09 09:15:23 -07:00
Justine Tunney 10aade69e3 Remove wildcard from Python build config
It's important for build performance to use := rather than = notation so
that $(wildcard foo/*) isn't a lazily evaluated lambda. In the case of
Python where we need a lot of tuning and excludes, it should help to
spell things out a bit more to just not use wildcard for now.
2021-08-09 08:59:18 -07:00
Justine Tunney 53b9f83e1c Make redbean SSL more tunable
This change enables SSL compression. It significantly reduces the
network load of the testing infrastructure, for free, since this
revision didn't need to change any runit protocol code. However we
turn it off by default in redbean since no browsers support it.

It turns out that some TLSv1.0 clients (e.g. curl command on RHEL5) will
send an SSLv2-style ClientHello. These types of clients are usually ten+
years old and were designed to interop with servers ten years older than
them. Your redbean is now able to interop with these clients even though
redbean doesn't actually support SSLv2 or SSLv3. Please note that the -B
flag may be passed to disable this along with TLSv1.0, TLSv1.1, 3DES, &c

The following Lua APIs have been added to redbean:

  - ProgramSslCompression(bool)
  - ProgramSslCiphersuite(name:str)
  - ProgramSslPresharedKey(key:str,identity:str)

Lastly the DHE ciphersuites have been enabled. IANA recommends DHE and
with old clients like RHEL5 it's the only perfect forward secrecy they
implement.
2021-08-09 07:38:57 -07:00
Justine Tunney d86027fe90 Integrate Chromium Zlib changes 2021-08-09 06:59:10 -07:00
Justine Tunney 798d542f15 Fix build and delete superfluous files
- Make Python make formatting pristine
- Add missing `#pragma weak` to Python source
- Fix Clang script flake due to missing directory
2021-08-09 06:57:14 -07:00
ahgamut 295b3d6ca5 removed unnecessary libs from zip store 2021-08-09 05:39:42 -07:00
ahgamut f9eae9794a stdlib sysconfig import fix 2021-08-09 05:39:42 -07:00
ahgamut 98f330b764 Added build config to get python.com
Modules/Setup and Modules/Setup.local contain the build recipes for
various extensions, wrote a custom script to translate them for
python.mk. Modules/config.c needs to be changed if any extensions are
removed or added.

Most of the source modifications are for missing headers or compile time
build vars like ABIFLAGS.

Created separate mk files for the C extensions and the Python stdlib.
Can use find for adding the python files to the APE ZIP store, but right
now necessary files are just hardcoded.

python.com loads but some build configs are still missing (showing 1 Jan
1970 as time of compilation).
2021-08-09 05:39:42 -07:00
ahgamut 5ef64dbcdb Source changes for compilation
These are the commits from
https://github.com/ahgamut/cpython/tree/cosmo_py36 squashed for
simplicity.

Also included is the pyconfig.h used for compilation. The pyconfig.h has
to be changed manually in case Cosmopolitan gets new features.
2021-08-09 05:39:42 -07:00
ahgamut 0c4c56ff39 python-3.6.zip added from Github
README.cosmo contains the necessary links.
2021-08-09 05:39:42 -07:00
Robert Hencke 75fc601ff5 Only re-open executable as O_RDWR if .ape present (#234)
AWS Lambda uses a nonstandard kernel behavior that causes
OpenExecutable() to SIGSEGV after redbean restores its APE
header. This change fixes a bug so that Lambda users may
work around the issue by removing the `.ape` file inside the
zip structure of redbean.com.

Fixes #233
2021-08-09 00:52:54 -07:00
Justine Tunney 28a592f2d4 Clarify kLogFatal documentation
Fixes #231
2021-08-07 18:18:12 -07:00
w13b3 d8faadf44e Fix redbean Log() in global scope (#230) 2021-08-07 17:30:49 -07:00
Justine Tunney 4daafef63a Implement RFC8442 2021-08-07 16:43:00 -07:00
Paul Kulchenko 2bc0901ce3 Revert adding lua array per discussion in #222 (#229)
This reverts commit 55a15c204e.
2021-08-07 15:20:33 -07:00
Paul Kulchenko 6bbb44c165 Add GetHostOs to redbean (#228) 2021-08-07 14:25:55 -07:00
Justine Tunney 0cdba6878b Secure the testing infrastructure 2021-08-07 13:22:35 -07:00
Justine Tunney 1f766a332f Add function for creating hex string literals 2021-08-07 07:05:19 -07:00
Justine Tunney aeeb851422 Fix bugs and make improvements to redbean
- Abort if .init.lua fails
- Refactor redbean to use new append library
- Use first certificate if SNI routing fails
- Use function/data sections when building Lua
- Don't use self-signed auto-generated cert for client
- Add -D staging dirs to redbean lua module default path
2021-08-06 14:18:34 -07:00
Paul Kulchenko 55a15c204e Add arrays to Lua (#222)
You can now have O(1) length and append.
2021-08-06 04:55:01 -07:00
Paul Kulchenko b142ea7176 Add following redirects to redbean Fetch (#226) 2021-08-06 04:48:46 -07:00
Paul Kulchenko fd76fa0016 Fix OnServerStart/Stop hooks (#225)
Fixes #224
2021-08-06 04:27:50 -07:00
Justine Tunney 533f3d1ef1 Reduce build latency and fix old cpu bugs 2021-08-05 14:43:53 -07:00
Justine Tunney df8ab0aa0c Restore Referer-Policy and wrap up MbedTLS changes
redbean will now set Referer-Policy to no-referrer-when-downgrade on
text/html responses by default. There's better explanations on the bits
of security redbean is offering. In short, it's 128+ for modern clients
and 112+ for legacy. If the -B flag is used then it's 192+ for modern
and 150+ for non-EC.
2021-08-04 01:05:49 -07:00
Paul Kulchenko 344d2dc356 Redbean doc update (#221)
- Update redbean documentation for consistency and fix typo (#97)
- Update redbean constants for consistency
- Add Fetch documentation to redbean (#97)
2021-08-03 17:57:15 -07:00
Paul Kulchenko f7b4804251 Add Sleep API to redbean (#220) 2021-08-02 14:53:24 -07:00
Paul Kulchenko 64d87d4e5a Add GetRedbeanVersion & rename GetVersion (#219)
- Add GetRedbeanVersion() to redbean (#97)
- Rename GetVersion to GetHttpVersion() for consistency (#97)
- Update Content-Length format to use a proper size modifier (#97, #218)
2021-08-02 14:46:43 -07:00
Paul Kulchenko 0b317523a0 Accept table arg in redbean Fetch() API (#218) 2021-07-28 09:33:10 -07:00
Paul Kulchenko a73e808b25 Upgrade Lua to 5.4.3 (#217)
Based on https://github.com/lua/lua/releases/tag/v5.4.3 (commit eadd8c7).
2021-07-28 09:26:35 -07:00
Paul Kulchenko 3ac6576fe5 Improve type descriptions in redbean help (#213) 2021-07-28 09:22:13 -07:00
Paul Kulchenko 312ccc919b Fix redbean help typos (#212) 2021-07-28 09:20:24 -07:00
Justine Tunney ea83cc0ad0 Make stronger crypto nearly as fast
One of the disadvantages of x25519 and ℘256 is it only provides 126 bits
of security, so that seems like a weak link in the chain, if we're using
ECDHE-ECDSA-AES256-GCM-SHA384. The U.S. government wants classified data
to be encrypted using a curve at least as strong as ℘384, which provides
192 bits of security, but if you read the consensus of stack exchange it
would give you the impression that ℘384 is three times slower.

This change (as well as the previous one) makes ℘384 three times as fast
by tuning its modulus and multiplication subroutines with new tests that
should convincingly show: the optimized code behaves the same way as the
old code. Some of the diff noise from the previous change is now removed
too, so that our vendored fork can be more easily compared with upstream
sources. So you can now have stronger cryptography without compromises.

℘384 modulus Justine                        l:         28𝑐          9𝑛𝑠
℘384 modulus MbedTLS NIST                   l:        127𝑐         41𝑛𝑠
℘384 modulus MbedTLS MPI                    l:      1,850𝑐        597𝑛𝑠

The benchmarks above show the improvements made by secp384r1() which is
an important function since it needs to be called 13,000 times whenever
someone establishes a connection to your web server. The same's true of
Mul6x6Adx() which is able to multiply 384-bit numbers in 73 cycles, but
only if your CPU was purchased after 2014 when Broadwell was introduced
2021-07-26 16:19:45 -07:00
Justine Tunney 398f0c16fb Add SNI support to redbean and improve SSL perf
This change makes SSL virtual hosting possible. You can now load
multiple certificates for multiple domains and redbean will just
figure out which one to use, even if you only have 1 ip address.
You can also use a jumbo certificate that lists all your domains
in the the subject alternative names.

This change also makes performance improvements to MbedTLS. Here
are some benchmarks vs. cc1920749e

                                   BEFORE    AFTER   (microsecs)
suite_ssl.com                     2512881   191738 13.11x faster
suite_pkparse.com                   36291     3295 11.01x faster
suite_x509parse.com                854669   120293  7.10x faster
suite_pkwrite.com                    6549     1265  5.18x faster
suite_ecdsa.com                     53347    18778  2.84x faster
suite_pk.com                        49051    18717  2.62x faster
suite_ecdh.com                      19535     9502  2.06x faster
suite_shax.com                      15848     7965  1.99x faster
suite_rsa.com                      353257   184828  1.91x faster
suite_x509write.com                162646    85733  1.90x faster
suite_ecp.com                       20503    11050  1.86x faster
suite_hmac_drbg.no_reseed.com       19528    11417  1.71x faster
suite_hmac_drbg.nopr.com            12460     8010  1.56x faster
suite_mpi.com                      687124   442661  1.55x faster
suite_hmac_drbg.pr.com              11890     7752  1.53x faster

There aren't any special tricks to the performance imporvements.
It's mostly due to code cleanup, assembly and intel instructions
like mulx, adox, and adcx.
2021-07-23 13:56:13 -07:00
Justine Tunney f3e28aa192 Make SSL handshakes much faster
This change boosts SSL handshake performance from 2,627 to ~10,000 per
second which is the same level of performance as NGINX at establishing
secure connections. That's impressive if we consider that redbean is a
forking frontend application server. This was accomplished by:

  1. Enabling either SSL session caching or SSL tickets. We choose to
     use tickets since they reduce network round trips too and that's
     a more important metric than wrk'ing localhost.

  2. Fixing mbedtls_mpi_sub_abs() which is the most frequently called
     function. It's called about 12,000 times during an SSL handshake
     since it's the basis of most arithmetic operations like addition
     and for some strange reason it was designed to make two needless
     copies in addition to calling malloc and free. That's now fixed.

  3. Improving TLS output buffering during the SSL handshake only, so
     that only a single is write and read system call is needed until
     blocking on the ping pong.

redbean will now do a better job wiping sensitive memory from a child
process as soon as it's not needed. The nice thing about fork is it's
much faster than reverse proxying so the goal is to use the different
address spaces along with setuid() to minimize the risk that a server
key will be compromised in the event that application code is hacked.
2021-07-11 23:17:47 -07:00
Justine Tunney 8c4cce043c Make improvements to redbean
The following Lua APIs have been added:

  - IsDaemon() → bool
  - ProgramPidPath(str)

The following Lua hooks have been added:

  - OnClientConnection(ip:int,port:int,serverip:int,serverport:int) → bool
  - OnProcessCreate(pid:int,ip:int,port:int,serverip:int,serverport:int)
  - OnProcessDestroy(pid:int)
  - OnServerStart()
  - OnServerStop()
  - OnWorkerStart()
  - OnWorkerStop()

redbean now does a better job at applying gzip on the fly from the local
filesystem, using a streaming chunked api with constant memory, which is
useful for doing things like serving a 4gb text file off NFS, and having
it start transmitting in milliseconds. redbean will also compute entropy
on the beginnings of files to determine if compression is profitable.

This change pays off technical debts relating to memory, such as relying
on exit() to free() allocations. That's now mostly fixed so it should be
easier now to spot memory leaks in malloc traces.

This change also fixes bugs and makes improvements to our SSL support.
Uniprocess mode failed handshakes are no longer an issue. Token Alpn is
offered so curl -v looks less weird. Hybrid SSL certificate loading is
now smarter about naming conflicts. Self-signed CA root anchors will no
longer be delivered to the client during the handshake.
2021-07-10 15:19:37 -07:00
Paul Kulchenko 98c674d915 Update Fetch() to POST if body is provided (#211) 2021-07-10 12:39:02 -07:00
Gautham e99a4dcc8c Add protoent and netent (#209)
The implementations of the getproto* functions follow from the getserv*
functions: same static name allocation, same type of internal function
that opens a file to search, aliases are not written to the struct, same
type of error handling/returns.

This changes also fixes a getaddrinfo AI_PASSIVE memory error. When
getaddrinfo is passed name = NULL and AI_PASSIVE in hints->ai_flags, it was
setting the s_addr value to INADDR_ANY but *not* returning the addrinfo
pointer via *res = ai. This caused a free(NULL) memory error when the caller
tried to free res, because the caller expects res to be a valid pointer to a
struct addrinfo.

Our non-standard API parseport() has been updated to use strtoimax.
strtoimax has an extra parameter endptr to store where the parsing was
terminated. endptr is used in parseport to check if the provided string
was valid.
2021-07-10 12:36:35 -07:00
Justine Tunney c002e4ba76 Support hybrid ECDSA / RSA certificate loading 2021-07-09 19:21:00 -07:00
Justine Tunney fe881982b5 Make slight SSL performance improvements 2021-07-08 21:54:21 -07:00
Justine Tunney 4178896aa0 Fix bug with redbean help flag 2021-07-08 18:28:11 -07:00
Justine Tunney 3641e99042 Add Lua API documentation to redbean -h | less 2021-07-08 17:55:35 -07:00
Justine Tunney 45d72920ba Fix chained certificate loading 2021-07-08 17:29:32 -07:00
Justine Tunney feb0f9fb3a Make improvements to redbean
- Fix Content-Type inference when file extension has number
- Remove shoddy Class A granular IP classiifcation
- Have setuid() and setgid() take effect w/o daemonization
- Make GetParams() return empty table instead of nil
- Change SetLogLevel(int) to only apply to one message
- Make SetLogLevel(int) good enough to be access_log off
- Introduce ProgramUid(int) which is same as -U INT
- Introduce ProgramGid(int) which is same as -G INT
- Introduce ProgramLogPath(str) which is same as -L PATH
- Introduce ProgramDirectory(str) which is same as -D PATH
- Introduce ProgramLogBodies(bool) which is same as -b
- Introduce ProgramLogMessages(bool) which is same as -m
2021-07-08 15:56:23 -07:00
Justine Tunney cc9366b200 Add file Slurp() API to redbean 2021-07-08 13:21:16 -07:00
Justine Tunney c89bc56f6a Add HTTP/HTTPS Fetch() API to redbean
You can now say the following in your redbean Lua code:

    status,headers,payload = Fetch("https://foo.example")

The following Lua APIs have been introduced:

  - Fetch(str) → str,{str:str},str
  - GetHttpReason(int) → str
  - GetHttpReason(int) → str
  - ProgramSslFetchVerify(bool)
  - ProgramSslClientVerify(bool)

The following flags have been introduced:

  - `-j` enables client SSL verification
  - `-k` disables Fetch() SSL verification
  - `-t INT` may now be passed a negative value for keepalive

Lua exceptions now invoke Cosmopolitan's garbage collector when
unwinding the stack. So it's now safe to use _gc() w/ Lua 𝔱𝔥𝔯𝔬𝔴

See #97
2021-07-07 21:44:27 -07:00
Justine Tunney 36b2710e1a Update curl example to support ssl / https
Now that we know our SSL client works, and that it's able to verify
certificates, the next step will be adding it as an API to redbean.

See #97
2021-07-06 13:39:18 -07:00
Justine Tunney e51034bab3 Make GCM AES faster
13.22% mbedtls_aesni_gcm_mult
    13.03% mbedtls_gcm_update
     9.85% mbedtls_aesni_crypt_ecb

Overhead improvement (perf record)

    10.97% mbedtls_aesni_gcm_mult
    10.59% mbedtls_aesni_crypt_ecb
     2.26% mbedtls_gcm_update
2021-07-06 08:27:16 -07:00
Justine Tunney f8b9bd2b47 Attempt to make LLD happy
Things are a little better. The LLD that comes with Linux seems to work.
Old versions like LLVM 8 haven't been supported since Cosmopolitan v0.2.
Running Clang on Windows with --target=x86_64-pc-linux-gnu doesn't seem
to work. It has something to do with the recently added .zip section in
the linker script. But even if that's removed, LLD on Windows thinks it
is building an EFI application for some reason. Linker scripts are such
a brittle house of cards, even for just ld.bfd alone..

We should just find a way to run our one true musl-cross-make linux gcc
toolchain under Blinkenlights on non-Linux because GCC and Clang are so
nondeterministic, inconsistent, and unreproducible when built for other
operating systems. We need an actually portable compiler/linker that'll
always behave the same way no matter what.

See #180
2021-07-05 19:10:06 -07:00
Justine Tunney 0ecd71f697 Make chacha20 go faster 2021-07-05 14:03:50 -07:00
Gautham c0bec24fa2 Improve getservbyname and getservbyport (#207)
- support aliases in /etc/services
- use case insensitive comparisons
- add tests
2021-07-05 12:25:26 -07:00
Justine Tunney 58fb2fb3d3 Add chunked transfer decoding to redbean 2021-07-05 01:05:10 -07:00
Justine Tunney 8d5f60a9cd Add more hashing apis to redbean 2021-07-05 01:05:10 -07:00
Gautham 0ea2907730 Add getservbyname and getservbyport (#204)
For every call of getservbyname/getservbyport the lookup of
/etc/services is done by opening the file and parsing each line
one-by-one. This is slow, but the implementation is simple.

This change also adds fixes for the gethostbyname function.
2021-07-04 16:31:42 -07:00
Justine Tunney cfbd2afc19 Add example for printing <img> tag 2021-07-04 15:41:43 -07:00
Justine Tunney a7bd4ed9ea Make redbean tinier
Under MODE=tiny or MODE=tinylinux we now go back to using my homebrew
version of DEFLATE decompression which is 10x smaller but 10x slower
than Chromium Zlib. In tiny mode we also disable compressed responses
howewver redbean will still serve precompressed responses. This change
also removes a few other dependencies like strftime() and getaddrinfo()
which means you can't say `-l localhost` in tiny mode, you have to say
something like `-l 127.0.0.1`.

    m=tinylinux
    make -j8 MODE=$m o/$m/tool/net/redbean-original.com
    ls -hal o/$m/tool/net/redbean-original.com

This change reduces the above size from 191.4 to 150.9 kb.
2021-07-04 12:26:54 -07:00
Justine Tunney 300876ee50 Fix typo 2021-07-03 10:16:38 -07:00
Justine Tunney e6b22f1f65 Remove remaining build references to zip command 2021-07-03 08:37:15 -07:00
Justine Tunney d6873f637f Release redbean 1.4 2021-07-03 05:58:47 -07:00
Justine Tunney 74200a0ea0 Make redbean ssl handshake go a little faster 2021-07-03 05:51:04 -07:00
Justine Tunney 87222aad35 Improve PrintMemoryIntervals 2021-07-03 04:19:10 -07:00
Justine Tunney 053ee714bd Add Braille Dump tool 2021-07-02 10:24:12 -07:00
Justine Tunney 8e69cf133a Restore basicidea.c from gist 2021-07-02 08:09:56 -07:00
Gautham 3fe7b95fd0 Add gethostbyname and gethostbyaddr (#200)
gethostbyname, gethostbyaddr follow simple implementations: they
internally call getaddrinfo and getnameinfo respectively, and fill out
the minimum details. remaining functions are stubs.
2021-07-01 07:55:11 -07:00
Justine Tunney 014d4bdab2 Make minor revisions to previous change 2021-06-30 10:45:27 -07:00
Justine Tunney a68cc690ff Merge HTTP request / response parsing code
This change also fixes a bug so that DNS lookups work correctly when the
first answer is a CNAME record.
2021-06-27 17:04:32 -07:00
fabriziobertocci 5a6c0f27c3 Fix redundancy in ioctl(SIOCGIFADDR) (#198) 2021-06-27 09:03:14 -07:00
Justine Tunney 2d79ab6c15 Make sha1 / sha256 / sha512 go faster 2021-06-26 00:11:12 -07:00
Justine Tunney 5144c22189 Add test for ioctl(SIOCGIFCONF) and polyfill on BSDs
- Use nullness checks when calling weakly linked functions.

- Avoid typedef for reasons described in Linux Kernel style guide.

- Avoid enum in in Windows headers. Earlier in Cosmo's history all one
  hundred files in libc/nt/enum/ used to be enums and it resulted in
  gigabytes of DWARF data almost as large as everything else in the
  codebase combined.

- Bitfields aren't our friends. They have frequent ABI breakages,
  inconsistent arithmetic across compilers, and different endianness
  between cpus. Compiler authors also haven't invested much roi into
  making bit fields go fast so they produce poor assembly.

- Use memccpy() instead of strncpy() or snprintf() for length-bounded
  copying of C strings. strncpy() is a misunderstood function and
  snprintf() is awesome but memccpy() deserves more love.
2021-06-25 18:44:04 -07:00
Justine Tunney 86ab24ce56 Correct minor issues with recent SSL change 2021-06-24 15:22:24 -07:00
Justine Tunney cc1920749e Add SSL to redbean
Your redbean can now interoperate with clients that require TLS crypto.
This is accomplished using a protocol polyglot that lets us distinguish
between HTTP and HTTPS regardless of the port number. Certificates will
be generated automatically, if none are supplied by the user. Footprint
increases by only a few hundred kb so redbean in MODY=tiny is now 1.0mb

- Add lseek() polyfills for ZIP executable
- Automatically polyfill /tmp/FOO paths on NT
- Fix readdir() / ftw() / nftw() bugs on Windows
- Introduce -B flag for slower SSL that's stronger
- Remove mbedtls features Cosmopolitan doesn't need
- Have base64 decoder support the uri-safe alternative
- Remove Truncated HMAC because it's forbidden by the IETF
- Add all the mbedtls test suites and make them go 3x faster
- Support opendir() / readdir() / closedir() on ZIP executable
- Use Everest for ECDHE-ECDSA because it's so good it's so good
- Add tinier implementation of sha1 since it's not worth the rom
- Add chi-square monte-carlo mean correlation tests for getrandom()
- Source entropy on Windows from the proper interface everyone uses

We're continuing to outperform NGINX and other servers on raw message
throughput. Using SSL means that instead of 1,000,000 qps you can get
around 300,000 qps. However redbean isn't as fast as NGINX yet at SSL
handshakes, since redbean can do 2,627 per second and NGINX does 4.3k

Right now, the SSL UX story works best if you give your redbean a key
signing key since that can be easily generated by openssl using a one
liner then redbean will do all the things that are impossibly hard to
do like signing ecdsa and rsa certificates that'll work in chrome. We
should integrate the let's encrypt acme protocol in the future.

Live Demo: https://redbean.justine.lol/
Root Cert: https://redbean.justine.lol/redbean1.crt
2021-06-24 13:20:50 -07:00
Justine Tunney 1beeb7a829 Flatten Mbed TLS directory structure 2021-06-24 11:13:12 -07:00
Justine Tunney d0ac995dc0 Get Mbed TLS to build
This change configures Mbed TLS to support the fewest number of things
possible required to run an HTTPS server that caters to the sweet spot
of being legacy enough to support the vast majority of user agents but
modern enough that Chrome and Firefox remain happy. That should entail

- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_RSA_WITH_AES_128_CBC_SHA

Even though other suites still get included so what usually happens in
practice is ECDHE-RSA-AES256-GCM-SHA384 under TLS 1.2 will be selected
and the binary footprint is reasonable, and should cost us about 200kb
2021-06-24 11:12:59 -07:00
Justine Tunney 19bd27358a Import Mbed TLS v2.26.0 2021-06-24 11:12:45 -07:00
Justine Tunney 1ba33d233c Add root certificates 2021-06-24 11:12:23 -07:00
fabriziobertocci fd0eefce17 Add ioctl(SIOCGIFxxx) support (#197)
- SIOCGIFCONFIG: reads and enumerate all the network interfaces
- SIOCGIFADDR: reads network address for a given interface
- SIOCGIFFLAGS: reads network flags for a given interface
- SIOCGIFNETMASK: reads network netmask for a given interface
- SIOCGIFBRDADDR: reads network broadcast address for a given interface
- SIOCGIFDSTADDR: reads peer destination address for a given
  interface (not supported for Windows)

This change defines Linux ABI structs for the above interfaces and adds
polyfills to ensure they behave consistently on XNU and Windows.
2021-06-24 10:53:27 -07:00
ahgamut 4d8f884e76 Get Info-ZIP's zip to build
* removed unnecessary files (like amiga/osdep.h)
* makefile has 4 targets: zip, zipnote, zipcloak, zipsplit
* added clang-format off at the start of all source files
* added necessary headers
2021-06-22 12:38:56 -07:00
ahgamut 4ce5664c4b added zip from Info-ZIP 2021-06-22 12:38:56 -07:00
Gautham 98c53ae526 Simplify getnameinfo (#196)
The getnameinfo implementation requires an address -> name lookup on the
hosts file (ie struct HostsTxt) and the previous implementation used
flags to check whether HostsTxt was sorted according to address or name,
and then re-sorted it if necessary. Now getnameinfo lookup does not
require sorting, it does a simple linear lookup, and so the related code
was simplified

See #172 for discussion.
2021-06-22 12:35:58 -07:00
Justine Tunney 1f87640d17 Add half close flag to netcat example 2021-06-15 11:24:24 -07:00
Justine Tunney e4ef38403b Make port optional in X-Forwarded-For
This parser was being overly restrictive which presented integration
issues with haproxy which doesn't make it easy to pass the port info
2021-06-15 06:46:30 -07:00
Justine Tunney 87d7010495 Improve performance of bitscanning intrinsics
This change helps spectre more intelligently plan execution, by working
around false output dependencies, impacting ops like popcnt bsr and bsf
2021-06-15 06:29:51 -07:00
Justine Tunney 29cb53881e Fix SQLite home directory discovery on Windows
See #193
2021-06-12 00:28:06 -07:00
Justine Tunney 8d7d00af3a Pacify file locks on Windows
This change gets redbean SQLite working in write mode on Windows.
Warnings have been added to the appropriate and responsible places.
Hacking proprietary PC systems into production-worthy servers isn't
terribly high on the list of priorities. Consider BSD or Linux when
building online systems that service requests from multiple people.

Fixes #193
2021-06-12 00:01:55 -07:00
Justine Tunney 9504ebaf7e Introduce fsum() 2021-06-11 16:49:30 -07:00
Justine Tunney 8b08e81a07 Fix build in opt mode 2021-06-11 16:47:48 -07:00
Justine Tunney a3ccc5af1f Fix redbean hidden path bug 2021-06-10 08:55:50 -07:00
Justine Tunney f271ffcf90 Release redbean 1.2 2021-06-10 08:14:45 -07:00
Justine Tunney 88806b79b1 Tune SQLite build for redbean (#97)
redbean lua handlers that perform sql queries can do 400k qps.

We now use a separate compile-time options for SQLite, when building the
SQLite shell versus building the production web serving code. It doesn't
seem appropriate for something like redbean to include backups, progress
callbacks, query completion, profiling, EXPLAIN, ALTER, ANALYZE, VACUUM,
etc. since those tasks are better left to the sqlite3.com shell program.

Lua SQLite pointer APIs have been removed since we're not using threads.
The Lua APIs for installing update / commit / rollback hooks are removed
due to a general sense of disagreement and an overall lack of comfort.

Full-Text Search and R*Tree are as large as the rest of SQLite combined.
Turning those off keeps redbean under 1mb when built for MODE=tiny which
is nice for marketing purposes.

If you need something that was removed, file an issue, and we'll add it.
2021-06-10 08:00:08 -07:00
Justine Tunney eb08b9fbeb Fix redbean inappropriately linking ASAN
Fixes #188
2021-06-10 07:59:50 -07:00
Gautham 248c6d54bb Added getnameinfo with only name lookup (#172)
Added necessary constants (DNS_TYPE_PTR, NI_NUMERICHOST etc.).
Implementation of getnameinfo is similar to getaddrinfo, with internal
functions:

* ResolveDnsReverse: performs rDNS query and parses the PTR record
* ResolveHostsReverse: reads /etc/hosts to map hostname to
  address

Earlier, the HOSTS.txt would only need to be sorted at loading time,
because the only kind of lookup was name -> address. Now since address
-> name lookups are also possible, so the HostsTxt struct, the sorting
method (and the related tests) was changed to reflect this.
2021-06-09 19:35:44 -07:00
Gautham 05350eca60 Added wcstok and wmemcmp (#183) 2021-06-09 19:34:27 -07:00
Justine Tunney f721d61b54 Fix build to not require bash #190 2021-06-09 04:39:52 -07:00
Paul Kulchenko cd2f984ec2 Fix lsqlite make #187 2021-06-08 14:55:30 -07:00
Paul Kulchenko b3a08d9286 Add sqlite3 support to Lua scripts in redbean. 2021-06-05 18:38:38 -07:00
Paul Kulchenko 067c14891f Add lsqlite source (v0.9.5). 2021-06-05 18:38:38 -07:00
dosisod b8f38cf55d Add ISO 646 header (#168) 2021-05-16 23:18:33 -07:00
Justine Tunney 7cbc2bc083 Cosmopolitan 1.0 2021-05-16 20:35:10 -07:00
Justine Tunney 1a3d22b2fd Improve LLVM compatibility a little bit 2021-05-16 20:34:46 -07:00
Justine Tunney 3057315a1b Make default redbean lua module path zip:.lua/...
Fixes #157
2021-05-16 19:05:35 -07:00
Justine Tunney 6a8c21269f Make trivial code size enhancements 2021-05-16 18:22:39 -07:00
Justine Tunney b3838173ec Remove undefined behaviors 2021-05-16 11:16:28 -07:00
Justine Tunney 4864565198 Make minor improvements 2021-05-15 21:53:26 -07:00
Justine Tunney 221817e537 Further polish SQLite vendoring
- Now integrated with `make tags` for Emacs IDE features
- Delete some old deprecated broken full-text search engines
- Rename .h → .inc files that don't meet our definition of header
- Make sure every #include line is normal form so tools understand

See #162
2021-05-14 10:43:58 -07:00
Justine Tunney 690be544da Make redbean StoreAsset() work better
- Better UBSAN error messages
- POSIX Advisory Locks polyfills
- Move redbean manual to /.help.txt
- System call memory safety in ASAN mode
- Character classification now does UNICODE
2021-05-14 05:44:37 -07:00
ahgamut 919b6fec10 Get SQLite to build
* changed headers
* removed redundant declarations
* ran clang-format
* added sqlite3.mk
2021-05-14 02:40:04 -07:00
Justine Tunney 644f290035 Added sqlite-preprocessed-3350500
From https://www.sqlite.org/2021/sqlite-preprocessed-3350500.zip
2021-05-14 02:07:09 -07:00
Dan Tocchini IV 4577f7fe11 Add MacOS toolchain instructions (#163) 2021-05-07 07:52:32 -07:00
Justine Tunney 1b5a5719c3 Improve some unicode functions 2021-05-05 07:25:39 -07:00
Justine Tunney b9187061a7 Let redbean use its own ZIP EXE as NoSQL database 2021-05-03 13:07:58 -07:00
Justine Tunney e56a9d0e23 Mold the redbean binary to minimize page faults
This change brings page faults for precompressed static asset serving
down from 27 to 20 (or fewer) after fork. This is more of an art than
science. Hopefully Blinkenlights can visualize page faults soon.
2021-05-03 12:14:13 -07:00
Justine Tunney 2d34819779 Escape LaunchBrowser path
This also fix a bug where CTRL-C'ing redbean on Linux would kill the
browser process. It furthermore fixes a regression with the APE self
repair process that happened in a recent change.

See #158
2021-05-03 11:52:24 -07:00
Rowan Easter-Robinson 6215c91e90 Added Parameter to LaunchBrowser to set path (#158) 2021-05-03 10:55:21 -07:00
Justine Tunney af59806a42 Add integration test for redbean 2021-05-03 01:59:27 -07:00
Justine Tunney 01e6b3ad8d Reduce number of disk seeks in redbean 2021-05-03 01:21:50 -07:00
Justine Tunney daa32d27d4 Add live reindexing to redbean when zip changes 2021-05-02 11:50:43 -07:00
Justine Tunney 84001a246c Fix redbean date header in daemonize mode 2021-05-02 11:11:26 -07:00
Justine Tunney 1f2288be6e Improve backwards compatibility with GNU Make 2021-05-02 07:48:59 -07:00
Justine Tunney fabf7f9f02 Fix popen_test in MODE=dbg
ASAN and vfork() don't appear to play well together. Maybe in later
versions of GCC it'll be better. But vfork() is flirting with danger
after all and that probably doesn't make sense in ASAN mode anyway.
2021-05-01 17:13:48 -07:00
Justine Tunney cef08d47b6 Fix typo in redbean.c 2021-05-01 05:42:02 -07:00
Justine Tunney 41801c9802 Change default redbean log level to info
A new -s flag has been added to increase silence. This change is
intended to make it a little less weird opening the redbean binary
directly from the browser and seeing an empty terminal window.
2021-05-01 05:28:15 -07:00
Justine Tunney 1966369e8e Fix bugs and make improvements
- Fix regression with `%lu`
- Added some more headers witnessed in the wild
- Added `-M INT` option to redbean to tune max payload size
- Work around InfoZIP 256 character limit on comment line size
2021-05-01 05:11:35 -07:00
Gautham 3aa8983ec1 Add strxfrm (#160) 2021-05-01 04:53:23 -07:00
Justine Tunney c029e83dd8 Set up http://redbean.justine.lol/ demo server 2021-04-24 19:49:49 -07:00
Justine Tunney 472b95fea3 Support OnHttpRequest Lua callback
If your redbean `/.init.lua` file defines a global callable named
`OnHttpRequest` then redbean will delegate all serving control to
your function. You may then restore the default serving paths, by
calling the new `Route()`, `RouteHost()`, and `RoutePath()` APIs.

Closes #150
2021-04-24 17:27:12 -07:00
Justine Tunney dc6d11a031 Improve performance of printf functions 2021-04-24 13:58:50 -07:00
Justine Tunney b107d2709f Add /statusz page to redbean plus other enhancements
redbean improvements:

- Explicitly disable corking
- Simulate Python regex API for Lua
- Send warmup requests in main process on startup
- Add Class-A granular IPv4 network classification
- Add /statusz page so you can monitor your redbean's health
- Fix regressions on OpenBSD/NetBSD caused by recent changes
- Plug Authorization header into Lua GetUser and GetPass APIs
- Recognize X-Forwarded-{For,Host} from local reverse proxies
- Add many additional functions to redbean Lua server page API
- Report resource usage of child processes on `/` listing page
- Introduce `-a` flag for logging child process resource usage
- Introduce `-t MILLIS` flag and `ProgramTimeout(ms)` init API
- Introduce `-H "Header: value"` flag and `ProgramHeader(k,v)` API

Cosmopolitan Libc improvements:

- Make strerror() simpler
- Make inet_pton() not depend on sscanf()
- Fix OpenExecutable() which broke .data section earlier
- Fix stdio in cases where it overflows kernel tty buffer
- Fix bugs in crash reporting w/o .com.dbg binary present
- Add polyfills for SO_LINGER, SO_RCVTIMEO, and SO_SNDTIMEO
- Polyfill TCP_CORK on BSD and XNU using TCP_NOPUSH magnums

New netcat clone in examples/nc.c:

While testing some of the failure conditions for redbean, I noticed that
BusyBox's `nc` command is pretty busted, if you use it as an interactive
tool, rather than having it be part of a pipeline. Unfortunately this'll
only work on UNIX since Windows doesn't let us poll on stdio and sockets
at the same time because I don't think they want tools like this running
on their platform. So if you want forbidden fruit, it's here so enjoy it
2021-04-23 18:53:57 -07:00
Justine Tunney 4effa23528 Make more major improvements to redbean
- POSIX regular expressions for Lua
- Improved protocol parsing and encoding
- Additional APIs for ZIP storage retrieval
- Fix st_mode issue on NT for regular files
- Generalized APIs for URL and Host handling
- Worked out the kinks in resource resolution
- Allow for custom error pages like /404.html
2021-04-20 19:14:21 -07:00
Justine Tunney 26ac6871da Add TUI paneling example 2021-04-18 12:40:48 -07:00
Justine Tunney bf03b2e64c Make major improvements to redbean and libraries
The most exciting improvement is dynamic pages will soon be able to use
the executable itself as an object store. it required a heroic technique
for overcoming ETXTBSY restrictions which lets us open the executable in
read/write mode, which means (1) wa can restore the APE header, and (2)
we can potentially containerize redbean extension code so that modules
you download for your redbean online will only impact your redbean.

Here's a list of breaking changes to redbean:

- Remove /tool/net/ prefix from magic ZIP paths
- GetHeader() now returns NIL if header is absent

Here's a list of fixes and enhancements to redbean:

- Support 64-bit ZIP archives
- Record User-Agent header in logs
- Add twelve error handlers to accept()
- Display octal st_mode on listing page
- Show ZIP file comments on listing page
- Restore APE MZ header on redbean startup
- Track request count on redbean index page
- Report server uptime on redbean index page
- Don't bind server socket using SO_REUSEPORT
- Fix #151 where Lua LoadAsset() could free twice
- Report rusage accounting when workers exit w/ -vv
- Use ZIP iattr field as text/plain vs. binary hint
- Add ParseUrl() API for parsing things like a.href
- Add ParseParams() API for parsing HTTP POST bodies
- Add IsAcceptablePath() API for checking dots, etc.
- Add IsValidHttpToken() API for validating sane ASCII
- Add IsAcceptableHostPort() for validating HOST[:PORT]
- Send 400 response to HTTP/1.1 requests without a Host
- Send 403 response if ZIP or file isn't other readable
- Add virtual hosting that tries prepending Host to path
- Route requests based on Host in Request-URI if present
- Host routing will attempt to remove or add the www. prefix
- Sign-extend UNIX timestamps and don't adjust FileTime zone

Here's some of the improvements made to Cosmopolitan Libc:

- Fix ape.S indentation
- Improve consts.sh magnums
- Write pretty good URL parser
- Improve rusage accounting apis
- Bring mremap() closer to working
- Added ZIP APIs which will change
- Check for overflow in reallocarray()
- Remove overly fancy linkage in strerror()
- Fix GDB attach on crash w/ OpenBSD msyscall()
- Make sigqueue() portable to most UNIX distros
- Make integer serialization macros more elegant
- Bring back 34x tprecode8to16() performance boost
- Make malloc() more resilient to absurdly large sizes
2021-04-18 12:34:15 -07:00
Rowan Easter-Robinson 69c508729e Added LaunchBrowser API (#153)
You can now add LaunchBrowser() to .init.lua which will ask
redbean to open your website in the local desktop browser
when the server is launched.
2021-04-18 07:24:36 -07:00
Justine Tunney 7ed524ca31 Disable fesetround() tests temporarily
This isn't working as intended in the Travis CI build environment.
There's likely some kind of microarchitectural issue. This change
gets us back into the green for the time being.
2021-04-11 01:42:31 -07:00
Justine Tunney 052682c2c0 Add CONTRIBUTING.md 2021-04-11 00:55:53 -07:00
Justine Tunney 8a91518633 Fix issues revealed by ECMAScript test262
Cosmopolitan's QuickJS is now equally conformant and performant, with
the exception of Atomics, which have been disabled since Cosmopolitan
currently doesn't support pthreads.

QuickJS memory usage -- BigNum 2021-03-27 version, 64-bit, malloc limit: -1

NAME                    COUNT     SIZE
memory allocated          937   131764  (140.6 per block)
memory used               938   116103  (8 overhead, 16.7 average slack)
atoms                     513    21408  (41.7 per atom)
objects                   170    12279  (72.2 per object)
  properties              864    15531  (5.1 per object)
  shapes                   58    12995  (224.1 per shape)
bytecode functions         13     1512
  bytecode                 13      867  (66.7 per function)
C functions                99
arrays                      1
  fast arrays               1
  elements                  1       16  (1.0 per fast array)

Result: 35/74740 errors, 1279 excluded, 485 skipped, 19 new, 2 fixed

real    2m40.828s
user    2m29.764s
sys     0m10.939s
2021-04-10 17:15:35 -07:00
Justine Tunney 8f52c0d773 Get Fabrice Bellard's JavaScript engine to build
$ m=tiny
$ make -j12 MODE=$m o/$m/third_party/quickjs/qjs.com
$ o/$m/third_party/quickjs/qjs.com -e 'console.log(2 + 2)'
4
$ ls -hal o/$m/third_party/quickjs/qjs.com
631.5K

See #97
2021-04-09 01:06:57 -07:00
Justine Tunney 1fbfbb3192 Add quickjs-2021-03-27 to third_party 2021-04-08 20:55:43 -07:00
Justine Tunney f40f97bd07 Fix test failure on Windows
The send{,to,msg} and recv{,from,msg} functions have been updated to
delegate to WriteFile and ReadFile when appropriate, due to the fact
that socketpair(AF_UNIX) is implemented using kFdFile.

Thanks @fabriziobertocci for writing the test that caught this.

See #148 and #122
2021-04-07 23:36:05 -07:00
fabriziobertocci 24d79599cc Add sendmsg and recvmsg (#148) 2021-04-07 22:53:23 -07:00
Justine Tunney da8a08fd58 Provide option to have APE not modify itself
This change introduces ape-no-modify-self.o to the amalgamated release
binaries, which may be used as an alternative to ape.o to make it easier
to use APE in cases where the self-modifying behavior isn't acceptable.

Please note that this alternative copying behavior isn't necessarily
better. It introduces a whole bunch of questions of its own, which are
documented in the ape.S source comment and should be considered by both
the program author as well as the end-user of programs linked this way.

For example, build environments that use read-only file systems and
would prefer to not have a launcher wrapper (like we use in our build)
can use ape-no-modify-self.o instead of ape.o and then set the $TMPDIR
environment variable to point to a sane read-write-exec location.

Fixes #146
See #82
2021-04-07 21:01:57 -07:00
Justine Tunney 59575f7e80 Perform some minor code cleanup 2021-04-06 12:46:52 -07:00
Justine Tunney 6c16f208b5 Remove unintended log statements 2021-04-01 20:01:26 -07:00
Justine Tunney bb96099c65 Define assert as an expression
Fixes #138
2021-04-01 19:42:02 -07:00
fabriziobertocci 2584a86ab4 Added struct ip_mreq (#143) 2021-04-01 19:38:11 -07:00
dosisod 9e98d6893d Add some missing prototypes (#142) 2021-04-01 19:36:37 -07:00
fabriziobertocci 6682013d12 Implement syslog (#136) 2021-04-01 19:32:39 -07:00
Justine Tunney 83abd68029 Parse Content-Range with missing right hand side
Fixes #144
2021-04-01 18:52:54 -07:00
Justine Tunney 7abca1531f Cosmopolitan 0.3 2021-03-29 03:20:03 -07:00
Justine Tunney 7dc8973567 Enable serving zip directory entries 2021-03-29 03:10:11 -07:00
Justine Tunney 1753b669cf Have redbean show zip listing as default / handler
If an "index.lua" or "index.html" doesn't exist in zip file or the
filesystem, and no redirects have been defined for it either, then
redbean will render a listing of the zip central directory content
only if the request uri points to the root path.
2021-03-29 01:22:49 -07:00
Justine Tunney ae300d0c40 Remove colliding name in syscalls.sh
Credit goes to @fabriziobertocci for finding this. See #136.
2021-03-28 18:26:56 -07:00
Justine Tunney c6f75bf95a Fix issue with testing service
What was I thinking imposing arbitrary limits. I hate limits.
2021-03-28 18:22:36 -07:00
Justine Tunney 52565e7af3 Make minor performance improvement to HTTP parser
redbean's message parser now takes 300 nanoseconds to parse a standard
request sent by chrome, whereas it previous took 600 nanoseconds.
2021-03-28 18:00:29 -07:00
Justine Tunney 3c19b6e352 Add support for serving directly from filesystem
You can now pass `-D directory` to redbean which will serve assets from
the local filesystem. This is useful for development since it allows us
to skip needing to shut down the server and run InfoZIP when testing an
iteration of a lua server page script.

See #97
2021-03-28 08:02:17 -07:00
Justine Tunney a1677d605a Transcode ISO-8859-1 in HTTP headers
If we keep making changes like this, redbean might not be a toy anymore.
Additional steps are also being taken now to prevent ANSI control codes
sent by the client from slipping into logs.
2021-03-28 00:10:17 -07:00
Justine Tunney dcbd2b8668 Add base64 support
Lua Server Pages may now call the EncodeBase64() and DecodeBase64()
functions should they wish to do things like emit embeded data URIs

See #97
2021-03-27 18:17:54 -07:00
Justine Tunney 4d21cd315d Support POST parameters in redbean server pages
See #97
2021-03-27 07:29:55 -07:00
Justine Tunney da36e7e256 Make major improvements to stdio
Buffering now has optimal performance, bugs have been fixed, and some
missing apis have been introduced. This implementation is also now more
production worthy since it's less brittle now in terms of system errors.
That's going to help redbean since lua i/o is all based on stdio.

See #97
2021-03-26 22:31:41 -07:00
Justine Tunney 09bcfa23d5 Make major improvements to redbean
- lua server pages
- lua http library
- http v0.9 support
- request uri parsing
- fork failure recovery
- accelerated redirects
- http pipelining support
- lenient message framing
- html / uri / js escaping
- fix shutdown signal handling
2021-03-25 02:24:05 -07:00
Justine Tunney 6b90ff60cd Add preliminary lua support to redbean
This change only implements enough Lua support to send a Hello World
response. The redbean executable size increases from ~128kb to 260kb
and the requests per second decreases from 1000k to 600k. That's the
fastest it can go and that's extremely impressive compared to Python

See #97
2021-03-21 17:27:53 -07:00
fabriziobertocci 2f41b4dcc6 Add prototype for srandom() (#132) 2021-03-21 07:33:33 -07:00
fabriziobertocci 5af25f687a Rename eai2str to gai_strerror (#131) 2021-03-20 20:48:40 -07:00
Alison Winters 9c81729008 Remove unused variable in fflush (#129) 2021-03-17 20:15:00 -07:00
dosisod 8a236433a2 Add more math functions (#128) 2021-03-17 20:05:12 -07:00
Justine Tunney ab64ef7364 Make fflush() return 0 on success (#114) 2021-03-17 13:02:15 -07:00
Justine Tunney 4177489762 Perform fine-tuning of socketpair and pipe
- removed unneeded share parameter from pipe on nt
- socktpair(type | SOCK_CLOEXEC) is now polyfilled
- use textwindows for linker micro-optimization
- apologies for auto clang-format diff noise :(
- improve socketpair docstring

See #122
2021-03-16 22:44:54 -07:00
Justine Tunney 4e93750afd Perform some minor fixups 2021-03-16 22:19:51 -07:00
fabriziobertocci ca88ce5026 Add socketpair (#122) 2021-03-16 22:05:59 -07:00
dosisod 6388ef21f8 Add noreturn macro (#118) 2021-03-13 20:46:12 -08:00
dosisod 7ffeb29bfc Add missing functions to tgmath (#124) 2021-03-13 20:43:57 -08:00
Justine Tunney da4dffccc5 Add random() and srandom()
Closes #123
2021-03-13 20:24:29 -08:00
Justine Tunney 807706a099 Perform minor fixups
One of those fixups is making sure that AF_LOCAL is equal to AF_UNIX on
the New Technology. See #122
2021-03-13 19:40:04 -08:00
Justine Tunney 83d0c3b870 Fix writev() on the New Technology (#117) 2021-03-09 11:33:48 -08:00
Alison Winters 6cd1037692 Get VSCode working with Linux and WSL (#116) 2021-03-09 10:12:39 -08:00
Justine Tunney e0566c9675 Fix Lua build config 2021-03-08 17:51:26 -08:00
Justine Tunney 3f35b37b68 Remove nonstandard defines from limits.h (#115) 2021-03-08 17:34:44 -08:00
Justine Tunney 67c27d9e6e Add Hello World example for LUA C API (#97) 2021-03-08 14:15:59 -08:00
Justine Tunney 2a3037d4e8 Delete Duktape (#97) 2021-03-08 13:17:52 -08:00
Justine Tunney 0a61fe4ea0 Add smoke test for timezone loading (#114) 2021-03-08 11:46:04 -08:00
Justine Tunney 33e8fc8687 Expose public garbage collector API for C language
You can now do epic things like this:

    puts(_gc(xasprintf("%d", 123)));

The _gc() API is shorthand for _defer() which works like Go's keyword:

    const char *s = xasprintf("%d", 123);
    _defer(free, s);
    puts(s);

Be sure to always use -fno-omit-frame-pointer which makes code fast too.

Enjoy! See also #114
2021-03-08 10:59:34 -08:00
Justine Tunney 0ad609268f Improve system call polyfills
- Polyfill open() w/ O_CLOEXEC on RHEL5
- Remove old workaround from rmdir() on the New Technology
- preadv() and pwritev() are now smarter about demodernization
- preadv() and pwritev() are now available on the New Technology
2021-03-08 10:07:02 -08:00
Justine Tunney 816b0e1851 Improve tmpfile api (#114) 2021-03-07 21:08:27 -08:00
Justine Tunney 2bd1e72d5a Remove garbage collector macro from header (#114)
We can put this back the moment someone requests it. Pain-free garbage
collection for the C language is pretty cool. All it does is overwrite
the return address with a trampoline that calls free(). It's not clear
what it should be named if it's made a public API.
2021-03-07 20:23:29 -08:00
Justine Tunney 5ce83b08c8 Add posix_spawn (#114) 2021-03-07 20:14:07 -08:00
Justine Tunney 5f088cec23 Rename Lua test folder 2021-03-07 18:22:53 -08:00
Justine Tunney a8945714e8 Make gdtoa less tunable (#104)
The -fno-math-errno flag shouldn't impact libraries since it's mostly
intended for permitting the compiler to generate sqrt() instructions.
2021-03-07 16:41:59 -08:00
Alison Winters 8a6ac6dd63 Set errno when out of range in strtoimax (#111) 2021-03-07 14:38:56 -08:00
Alison Winters f5da4efcaf Set errno in strtol family of functions (#110) 2021-03-07 14:18:08 -08:00
Justine Tunney b16b332539 Get Lua to build with all tests passing
Fixes #61
2021-03-07 13:31:09 -08:00
Justine Tunney 4d3195f57a Add Lua 2021-03-07 12:50:34 -08:00
Justine Tunney aad841610e Fix freopen so it resets stream buffer (#61) 2021-03-07 12:12:02 -08:00
Justine Tunney 7583b3accc Show better error on bind() error
See #51
2021-03-07 11:31:44 -08:00
Justine Tunney 06a4e2d29b Disable Travis emails 2021-03-07 08:29:43 -08:00
dosisod 67b9675c81 Make tgmath.h available (#109) 2021-03-06 22:40:18 -08:00
Justine Tunney 4d4aa9e791 Add automatic tests for pull requests
Now when you send a pull request Travis CI will build the entire
repository and run all the tests for you automatically. It takes
approximately two minutes to finish so you can get fast feedback
2021-03-06 21:39:03 -08:00
Alison Winters 813e11b90b Fix int parsing with base 2 and 16 (#107) 2021-03-06 21:12:32 -08:00
dosisod fb7b7c6e21 Fix isystem headers including wrong files (#108) 2021-03-06 21:06:29 -08:00
Justine Tunney d769df3482 Fix issues with stdio needed for Lua
See #61
2021-03-06 19:04:26 -08:00
Justine Tunney c3ed8d6c7f Make %p consistent with glibc and musl
See #61
2021-03-06 14:36:44 -08:00
Justine Tunney 937d921018 Add tests for the greatest of all libm functions 2021-03-06 12:59:35 -08:00
Justine Tunney bfef17eb6d Add more math fixes 2021-03-06 11:44:40 -08:00
Justine Tunney 11ec99931b Add Musl multibyte functions
These are standard functions that are needed to help support the Skull
language. Note that normally this codebase uses libc/str/thompike.h

See #105
2021-03-06 09:53:16 -08:00
Justine Tunney cfd453d125 Add more real formatting tests
See #61
2021-03-06 08:45:44 -08:00
dosisod 6fa049c9c7 Add macro for static_assert (#106) 2021-03-05 20:32:25 -08:00
Justine Tunney 3364fc5b03 Add modf(), modff(), and modfl()
See #104
2021-03-05 10:47:14 -08:00
Justine Tunney f064183646 Support proper %g, %f, and %a float formatting
See #61
See #104
2021-03-05 10:31:16 -08:00
Justine Tunney e26bdbec52 Make examples folder somewhat more focused 2021-03-05 06:09:12 -08:00
Justine Tunney 5141d00992 Perform some minor code cleanup 2021-03-04 13:22:32 -08:00
Justine Tunney b9f73e6a4d Clarify APE self-modifying behavior in README
See #102
2021-03-04 07:54:41 -08:00
Justine Tunney 43b2475aaa Handle more pow cases (#61) 2021-03-04 06:14:07 -08:00
Justine Tunney 1a08594f95 Add honeybadger to ape.S 2021-03-03 15:00:41 -08:00
Justine Tunney e55e71ab48 Delete some old build code 2021-03-03 14:30:25 -08:00
Justine Tunney 3573814e45 Change release process to use default mode
See #101
2021-03-03 13:47:22 -08:00
Justine Tunney 2134ffe005 Add features needed by Janet language
See #97
See https://github.com/ahgamut/janet/tree/f838e36#compiling-janet-on-cosmopolitan
2021-03-03 13:26:46 -08:00
Justine Tunney e3ee3c78e9 Refactor some Blinkenlights code 2021-03-03 13:09:06 -08:00
Justine Tunney 8af91bcbe7 Make pow() conform to standard definition 2021-03-03 09:21:27 -08:00
Justine Tunney 754974faaa Remove SOCK_NONBLOCK from Echo Server example
See #102 for further explanation.
2021-03-03 06:17:56 -08:00
Justine Tunney 9367253b4d Add more libm unit tests and fixes
See #61
2021-03-02 13:57:23 -08:00
Justine Tunney 32e289b1d8 Add error and gamma functions
Fixes #99
2021-03-02 11:58:00 -08:00
Justine Tunney d53a344e18 Remove getc() optimization
This has been reported as causing issues in #61 although it isn't clear
why that's happening. Having a function boundary is bullet proof.
2021-03-02 07:34:38 -08:00
Justine Tunney 3e19b96ab8 Add more POSIX function stubs
Cosmopolitan currently doesn't support threads and it doesn't do
anything fancy in longjmp/setjmp so this change was simple to do

- localeconv
- _setjmp (same as setjmp)
- _longjmp (same as longjmp)
- strcoll (same as strcmp)
- flockfile (does nothing)
- funlockfile (does nothing)
- ftrylockfile (does nothing)

See #61
2021-03-02 03:27:55 -08:00
Justine Tunney 1831e3ccf7 Bring life.com executable size back down to 12kb 2021-03-02 01:13:32 -08:00
Justine Tunney 4651962070 Limit frame size restriction to internal repo
Fixes #91
2021-03-02 01:05:37 -08:00
Justine Tunney 8a6a1e25b1 Fix redbean daemonization
Fixes #94
2021-03-02 00:43:30 -08:00
6392 changed files with 2113635 additions and 143762 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
# -*- conf -*-
/build/bootstrap/*.com binary
/usr/share/zoneinfo/* binary
+5
View File
@@ -1,5 +1,10 @@
# -*- conf -*-
/o
# TODO: Find some way to have Python write to o/
__pycache__
*.tmp
/.bochs.log
/HTAGS
+6
View File
@@ -0,0 +1,6 @@
virt: lxd
os: linux
language: c
script: make -j4 V=0
notifications:
email: false
+45 -2
View File
@@ -1,13 +1,12 @@
{
"configurations": [
{
"name": "Linux",
"name": "Win32",
"includePath": [
"${workspaceFolder}"
],
"cStandard": "c11",
"cppStandard": "c++11",
"compilerPath": "${workspaceFolder}/o/third_party/gcc/bin/x86_64-linux-musl-gcc",
"forcedInclude": ["${workspaceFolder}/.vscode/vscode.h"],
"defines": [
"libcesque=",
@@ -63,6 +62,50 @@
"attributeallocalign(x)=",
"nullterminated(x)="
]
},
{
"name": "Linux",
"includePath": [
"${workspaceFolder}"
],
"cStandard": "gnu17",
"compilerPath": "${workspaceFolder}/o/third_party/gcc/bin/x86_64-linux-musl-gcc",
"compilerArgs": [
"-Wall",
"-Werror",
"-fdebug-prefix-map=${workspaceFolder}=",
"-frecord-gcc-switches",
"-Wa,-W",
"-Wa,-I.",
"-Wa,--noexecstack",
"-Wa,--nocompress-debug-sections",
"-Og",
"-g",
"-gdescribe-dies",
"-msse3",
"-mno-red-zone",
"-fno-math-errno",
"-fno-trapping-math",
"-fno-fp-int-builtin-inexact",
"-fno-ident",
"-fno-common",
"-fno-gnu-unique",
"-fstrict-aliasing",
"-fstrict-overflow",
"-fno-semantic-interposition",
"-mno-omit-leaf-frame-pointer",
"-fno-jump-tables",
"-nostdinc",
"-iquote."
],
"forcedInclude": [
"libc/integral/normalize.inc"
],
"defines": [
"COSMO",
"MODE=",
"IMAGE_BASE_VIRTUAL=0x400000"
]
}
],
"version": 4
-157
View File
@@ -1,159 +1,2 @@
#define __VSCODE_INTELLISENSE__ 1
#include "libc/integral/normalize.inc"
#if 0
#define __VSCODE_INTELLISENSE__ 1
#define __BIGGEST_ALIGNMENT__ 1
#define __CHAR_MAX__ 0x7F
#define __SCHAR_MAX__ __CHAR_MAX__
#define __SHRT_MAX__ 0x7FFF
#define __INT_MAX__ 0x7FFFFFFF
#define __LONG_MAX__ 0x7FFFFFFFFFFFFFFF
#define __LONG_LONG_MAX__ __LONG_MAX__
#define __CHAR_MIN__ -((__CHAR_MAX__) + 1)
#define __SHRT_MIN__ -((__SHRT_MAX__) + 1)
#define __INT_MIN__ -((__INT_MAX__) + 1)
#define __LONG_MIN__ -((__LONG_MAX__) + 1)
#define __LONG_LONG_MIN__ -((__LONG_LONG_MAX__) + 1)
#define __UCHAR_MAX__ 0xFF
#define __USHRT_MAX__ 0xFFFF
#define __UINT_MAX__ 0xFFFFFFFF
#define __ULONG_MAX__ 0xFFFFFFFFFFFFFFFF
#define __SIZE_MAX__ __ULONG_MAX__
#define __SSIZE_MAX__ __LONG_MAX__
#define __UINTPTR_MAX__ __SIZE_MAX__
#define __INTPTR_MAX__ __SSIZE_MAX__
#define __WCHAR_MAX__ __UINT_MAX__
#define __PTRDIFF_MAX__ __UINTPTR_MAX__
#define __INTMAX_MAX__ __ULONG_MAX__
#define __SIZEOF_POINTER__ 8
#define __SIZEOF_SHORT__ 2
#define __SIZEOF_INT__ 4
#define __SIZEOF_LONG__ 8
#define __SIZEOF_LONG_LONG__ 8
#define __SIZEOF_PTRDIFF_T__ 8
#define __SIZEOF_SIZE_T__ 8
#define __SIZEOF_WCHAR_T__ 4
#define __SIZEOF_WINT_T__ 4
#define __SIZEOF_FLOAT__ 4
#define __SIZEOF_FLOAT128__ 16
#define __SIZEOF_DOUBLE__ 8
#define __SIZEOF_FLOAT80__ 10
#define __SIZEOF_LONG_DOUBLE__ 16
#define __FLT_MAX__ 1
#define __DBL_MAX__ 1
#define __INT_LEAST8_TYPE__ signed char
#define __INT_LEAST16_TYPE__ signed short
#define __INT_LEAST32_TYPE__ signed int
#define __INT_LEAST64_TYPE__ signed long long
#define __UINT_LEAST8_TYPE__ unsigned char
#define __UINT_LEAST16_TYPE__ unsigned short
#define __UINT_LEAST32_TYPE__ unsigned int
#define __UINT_LEAST64_TYPE__ unsigned long long
#define __UINT8_MAX__ __UCHAR_MAX__
#define __UINT16_MAX__ __USHRT_MAX__
#define __UINT32_MAX__ __UINT_MAX__
#define __UINT64_MAX__ __ULONG_MAX__
#define __INT8_MAX__ __CHAR_MAX__
#define __INT16_MAX__ __SHRT_MAX__
#define __INT32_MAX__ __INT_MAX__
#define __INT64_MAX__ __LONG_MAX__
#define ATEXIT_MAX 1
#define STACKSIZE 0x10000
#define ARG_MAX 255
#define OPEN_MAX 0x7FFF
#define CHAR_BIT 7
#define NSIG 1
#define NULL (0)
#define false 0
#define true (!(false))
#define COSMOPOLITAN_C_START_
#define COSMOPOLITAN_C_END_
#define PAGESIZE 0x1000
#define BIGPAGESIZE 0x10000
#define NAME_MAX 255
#define SWITCHEROO(...) 0
extern unsigned __log_level;
typedef void * va_list;
#define va_start(...) 0
#define va_end(...) 0
#define va_arg(x, y) (y)(0)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
#define int64_t long long
#define int128_t int64_t
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef unsigned long long uint128_t;
typedef int errno_t;
typedef uint64_t size_t;
typedef unsigned long long ssize_t;
typedef uint64_t uintptr_t;
typedef long long intptr_t;
typedef unsigned long long uintmax_t;
typedef long long intmax_t;
typedef uint32_t bool32;
#ifndef __cplusplus
typedef uint8_t bool;
typedef uint16_t char16_t;
typedef uint32_t char32_t;
#endif /* __cplusplus */
typedef char32_t wint_t;
typedef char32_t wchar_t;
typedef struct { int ax, dx; } axdx_t;
/* duplicate and replace xmmintrin.internal.h to fix it for IntelliSense
* SEE: <> */
#define _Vector_size(x) __attribute__((__vector_size__(x)))
#define IMAGE_BASE_VIRTUAL 0x400000
#define __SIGACTION(...) (0)
#define VEIL(x, y) (y)
#define STATIC_YOINK(x)
#define BUFSIZ 1
#define FRAMESIZE 0x10000
#define PATH_MAX 252
#define concat(x, y, z) 0
#define CONCAT(a, b, c, d, e) 0
#define shuffle(...) 0
#define reverse(x, y) 0
#define autotype(x) intptr_t
#define _Generic_(...) (void*)(0)
#define _Generic(...) _Generic_
#define _Alignas(...)
#define _Section(...)
#define offsetof(x, y) 0
#define INITIALIZER(...) struct _dummy
#define __far
#define BENCHLOOP(...) 0
#ifdef __hook
#undef __hook
#endif /* __hook */
#ifdef UriKeyval
#undef UriKeyval
#endif /* UriKeyval */
#define _Static_assert(...) 0
#endif /* 0 */
+62
View File
@@ -0,0 +1,62 @@
# Contributing Guidelines
We'd love to accept your patches! Please read this guide first.
## Copyright Assignment
Please send an email to Justine Tunney <jtunney@gmail.com> stating that
you intend to assign her the copyright to the changes you contribute to
Cosmopolitan. Please use the same email address you use for git commits
which should only contain original source code from you or other people
who are also assigning copyright. Please note that, if you're employed,
you may need to get your employer's approval beforehand. If you can not
assign copyright due to local laws, then you may alternatively consider
disclaiming it using the language in [Unlicense](https://unlicense.org)
or [CC-0](http://creativecommons.org/share-your-work/public-domain/cc0)
This is important because we can't produce 12kb single-file executables
that comply with license requirements if we have to embed lots of them.
Although that's less of an issue depending on the purpose of the files.
For example, ownership is much less of a concern in the unit test files
so you're encouraged to put your copyright on those, provided it's ISC.
## Style Guide
You can use clang-format to automatically format your files:
```sh
clang-format -i -style=file tool/net/redbean.c
```
If you use Emacs this can be automated on save for Cosmopolitan using
[tool/emacs/cosmo-format.el]([tool/emacs/cosmo-format.el]).
### Source Files
- Must use include paths relative to the root of the repository
- Must have comment at top of file documenting copyright and license
- Must have notice embedding if not owned by Justine (exception: tests)
- May use language extensions that are supported by both GCC and Clang
- Should use Google indentation (otherwise use `/* clang-format off */`)
- Should use asm() instead of compiler APIs (exception: ctz, clz, memcpy)
### Header Files
- Must not have copyright or license comments
- Must have once guards (otherwise change `.h` to `.inc`)
- Must be ANSI C89 compatible to be included in the amalgamation header
- Must include its dependencies (exception: libc/integral/normalize.inc)
- Must not define objects (i.e. `cc -c -xc foo.h` will produce empty `.o`)
- Should not use typedefs
- Should not use forward declarations
- Should not include documentation comments
- Should not include parameter names in prototypes
- Should not pose problems if included by C++ or Assembly sources
- Should not declare non-ANSI code, at all, when the user requests ANSI
### Build Config
- Must not write files outside `o/`
- Must not communicate with Internet
- Must not depend on system libraries
- Must not depend on system commands (exception: sh, make, gzip, zip)
+37 -22
View File
@@ -40,8 +40,7 @@
# o/dbg/examples/crashreport.com
# less examples/crashreport.c
#
# # extremely tiny binaries (scout's honor escape hatch)
# # please pay the $1k for commercial license if you can
# # extremely tiny binaries
# make -j8 -O MODE=tiny \
# LDFLAGS+=-s \
# CPPFLAGS+=-DIM_FEELING_NAUGHTY \
@@ -130,21 +129,28 @@ include libc/libc.mk #─┘
include libc/sock/sock.mk #─┐
include dsp/tty/tty.mk # ├──ONLINE RUNTIME
include libc/dns/dns.mk # │ You can communicate with the network
include libc/crypto/crypto.mk # │
include net/http/http.mk #─┘
include third_party/duktape/duktape.mk
include third_party/regex/regex.mk
include net/http/http.mk # │
include third_party/mbedtls/mbedtls.mk # │
include net/https/https.mk # │
include third_party/regex/regex.mk #─┘
include third_party/third_party.mk
include libc/testlib/testlib.mk
include tool/viz/lib/vizlib.mk
include examples/examples.mk
include third_party/linenoise/linenoise.mk
include third_party/lua/lua.mk
include third_party/sqlite3/sqlite3.mk
include third_party/mbedtls/test/test.mk
include third_party/quickjs/quickjs.mk
include third_party/lz4cli/lz4cli.mk
include third_party/infozip/infozip.mk
include third_party/python/python.mk
include tool/build/lib/buildlib.mk
include third_party/chibicc/chibicc.mk
include third_party/chibicc/test/test.mk
include tool/build/emucrt/emucrt.mk
include tool/build/emubin/emubin.mk
include tool/build/build.mk
include examples/examples.mk
include tool/decode/lib/decodelib.mk
include tool/decode/decode.mk
include tool/hash/hash.mk
@@ -159,7 +165,6 @@ include test/libc/nexgen32e/test.mk
include test/libc/runtime/test.mk
include test/libc/sock/test.mk
include test/libc/bits/test.mk
include test/libc/crypto/test.mk
include test/libc/str/test.mk
include test/libc/unicode/test.mk
include test/libc/calls/test.mk
@@ -173,6 +178,7 @@ include test/libc/stdio/test.mk
include test/libc/release/test.mk
include test/libc/test.mk
include test/net/http/test.mk
include test/net/https/test.mk
include test/net/test.mk
include test/tool/build/lib/test.mk
include test/tool/build/test.mk
@@ -189,13 +195,13 @@ include examples/package/build.mk
#-φ-examples/package/new.sh
include test/test.mk
OBJS = $(foreach x,$(PKGS),$($(x)_OBJS))
SRCS = $(foreach x,$(PKGS),$($(x)_SRCS))
HDRS = $(foreach x,$(PKGS),$($(x)_HDRS))
INCS = $(foreach x,$(PKGS),$($(x)_INCS))
BINS = $(foreach x,$(PKGS),$($(x)_BINS))
TESTS = $(foreach x,$(PKGS),$($(x)_TESTS))
CHECKS = $(foreach x,$(PKGS),$($(x)_CHECKS))
OBJS = $(foreach x,$(PKGS),$($(x)_OBJS))
SRCS := $(foreach x,$(PKGS),$($(x)_SRCS))
HDRS := $(foreach x,$(PKGS),$($(x)_HDRS))
INCS = $(foreach x,$(PKGS),$($(x)_INCS))
BINS = $(foreach x,$(PKGS),$($(x)_BINS))
TESTS = $(foreach x,$(PKGS),$($(x)_TESTS))
CHECKS = $(foreach x,$(PKGS),$($(x)_CHECKS))
bins: $(BINS)
check: $(CHECKS)
@@ -206,14 +212,24 @@ tags: TAGS HTAGS
o/$(MODE)/.x:
@mkdir -p $(@D) && touch $@
ifneq ($(findstring 4.,,$(MAKE_VERSION)),$(MAKE_VERSION))
o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x))))
$(file >$@) $(foreach x,$(SRCS),$(file >>$@,$(x)))
o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x))))
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
o/$(MODE)/incs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(INCS) $(INCS),$(dir $(x))))
$(file >$@) $(foreach x,$(INCS) $(INCS),$(file >>$@,$(x)))
else
o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x))))
$(MAKE) MODE=rel -j8 -pn bopit 2>/dev/null | sed -ne '/^SRCS/ {s/.*:= //;s/ */\n/g;p;q}' >$@
o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x))))
$(MAKE) MODE=rel -j8 -pn bopit 2>/dev/null | sed -ne '/^HDRS/ {s/.*:= //;s/ */\n/g;p;q}' >$@
o/$(MODE)/incs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(INCS) $(INCS),$(dir $(x))))
$(MAKE) MODE=rel -j8 -pn bopit 2>/dev/null | sed -ne '/^INCS/ {s/.*:= //;s/ */\n/g;p;q}' >$@
endif
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt $(SRCS) $(HDRS) $(INCS)
@$(COMPILE) -AMKDEPS $(MKDEPS) -o $@ -r o/$(MODE)/ o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt o/$(MODE)/incs.txt $(SRCS) $(HDRS) $(INCS)
@$(COMPILE) -AMKDEPS $(MKDEPS) -o $@ -r o/$(MODE)/ o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt o/$(MODE)/incs.txt
TAGS: o/$(MODE)/srcs.txt $(SRCS)
@rm -f $@
@@ -228,14 +244,13 @@ loc: o/$(MODE)/tool/build/summy.com
$(XARGS) wc -l | grep total | awk '{print $$1}' | $<
COSMOPOLITAN_OBJECTS = \
LIBC_CRYPTO \
LIBC_DNS \
LIBC_SOCK \
LIBC_NT_WS2_32 \
LIBC_NT_IPHLPAPI \
LIBC_NT_MSWSOCK \
LIBC_OHMYPLUS \
LIBC_X \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
LIBC_LOG \
LIBC_UNICODE \
@@ -244,6 +259,7 @@ COSMOPOLITAN_OBJECTS = \
THIRD_PARTY_ZLIB \
THIRD_PARTY_MUSL \
LIBC_STDIO \
THIRD_PARTY_GDTOA \
THIRD_PARTY_REGEX \
LIBC_ALG \
LIBC_MEM \
@@ -266,8 +282,8 @@ COSMOPOLITAN_OBJECTS = \
LIBC_FMT \
THIRD_PARTY_COMPILER_RT \
LIBC_TINYMATH \
LIBC_SYSV \
LIBC_STR \
LIBC_SYSV \
LIBC_INTRIN \
LIBC_NT_KERNEL32 \
LIBC_NEXGEN32E
@@ -277,7 +293,6 @@ COSMOPOLITAN_HEADERS = \
LIBC_ALG \
LIBC_BITS \
LIBC_CALLS \
LIBC_CRYPTO \
LIBC_DNS \
LIBC_ELF \
LIBC_FMT \
+52 -20
View File
@@ -19,31 +19,62 @@ libc](https://justine.lol/cosmopolitan/index.html) website. We also have
## Getting Started
If you're doing your development work on Linux or BSD then you need just
five files to get started:
five files to get started. Here's what you do on Linux:
```sh
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-0.2.zip
unzip cosmopolitan-amalgamation-0.2.zip
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-1.0.zip
unzip cosmopolitan-amalgamation-1.0.zip
printf 'main() { printf("hello world\\n"); }\n' >hello.c
gcc -g -O -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \
gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \
-fno-omit-frame-pointer -pg -mnop-mcount \
-o hello.com.dbg hello.c -fuse-ld=bfd -Wl,-T,ape.lds \
-include cosmopolitan.h crt.o ape.o cosmopolitan.a
objcopy -S -O binary hello.com.dbg hello.com
./hello.com
```
If you're developing on Windows or MacOS then you need to download an
You now have a portable program. Please note that your APE binary will
assimilate itself as a conventional resident of your platform after the
first run, so it can be fast and efficient for subsequent executions.
```sh
./hello.com
bash -c './hello.com' # zsh/fish workaround (we upstreamed patches)
```
So if you intend to copy the binary to Windows or Mac then please do
that before you run it, not after.
### MacOS
If you're developing on MacOS you can install the GNU compiler
collection for x86_64-elf via homebrew:
```sh
brew install x86_64-elf-gcc
```
Then in the above scripts just replace `gcc` and `objcopy` with
`x86_64-elf-gcc` and `x86_64-elf-objcopy` to compile your APE binary.
### Windows
If you're developing on Windows then you need to download an
x86_64-pc-linux-gnu toolchain beforehand. See the [Compiling on
Windows](https://justine.lol/cosmopolitan/windows-compiling.html)
tutorial. It's needed because the ELF object format is what makes
universal binaries possible.
Cosmopolitan can also be compiled from source on any Linux distro.
## Source Builds
Cosmopolitan can be compiled from source on any Linux distro. GNU make
needs to be installed beforehand. This is a freestanding hermetic
repository that bootstraps using a vendored static gcc9 executable.
No further dependencies are required.
```sh
wget https://justine.lol/cosmopolitan/cosmopolitan-0.2.tar.gz
tar xf cosmopolitan-0.2.tar.gz # see releases page
cd cosmopolitan-0.2
wget https://justine.lol/cosmopolitan/cosmopolitan-1.0.tar.gz
tar xf cosmopolitan-1.0.tar.gz # see releases page
cd cosmopolitan
make -j16
o//examples/hello.com
find o -name \*.com | xargs ls -rShal | less
@@ -51,13 +82,14 @@ find o -name \*.com | xargs ls -rShal | less
## Support Vector
| Platform | Min Version | Circa |
| :--- | ---: | ---: |
| AMD | K8 Venus | 2005 |
| Intel | Core | 2006 |
| New Technology | Vista | 2006 |
| GNU/Systemd | 2.6.18 | 2007 |
| XNU's Not UNIX | 15.6 | 2018 |
| FreeBSD | 12 | 2018 |
| OpenBSD | 6.4 | 2018 |
| NetBSD | 9.1 | 2020 |
| Platform | Min Version | Circa |
| :--- | ---: | ---: |
| AMD | K8 Venus | 2005 |
| Intel | Core | 2006 |
| New Technology | Vista | 2006 |
| GNU/Systemd | 2.6.18 | 2007 |
| XNU's Not UNIX! | 15.6 | 2018 |
| FreeBSD | 12 | 2018 |
| OpenBSD | 6.4 | 2018 |
| NetBSD | 9.1 | 2020 |
| GNU Make | 3.80 | 2010 |
+147 -57
View File
@@ -535,7 +535,53 @@ ape_disk:
#if SupportsWindows() || SupportsMetal() || SupportsXnu()
apesh: .ascii "'\n#'\"\n" # sixth edition shebang
// 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.
// There isn't a one-size-fits-all approach for this, thus we
// present two choices.
#ifndef APE_NO_MODIFY_SELF
// The default behavior is: to overwrite the header in place.
// We prefer this because it's a tiny constant one time cost.
// We simply printf a 64-byte header and call execve() again.
.ascii "o=\"$(command -v \"$0\")\"\n"
#ifdef APE_BUILDSAFE
// This code is intended for binaries in build/bootstrap/. It
// causes them to not self-modify since they're checked-in to
// version control. It assumes cosmopolitan's build prefix is
// being used by convention and that the program has the noop
// flag -n which is used to prime the binary.
.ascii "if [ ${o##o/} = $o ]; then\n"
.ascii " if ! [ o/$o -nt $o ]; then\n"
.ascii " mkdir -p o/${o%/*} || exit\n"
.ascii " cp -f $o o/$o.$$ || exit\n"
.ascii " o/$o.$$ -n || exit\n"
.ascii " mv -f o/$o.$$ o/$o || exit\n"
.ascii " fi\n"
.ascii " exec o/$o \"$@\"\n"
.ascii "fi\n"
#endif
#else
// The alternative behavior is to copy to $TMPDIR and edit.
// This imposes a variety of caveats of its own that should
// be considered by the user beforehand, such as whether or
// not /tmp is considered trustworthy on a given system, or
// if the administrator chose to mount it with noexec. It's
// up to the user to decide what's best in those situations
// and also note that argv[0] and getauxval(AT_EXECFN) will
// change as a result of this, and lastly note we don't try
// to cleanup the tmp copies for the sake of efficiency. It
// should also be noted that if $0 has directory components
// then permission clashes can happen between system users,
// since only root is able to set the sticky bit, which can
// be addressed simply by overriding the TMPDIR environment
.ascii "o=\"${TMPDIR:-/tmp}/$0\"\n"
.ascii "if [ ! -e \"$o\" ]; then\n"
.ascii "d=\"$o\"\n"
.ascii "o=\"$o.$$\"\n"
.ascii "mkdir -p \"${o%/*}\" 2>/dev/null\n"
.ascii "cp -f \"$0\" \"$o\" || exit 120\n"
#endif /* APE_NO_MODIFY_SELF */
#if SupportsXnu()
.ascii "if [ -d /Applications ]; then\n"
.ascii "dd if=\"$o\""
@@ -547,7 +593,7 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang
.shstub ape_macho_dd_count,2
.ascii "\" conv=notrunc 2>/dev/null\n"
.ascii "el"
#endif
#endif /* XNU */
.ascii "if exec 7<> \"$o\"; then\n"
.ascii "printf '"
.ascii "\\177ELF" # 0x0: ⌂ELF
@@ -574,19 +620,28 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang
.ascii "' >&7\n"
.ascii "exec 7<&-\n"
.ascii "else\n"
.ascii "exit 1\n"
.ascii "exit 121\n"
.ascii "fi\n"
.ascii "exec \"$0\" \"$@\"\n" # etxtbsy tail recursion
.ascii "R=$?\n" # architecture optimistic
#ifndef APE_NO_MODIFY_SELF
.ascii "exec \"$0\" \"$@\"\n" # optimistic execution
#else
.ascii "mv -f \"$o\" \"$d\" 2>/dev/null\n"
.ascii "o=\"$d\"\n"
.ascii "fi\n"
.ascii "exec \"$o\" \"$@\"\n"
#endif /* APE_NO_MODIFY_SELF */
.ascii "R=$?\n"
.ascii "\n"
.ascii "if [ $R -eq 126 ] && [ \"$(uname -m)\" != x86_64 ]; then\n"
.ascii "if Q=\"$(command -v qemu-x86_64)\"; then\n"
.ascii "exec \"$Q\" \"$0\" \"$@\"\n"
.ascii "exec \"$Q\" \"$o\" \"$@\"\n"
.ascii "else\n"
.ascii "echo error: need qemu-x86_64 >&2\n"
.ascii "fi\n"
#ifndef APE_NO_MODIFY_SELF
.ascii "elif [ $R -eq 127 ]; then\n" # means argv[0] was wrong
.ascii " exec \"$o\" \"$@\"\n" # so do a path resolution
#endif /* APE_NO_MODIFY_SELF */
.ascii "fi\n"
.ascii "exit $R\n"
.endobj apesh
@@ -826,48 +881,48 @@ ape_macho:
@see "The Portable Executable File Format from Top to Bottom",
Randy Kath, Microsoft Developer Network Technology Group. */
// ┌14:Uniprocessor Machine ┌─────────────────────────┐
// │┌13:DLL │ PE File Characteristics │
// ││┌12:System ├─────────────────────────┤
// │││┌11:If Net Run From Swap │ r │ reserved │
// ││││┌10:If Removable Run From Swap │ d │ deprecated │
// │││││┌9:Debug Stripped │ D │ deprecated with │
// ││││││┌8:32bit Machine │ │ extreme prejudice │
// │││││││ ┌5:Large Address Aware └───┴─────────────────────┘
// │││││││ │ ┌1:Executable
// │││││││ │ │┌0:Relocs Stripped
// d│││││││dr│Ddd││
PEEXE = 0b0000001000100011
// ┌14:Uniprocessor Machine ┌─────────────────────────┐
// │┌13:DLL │ PE File Characteristics │
// ││┌12:System ├─────────────────────────┤
// │││┌11:If Net Run From Swap │ r │ reserved │
// ││││┌10:If Removable Run From Swap │ d │ deprecated │
// │││││┌9:Debug Stripped │ D │ deprecated with │
// ││││││┌8:32bit Machine │ │ extreme prejudice │
// │││││││ ┌5:Large Address Aware └───┴─────────────────────┘
// │││││││ │ ┌1:Executable
// │││││││ │ │┌0:Relocs Stripped
// d│││││││dr│Ddd││
PEEXE = 0b00000001000100011
// ┌15:TERMINAL_SERVER_AWARE ┌─────────────────────────┐
// │┌14:GUARD_CF │ PE DLL Characteristics │
// ││┌13:WDM_DRIVER ├─────────────────────────┤
// │││┌12:APPCONTAINER │ r │ reserved │
// ││││┌11:NO_BIND └───┴─────────────────────┘
// │││││┌10:NO_SEH
// ││││││┌9:NO_ISOLATION
// │││││││┌8:NX_COMPAT
// ││││││││┌7:FORCE_INTEGRITY
// │││││││││┌6:DYNAMIC_BASE
// ││││││││││┌5:HIGH_ENTROPY_VA
// │││││││││││rrrrr
// ┌15:TERMINAL_SERVER_AWARE ┌─────────────────────────┐
// │┌14:GUARD_CF │ PE DLL Characteristics │
// ││┌13:WDM_DRIVER ├─────────────────────────┤
// │││┌12:APPCONTAINER │ r │ reserved │
// ││││┌11:NO_BIND └───┴─────────────────────┘
// │││││┌10:NO_SEH
// ││││││┌9:NO_ISOLATION
// │││││││┌8:NX_COMPAT
// ││││││││┌7:FORCE_INTEGRITY
// │││││││││┌6:DYNAMIC_BASE
// ││││││││││┌5:HIGH_ENTROPY_VA
// │││││││││││rrrrr
DLLSTD = 0b0000000100100000
DLLPIE = 0b0000000001100000
DLLEXE = DLLSTD
// ┌31:Writeable ┌─────────────────────────┐
// │┌30:Readable │ PE Section Flags │
// ││┌29:Executable ├─────────────────────────┤
// │││┌28:Shareable │ o │ for object files │
// ││││┌27:Unpageable │ r │ reserved │
// │││││┌26:Uncacheable └───┴─────────────────────┘
// ││││││┌25:Discardable
// │││││││┌24:Contains Extended Relocations
// ││││││││ ┌15:Contains Global Pointer (GP) Relative Data
// ││││││││ │ ┌7:Contains Uninitialized Data
// ││││││││ │ │┌6:Contains Initialized Data
// ││││││││ o │ ││┌5:Contains Code
// ││││││││┌┴─┐rrrr│ ooror│││rorrr
// ┌31:Writeable ┌─────────────────────────┐
// │┌30:Readable │ PE Section Flags │
// ││┌29:Executable ├─────────────────────────┤
// │││┌28:Shareable │ o │ for object files │
// ││││┌27:Unpageable │ r │ reserved │
// │││││┌26:Uncacheable └───┴─────────────────────┘
// ││││││┌25:Discardable
// │││││││┌24:Contains Extended Relocations
// ││││││││ ┌15:Contains Global Pointer (GP) Relative Data
// ││││││││ │ ┌7:Contains Uninitialized Data
// ││││││││ │ │┌6:Contains Initialized Data
// ││││││││ o │ ││┌5:Contains Code
// ││││││││┌┴─┐rrrr│ ooror│││rorrr
PETEXT = 0b01110000000000000000000001100000
PEDATA = 0b11000000000000000000000011000000
PEIMPS = 0b11000000000000000000000001000000
@@ -1393,21 +1448,66 @@ long: push $GDT_LONG_DATA
call __map_phdrs
push $0x037f
fldcw (%rsp)
movabs $1f,%rax
movabs $kernel,%rax
jmp *%rax
1: movabs $ape_stack_vaddr,%rsp
.endfn long
/* ▄▄▒▀▀▀▀▒▒▄
█████▓▓▄░░░░ ▒▒▄
▐█▓▓█▓▄█████▓░ ▀▒▄
▓█▓▓▓▓▓▓▓▓▓█▓ ░▀▒░
▀▀▓█▓▓▓▓▓▓█▓ ░▀▒▄▄▒▄▄▄▒▒▒▀▀▀▀▀▀▀▀▀▀▀▀▀▀▒▒▄▒
▀▓▓█▓▓▓▓▓▄ ░ ░▀▒▄▄ ▄
▀█▓▓▓▓▓▄░ ░▀▒░ ▄▓▌
▀█▓▓▓▓▓█▓░ ░▀▄░ ░▄▓██░
▀█▓▓▓▓▓█▄ ░▀▒▄▄▄▄▄▄▄▄▒▀▓█▓█▓░
▀█▓▓▓▓█▓░ ░▄▓█▓▓█▓▄▌
▀█▓▓▓▓▓▄ ▄▄▄▓▓██▓▓▒▒░ ▒▒▄▓█▓▓▓▓█▓
▀█▓▓▓▓▓▓▄▄░ ░▄▄▓██▓▓▓▓▓██████████████▓▓▓▓▓▓█▀
▐█▓▓▓▓▓▓▓██▓▓▄▄▄▄▄▄▄▄▄▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█████████▓▓▀
▀▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█░ ░░░░░░
▄░▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▌
█▓▄▀▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██▓▓▀▀▀▀▀▀▀▓█▓▓▓▓▓▓▓▓▓▓▓▓
▐█▓█▓░▓█▓▓▓▓▓▓▓█▀▀▀▀▒░ ▐▓▓▓▓▓▓▄▒▀▓█▓▓▓▓▓▓▓▓█▌
▐█▓▓▓█▒▀█▓▓▓▓▓▓█▌ ▀█▓▓▓▓▓█▄░▀▓▓█▓▓▓▓▓▓█░
█▓▓▓▓▓█░▐█▓▓▓▓▓█▌ ▀▓█▓▓▓▓█▌ ░▀█▓▓▓▓▓█▄
█▓▓▓▓█▌ ░█▓▓▓▓▓█░ ▓█▓▓▓▓▓░ ▒█▓▓▓▓▓█░
█▓▓▓▓█░ █▓▓▓▓▓█░ █▓▓▓▓▓█░ ▐█▓▓▓▓█▌
▐█▓▓▓▓▓▄ █▓▓▓▓▓█ ░▄▄▓█▓▓▓▓▓█░ ▐█▓▓▓▓█░
▓█▓▓▓█▓▐█▓▓▓▓█▌ ▓██▓▓▓▓▓▓█▀ ▓█▓▓▓▓█
▀▓██▒▄█▓▓▓▓▓█░ ░█▓▓▓▓▓██▀░ ░▓█▓▓▓▓█▌
░░█▓▓▓▓▓█▓ ░▀▀▀▀▀▀ ▓█▓▓▓▓▓▓
╔───────────────────────────────────────────────────────────▀▀▀▀▀▀───────────│─╗
│ αcτµαlly pδrταblε εxεcµταblε § cosmopolitan libc runtime runtime ─╬─│┼
╚────────────────────────────────────────────────────────────────────────────│*/
kernel: movabs $ape_stack_vaddr,%rsp
add $ape_stack_memsz,%rsp
movl $0,0x7b000 # unmap null 2mb
#if USE_SYMBOL_HACK
.byte 0x0f,0x1f,0207 # nop rdi binbase
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
#endif
movl $0,0x7b000 # unmap null 2mb
.weak __hostos
ezlea __hostos,ax
test %rax,%rax
jz 1f
movb $METAL,(%rax)
1: xor %eax,%eax
1: push $0
mov %rsp,%rbp
mov .Lenv0(%rip),%rax
mov %rax,(%rbp) # envp[0][0]
push $0 # argv[0][0]
push $0 # auxv[1][1]
push $0 # auxv[1][0]
push %rbp # auxv[0][1]
push $31 # auxv[0][0] AT_EXECFN
push $0 # envp[1]
push $.Lenv0 # envp[0]
push $0 # argv[1]
push %rbp # argv[0]
push $1 # argc
xor %ebp,%ebp
xor %eax,%eax
xor %ecx,%ecx
xor %edx,%edx
xor %edi,%edi
@@ -1416,20 +1516,10 @@ long: push $GDT_LONG_DATA
xor %r9d,%r9d
xor %r10d,%r10d
xor %r11d,%r11d
push $0 # auxv[1][1]
push $0 # auxv[1][0]
push $.Larg0 # auxv[0][1]
push $31 # auxv[0][0] AT_EXECFN
push $0 # envp[1]
push $.Lenv0 # envp[0]
push $0 # argv[1]
push $.Larg0 # argv[0]
push $1 # argc
jmp _start
.endfn long
.endfn kernel
.rodata
.Larg0: .asciz "ape.com"
.Lenv0: .asciz "METAL=1"
.previous
+3 -1
View File
@@ -201,6 +201,8 @@ SECTIONS {
/* Real Mode */
KEEP(*(.head))
KEEP(*(.apesh))
KEEP(*(.head2))
KEEP(*(.text.head))
/* Executable & Linkable Format */
@@ -375,7 +377,7 @@ SECTIONS {
/*END: file content */
/*BEGIN: bss memory that's addressable */
.bss ALIGN(__SIZEOF_POINTER__) : {
.bss ALIGN(64) : {
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
*(.piro.bss)
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
+14 -1
View File
@@ -19,6 +19,11 @@ APE = $(APE_DEPS) \
$(APE_OBJS) \
o/$(MODE)/ape/ape.lds
APE_BUILDSAFE = \
$(APE_DEPS) \
o/$(MODE)/ape/ape-buildsafe.o \
o/$(MODE)/ape/ape.lds
APELINK = \
$(COMPILE) \
-ALINK.ape \
@@ -46,5 +51,13 @@ o/ape/idata.inc: \
$(APE_OBJS): $(BUILD_FILES) \
ape/ape.mk
o/$(MODE)/ape/ape-no-modify-self.o: ape/ape.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -DAPE_NO_MODIFY_SELF $<
o/$(MODE)/ape/ape-buildsafe.o: ape/ape.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -DAPE_BUILDSAFE $<
.PHONY: o/$(MODE)/ape
o/$(MODE)/ape: $(APE) $(APE_CHECKS)
o/$(MODE)/ape: $(APE) \
$(APE_CHECKS) \
o/$(MODE)/ape/ape-no-modify-self.o
-1279
View File
File diff suppressed because it is too large. Load diff
-1294
View File
File diff suppressed because it is too large. Load diff
-29
View File
@@ -1,29 +0,0 @@
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
#
# SYNOPSIS
#
# Program Deprioritizer
#
# OVERVIEW
#
# This is a drop-in replacement for the traditional Unix `nice`
# command that also invokes `ionice`, which is important, since
# network and traffic is usually what clobber the system.
if [ -z "$IONICE" ]; then
if IONICE=$(command -v ionice 2>/dev/null); then
IONICE="$IONICE -c3"
fi
fi
if [ -z "$NICE" ]; then
NICE=$(command -v nice 2>/dev/null)
fi
if [ -z "$IONICE$NICE" ]; then
echo "error: can't be nice" >&2
fi
exec $IONICE $NICE "$@"
-9
View File
@@ -1,9 +0,0 @@
#!/bin/sh
# -*- mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8 -*-
# vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi
echo c |
bochs \
-q \
-f ape/etc/bochsrc.dbg \
floppya:1_44=$1,status=inserted
-51
View File
@@ -1,51 +0,0 @@
#!/bin/sh
# -*- mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8 -*-
# vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi
#
# bochs-scriptable executes a disk with serial uart stdio.
#
# USAGE
#
# build/bochs-scriptable IMAGE...
#
# DESCRIPTION
#
# This script is useful for end-to-end testing metal apps in <100ms.
#
# SEE ALSO
#
# build/boot(1)
while getopts h X; do
case $X in
h) exec less "$0" ;;
\?) echo "$0: bad arg" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
trap '' INT
IMG=$1
OUT=/tmp/$USER.$$.bochs.stdout
ERR=/tmp/$USER.$$.bochs.stderr
mkfifo $OUT || exit
cat <$OUT &
CAT=$!
exec 4>$OUT
rm -f $OUT
echo c |
bochs \
-q \
-f ape/etc/bochsrc.ffs \
display_library:nogui \
floppya:1_44=$1,status=inserted \
>>$ERR 2>>$ERR
RC=$?
kill $CAT
exec 4>&-
rm -f $ERR
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-21
View File
@@ -1,21 +0,0 @@
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
#
# OVERVIEW
#
# Source File Concatenation Tool
#
# DESCRIPTION
#
# This program is the same as cat, but inserts preprocessor directives
# that allow compiler errors to point back to the original lines.
if [ $# -eq 0 ]; then
cat
else
for x; do
printf '# 1 "%s"\n' "$x"
cat "$x"
done
fi
+41 -11
View File
@@ -50,6 +50,8 @@ endif
# Release Mode
#
# Follows traditional closed source release binary norms.
#
# - `make MODE=rel`
# - More optimized
# - Reasonably small
@@ -69,16 +71,45 @@ CONFIG_CCFLAGS += \
$(BACKTRACES) \
-O2
TARGET_ARCH ?= \
-msse3
endif
# Asan Mode
#
# Safer binaries good for backend production serving.
#
# - `make MODE=asan`
# - Memory safety
# - Production worthy
# - Backtraces
# - Debuggability
# - Larger binaries
ifeq ($(MODE), asan)
CONFIG_CCFLAGS += \
$(BACKTRACES) \
-O2
CONFIG_COPTS += \
-fsanitize=address
TARGET_ARCH ?= \
-msse3
endif
# Debug Mode
#
# - `make MODE=dbg`
# - Backtraces
# - Zero optimization
# - Enables sanitization
# - Enables stack canaries
# - Enormous binaries (b/c ubsan suboptimalities)
# - Enables asan
# - Enables ubsan (TODO)
# - Stack canaries
# - No optimization (TODO)
# - Enormous binaries
ifeq ($(MODE), dbg)
@@ -91,8 +122,7 @@ CONFIG_CCFLAGS += \
-O2
CONFIG_COPTS += \
$(SECURITY_BLANKETS) \
$(SANITIZER)
-fsanitize=address
TARGET_ARCH ?= \
-msse3
@@ -113,6 +143,7 @@ endif
# - No backtraces
# - No algorithmics
# - YOLO
ifeq ($(MODE), tiny)
CONFIG_CPPFLAGS += \
-DTINY \
@@ -140,6 +171,7 @@ endif
# - No portability
# - No algorithmics
# - YOLO
ifeq ($(MODE), tinylinux)
CONFIG_CPPFLAGS += \
-DTINY \
@@ -169,6 +201,7 @@ endif
# - No backtraces
# - No algorithmics
# - YOLO
ifeq ($(MODE), tinylinuxbsd)
CONFIG_CPPFLAGS += \
-DTINY \
@@ -197,6 +230,7 @@ endif
# - No backtraces
# - No algorithmics
# - YOLO
ifeq ($(MODE), tinysysv)
CONFIG_CPPFLAGS += \
-DTINY \
@@ -225,6 +259,7 @@ endif
# - No backtraces
# - No algorithmics
# - YOLO
ifeq ($(MODE), tinynowin)
CONFIG_CPPFLAGS += \
-DTINY \
@@ -282,11 +317,6 @@ endif
# such as MSVC or XCode. You can run your binary objects through a tool
# like objconv to convert them to COFF or MachO. Then use ANSI mode to
# rollup one header file that'll enable linkage with minimal issues.
#
# Lastly note that in some cases, such as gc(), there simply isn't any
# ANSI workaround available. It's only in cases like that when we'll use
# the __asm__() header workaround, rather than simply removing it. We do
# however try to do that much less often than mainstream C libraries.
ifeq ($(MODE), ansi)
+3 -3
View File
@@ -50,7 +50,6 @@ TAGS ?= /usr/bin/ctags # emacs source builds or something breaks it
ARFLAGS = rcsD
ZFLAGS ?=
XARGS ?= xargs -P4 -rs8000
NICE ?= build/actuallynice
DOT ?= dot
GZ ?= gzip
CLANG = clang
@@ -78,7 +77,8 @@ PWD := $(shell pwd)
IMAGE_BASE_VIRTUAL ?= 0x400000
HELLO := $(shell build/hello)
TMPDIR := $(shell build/findtmp)
COMPILE := $(shell build/getcompile) -V$(shell build/getccversion $(CC))
SPAWNER := $(shell build/getcompile) -V$(shell build/getccversion $(CC))
COMPILE = $(SPAWNER) $(QUOTA)
export ADDR2LINE
export LC_ALL
@@ -137,6 +137,7 @@ MATHEMATICAL = \
-fwrapv
DEFAULT_CPPFLAGS = \
-DCOSMO \
-DMODE='"$(MODE)"' \
-DIMAGE_BASE_VIRTUAL=$(IMAGE_BASE_VIRTUAL) \
-nostdinc \
@@ -181,7 +182,6 @@ DEFAULT_LDLIBS =
MCA = llvm-mca-10 \
-mtriple=x86_64-pc-linux-gnu \
-iterations=3 \
-instruction-info \
-iterations=3 \
-all-stats \
+1 -1
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
#
-7
View File
@@ -1,7 +0,0 @@
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
for x; do
printf '#include "%s"\n' "$x"
done
-2189
View File
File diff suppressed because it is too large. Load diff
-7
View File
@@ -1,7 +0,0 @@
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
for x; do
printf '#include "%s"\n' "$x"
done
+3
View File
@@ -79,4 +79,7 @@ o/$(MODE)/%.zip.o: % ; @$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLA
o/$(MODE)/%-gcc.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
o/$(MODE)/%-clang.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@
o/$(MODE)/%.lua: %.lua o/$(MODE)/third_party/lua/luac.com
@$(COMPILE) -ALUAC -T$@ o/$(MODE)/third_party/lua/luac.com -s -o $@ $<
o/$(MODE)/%-clang.asm: CC = $(CLANG)
-14
View File
@@ -1,14 +0,0 @@
#!/bin/sh
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
#
# OVERVIEW
#
# SSH Command Wrapper
#
# DESCRIPTION
#
# This script, like most of our wrappers, asks the tooling to whine
# less often.
exec ${SSH:-ssh} -o LogLevel=QUIET "$@"
+1 -1
View File
@@ -28,7 +28,7 @@
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/bsr.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/gc.internal.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
+1 -1
View File
@@ -18,7 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/tty/tty.h"
#include "libc/alg/arraylist2.internal.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/gc.internal.h"
#include "libc/x/x.h"
/* TODO(jart): DELETE */
+1 -1
View File
@@ -27,7 +27,7 @@
#include "libc/calls/ucontext.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/gc.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
+403
View File
@@ -0,0 +1,403 @@
/*-*- 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 The Mbed TLS Contributors │
│ │
│ Licensed under the Apache License, Version 2.0 (the "License"); │
│ you may not use this file except in compliance with the License. │
│ You may obtain a copy of the License at │
│ │
│ http://www.apache.org/licenses/LICENSE-2.0 │
│ │
│ Unless required by applicable law or agreed to in writing, software │
│ distributed under the License is distributed on an "AS IS" BASIS, │
│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │
│ See the License for the specific language governing permissions and │
│ limitations under the License. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/fmt/conv.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/exit.h"
#include "third_party/mbedtls/ctr_drbg.h"
#include "third_party/mbedtls/debug.h"
#include "third_party/mbedtls/entropy.h"
#include "third_party/mbedtls/net_sockets.h"
#include "third_party/mbedtls/ssl.h"
#include "third_party/mbedtls/x509_crt.h"
STATIC_YOINK("ssl_root_support");
#define MODE_NONE 0
#define MODE_FILE 1
#define MODE_SSL 2
#define DFL_MODE MODE_NONE
#define DFL_FILENAME "cert.crt"
#define DFL_CA_FILE ""
#define DFL_CRL_FILE ""
#define DFL_CA_PATH "zip:usr/share/ssl/root"
#define DFL_SERVER_NAME "localhost"
#define DFL_SERVER_PORT "4433"
#define DFL_DEBUG_LEVEL 0
#define DFL_PERMISSIVE 0
#define USAGE_IO \
" ca_file=%%s file containing top-level CAs\n" \
" ca_path=%%s dir containing top-level CAs\n" \
" crl_file=%%s The single CRL file you want to use\n"
#define USAGE \
"\n usage: %s param=<>...\n" \
"\n acceptable parameters:\n" \
" mode=file|ssl default: none\n" \
" filename=%%s default: cert.crt\n" USAGE_IO \
" server_name=%%s default: localhost\n" \
" server_port=%%d default: 4433\n" \
" debug_level=%%d default: 0 (disabled)\n" \
" permissive=%%d default: 0 (disabled)\n" \
"\n"
/*
* global options
*/
struct options {
int mode; /* the mode to run the application in */
const char *filename; /* filename of the certificate file */
const char *ca_file; /* the file with the CA certificate(s) */
const char *crl_file; /* the file with the CRL to use */
const char *ca_path; /* the path with the CA certificate(s) reside */
const char *server_name; /* hostname of the server (client only) */
const char *server_port; /* port on which the ssl service runs */
int debug_level; /* level of debugging */
int permissive; /* permissive parsing */
} opt;
static void my_debug(void *ctx, int level, const char *file, int line,
const char *str) {
fprintf((FILE *)ctx, "%s:%04d: %s", file, line, str);
fflush((FILE *)ctx);
}
static int my_verify(void *data, mbedtls_x509_crt *crt, int depth,
uint32_t *flags) {
char buf[1024];
printf("\nVerify requested for (Depth %d):\n", depth);
mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
printf("%s", buf);
if (*flags) {
mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", *flags);
printf("%s\n", buf);
}
return 0;
}
mbedtls_net_context server_fd;
unsigned char buf[1024];
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt cacert;
mbedtls_x509_crl cacrl;
int main(int argc, char *argv[]) {
int ret = 1;
int exit_code = EXIT_FAILURE;
int i, j;
uint32_t flags;
int verify = 0;
char *p, *q;
const char *pers = "cert_app";
/*
* Set to sane values
*/
mbedtls_net_init(&server_fd);
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
mbedtls_x509_crt_init(&cacert);
#if defined(MBEDTLS_X509_CRL_PARSE_C)
mbedtls_x509_crl_init(&cacrl);
#else
/* Zeroize structure as CRL parsing is not supported and we have to pass
it to the verify function */
memset(&cacrl, 0, sizeof(mbedtls_x509_crl));
#endif
if (argc == 0) {
usage:
printf(USAGE, program_invocation_name);
goto exit;
}
opt.mode = DFL_MODE;
opt.filename = DFL_FILENAME;
opt.ca_file = DFL_CA_FILE;
opt.crl_file = DFL_CRL_FILE;
opt.ca_path = DFL_CA_PATH;
opt.server_name = DFL_SERVER_NAME;
opt.server_port = DFL_SERVER_PORT;
opt.debug_level = DFL_DEBUG_LEVEL;
opt.permissive = DFL_PERMISSIVE;
for (i = 1; i < argc; i++) {
p = argv[i];
if ((q = strchr(p, '=')) == NULL) goto usage;
*q++ = '\0';
for (j = 0; p + j < q; j++) {
if (argv[i][j] >= 'A' && argv[i][j] <= 'Z') argv[i][j] |= 0x20;
}
if (strcmp(p, "mode") == 0) {
if (strcmp(q, "file") == 0)
opt.mode = MODE_FILE;
else if (strcmp(q, "ssl") == 0)
opt.mode = MODE_SSL;
else
goto usage;
} else if (strcmp(p, "filename") == 0)
opt.filename = q;
else if (strcmp(p, "ca_file") == 0)
opt.ca_file = q;
else if (strcmp(p, "crl_file") == 0)
opt.crl_file = q;
else if (strcmp(p, "ca_path") == 0)
opt.ca_path = q;
else if (strcmp(p, "server_name") == 0)
opt.server_name = q;
else if (strcmp(p, "server_port") == 0)
opt.server_port = q;
else if (strcmp(p, "debug_level") == 0) {
opt.debug_level = atoi(q);
if (opt.debug_level < 0 || opt.debug_level > 65535) goto usage;
} else if (strcmp(p, "permissive") == 0) {
opt.permissive = atoi(q);
if (opt.permissive < 0 || opt.permissive > 1) goto usage;
} else
goto usage;
}
/*
* 1.1. Load the trusted CA
*/
printf(" . Loading the CA root certificate ...");
fflush(stdout);
if (strlen(opt.ca_path)) {
if ((ret = mbedtls_x509_crt_parse_path(&cacert, opt.ca_path)) < 0) {
printf(" failed\n ! mbedtls_x509_crt_parse_path returned -0x%x\n\n",
(unsigned int)-ret);
goto exit;
}
verify = 1;
} else if (strlen(opt.ca_file)) {
if ((ret = mbedtls_x509_crt_parse_file(&cacert, opt.ca_file)) < 0) {
printf(" failed\n ! mbedtls_x509_crt_parse_file returned -0x%x\n\n",
(unsigned int)-ret);
goto exit;
}
verify = 1;
}
printf(" ok (%d skipped)\n", ret);
#if defined(MBEDTLS_X509_CRL_PARSE_C)
if (strlen(opt.crl_file)) {
if ((ret = mbedtls_x509_crl_parse_file(&cacrl, opt.crl_file)) != 0) {
printf(" failed\n ! mbedtls_x509_crl_parse returned -0x%x\n\n",
(unsigned int)-ret);
goto exit;
}
verify = 1;
}
#endif
if (opt.mode == MODE_FILE) {
mbedtls_x509_crt crt;
mbedtls_x509_crt *cur = &crt;
mbedtls_x509_crt_init(&crt);
/*
* 1.1. Load the certificate(s)
*/
printf("\n . Loading the certificate(s) ...");
fflush(stdout);
ret = mbedtls_x509_crt_parse_file(&crt, opt.filename);
if (ret < 0) {
printf(" failed\n ! mbedtls_x509_crt_parse_file returned -0x%04x\n\n",
-ret);
mbedtls_x509_crt_free(&crt);
goto exit;
}
if (opt.permissive == 0 && ret > 0) {
printf(" failed\n ! mbedtls_x509_crt_parse failed to parse %d "
"certificates\n\n",
ret);
mbedtls_x509_crt_free(&crt);
goto exit;
}
printf(" ok\n");
/*
* 1.2 Print the certificate(s)
*/
while (cur != NULL) {
printf(" . Peer certificate information ...\n");
ret = mbedtls_x509_crt_info((char *)buf, sizeof(buf) - 1, " ", cur);
if (ret == -1) {
printf(" failed\n ! mbedtls_x509_crt_info returned -0x%04x\n\n",
-ret);
mbedtls_x509_crt_free(&crt);
goto exit;
}
printf("%s\n", buf);
cur = cur->next;
}
/*
* 1.3 Verify the certificate
*/
if (verify) {
printf(" . Verifying X.509 certificate...");
if ((ret = mbedtls_x509_crt_verify(&crt, &cacert, &cacrl, NULL, &flags,
my_verify, NULL)) != 0) {
char vrfy_buf[512];
printf(" failed\n");
mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags);
printf("%s\n", vrfy_buf);
} else
printf(" ok\n");
}
mbedtls_x509_crt_free(&crt);
} else if (opt.mode == MODE_SSL) {
/*
* 1. Initialize the RNG and the session data
*/
printf("\n . Seeding the random number generator...");
fflush(stdout);
mbedtls_entropy_init(&entropy);
if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char *)pers,
strlen(pers))) != 0) {
printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret);
goto ssl_exit;
}
printf(" ok\n");
#if defined(MBEDTLS_DEBUG_C)
mbedtls_debug_set_threshold(opt.debug_level);
#endif
/*
* 2. Start the connection
*/
printf(" . Connecting to tcp/%s/%s...\n", opt.server_name,
opt.server_port);
if ((ret = mbedtls_net_connect(&server_fd, opt.server_name, opt.server_port,
MBEDTLS_NET_PROTO_TCP)) != 0) {
printf(" ! mbedtls_net_connect returned -0x%04x\n\n", -ret);
goto ssl_exit;
}
/*
* 3. Setup stuff
*/
if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
printf(" ! mbedtls_ssl_config_defaults returned -0x%04x\n\n", -ret);
goto exit;
}
if (verify) {
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
mbedtls_ssl_conf_verify(&conf, my_verify, NULL);
} else
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
printf(" ! mbedtls_ssl_setup returned -0x%04x\n\n", -ret);
goto ssl_exit;
}
if ((ret = mbedtls_ssl_set_hostname(&ssl, opt.server_name)) != 0) {
printf(" ! mbedtls_ssl_set_hostname returned -0x%04x\n\n", -ret);
goto ssl_exit;
}
mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv,
NULL);
/*
* 4. Handshake
*/
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
printf(" ! mbedtls_ssl_handshake returned -0x%04x\n\n", -ret);
goto ssl_exit;
}
}
/*
* 5. Print the certificate
*/
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
printf(" . Peer certificate information ... skipped\n");
#else
printf(" . Peer certificate information ...\n");
ret = mbedtls_x509_crt_info((char *)buf, sizeof(buf) - 1, " ",
mbedtls_ssl_get_peer_cert(&ssl));
if (ret == -1) {
printf(" failed\n ! mbedtls_x509_crt_info returned -0x%04x\n\n", -ret);
goto ssl_exit;
}
printf("%s\n", buf);
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
mbedtls_ssl_close_notify(&ssl);
ssl_exit:
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
} else
goto usage;
exit_code = MBEDTLS_EXIT_SUCCESS;
exit:
mbedtls_net_free(&server_fd);
mbedtls_x509_crt_free(&cacert);
#if defined(MBEDTLS_X509_CRL_PARSE_C)
mbedtls_x509_crl_free(&cacrl);
#endif
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
mbedtls_exit(exit_code);
}
+1 -1
View File
@@ -73,7 +73,7 @@ void GetOpts(int argc, char *argv[]) {
int cp(const char *src, const char *dst) {
if (endswith(dst, "/") || isdirectory(dst)) {
dst = gc(xasprintf("%s/%s", dst, basename));
dst = _gc(xasprintf("%s/%s", dst, basename));
}
if (!force && access(dst, W_OK) == -1 && errno != ENOENT) goto OnFail;
if (copyfile(src, dst, flags) == -1) goto OnFail;
+8 -73
View File
@@ -7,88 +7,23 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/bits/pushpop.h"
#include "libc/calls/calls.h"
#include "libc/calls/ucontext.h"
#include "libc/log/log.h"
#include "libc/math.h"
#include "libc/nt/enum/errormodeflags.h"
#include "libc/nt/signals.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
/**
* @fileoverview Demonstrates SEGFAULT via NULL pointer dereference.
* @fileoverview How to print backtraces and cpu state on crash.
*
* In MODE=dbg mode, UBSAN should catch this and display a backtrace.
* In most other modes, e.g. MODE=balanced, the oncrash.c sig handler
* will either launch GDB or display a very fancy report.
*
* make -j8 -O MODE=opt o/opt/examples/crashreportdemo.com
* o/opt/examples/crashreportdemo.com
* make -j8 -O o//examples/crashreport.com
* o//examples/crashreport.com
*
* To prevent the GDB GUI from popping up:
*
* export GDB=""
* make -j8 -O MODE=opt o/opt/examples/crashreportdemo.com
* o/opt/examples/crashreportdemo.com
* export GDB=
* make -j8 -O o//examples/crashreport.com
* o//examples/crashreport.com
*/
int boo;
void boop(void);
int main(int argc, char *argv[]) {
int64_t res;
volatile int64_t x;
showcrashreports();
res = 0;
asm volatile("mov\t$0x1111111111111111,%rax\n\t"
"mov\t$0x3333333333333333,%rcx\n\t"
"mov\t$0x4444444444444444,%rdx\n\t"
"mov\t$0x8888888888888888,%r8\n\t"
"mov\t$0x9999999999999999,%r9d\n\t"
"mov\t$0xaaaaaaaaaaaaaaaa,%r10d\n\t"
"mov\t$0xbbbbbbbbbbbbbbbb,%r11d\n\t"
"mov\t$0x0000000000000000,%rax\n\t"
"movd\t%rax,%xmm0\n\t"
"mov\t$0x1111111111111111,%rax\n\t"
"push\t%rax\n\t"
"push\t%rax\n\t"
"movdqu\t(%rsp),%xmm1\n\t"
"pop\t%rax\n\t"
"pop\t%rax\n\t"
"mov\t$0x2222222222220022,%rax\n\t"
"movd\t%rax,%xmm2\n\t"
"mov\t$0x3333333333333333,%rax\n\t"
"movd\t%rax,%xmm3\n\t"
"mov\t$0x4444444444444444,%rax\n\t"
"movd\t%rax,%xmm4\n\t"
"mov\t$0x5555555555555555,%rax\n\t"
"movd\t%rax,%xmm5\n\t"
"mov\t$0x6666666666666666,%rax\n\t"
"movd\t%rax,%xmm6\n\t"
"mov\t$0x7777777777777777,%rax\n\t"
"movd\t%rax,%xmm7\n\t"
"mov\t$0x8888888888888888,%rax\n\t"
"movd\t%rax,%xmm8\n\t"
"mov\t$0x9999999999999999,%rax\n\t"
"movd\t%rax,%xmm9\n\t"
"mov\t$0xaaaaaaaaaaaaaaaa,%rax\n\t"
"movd\t%rax,%xmm10\n\t"
"mov\t$0xbbbbbbbbbbbbbbbb,%rax\n\t"
"movd\t%rax,%xmm11\n\t"
"mov\t$0xcccccccccccccccc,%rax\n\t"
"movd\t%rax,%xmm12\n\t"
"mov\t$0xdddddddddddddddd,%rax\n\t"
"movd\t%rax,%xmm13\n\t"
"mov\t$0xeeeeeeeeeeeeeeee,%rax\n\t"
"movd\t%rax,%xmm14\n\t"
"mov\t$0xffffffffffffffff,%rax\n\t"
"movd\t%rax,%xmm15\n\t"
"fldpi\n\t"
"xor\t%eax,%eax\n\t"
"div\t%eax\n\t");
return res;
return 1 / (x = 0);
}
+2 -3
View File
@@ -14,7 +14,6 @@
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "libc/nt/thread.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
@@ -32,9 +31,9 @@ int main(int argc, char *argv[]) {
ssize_t rc;
size_t got, wrote;
unsigned char buf[512];
struct sigaction saint = {.sa_handler = GotCtrlC};
fprintf(stderr, "This echos stdio until Ctrl+C is pressed.\n");
CHECK_NE(
-1, sigaction(SIGINT, &(struct sigaction){.sa_handler = GotCtrlC}, NULL));
CHECK_NE(-1, sigaction(SIGINT, &saint, NULL));
for (;;) {
rc = read(0, buf, BUFSIZ);
if (rc != -1) {
+362 -63
View File
@@ -8,24 +8,49 @@
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/bits/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/dns/dns.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/goodsocket.internal.h"
#include "libc/sock/sock.h"
#include "libc/stdio/append.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/str/slice.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ai.h"
#include "libc/sysv/consts/dt.h"
#include "libc/sysv/consts/ex.h"
#include "libc/sysv/consts/exit.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/shut.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/so.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/sol.h"
#include "libc/sysv/consts/tcp.h"
#include "libc/time/struct/tm.h"
#include "libc/x/x.h"
#include "net/http/uri.h"
#include "net/http/http.h"
#include "net/http/url.h"
#include "net/https/https.h"
#include "net/https/sslcache.h"
#include "third_party/getopt/getopt.h"
#include "third_party/mbedtls/ctr_drbg.h"
#include "third_party/mbedtls/debug.h"
#include "third_party/mbedtls/error.h"
#include "third_party/mbedtls/pk.h"
#include "third_party/mbedtls/ssl.h"
#include "third_party/mbedtls/ssl_ticket.h"
/**
* @fileoverview Downloads HTTP URL to stdout.
@@ -34,73 +59,347 @@
* o//examples/curl.com http://justine.lol/ape.html
*/
#define HasHeader(H) (!!msg.headers[H].a)
#define HeaderData(H) (p + msg.headers[H].a)
#define HeaderLength(H) (msg.headers[H].b - msg.headers[H].a)
#define HeaderEqualCase(H, S) \
SlicesEqualCase(S, strlen(S), HeaderData(H), HeaderLength(H))
static bool TuneSocket(int fd, int a, int b, int x) {
if (!b) return false;
return setsockopt(fd, a, b, &x, sizeof(x)) != -1;
}
static int TlsSend(void *c, const unsigned char *p, size_t n) {
int rc;
NOISEF("begin send %zu", n);
CHECK_NE(-1, (rc = write(*(int *)c, p, n)));
NOISEF("end send %zu", n);
return rc;
}
static int TlsRecv(void *c, unsigned char *p, size_t n, uint32_t o) {
int r;
struct iovec v[2];
static unsigned a, b;
static unsigned char t[4096];
if (a < b) {
r = MIN(n, b - a);
memcpy(p, t + a, r);
if ((a += r) == b) a = b = 0;
return r;
}
v[0].iov_base = p;
v[0].iov_len = n;
v[1].iov_base = t;
v[1].iov_len = sizeof(t);
NOISEF("begin recv %zu", n + sizeof(t) - b);
CHECK_NE(-1, (r = readv(*(int *)c, v, 2)));
NOISEF("end recv %zu", r);
if (r > n) b = r - n;
return MIN(n, r);
}
static wontreturn void PrintUsage(FILE *f, int rc) {
fprintf(f, "usage: %s [-ksvV] URL\n", program_invocation_name);
exit(rc);
}
int main(int argc, char *argv[]) {
int sock;
ssize_t rc;
unsigned long need;
struct UriSlice path;
size_t i, got, toto, msglen;
char buf[1500], host[256], port[7];
const char *url, *msg, *pathstr, *crlfcrlf, *contentlength;
struct UriSlice us[16];
struct Uri u = {.segs.p = us, .segs.n = ARRAYLEN(us)};
struct addrinfo *addr, *addrs;
if (!NoDebug()) showcrashreports();
xsigaction(SIGPIPE, SIG_IGN, 0, 0, 0);
/*
* Read flags.
*/
int opt;
struct Headers {
size_t n;
char **p;
} headers = {0};
int method = kHttpGet;
bool authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
const char *agent = "hurl/1.o (https://github.com/jart/cosmopolitan)";
__log_level = kLogWarn;
while ((opt = getopt(argc, argv, "qksvVIX:H:A:")) != -1) {
switch (opt) {
case 's':
case 'q':
break;
case 'v':
++__log_level;
break;
case 'I':
method = kHttpHead;
break;
case 'A':
agent = optarg;
break;
case 'H':
headers.p = realloc(headers.p, ++headers.n * sizeof(*headers.p));
headers.p[headers.n - 1] = optarg;
break;
case 'X':
CHECK((method = GetHttpMethod(optarg, strlen(optarg))));
break;
case 'V':
++mbedtls_debug_threshold;
break;
case 'k':
authmode = MBEDTLS_SSL_VERIFY_NONE;
break;
case 'h':
PrintUsage(stdout, EXIT_SUCCESS);
default:
PrintUsage(stderr, EX_USAGE);
}
}
/*
* Get argument.
*/
const char *urlarg;
if (optind == argc) PrintUsage(stderr, EX_USAGE);
urlarg = argv[optind];
/*
* Parse URL.
*/
struct Url url;
char *host, *port;
bool usessl = false;
_gc(ParseUrl(urlarg, -1, &url));
_gc(url.params.p);
if (url.scheme.n) {
if (url.scheme.n == 5 && !memcasecmp(url.scheme.p, "https", 5)) {
usessl = true;
} else if (!(url.scheme.n == 4 && !memcasecmp(url.scheme.p, "http", 4))) {
fprintf(stderr, "error: not an http/https url: %s\n", urlarg);
exit(1);
}
}
if (url.host.n) {
host = _gc(strndup(url.host.p, url.host.n));
if (url.port.n) {
port = _gc(strndup(url.port.p, url.port.n));
} else {
port = usessl ? "443" : "80";
}
} else {
host = "127.0.0.1";
port = usessl ? "443" : "80";
}
if (!IsAcceptableHost(host, -1)) {
fprintf(stderr, "error: invalid host: %s\n", urlarg);
exit(1);
}
url.fragment.p = 0, url.fragment.n = 0;
url.scheme.p = 0, url.scheme.n = 0;
url.user.p = 0, url.user.n = 0;
url.pass.p = 0, url.pass.n = 0;
url.host.p = 0, url.host.n = 0;
url.port.p = 0, url.port.n = 0;
if (!url.path.n || url.path.p[0] != '/') {
char *p = _gc(xmalloc(1 + url.path.n));
mempcpy(mempcpy(p, "/", 1), url.path.p, url.path.n);
url.path.p = p;
++url.path.n;
}
/*
* Create HTTP message.
*/
char *request = 0;
appendf(&request,
"%s %s HTTP/1.1\r\n"
"Host: %s:%s\r\n"
"Connection: close\r\n"
"User-Agent: %s\r\n",
kHttpMethod[method], _gc(EncodeUrl(&url, 0)), host, port, agent);
for (int i = 0; i < headers.n; ++i) {
appendf(&request, "%s\r\n", headers.p[i]);
}
appendf(&request, "\r\n");
/*
* Setup crypto.
*/
mbedtls_ssl_config conf;
mbedtls_ssl_context ssl;
mbedtls_x509_crt *cachain = 0;
mbedtls_ctr_drbg_context drbg;
if (usessl) {
mbedtls_ssl_init(&ssl);
mbedtls_ctr_drbg_init(&drbg);
mbedtls_ssl_config_init(&conf);
cachain = GetSslRoots();
CHECK_EQ(0, mbedtls_ctr_drbg_seed(&drbg, GetEntropy, 0, "justine", 7));
CHECK_EQ(0, mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT));
mbedtls_ssl_conf_authmode(&conf, authmode);
mbedtls_ssl_conf_ca_chain(&conf, cachain, 0);
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &drbg);
if (!IsTiny()) mbedtls_ssl_conf_dbg(&conf, TlsDebug, 0);
CHECK_EQ(0, mbedtls_ssl_setup(&ssl, &conf));
CHECK_EQ(0, mbedtls_ssl_set_hostname(&ssl, host));
}
/*
* Perform DNS lookup.
*/
struct addrinfo *addr;
struct addrinfo hints = {.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
.ai_flags = AI_NUMERICSERV};
if (argc != 2) {
fprintf(stderr, "USAGE: %s URL\n", argv[0]);
exit(1);
}
url = argv[1];
CHECK_NE(-1, uriparse(&u, url, strlen(url)), "BAD URL: %`'s", url);
CHECK_EQ(kUriSchemeHttp, urischeme(u.scheme, url));
urislice2cstr(host, sizeof(host), u.host, url, "127.0.0.1");
urislice2cstr(port, sizeof(port), u.port, url, "80");
path = uripath(&u);
pathstr = path.n ? url + path.i : "/";
msg = gc(xstrcat("GET ", pathstr,
" HTTP/1.1\r\n"
"Host: ",
host,
"\r\n"
"Connection: close\r\n"
"Content-Length: 0\r\n"
"Accept: text/plain; */*\r\n"
"Accept-Encoding: identity\r\n"
"User-Agent: github.com/jart/cosmopolitan\r\n"
"\r\n"));
msglen = strlen(msg);
CHECK_EQ(EAI_SUCCESS, getaddrinfo(host, port, &hints, &addrs));
for (addr = addrs; addr; addr = addr->ai_next) {
CHECK_NE(-1, (sock = socket(addr->ai_family, addr->ai_socktype,
addr->ai_protocol)));
CHECK_NE(-1, connect(sock, addr->ai_addr, addr->ai_addrlen));
CHECK_EQ(msglen, write(sock, msg, msglen));
shutdown(sock, SHUT_WR);
buf[0] = '\0';
CHECK_NE(-1, (rc = read(sock, buf, sizeof(buf))));
got = rc;
CHECK(startswith(buf, "HTTP/1.1 200"), "%`'.*s", got, buf);
CHECK_NOTNULL((crlfcrlf = memmem(buf, got, "\r\n\r\n", 4)));
need = strtol((char *)firstnonnull(
memmem(buf, crlfcrlf - buf, "\r\nContent-Length: ", 18),
firstnonnull(memmem(buf, crlfcrlf - buf,
"\r\ncontent-length: ", 18),
"\r\nContent-Length: -1")) +
18,
NULL, 10);
got = MIN(got - (crlfcrlf + 4 - buf), need);
CHECK_EQ(got, write(1, crlfcrlf + 4, got));
for (toto = got; toto < need; toto += got) {
CHECK_NE(-1, (rc = read(sock, buf, sizeof(buf))));
if (!(got = rc)) exit(18);
got = MIN(got, need - toto);
CHECK_EQ(got, write(1, buf, got));
CHECK_EQ(EAI_SUCCESS, getaddrinfo(host, port, &hints, &addr));
/*
* Connect to server.
*/
int ret, sock;
CHECK_NE(-1, (sock = GoodSocket(addr->ai_family, addr->ai_socktype,
addr->ai_protocol, false,
&(struct timeval){-60})));
CHECK_NE(-1, connect(sock, addr->ai_addr, addr->ai_addrlen));
freeaddrinfo(addr);
if (usessl) {
mbedtls_ssl_set_bio(&ssl, &sock, TlsSend, 0, TlsRecv);
if ((ret = mbedtls_ssl_handshake(&ssl))) {
TlsDie("ssl handshake", ret);
}
close(sock);
break;
}
/*
* Send HTTP Message.
*/
size_t n;
n = appendz(request).i;
if (usessl) {
ret = mbedtls_ssl_write(&ssl, request, n);
if (ret != n) TlsDie("ssl write", ret);
} else {
CHECK_EQ(n, write(sock, request, n));
}
/*
* Handle response.
*/
int t;
char *p;
ssize_t rc;
struct HttpMessage msg;
struct HttpUnchunker u;
size_t g, i, hdrlen, paylen;
InitHttpMessage(&msg, kHttpResponse);
for (p = 0, hdrlen = paylen = t = i = n = 0;;) {
if (i == n) {
n += 1000;
n += n >> 1;
p = realloc(p, n);
}
if (usessl) {
if ((rc = mbedtls_ssl_read(&ssl, p + i, n - i)) < 0) {
if (rc == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
rc = 0;
} else {
TlsDie("ssl read", rc);
}
}
} else {
CHECK_NE(-1, (rc = read(sock, p + i, n - i)));
}
g = rc;
i += g;
switch (t) {
case kHttpClientStateHeaders:
CHECK(g);
CHECK_NE(-1, (rc = ParseHttpMessage(&msg, p, i)));
if (rc) {
hdrlen = rc;
if (100 <= msg.status && msg.status <= 199) {
CHECK(!HasHeader(kHttpContentLength) ||
HeaderEqualCase(kHttpContentLength, "0"));
CHECK(!HasHeader(kHttpTransferEncoding) ||
HeaderEqualCase(kHttpTransferEncoding, "identity"));
DestroyHttpMessage(&msg);
InitHttpMessage(&msg, kHttpResponse);
memmove(p, p + hdrlen, i - hdrlen);
i -= hdrlen;
break;
}
if (method == kHttpHead) {
CHECK_EQ(hdrlen, write(1, p, hdrlen));
goto Finished;
} else if (msg.status == 204 || msg.status == 304) {
goto Finished;
}
if (HasHeader(kHttpTransferEncoding) &&
!HeaderEqualCase(kHttpTransferEncoding, "identity")) {
CHECK(HeaderEqualCase(kHttpTransferEncoding, "chunked"));
t = kHttpClientStateBodyChunked;
memset(&u, 0, sizeof(u));
goto Chunked;
} else if (HasHeader(kHttpContentLength)) {
CHECK_NE(-1, (rc = ParseContentLength(
HeaderData(kHttpContentLength),
HeaderLength(kHttpContentLength))));
t = kHttpClientStateBodyLengthed;
paylen = rc;
if (paylen > i - hdrlen) {
CHECK_EQ(i - hdrlen, write(1, p + hdrlen, i - hdrlen));
} else {
CHECK_EQ(paylen, write(1, p + hdrlen, paylen));
goto Finished;
}
} else {
t = kHttpClientStateBody;
CHECK_EQ(i - hdrlen, write(1, p + hdrlen, i - hdrlen));
}
}
break;
case kHttpClientStateBody:
if (!g) goto Finished;
CHECK_EQ(g, write(1, p + i - g, g));
break;
case kHttpClientStateBodyLengthed:
CHECK(g);
if (i - hdrlen > paylen) g = hdrlen + paylen - (i - g);
CHECK_EQ(g, write(1, p + i - g, g));
if (i - hdrlen >= paylen) goto Finished;
break;
case kHttpClientStateBodyChunked:
Chunked:
CHECK_NE(-1, (rc = Unchunk(&u, p + hdrlen, i - hdrlen, &paylen)));
if (rc) {
CHECK_EQ(paylen, write(1, p + hdrlen, paylen));
goto Finished;
}
break;
default:
abort();
}
}
/*
* Close connection.
*/
Finished:
CHECK_NE(-1, close(sock));
/*
* Free memory.
*/
free(p);
free(headers.p);
if (usessl) {
mbedtls_ssl_free(&ssl);
mbedtls_ctr_drbg_free(&drbg);
mbedtls_ssl_config_free(&conf);
mbedtls_x509_crt_free(cachain);
mbedtls_ctr_drbg_free(&drbg);
}
return 0;
}
+1 -1
View File
@@ -16,6 +16,6 @@
*/
int main(int argc, char *argv[]) {
puts(gc(xiso8601ts(NULL)));
puts(_gc(xiso8601ts(NULL)));
return 0;
}
-376
View File
@@ -1,376 +0,0 @@
#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 "dsp/core/core.h"
#include "dsp/core/twixt8.h"
#include "dsp/scale/scale.h"
#include "dsp/tty/itoa8.h"
#include "dsp/tty/quant.h"
#include "libc/alg/arraylist2.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/struct/winsize.h"
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/termios.h"
#include "libc/x/x.h"
#include "third_party/stb/stb_image.h"
/**
* Hat tips go out to Hornet, CRTC, DESiRE, Hans Petter Jansson, Guihua
* Cui, Ming Ronnier Luoand anyone else Mister Rogers would describe as
* the The Helpers Of This World who've helped us learn more about the
* cool yet exceedingly difficult things possible to do with graphics.
*/
#define DIN99 1
#define GAMMA 4.1
#define GAMMA_A .05
#define GAMMA_B 50.
#define GAMMA_C .055
#define COLORSPACE_SRC kSrgbD65ToXyzD50
#define COLORSPACE_TTY kSrgbD65ToXyzD50
#define SQR(X) ((X) * (X))
#define DEG(X) ((X)*M_PI / 180)
const double kXyzKappa = 24389 / 27.;
const double kXyzEpsilon = 216 / 24389.;
const double kSrgbD65ToXyzD50[3][3] = {
{.4360747, .3850649, .1430804},
{.2225045, .7168786, .0606169},
{.0139322, .0971045, .7141733},
};
const double kCieRgbEToXyz[3][3] = {
{.4887180, .3106803, .2006017},
{.1762044, .8129847, .0108109},
{.0000000, .0102048, .9897952},
};
const unsigned char kShadePct[] = {0300, 0200, 0100};
const unsigned short kShadeRune[] = {u'▓', u'▒', u'░'};
const unsigned char kAnsiTango[16][3] = {
{46, 52, 54}, {204, 0, 0}, {78, 154, 6}, {196, 160, 0},
{52, 101, 164}, {117, 80, 123}, {6, 152, 154}, {211, 215, 207},
{85, 87, 83}, {239, 41, 41}, {138, 226, 52}, {252, 233, 79},
{114, 159, 207}, {173, 127, 168}, {52, 226, 226}, {238, 238, 236},
};
const unsigned char kCga[16][3] = {
{0, 0, 0}, {170, 0, 0}, {0, 170, 0}, {170, 85, 0},
{0, 0, 170}, {170, 0, 170}, {0, 170, 170}, {170, 170, 170},
{85, 85, 85}, {255, 85, 85}, {85, 255, 85}, {255, 255, 85},
{85, 85, 255}, {255, 85, 255}, {85, 255, 255}, {255, 255, 255},
};
struct Blends {
size_t i, n;
struct Blend {
unsigned char color[4];
unsigned char bg, fg;
unsigned short rune;
} * p;
} blends;
static double Gamma(double x) {
if (x < GAMMA_A) return x / GAMMA_B;
return pow(1 / (1 + GAMMA_C) * (x + GAMMA_C), GAMMA);
}
static void *LoadRgb(double rgb[3], const unsigned char pix[3]) {
rgb[0] = Gamma(1. / 255 * pix[0]);
rgb[1] = Gamma(1. / 255 * pix[1]);
rgb[2] = Gamma(1. / 255 * pix[2]);
return rgb;
}
static double Lab(double x) {
return x > kXyzEpsilon ? cbrtf(x) : (kXyzKappa * x + 16) / 116;
}
static void XyzToLab(double lab[3], const double d50xyz[3]) {
double Y, L, a, b;
Y = Lab(d50xyz[1]);
L = 116 * Y - 16;
a = 500 * (Lab(d50xyz[0]) - Y);
b = 200 * (Y - Lab(d50xyz[2]));
lab[0] = L, lab[1] = a, lab[2] = b;
}
static void XyzToDin99d(unsigned char din99d[3], const double d50xyz[3]) {
double e, f, G, C, h, xyz[3], lab[3];
memcpy(xyz, d50xyz, sizeof(xyz));
xyz[0] = 1.12f * xyz[0] - .12f * xyz[2];
XyzToLab(lab, xyz);
e = (+lab[1] * cosf(DEG(50)) + lab[2] * sinf(DEG(50)));
f = (-lab[1] * sinf(DEG(50)) + lab[2] + cosf(DEG(50))) * 1.14;
G = sqrtf(SQR(e) + SQR(f));
C = logf(1 + .06 * G) * 22.5f;
h = atan2f(f, e) + DEG(50);
h = fmodf(h, DEG(360));
if (h < 0) h += DEG(360);
din99d[0] = MIN(255, MAX(0, 325.22f * logf(1 + .0036 * lab[0]) * 2.5f));
din99d[1] = MIN(255, MAX(0, C * cos(h) * 2.5f + 128));
din99d[2] = MIN(255, MAX(0, C * sin(h) * 2.5f + 128));
}
static void AddColor(int bg, int fg, int rune, int r, int g, int b, int x) {
int i;
if (blends.i) {
for (i = blends.i; --i;) {
if (blends.p[i].color[0] == r && blends.p[i].color[1] == g &&
blends.p[i].color[2] == b) {
return;
}
}
}
CHECK_NE(
-1,
APPEND(&blends.p, &blends.i, &blends.n,
(&(struct Blend){
.bg = bg, .fg = fg, .rune = rune, .color = {r, g, b, x}})));
}
static void AddBlend(int bgxterm, int fgxterm, int rune, int shade,
const unsigned char bgrgb[4],
const unsigned char fgrgb[4]) {
AddColor(bgxterm, fgxterm, rune, twixt8(bgrgb[0], fgrgb[0], shade),
twixt8(bgrgb[1], fgrgb[1], shade), twixt8(bgrgb[2], fgrgb[2], shade),
0);
}
static void MakeBlends(const unsigned char palette[16][3]) {
int r, i, j, k;
double rgb[3], xyz[3];
unsigned char tab[256][4];
unsigned char cube[6] = {0, 0137, 0207, 0257, 0327, 0377};
unsigned char seqs[2][2] = {{16, 255}};
for (i = 0; i < 16; ++i) {
tab[i][0] = palette[i][0];
tab[i][1] = palette[i][1];
tab[i][2] = palette[i][2];
tab[i][3] = i;
}
for (i = 16; i < 232; ++i) {
tab[i][0] = cube[((i - 020) / 044) % 6];
tab[i][1] = cube[((i - 020) / 6) % 6];
tab[i][2] = cube[(i - 020) % 6];
tab[i][3] = i;
}
for (i = 232; i < 256; ++i) {
tab[i][0] = 8 + (i - 232) * 10;
tab[i][1] = 8 + (i - 232) * 10;
tab[i][2] = 8 + (i - 232) * 10;
tab[i][3] = i;
}
#if DIN99
for (i = 0; i < 256; ++i) {
LoadRgb(rgb, tab[i]);
vmatmul3(xyz, rgb, COLORSPACE_TTY);
XyzToDin99d(tab[i], xyz);
}
#endif
for (r = 0; r < ARRAYLEN(seqs); ++r) {
for (i = seqs[r][0]; i <= seqs[r][1]; ++i) {
for (j = seqs[r][0]; j <= seqs[r][1]; ++j) {
if (i == j) {
AddColor(i, 0, 0, tab[i][0], tab[i][1], tab[i][2], 0);
} else {
for (k = 0; k < ARRAYLEN(kShadeRune); ++k) {
AddBlend(i, j, kShadeRune[k], kShadePct[k], tab[i], tab[j]);
AddBlend(j, i, kShadeRune[k], kShadePct[k], tab[j], tab[i]);
}
}
}
}
}
}
static int PickColor(unsigned char color[3]) {
int i, best, least, dist;
best = -1;
least = INT_MAX;
for (i = 0; i < blends.i; ++i) {
dist = SQR(blends.p[i].color[0] - color[0]) +
SQR(blends.p[i].color[1] - color[1]) +
SQR(blends.p[i].color[2] - color[2]);
if (dist < least) {
least = dist;
best = i;
}
}
return best;
}
static void SetBg(int x) {
if (0 <= x && x < 16) {
if (x < 8) {
x += 40;
} else {
x -= 8;
x *= 100;
}
printf("\e[%dm", x);
} else {
/* assert(false); */
printf("\e[48;5;%dm", x);
}
}
static void SetFg(int x) {
if (0 <= x && x < 16) {
if (x < 8) {
x += 30;
} else {
x -= 8;
x *= 90;
}
printf("\e[%dm", x);
} else {
/* assert(false); */
printf("\e[38;5;%dm", x);
}
}
static void PrintImage(long yn, long xn, unsigned char src[4][yn][xn]) {
int y, x, c;
double rgb[3], xyz[3];
unsigned char din99d[3];
for (y = 0; y < yn; ++y) {
printf("\n");
for (x = 0; x < xn; ++x) {
din99d[0] = src[0][y][x];
din99d[1] = src[1][y][x];
din99d[2] = src[2][y][x];
#if DIN99
LoadRgb(rgb, din99d);
vmatmul3(xyz, rgb, COLORSPACE_SRC);
XyzToDin99d(din99d, xyz);
#endif
c = PickColor(din99d);
if (blends.p[c].rune) {
SetBg(blends.p[c].bg);
SetFg(blends.p[c].fg);
printf("%hc", blends.p[c].rune);
} else {
SetBg(blends.p[c].bg);
printf(" ");
}
}
printf("\e[0m");
}
printf("\r");
}
static void *Deinterlace(long dcn, long dyn, long dxn,
unsigned char dst[dcn][dyn][dxn], long syw, long sxw,
long scw, const unsigned char src[syw][sxw][scw],
long syn, long sxn, long sy0, long sx0, long sc0) {
long y, x, c;
for (y = 0; y < dyn; ++y) {
for (x = 0; x < dxn; ++x) {
for (c = 0; c < dcn; ++c) {
dst[c][y][x] = src[sy0 + y][sx0 + x][sc0 + c];
}
}
}
return dst;
}
static void GetTermSize(int out_rows[1], int out_cols[1]) {
struct winsize ws;
ws.ws_row = 24;
ws.ws_col = 80;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) {
ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
}
out_rows[0] = ws.ws_row;
out_cols[0] = ws.ws_col;
}
static void ProcessImage(long syn, long sxn, unsigned char img[syn][sxn][4]) {
int dyn, dxn;
double ry, rx;
GetTermSize(&dyn, &dxn);
ry = syn, rx = sxn;
ry /= dyn, rx /= dxn;
PrintImage(
dyn, dxn,
EzGyarados(4, dyn, dxn, gc(xmemalign(32, dyn * dxn * 4)), 4, syn, sxn,
Deinterlace(4, syn, sxn, gc(xmemalign(32, syn * sxn * 4)), syn,
sxn, 4, img, syn, sxn, 0, 0, 0),
0, 4, dyn, dxn, syn, sxn, ry, rx, 0, 0));
}
static void WithImageFile(const char *path,
void fn(long yn, long xn,
unsigned char src[yn][xn][4])) {
struct stat st;
void *map, *data;
int fd, yn, xn, cn;
CHECK_NE(-1, (fd = open(path, O_RDONLY)), "%s", path);
CHECK_NE(-1, fstat(fd, &st));
CHECK_GT(st.st_size, 0);
CHECK_LE(st.st_size, INT_MAX);
CHECK_NE(MAP_FAILED,
(map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)));
CHECK_NOTNULL(
(data = stbi_load_from_memory(map, st.st_size, &xn, &yn, NULL, 4)), "%s",
path);
CHECK_NE(-1, munmap(map, st.st_size));
CHECK_NE(-1, close(fd));
fn(yn, xn, data);
free(data);
}
static void PrintData(void) {
int i;
for (i = 0; i < blends.i; ++i) {
printf("%3d %3d %3d %3d %3d %d\n", blends.p[i].color[0],
blends.p[i].color[1], blends.p[i].color[2], blends.p[i].bg,
blends.p[i].fg, blends.p[i].rune);
}
}
void *OpenRgbMap(const char *path) {
int fd;
void *map;
size_t size;
size = 256 * 256 * 256 * 3;
CHECK_NE(-1, (fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644)));
CHECK_NE(-1, ftruncate(fd, size));
CHECK_NE(MAP_FAILED,
(map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)));
CHECK_NE(-1, close(fd));
return map;
}
int main(int argc, char *argv[]) {
int i;
MakeBlends(kCga);
for (i = 1; i < argc; ++i) {
WithImageFile(argv[i], ProcessImage);
}
return 0;
}
-44
View File
@@ -1,44 +0,0 @@
#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/fmt/itoa.h"
#include "libc/macros.internal.h"
#include "libc/runtime/e820.internal.h"
#include "libc/runtime/pc.internal.h"
#include "libc/stdio/stdio.h"
const char *DescribeMemoryType(int type) {
switch (type) {
case kMemoryUsable:
return "kMemoryUsable";
case kMemoryUnusable:
return "kMemoryUnusable";
case kMemoryAcpiReclaimable:
return "kMemoryAcpiReclaimable";
case kMemoryAcpiNvs:
return "kMemoryAcpiNvs";
case kMemoryBad:
return "kMemoryBad";
default:
return "UNKNOWN";
}
}
int main(int argc, char *argv[]) {
int i;
const char *ts;
struct mman *mm;
mm = (struct mman *)(BANE + 0x0500);
for (i = 0; i < mm->e820n; ++i) {
printf("%p-%p %s\n", mm->e820[i].addr, mm->e820[i].size,
DescribeMemoryType(mm->e820[i].type));
}
for (;;) asm("pause");
return 0;
}
+9 -6
View File
@@ -45,6 +45,7 @@ EXAMPLES_DIRECTDEPS = \
LIBC_LOG \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT_IPHLPAPI \
LIBC_NT_KERNEL32 \
LIBC_NT_NTDLL \
LIBC_NT_USER32 \
@@ -65,14 +66,19 @@ EXAMPLES_DIRECTDEPS = \
LIBC_X \
LIBC_ZIPOS \
NET_HTTP \
NET_HTTPS \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_QUICKJS \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
THIRD_PARTY_LUA \
THIRD_PARTY_MBEDTLS \
THIRD_PARTY_MUSL \
THIRD_PARTY_STB \
THIRD_PARTY_XED \
THIRD_PARTY_ZLIB \
TOOL_BUILD_LIB \
TOOL_VIZ_LIB
EXAMPLES_DEPS := \
@@ -80,7 +86,6 @@ EXAMPLES_DEPS := \
o/$(MODE)/examples/examples.pkg: \
$(EXAMPLES_OBJS) \
$(THIRD_PARTY_DUKTAPE_A).pkg \
$(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/examples/unbourne.o: \
@@ -95,11 +100,10 @@ o/$(MODE)/examples/%.com.dbg: \
$(APE)
@$(APELINK)
o/$(MODE)/examples/hellojs.com.dbg: \
o/$(MODE)/examples/hellolua.com.dbg: \
$(EXAMPLES_DEPS) \
$(THIRD_PARTY_DUKTAPE) \
o/$(MODE)/examples/hellojs.o \
o/$(MODE)/examples/hello.js.zip.o \
o/$(MODE)/examples/hellolua.o \
o/$(MODE)/examples/hellolua.lua.zip.o \
o/$(MODE)/examples/examples.pkg \
$(CRT) \
$(APE)
@@ -116,7 +120,6 @@ o/$(MODE)/examples/ispell.com.dbg: \
o/$(MODE)/examples/nesemu1.com.dbg: \
$(EXAMPLES_DEPS) \
$(THIRD_PARTY_DUKTAPE) \
o/$(MODE)/examples/nesemu1.o \
o/$(MODE)/usr/share/rom/mario.nes.zip.o \
o/$(MODE)/usr/share/rom/zelda.nes.zip.o \
-17
View File
@@ -1,17 +0,0 @@
#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/runtime/runtime.h"
int main(int argc, char *argv[]) {
if (argc < 2) return 1;
execv(argv[1], argv + 1);
abort();
}
+62
View File
@@ -0,0 +1,62 @@
#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/macros.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/ezbench.h"
/**
* @fileoverview Fast Division Using Multiplication Tutorial
*
* Expected program output:
*
* 23 / 3 = 7
* 0x5555555555555556 1 1
* division l: 16𝑐 5𝑛𝑠
* fast div l: 5𝑐 2𝑛𝑠
* precomps l: 70𝑐 23𝑛𝑠
*/
struct Divisor {
uint64_t m;
uint8_t s;
uint8_t t;
};
struct Divisor GetDivisor(uint64_t d) {
int b;
uint128_t x;
if (!d) raise(SIGFPE);
b = __builtin_clzll(d) ^ 63;
x = -d & (((1ull << b) - 1) | (1ull << b));
return (struct Divisor){(x << 64) / d + 1, MIN(1, b + 1), MAX(0, b)};
}
uint64_t Divide(uint64_t x, struct Divisor d) {
uint128_t t;
uint64_t l, h;
t = d.m;
t *= x;
l = t;
h = t >> 64;
l = (x - h) >> d.s;
return (h + l) >> d.t;
}
int main(int argc, char *argv[]) {
printf("23 / 3 = %ld\n", Divide(23, GetDivisor(3)));
volatile struct Divisor v = GetDivisor(3);
volatile uint64_t x = 23, y = 3, z;
EZBENCH2("division", donothing, z = x / y);
EZBENCH2("fast div", donothing, z = Divide(x, v));
EZBENCH2("precomp ", donothing, v = GetDivisor(y));
return 0;
}
+47
View File
@@ -0,0 +1,47 @@
#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/stdio/stdio.h"
#include "libc/testlib/ezbench.h"
/**
* @fileoverview Fast Modulus Using Multiplication Tutorial
*
* Expected program output:
*
* 23 / 3 = 7
* 0x5555555555555556 1 1
* modulus l: 15𝑐 5𝑛𝑠
* fastmod l: 4𝑐 1𝑛𝑠
* precomp l: 18𝑐 6𝑛𝑠
*/
struct Modulus {
uint64_t c;
uint64_t d;
};
struct Modulus GetModulus(uint64_t d) {
return (struct Modulus){0xFFFFFFFFFFFFFFFFull / d + 1, d};
}
uint64_t Modulus(uint64_t x, struct Modulus m) {
return ((uint128_t)(m.c * x) * m.d) >> 64;
}
int main(int argc, char *argv[]) {
printf("%#lx %% %d = %d\n", 0x23, 3, Modulus(23, GetModulus(3)));
printf("%#lx %% %d = %d\n", 0x123, 17, Modulus(0x123, GetModulus(17)));
volatile struct Modulus v = GetModulus(3);
volatile uint64_t x = 23, y = 3, z;
EZBENCH2("modulus", donothing, z = x % y);
EZBENCH2("fastmod", donothing, z = Modulus(x, v));
EZBENCH2("precomp", donothing, v = GetModulus(y));
return 0;
}
-66
View File
@@ -1,66 +0,0 @@
#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/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/itimerval.h"
#include "libc/fmt/conv.h"
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/log/color.internal.h"
#include "libc/log/log.h"
#include "libc/math.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/itimer.h"
#include "libc/sysv/consts/sig.h"
#include "libc/time/time.h"
static const struct itimerval kTimer = {{0, 10000}, {0, 10000}}; /* 10ms */
static volatile bool32 showprogress_;
static const char *magic_;
void OnInterrupt(int sig) {
showprogress_ = true;
}
void ShowProgress(uintmax_t i, uintmax_t j, uintmax_t n) {
fprintf(stderr, "%s%,40jd%,40jd%,40jd\r\n", magic_, i, j, n);
showprogress_ = false;
}
static bool IsPrime(uintmax_t i) {
uintmax_t j, n;
for (j = 3, n = (unsigned long)floorl(sqrtl(i)); j <= n; j += 2) {
if (showprogress_) ShowProgress(i, j, n);
if (i % j == 0) return false;
}
return true;
}
static void TryNumber(uintmax_t x, uintmax_t i) {
if (IsPrime(i)) {
printf("%s%,jd%s%,jd\n", "the prime nearest ", x, " is ", i);
exit(0);
}
}
int main(int argc, char **argv) {
uintmax_t x, i, j;
CHECK_EQ(2, argc);
signal(SIGALRM, OnInterrupt);
setitimer(ITIMER_REAL, &kTimer, NULL);
magic_ = cancolor() ? "\e[F\e[K" : "";
if ((x = strtoumax(argv[1], NULL, 0)) % 2 == 0) ++x;
TryNumber(x, x);
for (i = x, j = x;;) {
if (i < UINTMAX_MAX) TryNumber(x, i), i += 2;
if (j > 1) TryNumber(x, j), j -= 2;
}
}
-18
View File
@@ -1,18 +0,0 @@
#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[]) {
int pid;
pid = fork();
fprintf(stderr, "fork returned %d\n", pid);
return 0;
}
+25
View File
@@ -0,0 +1,25 @@
#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/fmt/itoa.h"
#include "libc/runtime/sysconf.h"
#include "libc/stdio/stdio.h"
int main(int argc, char *argv[]) {
int c, n;
char a[22];
if ((c = GetCpuCount())) {
n = int64toarray_radix10(c, a);
a[n++] = '\n';
return write(1, a, n) == n ? 0 : 1;
} else {
return 1;
}
}
+291
View File
@@ -0,0 +1,291 @@
#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/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/rand/rand.h"
#include "libc/rand/xorshift.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ex.h"
#include "libc/sysv/consts/exit.h"
#include "libc/sysv/consts/grnd.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/hyperion.h"
#include "third_party/getopt/getopt.h"
#define B 4096
bool isdone;
bool isbinary;
unsigned long count = -1;
uint64_t bcast(uint64_t f(void)) {
unsigned i;
uint64_t x;
for (x = i = 0; i < 8; ++i) {
x <<= 8;
x |= f() & 255;
}
return x;
}
uint64_t randv6(void) {
static int16_t gorp;
gorp = (gorp + 625) & 077777;
return gorp;
}
uint64_t randv7(void) {
static uint32_t randx = 1;
return ((randx = randx * 1103515245 + 12345) >> 16) & 077777;
}
uint64_t zero(void) {
return 0;
}
uint64_t inc(void) {
static uint64_t x;
return x++;
}
uint64_t unixv6(void) {
return bcast(randv6);
}
uint64_t unixv7(void) {
return bcast(randv7);
}
uint64_t ape(void) {
static int i;
if ((i += 8) > _end - _base) i = 8;
return READ64LE(_base + i);
}
uint64_t moby(void) {
static int i;
if ((i += 8) > kMobySize) i = 8;
return READ64LE(kMoby + i);
}
uint64_t knuth(void) {
uint64_t a, b;
static uint64_t x = 1;
x *= 6364136223846793005;
x += 1442695040888963407;
a = x >> 32;
x *= 6364136223846793005;
x += 1442695040888963407;
b = x >> 32;
return a | b << 32;
}
uint64_t vigna(void) {
static uint64_t x;
uint64_t z = (x += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
}
uint64_t rngset64(void) {
static unsigned i;
static uint64_t s;
if (!i) {
s = rand64();
i = (s + 1) & (511);
}
return MarsagliaXorshift64(&s);
}
uint64_t xorshift64(void) {
static uint64_t s = kMarsagliaXorshift64Seed;
return MarsagliaXorshift64(&s);
}
uint64_t xorshift32(void) {
static uint32_t s = kMarsagliaXorshift32Seed;
uint64_t a = MarsagliaXorshift32(&s);
uint64_t b = MarsagliaXorshift32(&s);
return (uint64_t)a << 32 | b;
}
uint64_t libc(void) {
uint64_t x;
CHECK_EQ(8, getrandom(&x, 8, 0));
return x;
}
uint64_t kernel(void) {
uint64_t x;
CHECK_EQ(8, getrandom(&x, 8, GRND_NORDRND));
return x;
}
uint64_t hardware(void) {
uint64_t x;
CHECK_EQ(8, getrandom(&x, 8, GRND_NOSYSTEM));
return x;
}
uint64_t rdrnd(void) {
char cf;
int i = 0;
uint64_t x;
CHECK(X86_HAVE(RDRND));
for (;;) {
asm volatile(CFLAG_ASM("rdrand\t%1")
: CFLAG_CONSTRAINT(cf), "=r"(x)
: /* no inputs */
: "cc");
if (cf) return x;
if (++i < 10) continue;
asm volatile("pause");
i = 0;
}
}
uint64_t rdseed(void) {
char cf;
int i = 0;
uint64_t x;
CHECK(X86_HAVE(RDSEED));
for (;;) {
asm volatile(CFLAG_ASM("rdseed\t%1")
: CFLAG_CONSTRAINT(cf), "=r"(x)
: /* no inputs */
: "cc");
if (cf) return x;
if (++i < 10) continue;
asm volatile("pause");
i = 0;
}
}
const struct Function {
const char *s;
uint64_t (*f)(void);
} kFunctions[] = {
{"ape", ape}, //
{"hardware", hardware}, //
{"inc", inc}, //
{"kernel", kernel}, //
{"knuth", knuth}, //
{"libc", libc}, //
{"moby", moby}, //
{"rand64", rand64}, //
{"rdrand", rdrnd}, //
{"rdrnd", rdrnd}, //
{"rdseed", rdseed}, //
{"rngset64", rngset64}, //
{"unixv6", unixv6}, //
{"unixv7", unixv7}, //
{"vigna", vigna}, //
{"xorshift32", xorshift32}, //
{"xorshift64", xorshift64}, //
{"zero", zero}, //
};
void OnInt(int sig) {
isdone = true;
}
wontreturn void PrintUsage(FILE *f, int rc) {
fprintf(f, "Usage: %s [-b] [-n NUM] [FUNC]\n", program_invocation_name);
exit(rc);
}
int main(int argc, char *argv[]) {
char *p;
int i, opt;
ssize_t rc;
uint64_t x;
static char buf[B];
uint64_t (*f)(void);
while ((opt = getopt(argc, argv, "hbc:n:")) != -1) {
switch (opt) {
case 'b':
isbinary = true;
break;
case 'c':
case 'n':
count = strtoul(optarg, 0, 0);
break;
case 'h':
PrintUsage(stdout, EXIT_SUCCESS);
default:
PrintUsage(stderr, EX_USAGE);
}
}
if (optind == argc) {
f = libc;
} else {
for (f = 0, i = 0; i < ARRAYLEN(kFunctions); ++i) {
if (!strcasecmp(argv[optind], kFunctions[i].s)) {
f = kFunctions[i].f;
break;
}
}
if (!f) {
fprintf(stderr, "unknown function: %`'s\n", argv[optind]);
fprintf(stderr, "try: ");
for (i = 0; i < ARRAYLEN(kFunctions); ++i) {
if (i) fprintf(stderr, ", ");
fprintf(stderr, "%s", kFunctions[i].s);
}
fprintf(stderr, "\n");
return 1;
}
}
signal(SIGINT, OnInt);
signal(SIGPIPE, SIG_IGN);
if (!isbinary) {
for (; count && !isdone && !feof(stdout); --count) {
printf("0x%016lx\n", f());
}
fflush(stdout);
return ferror(stdout) ? 1 : 0;
}
while (count && !isdone) {
if (count >= B) {
for (i = 0; i < B / 8; ++i) {
x = f();
p = buf + i * 8;
WRITE64LE(p, x);
}
for (i = 0; i < B; i += rc) {
rc = write(1, buf + i, B - i);
if (rc == -1 && errno == EPIPE) exit(1);
if (rc == -1) perror("write"), exit(1);
}
} else {
x = f();
rc = write(1, &x, MIN(8, count));
}
if (!rc) break;
if (rc == -1 && errno == EPIPE) exit(1);
if (rc == -1) perror("write"), exit(1);
count -= rc;
}
return 0;
}
+65 -1
View File
@@ -7,9 +7,73 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/dce.h"
#include "libc/nexgen32e/nt2sysv.h"
#include "libc/nt/dll.h"
#include "libc/nt/enum/cw.h"
#include "libc/nt/enum/mb.h"
#include "libc/nt/enum/sw.h"
#include "libc/nt/enum/wm.h"
#include "libc/nt/enum/ws.h"
#include "libc/nt/events.h"
#include "libc/nt/messagebox.h"
#include "libc/nt/struct/msg.h"
#include "libc/nt/struct/wndclass.h"
#include "libc/nt/windows.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
/**
* @fileoverview GUI Example
*
* Cosmopolitan has had a razor sharp focus on making sockets and stdio
* work well across platforms. When you call a function like read(), it
* will just work on platforms like Windows too. In order to do that we
* need to support the WIN32 API, which you can use, but please note it
* isn't polyfilled on other platforms in the same way as POSIX APIs.
*/
static const char16_t kClassName[] = u"cosmopolitan";
static int64_t WindowProc(int64_t hwnd, uint32_t uMsg, uint64_t wParam,
int64_t lParam) {
switch (uMsg) {
case kNtWmDestroy:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
static void Gui(void) {
int64_t h;
struct NtMsg msg;
struct NtWndClass wc;
memset(&wc, 0, sizeof(wc));
wc.lpfnWndProc = NT2SYSV(WindowProc);
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = kClassName;
RegisterClass(&wc);
h = CreateWindowEx(0, kClassName, u"Hello Cosmopolitan",
kNtWsOverlappedwindow, kNtCwUsedefault, kNtCwUsedefault,
kNtCwUsedefault, kNtCwUsedefault, 0, 0, wc.hInstance, 0);
ShowWindow(h, kNtSwNormal);
/*
* NOTE: Cosmopolitan linker script is hard-coded to change the
* subsystem from CUI to GUI when GetMessage() is linked.
*/
while (GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
int main(int argc, char *argv[]) {
return MessageBox(0, u"hello world", u"cosmopolitan", kNtMbOk) ? 0 : 1;
if (!IsWindows()) {
fputs("Sorry! This GUI demo only runs on Windows\n", stderr);
fputs("https://github.com/jart/cosmopolitan/issues/57\n", stderr);
return 1;
}
Gui();
}
-7
View File
@@ -10,13 +10,6 @@
#include "libc/stdio/stdio.h"
int main() {
/*
* Cosmopolitan's "Hello World" demonstrates a best practice.
*
* Since we conditionally link heavyweight features based on which
* characters are present in the format string, it's a good idea to
* have that string consist solely of directives.
*/
printf("%s\n", "hello world");
return 0;
}
-2
View File
@@ -1,2 +0,0 @@
console.log('Hello world!\n');
console.log('2+3=' + NativeAdd(2, 3) + '\n');
+3 -5
View File
@@ -8,12 +8,10 @@
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/errno.h"
#include "libc/runtime/gc.h"
#include "libc/calls/calls.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/x/x.h"
#include "libc/fmt/fmt.h"
#include "libc/stdio/stdio.h"
int main() {
dprintf(STDOUT_FILENO, "%s\n", gc(xasprintf("%'s", "(╯°□°)╯︵' ┻━┻")));
printf("%`'s\n", "hello\1\2world→→");
return errno;
}
-16
View File
@@ -1,16 +0,0 @@
#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/errno.h"
#include "libc/stdio/stdio.h"
int main() {
printf("%s \n", "hello world");
return errno;
}
-70
View File
@@ -1,70 +0,0 @@
#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/calls/struct/stat.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.h"
#include "libc/sysv/consts/o.h"
#include "third_party/duktape/duktape.h"
STATIC_YOINK("zip_uri_support");
static duk_ret_t NativePrint(duk_context *ctx) {
duk_push_string(ctx, " ");
duk_insert(ctx, 0);
duk_join(ctx, duk_get_top(ctx) - 1);
fputs(duk_safe_to_string(ctx, -1), stdout);
return 0;
}
static duk_ret_t NativeAdd(duk_context *ctx) {
int i, n;
double r;
n = duk_get_top(ctx);
for (r = i = 0; i < n; i++) r += duk_to_number(ctx, i);
duk_push_number(ctx, r);
return 1;
}
int main(int argc, char *argv[]) {
int fd;
struct stat st;
const char *code;
duk_context *ctx;
showcrashreports();
ctx = duk_create_heap_default();
/* define NativeAdd() */
duk_push_c_function(ctx, NativeAdd, DUK_VARARGS);
duk_put_global_string(ctx, "NativeAdd");
/* define console.log() */
duk_push_global_object(ctx);
duk_push_c_function(ctx, NativePrint, DUK_VARARGS);
duk_push_string(ctx, "name");
duk_push_string(ctx, "log");
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE);
duk_set_magic(ctx, -1, 0);
duk_put_prop_string(ctx, -2, "log");
duk_put_global_string(ctx, "console");
CHECK_NE(-1, (fd = open("zip:examples/hello.js", O_RDONLY)));
CHECK_NE(-1, fstat(fd, &st));
CHECK_NOTNULL((code = gc(calloc(1, st.st_size + 1))));
CHECK_EQ(st.st_size, read(fd, code, st.st_size));
CHECK_NE(-1, close(fd));
duk_eval_string(ctx, code);
duk_pop(ctx);
duk_destroy_heap(ctx);
return 0;
}
+30
View File
@@ -0,0 +1,30 @@
#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 "third_party/lua/lauxlib.h"
#include "third_party/lua/lualib.h"
int NativeAdd(lua_State *L) {
lua_Number x, y;
x = luaL_checknumber(L, 1);
y = luaL_checknumber(L, 2);
lua_pushnumber(L, x + y);
return 1; /* number of results */
}
int main(int argc, char *argv[]) {
lua_State *L;
L = luaL_newstate();
luaL_openlibs(L);
lua_pushcfunction(L, NativeAdd);
lua_setglobal(L, "NativeAdd");
luaL_dofile(L, "zip:examples/hellolua.lua");
lua_close(L);
return 0;
}
+1
View File
@@ -0,0 +1 @@
print(string.format("2 + 3 = %g", NativeAdd(2, 3)))
+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/calls/calls.h"
#include "libc/calls/struct/itimerval.h"
#include "libc/errno.h"
#include "libc/log/check.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/itimer.h"
#include "libc/sysv/consts/sig.h"
#include "libc/time/time.h"
#include "libc/x/x.h"
const struct itimerval kHertz = {
{1, 0},
{0, 1},
};
bool hertz;
void OnAlrm(void) {
hertz = true;
}
int main(int argc, char *argv[]) {
CHECK_NE(-1, xsigaction(SIGALRM, OnAlrm, 0, 0, 0));
CHECK_NE(-1, setitimer(ITIMER_REAL, &kHertz, NULL));
for (;;) {
CHECK_EQ(-1, pause());
CHECK_EQ(EINTR, errno);
if (hertz) {
hertz = false;
printf("ding\n");
}
}
return 0;
}
+29
View File
@@ -0,0 +1,29 @@
#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/stdio/stdio.h"
#include "libc/x/x.h"
#include "third_party/stb/stb_image.h"
/**
* @fileoverview Utility for printing HTML <img> tags.
*/
int main(int argc, char *argv[]) {
void *p;
size_t n;
int yn, xn, cn;
if (argc != 2) return 1;
if (!(p = xslurp(argv[1], &n))) return 2;
if (!(p = stbi_load_from_memory(p, n, &xn, &yn, &cn, 0))) return 3;
printf("<img src=\"%s\" width=\"%d\" height=\"%d\"\n"
" alt=\"[%s]\">\n",
argv[1], (xn + 1) >> 1, (yn + 1) >> 1, argv[1]);
return 0;
}
-80
View File
@@ -1,80 +0,0 @@
#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/bits/bits.h"
#include "libc/dce.h"
#include "libc/log/check.h"
#include "libc/nexgen32e/rdtsc.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/sig.h"
#include "libc/time/time.h"
#include "libc/x/x.h"
#include "third_party/gdtoa/gdtoa.h"
/**
* @fileoverview Measure CPU clock mystery constants.
* @note CPUID EAX=15h/16h is a joke
*/
const long double kInterval = 0.001L;
long double start_;
char dtoabuf_[3][32];
volatile bool isdone_;
void OnCtrlC(int sig) {
isdone_ = true;
}
long double now(void) {
return dtime(CLOCK_MONOTONIC);
}
long double GetSample(void) {
uint64_t tick1, tick2;
long double time1, time2;
time1 = now();
tick1 = rdtsc();
nanosleep(&(struct timespec){0, 100000}, NULL);
time2 = now();
tick2 = rdtsc();
return ((time2 - time1) * 1e9L) / (long double)(tick2 - tick1);
}
void MeasureNanosecondsPerAlwaysRunningTimerCycle(void) {
int i;
long double avg, samp, elapsed;
start_ = now();
for (i = 1, avg = 1.0L; !isdone_; ++i) {
samp = GetSample();
avg += (samp - avg) / i;
dsleep(kInterval);
elapsed = now() - start_;
g_xfmt_p(dtoabuf_[0], &avg, 15, 32, 0);
g_xfmt_p(dtoabuf_[1], &samp, 15, 32, 0);
g_xfmt_p(dtoabuf_[2], &elapsed, 15, 32, 0);
printf("1c = %sns (last=%sns spent=%ss)\n", dtoabuf_[0], dtoabuf_[1],
dtoabuf_[2]);
}
}
int main(int argc, char *argv[]) {
if (!X86_HAVE(INVTSC)) {
fprintf(stderr, "warning: html can reprogram your microcode\n");
}
if (X86_HAVE(HYPERVISOR)) {
fprintf(stderr, "warning: virtual machine rdtsc isn't great\n");
}
CHECK_NE(-1, xsigaction(SIGINT, OnCtrlC, 0, 0, NULL));
MeasureNanosecondsPerAlwaysRunningTimerCycle();
return 0;
}
+4
View File
@@ -267,8 +267,12 @@ int editorReadKey(int64_t fd) {
if (read(fd, seq + 2, 1) == 0) return CTRL('[');
if (seq[2] == '~') {
switch (seq[1]) {
case '1':
return HOME_KEY;
case '3':
return DEL_KEY;
case '4':
return END_KEY;
case '5':
return PAGE_UP;
case '6':
+1 -1
View File
@@ -49,7 +49,7 @@ void List(const char *path) {
if (strcmp(path, ".") == 0) {
vpath = "";
} else if (!endswith(path, "/")) {
vpath = gc(xasprintf("%s/", path));
vpath = _gc(xasprintf("%s/", path));
} else {
vpath = path;
}
+1 -1
View File
@@ -51,7 +51,7 @@ void WalkPaths(const char *dirpath) {
if (strcmp(e->d_name, "o") == 0) continue;
if (strcmp(e->d_name, ".git") == 0) continue;
if (e->d_type == DT_DIR) {
WalkPaths(gc(path));
WalkPaths(_gc(path));
} else {
CHECK_NE(-1, lstat(path, &st), "%s", path);
f.mt = st.st_mtim;
-19
View File
@@ -1,19 +0,0 @@
#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/mem/mem.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
int main(int argc, char *argv[]) {
char *s = malloc(1024 * 1024 * 2 + argc);
strcpy(s, "hello");
puts(s);
return 0;
}
-50
View File
@@ -1,50 +0,0 @@
#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/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/macros.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
/*
OpenBSD
00025ff61000 000000000000 65536
00026cf1d000 00000cfbc000 65536
000254d83000 ffffe7e66000 65536
0002c7bde000 000072e5b000 65536
000253ff9000 ffff8c41b000 65536
0002e96f3000 0000956fa000 65536
000236346000 ffff4cc53000 65536
0002ce744000 0000983fe000 65536
0002fe0b8000 00002f974000 65536
000225cd7000 ffff27c1f000 65536
*/
struct Mapping {
uint8_t *map;
size_t mapsize;
};
int main(int argc, char *argv[]) {
size_t i;
struct Mapping m[10];
for (i = 0; i < ARRAYLEN(m); ++i) {
m[i].mapsize = FRAMESIZE;
m[i].map = mmap(NULL, m[i].mapsize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
for (i = 0; i < ARRAYLEN(m); ++i) {
printf("%p %p %zu\n", m[i].map, i ? m[i].map - m[i - 1].map : 0,
m[i].mapsize);
}
return 0;
}
+157
View File
@@ -0,0 +1,157 @@
#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/dns/dns.h"
#include "libc/fmt/conv.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/poll.h"
#include "libc/sysv/consts/shut.h"
#include "libc/sysv/consts/so.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/sol.h"
#include "third_party/getopt/getopt.h"
/**
* @fileoverview netcat clone
*
* Implemented because BusyBox's netcat doesn't detect remote close and
* lingers in the CLOSE_WAIT wait possibly due to file descriptor leaks
*
* Here's an example usage:
*
* make -j8 o//examples/nc.com
* printf 'GET /\r\n\r\n' | o//examples/nc.com justine.lol 80
*
* Once upon time we called this command "telnet"
*/
int main(int argc, char *argv[]) {
ssize_t rc;
size_t i, got;
char buf[1500];
bool halfclose = true;
const char *host, *port;
int opt, err, toto, sock;
struct addrinfo *ai = NULL;
struct linger linger = {true, 1};
struct pollfd fds[2] = {{-1, POLLIN}, {-1, POLLIN}};
struct addrinfo hint = {AI_NUMERICSERV, AF_INET, SOCK_STREAM, IPPROTO_TCP};
while ((opt = getopt(argc, argv, "hH")) != -1) {
switch (opt) {
case 'H':
halfclose = false;
break;
case 'h':
fputs("Usage: ", stdout);
fputs(argv[0], stdout);
fputs(" [-hH] IP PORT\n", stdout);
exit(0);
default:
fprintf(stderr, "bad option %d\n", opt);
exit(1);
}
}
if (argc - optind != 2) {
fputs("missing args\n", stderr);
exit(1);
}
host = argv[optind + 0];
port = argv[optind + 1];
switch ((rc = getaddrinfo(host, port, &hint, &ai))) {
case EAI_SUCCESS:
break;
case EAI_SYSTEM:
perror("getaddrinfo");
exit(1);
default:
fputs("EAI_", stderr);
fputs(gai_strerror(rc), stderr);
fputs("\n", stderr);
exit(1);
}
if ((sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) {
perror("socket");
exit(1);
}
if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == -1) {
perror("setsockopt(SO_LINGER)");
exit(1);
}
if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
perror("connect");
exit(1);
}
fds[0].fd = 0;
fds[1].fd = sock;
for (;;) {
fds[0].revents = 0;
fds[1].revents = 0;
if (poll(fds, ARRAYLEN(fds), -1) == -1) {
perror("poll");
exit(1);
}
if (fds[0].revents & (POLLIN | POLLERR | POLLHUP)) {
if ((rc = read(0, buf, 1400)) == -1) {
perror("read(stdin)");
exit(1);
}
if (!(got = rc)) {
if (halfclose) {
shutdown(sock, SHUT_WR);
}
fds[0].fd = -1;
}
for (i = 0; i < got; i += rc) {
if ((rc = write(sock, buf + i, got - i)) == -1) {
perror("write(sock)");
exit(1);
}
}
}
if (fds[1].revents & (POLLIN | POLLERR | POLLHUP)) {
if ((rc = read(sock, buf, 1500)) == -1) {
perror("read(sock)");
exit(1);
}
if (!(got = rc)) {
break;
}
for (i = 0; i < got; i += rc) {
if ((rc = write(1, buf + i, got - i)) == -1) {
perror("write(stdout)");
exit(1);
}
}
}
}
if (close(sock) == -1) {
perror("close");
exit(1);
}
freeaddrinfo(ai);
return 0;
}
-1
View File
@@ -27,7 +27,6 @@
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/ohmyplus/vector.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
+175
View File
@@ -0,0 +1,175 @@
#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/calls/ioctl.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/termios.h"
#include "libc/calls/struct/winsize.h"
#include "libc/log/check.h"
#include "libc/log/gdb.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/runtime/gc.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/termios.h"
#include "libc/x/x.h"
#include "tool/build/lib/panel.h"
/**
* @fileoverview Cosmopolitan Paneling Demo.
*
* This is useful for creating terminal user interfaces. We take the
* simplest approach possible. The main thing we abstract is like,
* truncating the lines that overflow within a panel. In order to do
* that, we abstract the ANSI parsing and the implementation is able to
* tell how many cells wide each UNICODE character is.
*
* There are smarter ways for Cosmopolitan to do this. For example, it'd
* be great to have automatic flex boxes. It'd also be nice to be able
* to use dynamic programming for low bandwidth display updates, like
* Emacs does, but that's less of an issue these days and can actually
* make things slower, since for heavy workloads like printing videos,
* having ANSI codes bouncing around the display actually goes slower.
*
* Beyond basic paneling, a message box widget is also provided, which
* makes it easier to do modal dialogs.
*/
struct Panels {
union {
struct {
struct Panel left;
struct Panel right;
};
struct Panel p[2];
};
} pan;
long tyn;
long txn;
char key[8];
bool shutdown;
bool invalidated;
struct termios oldterm;
void OnShutdown(int sig) {
shutdown = true;
}
void OnInvalidate(int sig) {
invalidated = true;
}
void GetTtySize(void) {
struct winsize wsize;
wsize.ws_row = tyn;
wsize.ws_col = txn;
getttysize(1, &wsize);
tyn = wsize.ws_row;
txn = wsize.ws_col;
}
int Write(const char *s) {
return write(1, s, strlen(s));
}
void Setup(void) {
CHECK_NE(-1, ioctl(1, TCGETS, &oldterm));
}
void Enter(void) {
struct termios term;
memcpy(&term, &oldterm, sizeof(term));
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 1;
term.c_iflag &= ~(INPCK | ISTRIP | PARMRK | INLCR | IGNCR | ICRNL | IXON);
term.c_lflag &= ~(IEXTEN | ICANON | ECHO | ECHONL);
term.c_cflag &= ~(CSIZE | PARENB);
term.c_cflag |= CS8;
term.c_iflag |= IUTF8;
CHECK_NE(-1, ioctl(1, TCSETS, &term));
Write("\e[?25l");
}
void Leave(void) {
Write(gc(xasprintf("\e[?25h\e[%d;%dH\e[S\r\n", tyn, txn)));
ioctl(1, TCSETS, &oldterm);
}
void Clear(void) {
long i, j;
for (i = 0; i < ARRAYLEN(pan.p); ++i) {
for (j = 0; j < pan.p[i].n; ++j) {
free(pan.p[i].lines[j].p);
}
free(pan.p[i].lines);
pan.p[i].lines = 0;
pan.p[i].n = 0;
}
}
void Layout(void) {
long i, j;
i = txn >> 1;
pan.left.top = 0;
pan.left.left = 0;
pan.left.bottom = tyn;
pan.left.right = i;
pan.right.top = 0;
pan.right.left = i + 1;
pan.right.bottom = tyn;
pan.right.right = txn;
pan.left.n = pan.left.bottom - pan.left.top;
pan.left.lines = xcalloc(pan.left.n, sizeof(*pan.left.lines));
pan.right.n = pan.right.bottom - pan.right.top;
pan.right.lines = xcalloc(pan.right.n, sizeof(*pan.right.lines));
}
void Append(struct Panel *p, int i, const char *s) {
if (i >= p->n) return;
AppendStr(p->lines + i, s);
}
void Draw(void) {
Append(&pan.left, 0, gc(xasprintf("you typed %`'s", key)));
Append(&pan.left, ((tyn + 1) >> 1) + 0, "hello left 1 𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷");
Append(&pan.left, ((tyn + 1) >> 1) + 1, "hello left 2 (╯°□°)╯");
Append(&pan.right, ((tyn + 1) >> 1) + 0, "hello right 1");
Append(&pan.right, ((tyn + 1) >> 1) + 1, "hello right 2");
PrintPanels(1, ARRAYLEN(pan.p), pan.p, tyn, txn);
}
int main(int argc, char *argv[]) {
struct sigaction sa[2] = {{.sa_handler = OnShutdown},
{.sa_handler = OnInvalidate}};
showcrashreports();
Setup();
Enter();
GetTtySize();
sigaction(SIGINT, &sa[0], 0);
sigaction(SIGCONT, &sa[1], 0);
sigaction(SIGWINCH, &sa[1], 0);
atexit(Leave);
do {
Clear();
Layout();
Draw();
if (invalidated) {
Enter();
GetTtySize();
invalidated = false;
} else {
readansi(0, key, sizeof(key));
}
} while (!shutdown);
}
-39
View File
@@ -1,39 +0,0 @@
/*-*- 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 2020 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/fmt/conv.h"
#include "libc/runtime/interruptiblecall.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/sig.h"
struct InterruptibleCall icall;
static intptr_t peek(intptr_t *addr) {
return *addr;
}
int main(int argc, char *argv[]) {
int i;
for (i = 1; i < argc; ++i) {
intptr_t addr = strtoul(argv[i], NULL, 0);
icall.sig = SIGSEGV;
printf("%#p → %#lx\n", addr,
interruptiblecall(&icall, (void *)peek, addr, 0, 0, 0));
}
return 0;
}
-27
View File
@@ -1,27 +0,0 @@
/*-*- 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 2020 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/stdio/stdio.h"
int main(int argc, char *argv[]) {
int pipefds[2] = {-1, -1};
int rc = pipe(pipefds);
printf("%d → %ld %ld\n", rc, pipefds[0], pipefds[1]);
return 0;
}
-26
View File
@@ -1,26 +0,0 @@
#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/bits/bits.h"
#include "libc/macros.internal.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/poll.h"
int main(int argc, char *argv[]) {
int rc;
int pollms = 1;
struct pollfd fds[] = {{-1, 0}, {STDIN_FILENO, POLLIN}};
if ((rc = poll(fds, ARRAYLEN(fds), pollms)) != -1) {
printf("toto=%d\n", rc);
return 0;
}
return 0;
}
+41 -24
View File
@@ -20,39 +20,56 @@ const struct AuxiliaryValue {
const char *name;
const char *description;
} kAuxiliaryValues[] = {
{"%p", &AT_EXECFD, "AT_EXECFD", "file descriptor of program"},
{"%p", &AT_PHDR, "AT_PHDR", "address of elf program headers"},
{"%p", &AT_PHENT, "AT_PHENT", "size of program header entry"},
{"%p", &AT_PHNUM, "AT_PHNUM", "number of program headers"},
{"%p", &AT_PAGESZ, "AT_PAGESZ", "system page size"},
{"%p", &AT_BASE, "AT_BASE", "base address of the program interpreter"},
{"%p", &AT_ENTRY, "AT_ENTRY", "entry address of executable"},
{"%p", &AT_NOTELF, "AT_NOTELF", "set if not an elf"},
{"%012lx", &AT_EXECFD, "AT_EXECFD", "file descriptor of program"},
{"%012lx", &AT_PHDR, "AT_PHDR", "address of elf program headers"},
{"%012lx", &AT_PHENT, "AT_PHENT", "size of program header entry"},
{"%012lx", &AT_PHNUM, "AT_PHNUM", "number of program headers"},
{"%012lx", &AT_PAGESZ, "AT_PAGESZ", "system page size"},
{"%012lx", &AT_BASE, "AT_BASE", "base address of the program interpreter"},
{"%012lx", &AT_ENTRY, "AT_ENTRY", "entry address of executable"},
{"%012lx", &AT_NOTELF, "AT_NOTELF", "set if not an elf"},
{"%-12d", &AT_UID, "AT_UID", "real user id of thread"},
{"%-12d", &AT_EUID, "AT_EUID", "effective user id of thread"},
{"%-12d", &AT_GID, "AT_GID", "real group id of thread"},
{"%-12d", &AT_EGID, "AT_EGID", "effective group id of thread"},
{"%-12d", &AT_CLKTCK, "AT_CLKTCK", "frequency of times() counts"},
{"%p", &AT_OSRELDATE, "AT_OSRELDATE",
{"%012lx", &AT_OSRELDATE, "AT_OSRELDATE",
"freebsd release number, e.g. 1200086"},
{"%p", &AT_PLATFORM, "AT_PLATFORM", "string identifying hardware platform"},
{"%p", &AT_DCACHEBSIZE, "AT_DCACHEBSIZE", "data cache block size"},
{"%p", &AT_ICACHEBSIZE, "AT_ICACHEBSIZE", "instruction cache block size"},
{"%p", &AT_UCACHEBSIZE, "AT_UCACHEBSIZE", "unified cache block size"},
{"%p", &AT_SECURE, "AT_SECURE", "for set{u,g}id binz & security blankets"},
{"%012lx", &AT_PLATFORM, "AT_PLATFORM",
"string identifying hardware platform"},
{"%012lx", &AT_DCACHEBSIZE, "AT_DCACHEBSIZE", "data cache block size"},
{"%012lx", &AT_ICACHEBSIZE, "AT_ICACHEBSIZE",
"instruction cache block size"},
{"%012lx", &AT_UCACHEBSIZE, "AT_UCACHEBSIZE", "unified cache block size"},
{"%012lx", &AT_SECURE, "AT_SECURE",
"for set{u,g}id binz & security blankets"},
{"%-12s", &AT_BASE_PLATFORM, "AT_BASE_PLATFORM",
"string identifying real platform"},
{"%p", &AT_RANDOM, "AT_RANDOM", "address of sixteen random bytes"},
{"%012lx", &AT_RANDOM, "AT_RANDOM", "address of sixteen random bytes"},
{"%-12s", &AT_EXECFN, "AT_EXECFN", "pathname used to execute program"},
{"%p", &AT_SYSINFO_EHDR, "AT_SYSINFO_EHDR",
{"%012lx", &AT_SYSINFO_EHDR, "AT_SYSINFO_EHDR",
"linux virtual dso page address"},
{"%012lx", &AT_FLAGS, "AT_FLAGS", "unused?"},
{"%012lx", &AT_HWCAP, "AT_HWCAP", "cpu stuff"},
{"%012lx", &AT_HWCAP2, "AT_HWCAP2", "more cpu stuff"},
};
const struct AuxiliaryValue *DescribeAuxv(unsigned long x) {
int i;
for (i = 0; i < ARRAYLEN(kAuxiliaryValues); ++i) {
if (x == *kAuxiliaryValues[i].id) {
return kAuxiliaryValues + i;
}
}
return NULL;
}
int main(int argc, char *argv[], char **envp) {
long key;
unsigned i;
unsigned long val;
unsigned long *auxp;
char fmt[64], **env;
struct AuxiliaryValue *auxinfo;
printf("\nArguments:\n");
for (i = 0; i < __argc; ++i) {
printf(" ☼ %s\n", argv[i]);
@@ -62,13 +79,13 @@ int main(int argc, char *argv[], char **envp) {
printf(" ☼ %s\n", *env);
}
printf("\nAuxiliary Values:\n");
for (i = 0; i < ARRAYLEN(kAuxiliaryValues); ++i) {
key = *kAuxiliaryValues[i].id;
val = getauxval(key);
stpcpy(stpcpy(stpcpy(fmt, "%16s[%p] = "), kAuxiliaryValues[i].fmt),
" # %s\n");
printf(fmt, kAuxiliaryValues[i].name, key, val,
kAuxiliaryValues[i].description);
for (auxp = __auxv; *auxp; auxp += 2) {
if ((auxinfo = DescribeAuxv(auxp[0]))) {
stpcpy(stpcpy(stpcpy(fmt, "%16s[%4ld] = "), auxinfo->fmt), " # %s\n");
printf(fmt, auxinfo->name, auxp[0], auxp[1], auxinfo->description);
} else {
printf("%16s[%4ld] = %012lx\n", "unknown", auxp[0], auxp[1]);
}
}
printf("\nSpecial Directories:\n");
printf(" ☼ kTmpPath = %`'s\n", kTmpPath);
-26
View File
@@ -1,26 +0,0 @@
#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 "dsp/tty/tty.h"
#include "libc/log/log.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/time/time.h"
int main(int argc, char *argv[]) {
setenv("GDB", "nopenopenope", true);
showcrashreports();
ttyraw(kTtyLfToCrLf | kTtySigs);
printf("hi\n"), sleep(1);
if (argc > 1 && strstr(argv[1], "crash")) abort();
printf("there\n"), sleep(1);
return 0;
}
+87 -28
View File
@@ -8,58 +8,117 @@
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/calls/sigbits.h"
#include "libc/calls/struct/rusage.h"
#include "libc/errno.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/math.h"
#include "libc/runtime/clktck.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/sig.h"
#include "libc/time/time.h"
void Show(const char *name, long measurement, const char *unit) {
fprintf(stderr, "%-*s%,*d %s\n", 32, name, 32, measurement, unit);
#define PREFIX "\e[1mRL\e[0m: "
static void PrintResourceReport(struct rusage *ru) {
long utime, stime;
long double ticks;
if (ru->ru_maxrss) {
fprintf(stderr, "%sballooned to %,ldkb in size\n", PREFIX, ru->ru_maxrss);
}
if ((utime = ru->ru_utime.tv_sec * 1000000 + ru->ru_utime.tv_usec) |
(stime = ru->ru_stime.tv_sec * 1000000 + ru->ru_stime.tv_usec)) {
ticks = ceill((long double)(utime + stime) / (1000000.L / CLK_TCK));
fprintf(stderr, "%sneeded %,ldµs cpu (%d%% kernel)\n", PREFIX,
utime + stime, (int)((long double)stime / (utime + stime) * 100));
if (ru->ru_idrss) {
fprintf(stderr, "%sneeded %,ldkb memory on average\n", PREFIX,
lroundl(ru->ru_idrss / ticks));
}
if (ru->ru_isrss) {
fprintf(stderr, "%sneeded %,ldkb stack on average\n", PREFIX,
lroundl(ru->ru_isrss / ticks));
}
if (ru->ru_ixrss) {
fprintf(stderr, "%smapped %,ldkb shared on average\n", PREFIX,
lroundl(ru->ru_ixrss / ticks));
}
}
if (ru->ru_minflt || ru->ru_majflt) {
fprintf(stderr, "%scaused %,ld page faults (%d%% memcpy)\n", PREFIX,
ru->ru_minflt + ru->ru_majflt,
(int)((long double)ru->ru_minflt / (ru->ru_minflt + ru->ru_majflt) *
100));
}
if (ru->ru_nvcsw + ru->ru_nivcsw > 1) {
fprintf(stderr, "%s%,ld context switches (%d%% consensual)\n", PREFIX,
ru->ru_nvcsw + ru->ru_nivcsw,
(int)((long double)ru->ru_nvcsw / (ru->ru_nvcsw + ru->ru_nivcsw) *
100));
}
if (ru->ru_msgrcv || ru->ru_msgsnd) {
fprintf(stderr, "%sreceived %,ld message%s and sent %,ld\n", PREFIX,
ru->ru_msgrcv, ru->ru_msgrcv == 1 ? "" : "s", ru->ru_msgsnd);
}
if (ru->ru_inblock || ru->ru_oublock) {
fprintf(stderr, "%sperformed %,ld read%s and %,ld write i/o operations\n",
PREFIX, ru->ru_inblock, ru->ru_inblock == 1 ? "" : "s",
ru->ru_oublock);
}
if (ru->ru_nsignals) {
fprintf(stderr, "%sreceived %,ld signals\n", PREFIX, ru->ru_nsignals);
}
if (ru->ru_nswap) {
fprintf(stderr, "%sgot swapped %,ld times\n", PREFIX, ru->ru_nswap);
}
}
long TvToNs(struct timeval tv) {
return tv.tv_sec * 1000000000 + tv.tv_usec * 1000;
}
struct rusage rusage;
int main(int argc, char *argv[]) {
int pid, wstatus;
long double ts1, ts2;
struct rusage rusage;
sigset_t chldmask, savemask;
struct sigaction dflt, ignore, saveint, savequit;
if (argc < 2) {
fprintf(stderr, "Usage: %s PROG [ARGS...]\n", argv[0]);
return 1;
}
memset(&rusage, -1, sizeof(rusage));
CHECK_GT(argc, 1);
dflt.sa_flags = 0;
dflt.sa_handler = SIG_DFL;
sigemptyset(&dflt.sa_mask);
ignore.sa_flags = 0;
ignore.sa_handler = SIG_IGN;
sigemptyset(&ignore.sa_mask);
sigaction(SIGINT, &ignore, &saveint);
sigaction(SIGQUIT, &ignore, &savequit);
sigemptyset(&chldmask);
sigaddset(&chldmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
ts1 = nowl();
if (!(pid = vfork())) {
CHECK_NE(-1, (pid = vfork()));
if (!pid) {
sigaction(SIGINT, &dflt, 0);
sigaction(SIGQUIT, &dflt, 0);
sigprocmask(SIG_SETMASK, &savemask, 0);
execvp(argv[1], argv + 1);
abort();
fprintf(stderr, "exec failed %d\n", errno);
_Exit(127);
}
while (wait4(pid, &wstatus, 0, &rusage) == -1) {
CHECK_EQ(EINTR, errno);
}
CHECK_NE(-1, wait4(pid, &wstatus, 0, &rusage));
ts2 = nowl();
Show("wall time", lroundl((ts2 - ts1) * 1e9l), "ns");
Show("user time", TvToNs(rusage.ru_utime), "ns");
Show("sys time", TvToNs(rusage.ru_stime), "ns");
Show("maximum resident set size", rusage.ru_maxrss, "");
Show("integral shared memory size", rusage.ru_ixrss, "");
Show("integral unshared data size", rusage.ru_idrss, "");
Show("integral unshared stack size", rusage.ru_isrss, "");
Show("minor page faults", rusage.ru_minflt, "");
Show("major page faults", rusage.ru_majflt, "");
Show("swaps", rusage.ru_nswap, "");
Show("block input ops", rusage.ru_inblock, "");
Show("block output ops", rusage.ru_oublock, "");
Show("ipc messages sent", rusage.ru_msgsnd, "");
Show("ipc messages received", rusage.ru_msgrcv, "");
Show("signals received", rusage.ru_nsignals, "");
Show("voluntary context switches", rusage.ru_nvcsw, "");
Show("involuntary context switches", rusage.ru_nivcsw, "");
sigaction(SIGINT, &saveint, 0);
sigaction(SIGQUIT, &savequit, 0);
sigprocmask(SIG_SETMASK, &savemask, 0);
fprintf(stderr, "%stook %,ldµs wall time\n", PREFIX,
(int64_t)((ts2 - ts1) * 1e6));
PrintResourceReport(&rusage);
if (WIFEXITED(wstatus)) {
return WEXITSTATUS(wstatus);
} else {
-23
View File
@@ -1,23 +0,0 @@
#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/runtime/runtime.h"
int main(int argc, char *argv[]) {
int pid, wstatus;
if (argc < 2) return 1;
pid = fork();
if (!pid) {
execv(argv[1], argv + 1);
abort();
}
waitpid(pid, &wstatus, 0);
return WEXITSTATUS(wstatus);
}
+3 -3
View File
@@ -44,9 +44,9 @@ void PrintFileMetadata(const char *pathname, struct stat *st) {
"hard link count", st->st_nlink, "mode / permissions", st->st_mode,
"owner id", st->st_uid, "group id", st->st_gid,
"device id (if special)", st->st_rdev, "block size", st->st_blksize,
"access time", gc(xiso8601(&st->st_atim)), "modified time",
gc(xiso8601(&st->st_mtim)), "c[omplicated]time",
gc(xiso8601(&st->st_ctim)));
"access time", _gc(xiso8601(&st->st_atim)), "modified time",
_gc(xiso8601(&st->st_mtim)), "c[omplicated]time",
_gc(xiso8601(&st->st_ctim)));
}
int main(int argc, char *argv[]) {
-18
View File
@@ -1,18 +0,0 @@
#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/calls/struct/stat.h"
int main(int argc, char *argv[]) {
struct stat st;
st.st_size = -1;
stat(argv[1], &st);
return st.st_size;
}
+35
View File
@@ -0,0 +1,35 @@
#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/fmt/fmt.h"
#include "libc/log/check.h"
#include "libc/stdio/append.internal.h"
/**
* @fileoverview Fast Growable Strings Tutorial
*/
int main(int argc, char *argv[]) {
char *b = 0;
appendf(&b, "hello "); // guarantees nul terminator
CHECK_EQ(6, strlen(b));
CHECK_EQ(6, appendz(b).i);
appendf(&b, " world\n");
CHECK_EQ(13, strlen(b));
CHECK_EQ(13, appendz(b).i);
appendd(&b, "\0", 1); // supports binary
CHECK_EQ(13, strlen(b));
CHECK_EQ(14, appendz(b).i);
appendf(&b, "%d arg%s\n", argc, argc == 1 ? "" : "s");
appendf(&b, "%s\n", "have a nice day");
write(1, b, appendz(b).i);
free(b);
return 0;
}
-67
View File
@@ -1,67 +0,0 @@
#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/log/log.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/calls/struct/utsname.h"
#include "libc/calls/calls.h"
#include "libc/sysv/consts/exit.h"
#include "third_party/getopt/getopt.h"
int main(int argc, char *argv[]) {
unsigned need = 0;
int opt;
while ((opt = getopt(argc, argv, "hasnrvmd")) != -1) {
switch (opt) {
case 'a':
need |= 0b111111;
break;
case 's':
need |= 0b000001;
break;
case 'n':
need |= 0b000010;
break;
case 'r':
need |= 0b000100;
break;
case 'v':
need |= 0b001000;
break;
case 'm':
need |= 0b010000;
break;
case 'd':
need |= 0b100000;
break;
default: /* -? or -h */
fprintf(stderr, "%s: %s [%s]\n%s", "Usage", argv[0], "FLAGS",
" -a\tprint all\n"
" -s\tprint sysname\n"
" -n\tprint nodename\n"
" -r\tprint release\n"
" -v\tprint version\n"
" -m\tprint machine\n"
" -d\tprint domainname\n");
exit(EXIT_FAILURE);
}
}
if (!need) need = 0b000001;
struct utsname data;
if (uname(&data) == -1) perror("uname"), exit(EXIT_FAILURE);
if (need & 0b000001) printf("%s ", data.sysname);
if (need & 0b000010) printf("%s ", data.nodename);
if (need & 0b000100) printf("%s ", data.release);
if (need & 0b001000) printf("%s ", data.version);
if (need & 0b010000) printf("%s ", data.machine);
if (need & 0b100000) printf("%s ", data.domainname);
printf("\n");
return 0;
}
+58
View File
@@ -0,0 +1,58 @@
#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/calls/struct/stat.h"
#include "libc/errno.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/exit.h"
#include "libc/x/x.h"
#include "third_party/musl/ftw.h"
/**
* @fileoverview Directory walker example.
* Copied from IEEE Std 1003.1-2017
*/
static int display_info(const char *fpath, const struct stat *sb, int tflag,
struct FTW *ftwbuf) {
printf("%-3s %2d %7jd %-40s %d %s\n",
(tflag == FTW_D) ? "d"
: (tflag == FTW_DNR) ? "dnr"
: (tflag == FTW_DP) ? "dp"
: (tflag == FTW_F) ? (S_ISBLK(sb->st_mode) ? "f b"
: S_ISCHR(sb->st_mode) ? "f c"
: S_ISFIFO(sb->st_mode) ? "f p"
: S_ISREG(sb->st_mode) ? "f r"
: S_ISSOCK(sb->st_mode) ? "f s"
: "f ?")
: (tflag == FTW_NS) ? "ns"
: (tflag == FTW_SL) ? "sl"
: (tflag == FTW_SLN) ? "sln"
: "?",
ftwbuf->level, (intmax_t)sb->st_size, fpath, ftwbuf->base,
fpath + ftwbuf->base);
return 0; /* To tell nftw() to continue */
}
int main(int argc, char *argv[]) {
int flags = 0;
const char *dir;
if (argc > 2 && strchr(argv[2], 'd') != NULL) flags |= FTW_DEPTH;
if (argc > 2 && strchr(argv[2], 'p') != NULL) flags |= FTW_PHYS;
dir = argc < 2 ? "." : argv[1];
if (nftw(dir, display_info, 20, flags) == -1) {
fprintf(stderr, "nftw() failed: %s: %s\n", strerror(errno), dir);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
+18
View File
@@ -16,6 +16,24 @@
/**
* @fileoverview x86 instruction length decoder by way of hex pipe.
*
* Here's an example of how you can use it to decode a NOP stream:
*
* $ make -j8 o//examples/x86split.com
* $ echo 909090 | o//examples/x86split.com
* 90
* 90
* 90
*
* If there was a XOR instruction in there, it'd do this:
*
* $ make -j8 o//examples/x86split.com
* $ echo 904531FF90 | o//examples/x86split.com
* 90 # NOP
* 4531FF # XOR R15D,R15D
* 90 # NOP
*
* Now that you're able to split x86 instructions the rest is easy.
*/
int fgethex(FILE *f) {
+17 -13
View File
@@ -6,19 +6,23 @@ COSMOPOLITAN_C_START_
forceinline void *bisect(const void *k, const void *data, size_t n, size_t size,
int cmp(const void *a, const void *b, void *arg),
void *arg) {
int dir;
const char *p, *pos;
p = data;
while (n > 0) {
pos = p + size * (n / 2);
dir = cmp(k, pos, arg);
if (dir < 0) {
n /= 2;
} else if (dir > 0) {
p = pos + size;
n -= n / 2 + 1;
} else {
return (void *)pos;
int c;
const char *p;
ssize_t m, l, r;
if (n) {
l = 0;
r = n - 1;
p = data;
while (l <= r) {
m = (l + r) >> 1;
c = cmp(k, p + m * size, arg);
if (c > 0) {
l = m + 1;
} else if (c < 0) {
r = m - 1;
} else {
return p + m * size;
}
}
}
return NULL;
+4 -9
View File
@@ -6,18 +6,13 @@ COSMOPOLITAN_C_START_
void __assert_fail(const char *, const char *, int) hidden wontreturn relegated;
#ifdef NDEBUG
#define __ASSERT_FAIL(EXPR, FILE, LINE)
#define assert(EXPR) ((void)0)
#else
#define __ASSERT_FAIL(EXPR, FILE, LINE) __assert_fail(EXPR, FILE, LINE)
#define assert(EXPR) \
((void)((EXPR) || (__assert_fail(#EXPR, __FILE__, __LINE__), 0)))
#endif
#define assert(EXPR) \
do { \
if (!(EXPR)) { \
__ASSERT_FAIL(#EXPR, __FILE__, __LINE__); \
unreachable; \
} \
} while (0)
#define static_assert _Static_assert
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+1 -1
View File
@@ -22,6 +22,6 @@
/**
* Returns absolute value of x.
*/
int(abs)(int x) {
int abs(int x) {
return ABS(x);
}
+2 -2
View File
@@ -21,6 +21,6 @@
/**
* Reverses bits in 16-bit word.
*/
uint16_t(bitreverse16)(uint16_t x) {
return kReverseBits[x & 0x00FF] << 8 | kReverseBits[(x & 0xFF00) >> 8];
int bitreverse16(int x) {
return BITREVERSE16(x);
}
+4 -4
View File
@@ -22,10 +22,10 @@
/**
* Reverses bits in 32-bit word.
*/
uint32_t(bitreverse32)(uint32_t x) {
uint32_t bitreverse32(uint32_t x) {
x = bswap_32(x);
x = ((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1);
x = ((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2);
x = ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4);
x = (x & 0xaaaaaaaa) >> 1 | (x & 0x55555555) << 1;
x = (x & 0xcccccccc) >> 2 | (x & 0x33333333) << 2;
x = (x & 0xf0f0f0f0) >> 4 | (x & 0x0f0f0f0f) << 4;
return x;
}
+3 -3
View File
@@ -24,8 +24,8 @@
*/
uint64_t bitreverse64(uint64_t x) {
x = bswap_64(x);
x = ((x & 0xaaaaaaaaaaaaaaaa) >> 1) | ((x & 0x5555555555555555) << 1);
x = ((x & 0xcccccccccccccccc) >> 2) | ((x & 0x3333333333333333) << 2);
x = ((x & 0xf0f0f0f0f0f0f0f0) >> 4) | ((x & 0x0f0f0f0f0f0f0f0f) << 4);
x = (x & 0xaaaaaaaaaaaaaaaa) >> 1 | (x & 0x5555555555555555) << 1;
x = (x & 0xcccccccccccccccc) >> 2 | (x & 0x3333333333333333) << 2;
x = (x & 0xf0f0f0f0f0f0f0f0) >> 4 | (x & 0x0f0f0f0f0f0f0f0f) << 4;
return x;
}
+2 -2
View File
@@ -21,6 +21,6 @@
/**
* Reverses bits in 8-bit word.
*/
uint8_t(bitreverse8)(uint8_t x) {
return kReverseBits[x];
int bitreverse8(int x) {
return BITREVERSE8(x);
}
+98 -100
View File
@@ -13,8 +13,8 @@ extern const uint8_t kReverseBits[256];
uint32_t gray(uint32_t) pureconst;
uint32_t ungray(uint32_t) pureconst;
uint8_t bitreverse8(uint8_t) libcesque pureconst;
uint16_t bitreverse16(uint16_t) libcesque pureconst;
int bitreverse8(int) libcesque pureconst;
int bitreverse16(int) libcesque pureconst;
uint32_t bitreverse32(uint32_t) libcesque pureconst;
uint64_t bitreverse64(uint64_t) libcesque pureconst;
unsigned long roundup2pow(unsigned long) libcesque pureconst;
@@ -31,106 +31,104 @@ intptr_t atomic_store(void *, intptr_t, size_t);
│ cosmopolitan § bits » no assembly required ─╬─│┼
╚────────────────────────────────────────────────────────────────────────────│*/
#define bitreverse8(X) (kReverseBits[(uint8_t)(X)])
#define bitreverse16(X) \
((uint16_t)kReverseBits[(uint8_t)(X)] << 010 | \
kReverseBits[((uint16_t)(X) >> 010) & 0xff])
#define BITREVERSE8(X) (kReverseBits[255 & (X)])
#define BITREVERSE16(X) \
(kReverseBits[0x00FF & (X)] << 8 | kReverseBits[(0xFF00 & (X)) >> 8])
#define READ16LE(S) \
((uint16_t)((unsigned char *)(S))[1] << 010 | \
(uint16_t)((unsigned char *)(S))[0] << 000)
#define READ32LE(S) \
((uint32_t)((unsigned char *)(S))[3] << 030 | \
(uint32_t)((unsigned char *)(S))[2] << 020 | \
(uint32_t)((unsigned char *)(S))[1] << 010 | \
(uint32_t)((unsigned char *)(S))[0] << 000)
#define READ64LE(S) \
((uint64_t)((unsigned char *)(S))[7] << 070 | \
(uint64_t)((unsigned char *)(S))[6] << 060 | \
(uint64_t)((unsigned char *)(S))[5] << 050 | \
(uint64_t)((unsigned char *)(S))[4] << 040 | \
(uint64_t)((unsigned char *)(S))[3] << 030 | \
(uint64_t)((unsigned char *)(S))[2] << 020 | \
(uint64_t)((unsigned char *)(S))[1] << 010 | \
(uint64_t)((unsigned char *)(S))[0] << 000)
#ifdef __STRICT_ANSI__
#define READ16LE(S) ((255 & (S)[1]) << 8 | (255 & (S)[0]))
#define READ16BE(S) ((255 & (S)[0]) << 8 | (255 & (S)[1]))
#define READ32LE(S) \
((uint32_t)(255 & (S)[3]) << 030 | (uint32_t)(255 & (S)[2]) << 020 | \
(uint32_t)(255 & (S)[1]) << 010 | (uint32_t)(255 & (S)[0]) << 000)
#define READ32BE(S) \
((uint32_t)(255 & (S)[0]) << 030 | (uint32_t)(255 & (S)[1]) << 020 | \
(uint32_t)(255 & (S)[2]) << 010 | (uint32_t)(255 & (S)[3]) << 000)
#define READ64LE(S) \
((uint64_t)(255 & (S)[7]) << 070 | (uint64_t)(255 & (S)[6]) << 060 | \
(uint64_t)(255 & (S)[5]) << 050 | (uint64_t)(255 & (S)[4]) << 040 | \
(uint64_t)(255 & (S)[3]) << 030 | (uint64_t)(255 & (S)[2]) << 020 | \
(uint64_t)(255 & (S)[1]) << 010 | (uint64_t)(255 & (S)[0]) << 000)
#define READ64BE(S) \
((uint64_t)(255 & (S)[0]) << 070 | (uint64_t)(255 & (S)[1]) << 060 | \
(uint64_t)(255 & (S)[2]) << 050 | (uint64_t)(255 & (S)[3]) << 040 | \
(uint64_t)(255 & (S)[4]) << 030 | (uint64_t)(255 & (S)[5]) << 020 | \
(uint64_t)(255 & (S)[6]) << 010 | (uint64_t)(255 & (S)[7]) << 000)
#else /* gcc needs help knowing above are mov if s isn't a variable */
#define READ16LE(S) \
({ \
const uint8_t *Ptr = (const uint8_t *)(S); \
Ptr[1] << 8 | Ptr[0]; \
})
#define READ16BE(S) \
({ \
const uint8_t *Ptr = (const uint8_t *)(S); \
Ptr[0] << 8 | Ptr[1]; \
})
#define READ32LE(S) \
({ \
const uint8_t *Ptr = (const uint8_t *)(S); \
((uint32_t)Ptr[3] << 030 | (uint32_t)Ptr[2] << 020 | \
(uint32_t)Ptr[1] << 010 | (uint32_t)Ptr[0] << 000); \
})
#define READ32BE(S) \
({ \
const uint8_t *Ptr = (const uint8_t *)(S); \
((uint32_t)Ptr[0] << 030 | (uint32_t)Ptr[1] << 020 | \
(uint32_t)Ptr[2] << 010 | (uint32_t)Ptr[3] << 000); \
})
#define READ64LE(S) \
({ \
const uint8_t *Ptr = (const uint8_t *)(S); \
((uint64_t)Ptr[7] << 070 | (uint64_t)Ptr[6] << 060 | \
(uint64_t)Ptr[5] << 050 | (uint64_t)Ptr[4] << 040 | \
(uint64_t)Ptr[3] << 030 | (uint64_t)Ptr[2] << 020 | \
(uint64_t)Ptr[1] << 010 | (uint64_t)Ptr[0] << 000); \
})
#define READ64BE(S) \
({ \
const uint8_t *Ptr = (const uint8_t *)(S); \
((uint64_t)Ptr[0] << 070 | (uint64_t)Ptr[1] << 060 | \
(uint64_t)Ptr[2] << 050 | (uint64_t)Ptr[3] << 040 | \
(uint64_t)Ptr[4] << 030 | (uint64_t)Ptr[5] << 020 | \
(uint64_t)Ptr[6] << 010 | (uint64_t)Ptr[7] << 000); \
})
#endif
#define READ16BE(S) \
((uint16_t)((unsigned char *)(S))[0] << 010 | \
(uint16_t)((unsigned char *)(S))[1] << 000)
#define READ32BE(S) \
((uint32_t)((unsigned char *)(S))[0] << 030 | \
(uint32_t)((unsigned char *)(S))[1] << 020 | \
(uint32_t)((unsigned char *)(S))[2] << 010 | \
(uint32_t)((unsigned char *)(S))[3] << 000)
#define READ64BE(S) \
((uint64_t)((unsigned char *)(S))[0] << 070 | \
(uint64_t)((unsigned char *)(S))[1] << 060 | \
(uint64_t)((unsigned char *)(S))[2] << 050 | \
(uint64_t)((unsigned char *)(S))[3] << 040 | \
(uint64_t)((unsigned char *)(S))[4] << 030 | \
(uint64_t)((unsigned char *)(S))[5] << 020 | \
(uint64_t)((unsigned char *)(S))[6] << 010 | \
(uint64_t)((unsigned char *)(S))[7] << 000)
#define WRITE16LE(P, V) \
do { \
uint8_t *Ple = (uint8_t *)(P); \
uint16_t Vle = (V); \
Ple[0] = (uint8_t)(Vle >> 000); \
Ple[1] = (uint8_t)(Vle >> 010); \
} while (0)
#define WRITE32LE(P, V) \
do { \
uint8_t *Ple = (uint8_t *)(P); \
uint32_t Vle = (V); \
Ple[0] = (uint8_t)(Vle >> 000); \
Ple[1] = (uint8_t)(Vle >> 010); \
Ple[2] = (uint8_t)(Vle >> 020); \
Ple[3] = (uint8_t)(Vle >> 030); \
} while (0)
#define WRITE64LE(P, V) \
do { \
uint8_t *Ple = (uint8_t *)(P); \
uint64_t Vle = (V); \
Ple[0] = (uint8_t)(Vle >> 000); \
Ple[1] = (uint8_t)(Vle >> 010); \
Ple[2] = (uint8_t)(Vle >> 020); \
Ple[3] = (uint8_t)(Vle >> 030); \
Ple[4] = (uint8_t)(Vle >> 040); \
Ple[5] = (uint8_t)(Vle >> 050); \
Ple[6] = (uint8_t)(Vle >> 060); \
Ple[7] = (uint8_t)(Vle >> 070); \
} while (0)
#define WRITE16BE(P, V) \
do { \
uint8_t *Ple = (uint8_t *)(P); \
uint16_t Vle = (V); \
Ple[1] = (uint8_t)(Vle >> 000); \
Ple[0] = (uint8_t)(Vle >> 010); \
} while (0)
#define WRITE32BE(P, V) \
do { \
uint8_t *Ple = (uint8_t *)(P); \
uint32_t Vle = (V); \
Ple[3] = (uint8_t)(Vle >> 000); \
Ple[2] = (uint8_t)(Vle >> 010); \
Ple[1] = (uint8_t)(Vle >> 020); \
Ple[0] = (uint8_t)(Vle >> 030); \
} while (0)
#define WRITE64BE(P, V) \
do { \
uint8_t *Ple = (uint8_t *)(P); \
uint64_t Vle = (V); \
Ple[7] = (uint8_t)(Vle >> 000); \
Ple[6] = (uint8_t)(Vle >> 010); \
Ple[5] = (uint8_t)(Vle >> 020); \
Ple[4] = (uint8_t)(Vle >> 030); \
Ple[3] = (uint8_t)(Vle >> 040); \
Ple[2] = (uint8_t)(Vle >> 050); \
Ple[1] = (uint8_t)(Vle >> 060); \
Ple[0] = (uint8_t)(Vle >> 070); \
} while (0)
#define WRITE16LE(P, V) \
((P)[0] = (0x00000000000000FF & (V)) >> 000, \
(P)[1] = (0x000000000000FF00 & (V)) >> 010, (P) + 2)
#define WRITE16BE(P, V) \
((P)[0] = (0x000000000000FF00 & (V)) >> 010, \
(P)[1] = (0x00000000000000FF & (V)) >> 000, (P) + 2)
#define WRITE32LE(P, V) \
((P)[0] = (0x00000000000000FF & (V)) >> 000, \
(P)[1] = (0x000000000000FF00 & (V)) >> 010, \
(P)[2] = (0x0000000000FF0000 & (V)) >> 020, \
(P)[3] = (0x00000000FF000000 & (V)) >> 030, (P) + 4)
#define WRITE32BE(P, V) \
((P)[0] = (0x00000000FF000000 & (V)) >> 030, \
(P)[1] = (0x0000000000FF0000 & (V)) >> 020, \
(P)[2] = (0x000000000000FF00 & (V)) >> 010, \
(P)[3] = (0x00000000000000FF & (V)) >> 000, (P) + 4)
#define WRITE64LE(P, V) \
((P)[0] = (0x00000000000000FF & (V)) >> 000, \
(P)[1] = (0x000000000000FF00 & (V)) >> 010, \
(P)[2] = (0x0000000000FF0000 & (V)) >> 020, \
(P)[3] = (0x00000000FF000000 & (V)) >> 030, \
(P)[4] = (0x000000FF00000000 & (V)) >> 040, \
(P)[5] = (0x0000FF0000000000 & (V)) >> 050, \
(P)[6] = (0x00FF000000000000 & (V)) >> 060, \
(P)[7] = (0xFF00000000000000 & (V)) >> 070, (P) + 8)
#define WRITE64BE(P, V) \
((P)[0] = (0xFF00000000000000 & (V)) >> 070, \
(P)[1] = (0x00FF000000000000 & (V)) >> 060, \
(P)[2] = (0x0000FF0000000000 & (V)) >> 050, \
(P)[3] = (0x000000FF00000000 & (V)) >> 040, \
(P)[4] = (0x00000000FF000000 & (V)) >> 030, \
(P)[5] = (0x0000000000FF0000 & (V)) >> 020, \
(P)[6] = (0x000000000000FF00 & (V)) >> 010, \
(P)[7] = (0x00000000000000FF & (V)) >> 000, (P) + 8)
/*───────────────────────────────────────────────────────────────────────────│─╗
│ cosmopolitan § bits » some assembly required ─╬─│┼
+55
View File
@@ -0,0 +1,55 @@
#ifndef COSMOPOLITAN_LIBC_BITS_NEWBIE_H_
#define COSMOPOLITAN_LIBC_BITS_NEWBIE_H_
#include "libc/bits/bswap.h"
/*
* Macros for newbies.
* https://justine.lol/endian.html
*/
#define BYTE_ORDER __BYTE_ORDER__
#define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
#define BIG_ENDIAN __ORDER_BIG_ENDIAN__
#define PDP_ENDIAN __ORDER_PDP_ENDIAN__
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define htobe16(x) bswap_16(x)
#define be16toh(x) bswap_16(x)
#define betoh16(x) bswap_16(x)
#define htobe32(x) bswap_32(x)
#define be32toh(x) bswap_32(x)
#define betoh32(x) bswap_32(x)
#define htobe64(x) bswap_64(x)
#define be64toh(x) bswap_64(x)
#define betoh64(x) bswap_64(x)
#define htole16(x) (uint16_t)(x)
#define le16toh(x) (uint16_t)(x)
#define letoh16(x) (uint16_t)(x)
#define htole32(x) (uint32_t)(x)
#define le32toh(x) (uint32_t)(x)
#define letoh32(x) (uint32_t)(x)
#define htole64(x) (uint64_t)(x)
#define le64toh(x) (uint64_t)(x)
#define letoh64(x) (uint64_t)(x)
#else
#define htobe16(x) (uint16_t)(x)
#define be16toh(x) (uint16_t)(x)
#define betoh16(x) (uint16_t)(x)
#define htobe32(x) (uint32_t)(x)
#define be32toh(x) (uint32_t)(x)
#define betoh32(x) (uint32_t)(x)
#define htobe64(x) (uint64_t)(x)
#define be64toh(x) (uint64_t)(x)
#define betoh64(x) (uint64_t)(x)
#define htole16(x) bswap_16(x)
#define le16toh(x) bswap_16(x)
#define letoh16(x) bswap_16(x)
#define htole32(x) bswap_32(x)
#define le32toh(x) bswap_32(x)
#define letoh32(x) bswap_32(x)
#define htole64(x) bswap_64(x)
#define le64toh(x) bswap_64(x)
#define letoh64(x) bswap_64(x)
#endif
#endif /* COSMOPOLITAN_LIBC_BITS_NEWBIE_H_ */
+9 -9
View File
@@ -7,15 +7,15 @@ COSMOPOLITAN_C_START_
unsigned long popcnt(unsigned long) pureconst;
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define popcnt(X) \
(__builtin_constant_p(X) ? __builtin_popcountll(X) : ({ \
unsigned long Res, Pop = (X); \
if (X86_HAVE(POPCNT)) { \
asm("popcnt\t%1,%0" : "=r"(Res) : "r"(Pop) : "cc"); \
} else { \
Res = (popcnt)(Pop); \
} \
Res; \
#define popcnt(X) \
(__builtin_constant_p(X) ? __builtin_popcountll(X) : ({ \
unsigned long PoP = (X); \
if (X86_HAVE(POPCNT)) { \
asm("popcnt\t%0,%0" : "+r"(PoP) : /* no inputs */ : "cc"); \
} else { \
PoP = (popcnt)(PoP); \
} \
PoP; \
}))
#endif /* GNUC && !ANSI */
+39
View File
@@ -0,0 +1,39 @@
/*-*- 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 2021 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/math.h"
#include "libc/macros.internal.h"
void AddRusage(struct rusage *x, const struct rusage *y) {
AddTimeval(&x->ru_utime, &y->ru_utime);
AddTimeval(&x->ru_stime, &y->ru_stime);
x->ru_maxrss = MAX(x->ru_maxrss, y->ru_maxrss);
x->ru_ixrss += y->ru_ixrss;
x->ru_idrss += y->ru_idrss;
x->ru_isrss += y->ru_isrss;
x->ru_minflt += y->ru_minflt;
x->ru_majflt += y->ru_majflt;
x->ru_nswap += y->ru_nswap;
x->ru_inblock += y->ru_inblock;
x->ru_oublock += y->ru_oublock;
x->ru_msgsnd += y->ru_msgsnd;
x->ru_msgrcv += y->ru_msgrcv;
x->ru_nsignals += y->ru_nsignals;
x->ru_nvcsw += y->ru_nvcsw;
x->ru_nivcsw += y->ru_nivcsw;
}
+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 2021 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/math.h"
void AddTimeval(struct timeval *x, const struct timeval *y) {
x->tv_sec += y->tv_sec;
x->tv_usec += y->tv_usec;
if (x->tv_usec >= 1000000) {
x->tv_usec -= 1000000;
x->tv_sec += 1;
}
}
+22 -19
View File
@@ -5,6 +5,7 @@
#include "libc/calls/struct/rlimit.h"
#include "libc/calls/struct/rusage.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/sigval.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/struct/sysinfo.h"
#include "libc/calls/struct/timespec.h"
@@ -29,7 +30,7 @@
#define SIG_DFL ((void *)0)
#define SIG_IGN ((void *)1)
#define MAP_FAILED ((void *)__SIZE_MAX__)
#define MAP_FAILED ((void *)-1)
#define ARCH_SET_GS 0x1001
#define ARCH_SET_FS 0x1002
@@ -64,9 +65,6 @@ COSMOPOLITAN_C_START_
typedef int sig_atomic_t;
extern const struct sigset kSigsetFull;
extern const struct sigset kSigsetEmpty;
DIR *fdopendir(int) nodiscard;
DIR *opendir(const char *) nodiscard;
bool fileexists(const char *);
@@ -86,6 +84,7 @@ int arch_prctl();
int chdir(const char *);
int chmod(const char *, uint32_t);
int chown(const char *, uint32_t, uint32_t);
int chroot(const char *);
int close(int);
int closedir(DIR *);
int creat(const char *, uint32_t) nodiscard;
@@ -102,6 +101,7 @@ int execvp(const char *, char *const[]) paramsnonnull();
int execvpe(const char *, char *const[], char *const[]) paramsnonnull();
int faccessat(int, const char *, int, uint32_t);
int fadvise(int, uint64_t, uint64_t, int);
int fchdir(int);
int fchmod(int, uint32_t) nothrow;
int fchmodat(int, const char *, uint32_t, uint32_t);
int fchown(int, uint32_t, uint32_t);
@@ -117,6 +117,8 @@ int fsync(int);
int ftruncate(int, int64_t);
int getdomainname(char *, size_t);
int gethostname(char *, size_t);
int getpgid(int);
int getpid(void);
int getppid(void);
int getpriority(int, unsigned);
int getrlimit(int, struct rlimit *);
@@ -130,6 +132,7 @@ int madvise(void *, uint64_t, int);
int mkdir(const char *, uint32_t);
int mkdirat(int, const char *, uint32_t);
int mkfifo(const char *, uint32_t);
int mkfifoat(int, const char *, uint32_t);
int mknod(const char *, uint32_t, uint64_t);
int mknodat(int, const char *, int32_t, uint64_t);
int mlock(const void *, size_t);
@@ -138,8 +141,8 @@ int mlockall(int);
int munlock(const void *, size_t);
int munlockall(void);
int nice(int);
int open(const char *, int, ...) nodiscard;
int openanon(char *, unsigned) nodiscard;
int open(const char *, int, ...);
int openanon(char *, unsigned);
int openat(int, const char *, int, ...);
int pause(void);
int personality(uint64_t);
@@ -147,8 +150,10 @@ int pipe(int[hasatleast 2]);
int pipe2(int[hasatleast 2], int);
int posix_fadvise(int, uint64_t, uint64_t, int);
int posix_madvise(void *, uint64_t, int);
int prctl();
int raise(int);
int readlink(const char *, char *, size_t);
int reboot(int);
int remove(const char *);
int rename(const char *, const char *);
int renameat(int, const char *, int, const char *);
@@ -172,12 +177,14 @@ int setuid(uint32_t);
int sigaction(int, const struct sigaction *, struct sigaction *);
int sigignore(int);
int sigprocmask(int, const struct sigset *, struct sigset *);
int sigqueue(int, int, const union sigval);
int sigsuspend(const struct sigset *);
int stat(const char *, struct stat *);
int symlink(const char *, const char *);
int symlinkat(const char *, int, const char *);
int sync_file_range(int, int64_t, int64_t, unsigned);
int sysinfo(struct sysinfo *) paramsnonnull();
int sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
int sysinfo(struct sysinfo *);
int touch(const char *, uint32_t);
int truncate(const char *, uint64_t);
int ttyname_r(int, char *, size_t);
@@ -190,21 +197,20 @@ int wait(int *);
int wait3(int *, int, struct rusage *);
int wait4(int, int *, int, struct rusage *);
int waitpid(int, int *, int);
ssize_t lseek(int, int64_t, unsigned);
ssize_t pread(int, void *, size_t, int64_t);
ssize_t preadv(int, struct iovec *, int, int64_t);
ssize_t pwrite(int, const void *, size_t, int64_t);
ssize_t pwritev(int, const struct iovec *, int, int64_t);
intptr_t syscall(int, ...);
void sync(void);
long ptrace(int, int, void *, void *);
long telldir(DIR *);
int getpid(void);
long times(struct tms *);
sighandler_t signal(int, sighandler_t);
size_t GetFileSize(const char *);
size_t getfiledescriptorsize(int);
ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t);
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t);
ssize_t lseek(int, int64_t, unsigned);
ssize_t pread(int, void *, size_t, int64_t);
ssize_t preadv(int, struct iovec *, int, int64_t);
ssize_t pwrite(int, const void *, size_t, int64_t);
ssize_t pwritev(int, const struct iovec *, int, int64_t);
ssize_t read(int, void *, size_t);
ssize_t readansi(int, char *, size_t);
ssize_t readlinkat(int, const char *, char *, size_t);
@@ -220,11 +226,8 @@ uint32_t getsid(int) nosideeffect;
uint32_t gettid(void) nosideeffect;
uint32_t getuid(void) nosideeffect;
uint32_t umask(int32_t);
long ptrace(int, int, void *, void *);
int chroot(const char *);
int prctl();
int sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
int fchdir(int);
void rewinddir(DIR *);
void sync(void);
/*───────────────────────────────────────────────────────────────────────────│─╗
│ cosmopolitan § system calls » formatting ─╬─│┼
+9 -4
View File
@@ -41,8 +41,11 @@ LIBC_CALLS_A_DIRECTDEPS = \
LIBC_INTRIN \
LIBC_NEXGEN32E \
LIBC_NT_ADVAPI32 \
LIBC_NT_IPHLPAPI \
LIBC_NT_KERNEL32 \
LIBC_NT_NTDLL \
LIBC_NT_POWERPROF \
LIBC_NT_WS2_32 \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV_CALLS \
@@ -64,10 +67,6 @@ o/$(MODE)/libc/calls/raise.o: \
OVERRIDE_COPTS += \
$(NO_MAGIC)
o/$(MODE)/libc/calls/siggy.o: \
OVERRIDE_COPTS += \
-ffunction-sections
o/$(MODE)/libc/calls/sigenter-freebsd.o \
o/$(MODE)/libc/calls/sigenter-netbsd.o \
o/$(MODE)/libc/calls/sigenter-openbsd.o \
@@ -85,6 +84,12 @@ o/$(MODE)/libc/calls/mkntenvblock.o: \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
o/$(MODE)/libc/calls/ioctl-siocgifconf.o \
o/$(MODE)/libc/calls/ioctl-siocgifconf-nt.o: \
OVERRIDE_COPTS += \
-ffunction-sections \
-fdata-sections
LIBC_CALLS_LIBS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)))
LIBC_CALLS_SRCS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_SRCS))
LIBC_CALLS_HDRS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_HDRS))
+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 2021 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/termios.h"
#include "libc/sysv/consts/termios.h"
uint32_t cfgetispeed(const struct termios *t) {
if (CBAUD) {
return t->c_cflag & CBAUD;
} else {
return t->c_ispeed;
}
}
+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 2021 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/termios.h"
#include "libc/sysv/consts/termios.h"
uint32_t cfgetospeed(const struct termios *t) {
if (CBAUD) {
return t->c_cflag & CBAUD;
} else {
return t->c_ospeed;
}
}
+31
View File
@@ -0,0 +1,31 @@
/*-*- 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 2021 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/termios.h"
#include "libc/sysv/consts/termios.h"
void cfmakeraw(struct termios *t) {
t->c_iflag &=
~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
t->c_oflag &= ~OPOST;
t->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
t->c_cflag &= ~(CSIZE | PARENB);
t->c_cflag |= CS8;
t->c_cc[VMIN] = 1;
t->c_cc[VTIME] = 0;
}
+33
View File
@@ -0,0 +1,33 @@
/*-*- 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 2021 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/termios.h"
#include "libc/sysv/errfuns.h"
int cfsetispeed(struct termios *t, int speed) {
if (speed) {
if (CBAUD) {
if (speed & ~CBAUD) return einval();
t->c_cflag &= ~CBAUD;
t->c_cflag |= speed;
} else {
t->c_ispeed = speed;
}
}
return 0;
}
+36
View File
@@ -0,0 +1,36 @@
/*-*- 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 2021 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/termios.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
int cfsetospeed(struct termios *t, int speed) {
if (CBAUD) {
if (!(speed & ~CBAUD)) {
t->c_cflag &= ~CBAUD;
t->c_cflag |= speed;
return 0;
} else {
return einval();
}
} else {
t->c_ospeed = speed;
return 0;
}
}
Loaded 100 of 6392 files, more files were not shown because too many files have changed in this diff. Show more