diff --git a/dsp/audio/audio.c b/dsp/audio/audio.c index b81985ee0..f05a6a3b6 100644 --- a/dsp/audio/audio.c +++ b/dsp/audio/audio.c @@ -18,7 +18,9 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "dsp/audio/cosmoaudio/cosmoaudio.h" #include "dsp/audio/describe.h" +#include "libc/calls/blockcancel.internal.h" #include "libc/calls/calls.h" +#include "libc/calls/struct/sigset.internal.h" #include "libc/calls/struct/stat.h" #include "libc/calls/struct/timespec.h" #include "libc/dce.h" @@ -201,7 +203,7 @@ static void *cosmoaudio_dlopen(const char *name) { return 0; } -static void cosmoaudio_setup(void) { +static void cosmoaudio_setup_impl(void) { void *handle; if (IsOpenbsd()) return; // no dlopen support yet @@ -239,6 +241,12 @@ WeAreGood: g_audio.poll = cosmo_dlsym(handle, "cosmoaudio_poll"); } +static void cosmoaudio_setup(void) { + BLOCK_CANCELATION; + cosmoaudio_setup_impl(); + ALLOW_CANCELATION; +} + static void cosmoaudio_init(void) { pthread_once(&g_audio.once, cosmoaudio_setup); } @@ -249,10 +257,13 @@ COSMOAUDIO_ABI int cosmoaudio_open( char sbuf[32]; char dbuf[256]; cosmoaudio_init(); - if (g_audio.open) + if (g_audio.open) { + BLOCK_SIGNALS; status = g_audio.open(out_ca, options); - else + ALLOW_SIGNALS; + } else { status = COSMOAUDIO_ELINK; + } STRACE("cosmoaudio_open([%p], %s) → %s", out_ca ? *out_ca : (struct CosmoAudio *)-1, cosmoaudio_describe_open_options(dbuf, sizeof(dbuf), options), @@ -263,10 +274,13 @@ COSMOAUDIO_ABI int cosmoaudio_open( COSMOAUDIO_ABI int cosmoaudio_close(struct CosmoAudio *ca) { int status; char sbuf[32]; - if (g_audio.close) + if (g_audio.close) { + BLOCK_SIGNALS; status = g_audio.close(ca); - else + ALLOW_SIGNALS; + } else { status = COSMOAUDIO_ELINK; + } STRACE("cosmoaudio_close(%p) → %s", ca, cosmoaudio_describe_status(sbuf, sizeof(sbuf), status)); return status; @@ -276,10 +290,13 @@ COSMOAUDIO_ABI int cosmoaudio_write(struct CosmoAudio *ca, const float *data, int frames) { int status; char sbuf[32]; - if (g_audio.write) + if (g_audio.write) { + BLOCK_SIGNALS; status = g_audio.write(ca, data, frames); - else + ALLOW_SIGNALS; + } else { status = COSMOAUDIO_ELINK; + } if (frames <= 0 || frames >= 160) DATATRACE("cosmoaudio_write(%p, %p, %d) → %s", ca, data, frames, cosmoaudio_describe_status(sbuf, sizeof(sbuf), status)); @@ -290,10 +307,13 @@ COSMOAUDIO_ABI int cosmoaudio_read(struct CosmoAudio *ca, float *data, int frames) { int status; char sbuf[32]; - if (g_audio.read) + if (g_audio.read) { + BLOCK_SIGNALS; status = g_audio.read(ca, data, frames); - else + ALLOW_SIGNALS; + } else { status = COSMOAUDIO_ELINK; + } if (frames <= 0 || frames >= 160) DATATRACE("cosmoaudio_read(%p, %p, %d) → %s", ca, data, frames, cosmoaudio_describe_status(sbuf, sizeof(sbuf), status)); @@ -303,10 +323,13 @@ COSMOAUDIO_ABI int cosmoaudio_read(struct CosmoAudio *ca, float *data, COSMOAUDIO_ABI int cosmoaudio_flush(struct CosmoAudio *ca) { int status; char sbuf[32]; - if (g_audio.flush) + if (g_audio.flush) { + BLOCK_SIGNALS; status = g_audio.flush(ca); - else + ALLOW_SIGNALS; + } else { status = COSMOAUDIO_ELINK; + } DATATRACE("cosmoaudio_flush(%p) → %s", ca, cosmoaudio_describe_status(sbuf, sizeof(sbuf), status)); return status; @@ -318,10 +341,13 @@ COSMOAUDIO_ABI int cosmoaudio_poll(struct CosmoAudio *ca, int status; char sbuf[32]; char fbuf[2][20]; - if (g_audio.poll) + if (g_audio.poll) { + BLOCK_SIGNALS; status = g_audio.poll(ca, in_out_readFrames, in_out_writeFrames); - else + ALLOW_SIGNALS; + } else { status = COSMOAUDIO_ELINK; + } DATATRACE("cosmoaudio_poll(%p, %s, %s) → %s", ca, cosmoaudio_describe_poll_frames(fbuf[0], sizeof(fbuf[0]), in_out_readFrames), diff --git a/dsp/audio/cosmoaudio/cosmoaudio.c b/dsp/audio/cosmoaudio/cosmoaudio.c index d09b7b69d..bff7d14cf 100644 --- a/dsp/audio/cosmoaudio/cosmoaudio.c +++ b/dsp/audio/cosmoaudio/cosmoaudio.c @@ -19,25 +19,19 @@ #include #include -#define MA_STATIC +#define MA_DEBUG_OUTPUT +#define MA_DR_MP3_NO_STDIO #define MA_NO_DECODING #define MA_NO_ENCODING #define MA_NO_ENGINE #define MA_NO_GENERATION #define MA_NO_NODE_GRAPH #define MA_NO_RESOURCE_MANAGER -#ifdef NDEBUG -#define MA_DR_MP3_NO_STDIO -#endif +#define MA_STATIC + #define MINIAUDIO_IMPLEMENTATION #include "miniaudio.h" -#ifndef NDEBUG -#define LOG(...) fprintf(stderr, __VA_ARGS__) -#else -#define LOG(...) (void)0 -#endif - struct CosmoAudio { enum CosmoAudioDeviceType deviceType; ma_uint32 outputBufferFrames; @@ -45,14 +39,16 @@ struct CosmoAudio { int sampleRate; int channels; int isLeft; + ma_context context; ma_device device; ma_pcm_rb output; ma_pcm_rb input; ma_event event; + ma_log log; }; -static int read_ring_buffer(ma_pcm_rb* rb, float* pOutput, ma_uint32 frameCount, - ma_uint32 channels) { +static int read_ring_buffer(ma_log* log, ma_pcm_rb* rb, float* pOutput, + ma_uint32 frameCount, ma_uint32 channels) { ma_result result; ma_uint32 framesRead; ma_uint32 framesToRead; @@ -61,7 +57,9 @@ static int read_ring_buffer(ma_pcm_rb* rb, float* pOutput, ma_uint32 frameCount, void* pMappedBuffer; result = ma_pcm_rb_acquire_read(rb, &framesToRead, &pMappedBuffer); if (result != MA_SUCCESS) { - LOG("ma_pcm_rb_acquire_read failed: %s\n", ma_result_description(result)); + ma_log_postf(log, MA_LOG_LEVEL_WARNING, + "ma_pcm_rb_acquire_read failed: %s\n", + ma_result_description(result)); return COSMOAUDIO_ERROR; } if (!framesToRead) @@ -74,14 +72,16 @@ static int read_ring_buffer(ma_pcm_rb* rb, float* pOutput, ma_uint32 frameCount, framesRead += framesToRead; break; } - LOG("ma_pcm_rb_commit_read failed: %s\n", ma_result_description(result)); + ma_log_postf(log, MA_LOG_LEVEL_WARNING, + "ma_pcm_rb_commit_read failed: %s\n", + ma_result_description(result)); return COSMOAUDIO_ERROR; } } return framesRead; } -static int write_ring_buffer(ma_pcm_rb* rb, const float* pInput, +static int write_ring_buffer(ma_log* log, ma_pcm_rb* rb, const float* pInput, ma_uint32 frameCount, ma_uint32 channels) { ma_result result; ma_uint32 framesWritten; @@ -92,8 +92,9 @@ static int write_ring_buffer(ma_pcm_rb* rb, const float* pInput, void* pMappedBuffer; result = ma_pcm_rb_acquire_write(rb, &framesToWrite, &pMappedBuffer); if (result != MA_SUCCESS) { - LOG("ma_pcm_rb_acquire_write failed: %s\n", - ma_result_description(result)); + ma_log_postf(log, MA_LOG_LEVEL_WARNING, + "ma_pcm_rb_acquire_write failed: %s\n", + ma_result_description(result)); return COSMOAUDIO_ERROR; } if (!framesToWrite) @@ -106,7 +107,9 @@ static int write_ring_buffer(ma_pcm_rb* rb, const float* pInput, framesWritten += framesToWrite; break; } - LOG("ma_pcm_rb_commit_write failed: %s\n", ma_result_description(result)); + ma_log_postf(log, MA_LOG_LEVEL_WARNING, + "ma_pcm_rb_commit_write failed: %s\n", + ma_result_description(result)); return COSMOAUDIO_ERROR; } } @@ -126,8 +129,8 @@ static void data_callback_f32(ma_device* pDevice, float* pOutput, // —Quoth miniaudio documentation § 16.1. Low Level API // if (ca->isLeft) { - int framesCopied = - read_ring_buffer(&ca->output, pOutput, frameCount, ca->channels); + int framesCopied = read_ring_buffer(&ca->log, &ca->output, pOutput, + frameCount, ca->channels); if (framesCopied < (int)frameCount) ca->isLeft = 0; } else { @@ -140,13 +143,14 @@ static void data_callback_f32(ma_device* pDevice, float* pOutput, frameOffset = frameCount - availableFrames; frameCount = availableFrames; } - read_ring_buffer(&ca->output, pOutput + frameOffset * ca->channels, - frameCount, ca->channels); + read_ring_buffer(&ca->log, &ca->output, + pOutput + frameOffset * ca->channels, frameCount, + ca->channels); ca->isLeft = 1; } } if (ca->deviceType & kCosmoAudioDeviceTypeCapture) - write_ring_buffer(&ca->input, pInput, frameCount, ca->channels); + write_ring_buffer(&ca->log, &ca->input, pInput, frameCount, ca->channels); ma_event_signal(&ca->event); } @@ -211,6 +215,25 @@ COSMOAUDIO_ABI int cosmoaudio_open( // return COSMOAUDIO_ERROR; } + // Create audio log. + if (ma_log_init(NULL, &ca->log) != MA_SUCCESS) { + ma_event_uninit(&ca->event); + free(ca); + return COSMOAUDIO_ERROR; + } + if (!options->debugLog) + ca->log.callbackCount = 0; + + // Create audio context. + ma_context_config contextConfig = ma_context_config_init(); + contextConfig.pLog = &ca->log; + if (ma_context_init(NULL, 0, &contextConfig, &ca->context) != MA_SUCCESS) { + ma_event_uninit(&ca->event); + ma_log_uninit(&ca->log); + free(ca); + return COSMOAUDIO_ERROR; + } + // Initialize device. ma_result result; ma_device_config deviceConfig; @@ -227,9 +250,11 @@ COSMOAUDIO_ABI int cosmoaudio_open( // } deviceConfig.dataCallback = data_callback; deviceConfig.pUserData = ca; - result = ma_device_init(NULL, &deviceConfig, &ca->device); + result = ma_device_init(&ca->context, &deviceConfig, &ca->device); if (result != MA_SUCCESS) { + ma_context_uninit(&ca->context); ma_event_uninit(&ca->event); + ma_log_uninit(&ca->log); free(ca); return COSMOAUDIO_ERROR; } @@ -248,7 +273,9 @@ COSMOAUDIO_ABI int cosmoaudio_open( // NULL, NULL, &ca->output); if (result != MA_SUCCESS) { ma_device_uninit(&ca->device); + ma_context_uninit(&ca->context); ma_event_uninit(&ca->event); + ma_log_uninit(&ca->log); free(ca); return COSMOAUDIO_ERROR; } @@ -268,10 +295,12 @@ COSMOAUDIO_ABI int cosmoaudio_open( // result = ma_pcm_rb_init(ma_format_f32, ca->channels, ca->inputBufferFrames, NULL, NULL, &ca->input); if (result != MA_SUCCESS) { + ma_device_uninit(&ca->device); if (ca->deviceType & kCosmoAudioDeviceTypePlayback) ma_pcm_rb_uninit(&ca->output); - ma_device_uninit(&ca->device); + ma_context_uninit(&ca->context); ma_event_uninit(&ca->event); + ma_log_uninit(&ca->log); free(ca); return COSMOAUDIO_ERROR; } @@ -280,12 +309,14 @@ COSMOAUDIO_ABI int cosmoaudio_open( // // Start audio playback. if (ma_device_start(&ca->device) != MA_SUCCESS) { + ma_device_uninit(&ca->device); if (ca->deviceType & kCosmoAudioDeviceTypePlayback) ma_pcm_rb_uninit(&ca->output); if (ca->deviceType & kCosmoAudioDeviceTypeCapture) ma_pcm_rb_uninit(&ca->input); - ma_device_uninit(&ca->device); + ma_context_uninit(&ca->context); ma_event_uninit(&ca->event); + ma_log_uninit(&ca->log); free(ca); return COSMOAUDIO_ERROR; } @@ -311,12 +342,14 @@ COSMOAUDIO_ABI int cosmoaudio_open( // COSMOAUDIO_ABI int cosmoaudio_close(struct CosmoAudio* ca) { if (!ca) return COSMOAUDIO_EINVAL; + ma_device_uninit(&ca->device); // do this first if (ca->deviceType & kCosmoAudioDeviceTypePlayback) ma_pcm_rb_uninit(&ca->output); if (ca->deviceType & kCosmoAudioDeviceTypeCapture) ma_pcm_rb_uninit(&ca->input); - ma_device_uninit(&ca->device); + ma_context_uninit(&ca->context); ma_event_uninit(&ca->event); + ma_log_uninit(&ca->log); free(ca); return COSMOAUDIO_SUCCESS; } @@ -330,6 +363,12 @@ COSMOAUDIO_ABI int cosmoaudio_close(struct CosmoAudio* ca) { * repeatedly called at a regular time interval. The caller should * have its own sleep loop for this purpose. * + * This function never blocks. Programs that don't have their own timer + * can use cosmoaudio_poll() to wait until audio may be written. + * + * For any given CosmoAudio object, it's assumed that only a single + * thread will call this function. + * * @param ca is CosmoAudio object returned earlier by cosmoaudio_open() * @param data is pointer to raw audio samples, expected to be in the range * -1.0 to 1.0, where channels are interleaved @@ -351,17 +390,23 @@ COSMOAUDIO_ABI int cosmoaudio_write(struct CosmoAudio* ca, const float* data, return 0; if (!data) return COSMOAUDIO_EINVAL; - return write_ring_buffer(&ca->output, data, frames, ca->channels); + return write_ring_buffer(&ca->log, &ca->output, data, frames, ca->channels); } /** * Reads raw audio data from microphone. * * The data is read from a ring buffer in real-time, which is then - * played back very soon on the audio device. This has tolerence for - * a certain amount of buffering, but expects that this function is - * repeatedly called at a regular time interval. The caller should - * have its own sleep loop for this purpose. + * played back on the audio device. This has tolerence for a certain + * amount of buffering (based on the `bufferFrames` parameter passed to + * cosmoaudio_open(), which by default assumes this function will be + * called at at a regular time interval. + * + * This function never blocks. Programs that don't have their own timer + * can use cosmoaudio_poll() to wait until audio may be read. + * + * For any given CosmoAudio object, it's assumed that only a single + * thread will call this function. * * @param ca is CosmoAudio object returned earlier by cosmoaudio_open() * @param data is pointer to raw audio samples, expected to be in the range @@ -382,11 +427,16 @@ COSMOAUDIO_ABI int cosmoaudio_read(struct CosmoAudio* ca, float* data, return 0; if (!data) return COSMOAUDIO_EINVAL; - return read_ring_buffer(&ca->input, data, frames, ca->channels); + return read_ring_buffer(&ca->log, &ca->input, data, frames, ca->channels); } /** - * Waits for read and/or write to become possible. + * Waits until it's possible to read/write audio. + * + * This function is uninterruptible. All signals are masked throughout + * the duration of time this function may block, including cancelation + * signals, because this is not a cancelation point. Cosmopolitan Libc + * applies this masking in its dlopen wrapper. * * @param ca is CosmoAudio object returned earlier by cosmoaudio_open() * @param in_out_readFrames if non-NULL specifies how many frames of @@ -447,6 +497,11 @@ COSMOAUDIO_ABI int cosmoaudio_poll(struct CosmoAudio* ca, * * This function is only valid to call in playback or duplex mode. * + * This function is uninterruptible. All signals are masked throughout + * the duration of time this function may block, including cancelation + * signals, because this is not a cancelation point. Cosmopolitan Libc + * applies this masking in its dlopen wrapper. + * * @param ca is CosmoAudio object returned earlier by cosmoaudio_open() * @return 0 on success, or negative error code on failure */ diff --git a/dsp/audio/cosmoaudio/cosmoaudio.dll b/dsp/audio/cosmoaudio/cosmoaudio.dll index 4e4d1e863..7ef152aa4 100644 Binary files a/dsp/audio/cosmoaudio/cosmoaudio.dll and b/dsp/audio/cosmoaudio/cosmoaudio.dll differ diff --git a/dsp/audio/cosmoaudio/cosmoaudio.h b/dsp/audio/cosmoaudio/cosmoaudio.h index ce2bc48ce..40158ab81 100644 --- a/dsp/audio/cosmoaudio/cosmoaudio.h +++ b/dsp/audio/cosmoaudio/cosmoaudio.h @@ -59,6 +59,9 @@ struct CosmoAudioOpenOptions { // sample for each channel. Set to 0 for default. If this is less than // the device period size times two, it'll be increased to that value. int bufferFrames; + + // Enables debug logging if non-zero. + int debugLog; }; COSMOAUDIO_API int cosmoaudio_version(void) COSMOAUDIO_ABI; diff --git a/dsp/audio/cosmoaudio/test.c b/dsp/audio/cosmoaudio/test.c index b554d4da8..a6c7e2375 100644 --- a/dsp/audio/cosmoaudio/test.c +++ b/dsp/audio/cosmoaudio/test.c @@ -53,7 +53,7 @@ int main() { float t = (float)g++ / SAMPLING_RATE; float s = sinf(2 * M_PIf * WAVE_INTERVAL * t); for (int c = 0; c < CHANNELS; c++) - buf[f * CHANNELS + c] = s; + buf[f * CHANNELS + c] = s * .3f; } status = cosmoaudio_write(ca, buf, frames); if (status != frames) { diff --git a/dsp/audio/describe.c b/dsp/audio/describe.c index feb565bb4..71d6eb91d 100644 --- a/dsp/audio/describe.c +++ b/dsp/audio/describe.c @@ -90,6 +90,13 @@ const char *cosmoaudio_describe_open_options( gotsome = true; } + if (options->debugLog) { + if (gotsome) + append(", "); + append(".debugLog=%d", options->debugLog); + gotsome = true; + } + if (options->sizeofThis) { if (gotsome) append(", "); diff --git a/examples/a440.c b/examples/a440.c new file mode 100644 index 000000000..3b927da7d --- /dev/null +++ b/examples/a440.c @@ -0,0 +1,80 @@ +#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 +#include +#include +#include +#include + +/** + * @fileoverview plays pure A.440 tone on speakers for 1 second + * @see https://en.wikipedia.org/wiki/A440_%28pitch_standard%29 + */ + +#define SAMPLING_RATE 44100 +#define WAVE_INTERVAL 440 +#define CHANNELS 2 +#define LOUDNESS .3 +#define DEBUG_LOG 1 + +int main() { + + struct CosmoAudioOpenOptions cao = {0}; + cao.sizeofThis = sizeof(struct CosmoAudioOpenOptions); + cao.deviceType = kCosmoAudioDeviceTypePlayback; + cao.sampleRate = SAMPLING_RATE; + cao.debugLog = DEBUG_LOG; + cao.channels = CHANNELS; + + int status; + struct CosmoAudio *ca; + status = cosmoaudio_open(&ca, &cao); + if (status != COSMOAUDIO_SUCCESS) { + fprintf(stderr, "failed to open audio: %d\n", status); + return 1; + } + + float buf[256 * CHANNELS]; + for (int g = 0; g < SAMPLING_RATE;) { + int frames = 1; + status = cosmoaudio_poll(ca, NULL, &frames); + if (status != COSMOAUDIO_SUCCESS) { + fprintf(stderr, "failed to poll output: %d\n", status); + return 2; + } + if (frames > 256) + frames = 256; + if (frames > SAMPLING_RATE - g) + frames = SAMPLING_RATE - g; + for (int f = 0; f < frames; ++f) { + float t = (float)g++ / SAMPLING_RATE; + float s = sinf(2 * M_PIf * WAVE_INTERVAL * t); + for (int c = 0; c < CHANNELS; c++) + buf[f * CHANNELS + c] = s * LOUDNESS; + } + status = cosmoaudio_write(ca, buf, frames); + if (status != frames) { + fprintf(stderr, "failed to write output: %d\n", status); + return 3; + } + } + + status = cosmoaudio_flush(ca); + if (status != COSMOAUDIO_SUCCESS) { + fprintf(stderr, "failed to flush output: %d\n", status); + return 4; + } + + status = cosmoaudio_close(ca); + if (status != COSMOAUDIO_SUCCESS) { + fprintf(stderr, "failed to close audio: %d\n", status); + return 5; + } +} diff --git a/examples/blas.cc b/examples/blas.cc index 70c32c451..1dbdec7cc 100644 --- a/examples/blas.cc +++ b/examples/blas.cc @@ -14,16 +14,16 @@ // PERFORMANCE OF THIS SOFTWARE. #include +#include #include #include #include #include #include -#include "libc/assert.h" // high performance high accuracy matrix multiplication in ansi c -#define MATH __target_clones("avx512f,fma") +#define MATH __target_clones("avx512f,fma,avx") namespace { namespace ansiBLAS { diff --git a/examples/clear.c b/examples/clear.c index f008c5845..c03453e0e 100644 --- a/examples/clear.c +++ b/examples/clear.c @@ -7,7 +7,7 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" +#include // clears teletypewriter display // diff --git a/examples/crashreport.c b/examples/crashreport.c index 4e41ebf7f..b8219d83c 100644 --- a/examples/crashreport.c +++ b/examples/crashreport.c @@ -7,12 +7,7 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/intrin/kprintf.h" -#include "libc/math.h" -#include "libc/runtime/runtime.h" -#include "libc/runtime/symbols.internal.h" -#include "libc/stdio/stdio.h" +#include /** * @fileoverview How to print backtraces and cpu state on crash. diff --git a/examples/date.c b/examples/date.c index 7bfeaca5d..a0d3c6656 100644 --- a/examples/date.c +++ b/examples/date.c @@ -7,18 +7,11 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/calls/struct/timespec.h" -#include "libc/intrin/kprintf.h" -#include "libc/macros.h" -#include "libc/nt/enum/timezoneid.h" -#include "libc/nt/struct/timezoneinformation.h" -#include "libc/nt/time.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/thread/threads.h" -#include "libc/time.h" +#include +#include +#include +#include +#include /** * @fileoverview High performance ISO-8601 timestamp formatter. @@ -27,6 +20,8 @@ * Consider using something like this instead for your loggers. */ +#define ABS(X) ((X) >= 0 ? (X) : -(X)) + char *GetTimestamp(void) { int x; struct timespec ts; diff --git a/examples/dlopen.c b/examples/dlopen.c index 545513918..3198e5361 100644 --- a/examples/dlopen.c +++ b/examples/dlopen.c @@ -7,11 +7,9 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/dlopen/dlfcn.h" -#include "libc/fmt/itoa.h" -#include "libc/nt/thunk/msabi.h" -#include "libc/runtime/runtime.h" +#include +#include +#include /** * @fileoverview cosmopolitan dynamic runtime linking demo diff --git a/examples/env.c b/examples/env.c index 5e607ddad..83973ddee 100644 --- a/examples/env.c +++ b/examples/env.c @@ -1,10 +1,21 @@ -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" +#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 +#include + +/** + * @fileoverview prints environment variables + */ int main(int argc, char* argv[]) { - fprintf(stderr, "%s (%s)\n", argv[0], GetProgramExecutableName()); - for (char** p = environ; *p; ++p) { - printf("%s\n", *p); - } + for (char** p = environ; *p; ++p) + puts(*p); return 0; } diff --git a/examples/greenbean.c b/examples/greenbean.c index 8ffc51622..fda9ae999 100644 --- a/examples/greenbean.c +++ b/examples/greenbean.c @@ -23,8 +23,6 @@ #include #include #include -#include "libc/mem/leaks.h" -#include "libc/runtime/runtime.h" /** * @fileoverview greenbean lightweight threaded web server diff --git a/examples/hangman.c b/examples/hangman.c index 4aa736490..a739af289 100644 --- a/examples/hangman.c +++ b/examples/hangman.c @@ -36,14 +36,10 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "libc/calls/calls.h" -#include "libc/calls/struct/stat.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/rand.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/time.h" -#include "third_party/zlib/zlib.h" +#include +#include +#include +#include // clang-format off #define DICT "usr/share/dict/hangman" diff --git a/examples/hello.c b/examples/hello.c index f56cbae1e..f3cc59316 100644 --- a/examples/hello.c +++ b/examples/hello.c @@ -7,9 +7,8 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/stdio/stdio.h" +#include int main() { printf("hello world\n"); - return 0; } diff --git a/examples/hello2.c b/examples/hello2.c index ecf749dee..25cbd9a07 100644 --- a/examples/hello2.c +++ b/examples/hello2.c @@ -7,7 +7,7 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" +#include int main() { write(1, "hello world\n", 12); diff --git a/examples/localtime.c b/examples/localtime.c deleted file mode 100644 index 70d67c1c2..000000000 --- a/examples/localtime.c +++ /dev/null @@ -1,15 +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/time.h" - -int main(int argc, char *argv[]) { - int64_t t = 0; - localtime(&t); -} diff --git a/examples/loudness.c b/examples/loudness.c new file mode 100644 index 000000000..194600f08 --- /dev/null +++ b/examples/loudness.c @@ -0,0 +1,133 @@ +#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 +#include +#include +#include +#include +#include + +/** + * @fileoverview prints ascii meter of microphone loudness + * + * 0. -60 dB is nearly silent, barely audible, even in a quiet room + * 1. -50 dB is very quiet background sounds + * 2. -40 dB is quiet ambient noise + * 3. -30 dB is clear but soft sounds + * 4. -20 dB is moderate volume, comfortable for extended listening + * 5. -10 dB is fairly loud, but not uncomfortable + * 6. -6 dB is loud, but not at full volume + * 7. -3 dB is very loud, approaching system limits + * 8. -1 dB is extremely loud, just below maximum + * 9. -0 dB is maximum volume without distortion + */ + +#define SAMPLING_RATE 44100 +#define ASCII_METER_WIDTH 20 +#define FRAMES_PER_SECOND 30 +#define MIN_DECIBEL -60 +#define MAX_DECIBEL 0 +#define DEBUG_LOG 1 + +sig_atomic_t g_done; + +void on_signal(int sig) { + g_done = 1; +} + +// computes root of mean squares +double rms(float* p, int n) { + double s = 0; + for (int i = 0; i < n; ++i) + s += p[i] * p[i]; + return sqrt(s / n); +} + +// converts rms to decibel +double rms_to_db(double rms) { + double db = 20 * log10(rms); + db = fmin(db, MAX_DECIBEL); + db = fmax(db, MIN_DECIBEL); + return db; +} + +int main() { + signal(SIGINT, on_signal); + + // how many samples should we process at once + int chunkFrames = SAMPLING_RATE / FRAMES_PER_SECOND; + + // configure cosmo audio + struct CosmoAudioOpenOptions cao = {0}; + cao.sizeofThis = sizeof(struct CosmoAudioOpenOptions); + cao.deviceType = kCosmoAudioDeviceTypeCapture; + cao.sampleRate = SAMPLING_RATE; + cao.bufferFrames = chunkFrames * 2; + cao.debugLog = DEBUG_LOG; + cao.channels = 1; + + // connect to microphone + int status; + struct CosmoAudio* ca; + status = cosmoaudio_open(&ca, &cao); + if (status != COSMOAUDIO_SUCCESS) { + fprintf(stderr, "failed to open microphone: %d\n", status); + return 1; + } + + // allocate memory for audio work area + float* chunk = malloc(chunkFrames * sizeof(float)); + if (!chunk) { + fprintf(stderr, "out of memory\n"); + return 1; + } + + while (!g_done) { + + // wait for full chunk of audio to become available + int need_in_frames = chunkFrames; + status = cosmoaudio_poll(ca, &need_in_frames, NULL); + if (status != COSMOAUDIO_SUCCESS) { + fprintf(stderr, "failed to poll microphone: %d\n", status); + return 2; + } + + // read audio frames from microphone ring buffer + status = cosmoaudio_read(ca, chunk, chunkFrames); + if (status != chunkFrames) { + fprintf(stderr, "failed to read microphone: %d\n", status); + return 3; + } + + // convert audio chunk to to ascii meter + char s[ASCII_METER_WIDTH + 1] = {0}; + double db = rms_to_db(rms(chunk, chunkFrames)); + double db_range = MAX_DECIBEL - MIN_DECIBEL; + int filled_length = (db - MIN_DECIBEL) / db_range * ASCII_METER_WIDTH; + for (int i = 0; i < ASCII_METER_WIDTH; ++i) { + if (i < filled_length) { + s[i] = '='; + } else { + s[i] = ' '; + } + } + printf("\r%s| %+6.2f dB", s, db); + fflush(stdout); + } + printf("\n"); + + // clean up resources + status = cosmoaudio_close(ca); + if (status != COSMOAUDIO_SUCCESS) { + fprintf(stderr, "failed to close microphone: %d\n", status); + return 5; + } + free(chunk); +} diff --git a/examples/ls.c b/examples/ls.c deleted file mode 100644 index 7d8e509f1..000000000 --- a/examples/ls.c +++ /dev/null @@ -1,83 +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/dirent.h" -#include "libc/calls/struct/stat.h" -#include "libc/log/check.h" -#include "libc/mem/gc.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/dt.h" -#include "libc/sysv/consts/s.h" -#include "libc/x/xasprintf.h" - -struct stat st; - -const char *TypeToString(uint8_t type) { - switch (type) { - case DT_UNKNOWN: - return "DT_UNKNOWN"; - case DT_FIFO: - return "DT_FIFO"; - case DT_CHR: - return "DT_CHR"; - case DT_DIR: - return "DT_DIR"; - case DT_BLK: - return "DT_BLK"; - case DT_REG: - return "DT_REG"; - case DT_LNK: - return "DT_LNK"; - case DT_SOCK: - return "DT_SOCK"; - default: - return "UNKNOWN"; - } -} - -void List(const char *path) { - DIR *d; - struct dirent *e; - const char *vpath; - if (strcmp(path, ".") == 0) { - vpath = ""; - } else if (!endswith(path, "/")) { - vpath = gc(xasprintf("%s/", path)); - } else { - vpath = path; - } - if (stat(path, &st) != -1) { - if (S_ISDIR(st.st_mode)) { - CHECK((d = opendir(path))); - while ((e = readdir(d))) { - printf("0x%016x 0x%016x %-10s %s%s\n", e->d_ino, e->d_off, - TypeToString(e->d_type), vpath, e->d_name); - } - closedir(d); - } else { - printf("%s\n", path); - } - } else { - fprintf(stderr, "not found: %s\n", path); - } -} - -int main(int argc, char *argv[]) { - int i; - if (argc == 1) { - List("."); - } else { - for (i = 1; i < argc; ++i) { - List(argv[i]); - } - } - return 0; -} diff --git a/examples/nc.c b/examples/nc.c index 34483cf01..1e4f9945b 100644 --- a/examples/nc.c +++ b/examples/nc.c @@ -7,25 +7,16 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/fmt/conv.h" -#include "libc/log/log.h" -#include "libc/macros.h" -#include "libc/runtime/runtime.h" -#include "libc/sock/sock.h" -#include "libc/sock/struct/linger.h" -#include "libc/sock/struct/pollfd.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.internal.h" -#include "third_party/musl/netdb.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +// clang-format off /** * @fileoverview netcat clone @@ -36,12 +27,14 @@ * Here's an example usage: * * make -j8 o//examples/nc.com - * printf 'GET /\r\nHost: justine.lol\r\n\r\n' | o//examples/nc.com - * justine.lol 80 + * printf 'GET /\r\nHost: justine.lol\r\n\r\n' | o//examples/nc.com justine.lol 80 * - * Once upon time we called this command "telnet" + * Once upon time we called this command basically "telnet" */ +#define ARRAYLEN(A) \ + ((sizeof(A) / sizeof(*(A))) / ((unsigned)!(sizeof(A) % sizeof(*(A))))) + int main(int argc, char *argv[]) { ssize_t rc; size_t i, got; diff --git a/examples/parsefloat.c b/examples/parsefloat.c index c9f049aef..eb8e21aaa 100644 --- a/examples/parsefloat.c +++ b/examples/parsefloat.c @@ -1,3 +1,12 @@ +#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 #define PARSE_AND_PRINT(type, scan_fmt, print_fmt, str) \ diff --git a/examples/pause.c b/examples/pause.c index be13f5f45..a36ccdec1 100644 --- a/examples/pause.c +++ b/examples/pause.c @@ -7,10 +7,10 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/calls/struct/sigaction.h" -#include "libc/fmt/itoa.h" -#include "libc/str/str.h" +#include +#include +#include +#include volatile int g_sig; @@ -21,16 +21,13 @@ void OnSig(int sig) { int main(int argc, char *argv[]) { // listen for all signals - for (int sig = 1; sig <= NSIG; ++sig) { + for (int sig = 1; sig <= NSIG; ++sig) signal(sig, OnSig); - } // wait for a signal - char ibuf[12]; - FormatInt32(ibuf, getpid()); - tinyprint(2, "waiting for signal to be sent to ", ibuf, "\n", NULL); + printf("waiting for signal to be sent to my pid %d\n", getpid()); pause(); // report the signal - tinyprint(1, "got ", strsignal(g_sig), "\n", NULL); + printf("got %s\n", strsignal(g_sig)); } diff --git a/examples/picol.c b/examples/picol.c index fd54cca53..449e98ed4 100644 --- a/examples/picol.c +++ b/examples/picol.c @@ -32,12 +32,9 @@ * . Formatted as per Cosmopolitan's standards. */ -#include "libc/fmt/conv.h" -#include "libc/log/log.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" +#include +#include +#include enum { PICOL_OK, PICOL_ERR, PICOL_RETURN, PICOL_BREAK, PICOL_CONTINUE }; enum { PT_ESC, PT_STR, PT_CMD, PT_VAR, PT_SEP, PT_EOL, PT_EOF }; diff --git a/examples/printargs.c b/examples/printargs.c index 60ce148ed..d65954fcb 100644 --- a/examples/printargs.c +++ b/examples/printargs.c @@ -7,7 +7,7 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/runtime/runtime.h" +#include int main() { __printargs(""); diff --git a/examples/romanize.c b/examples/romanize.c index a31b1ab1f..2b7df6561 100644 --- a/examples/romanize.c +++ b/examples/romanize.c @@ -13,11 +13,11 @@ // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include #include #include #include #include -#include "libc/ctype.h" /** * @fileoverview Roman Transliteration, e.g. diff --git a/examples/script.c b/examples/script.c index 12ad64a26..8068a75d5 100644 --- a/examples/script.c +++ b/examples/script.c @@ -29,29 +29,20 @@ │ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF │ │ SUCH DAMAGE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" -#include "libc/calls/struct/iovec.h" -#include "libc/calls/struct/stat.h" -#include "libc/calls/struct/termios.h" -#include "libc/calls/struct/timeval.h" -#include "libc/calls/struct/winsize.h" -#include "libc/calls/termios.h" -#include "libc/calls/weirdtypes.h" -#include "libc/errno.h" -#include "libc/fmt/conv.h" -#include "libc/intrin/bswap.h" -#include "libc/log/bsd.h" -#include "libc/macros.h" -#include "libc/mem/mem.h" -#include "libc/paths.h" -#include "libc/runtime/runtime.h" -#include "libc/sock/select.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/fileno.h" -#include "libc/sysv/consts/s.h" -#include "libc/sysv/consts/termios.h" -#include "libc/time.h" -#include "third_party/getopt/getopt.internal.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // clang-format off /** diff --git a/examples/seq.c b/examples/seq.c index 4d401133b..f8403f60f 100644 --- a/examples/seq.c +++ b/examples/seq.c @@ -7,9 +7,8 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/fmt/conv.h" -#include "libc/fmt/itoa.h" +#include +#include /** * @fileoverview Prints sequence of numbers. diff --git a/examples/setcontext.c b/examples/setcontext.c index 07afabe30..ff20aee7e 100644 --- a/examples/setcontext.c +++ b/examples/setcontext.c @@ -7,12 +7,9 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/calls/ucontext.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/exit.h" +#include +#include +#include /** * @fileoverview swapcontext() and makecontext() example @@ -33,18 +30,16 @@ static ucontext_t uctx_func2; static void func1(void) { say("func1: started\n"); say("func1: swapcontext(&uctx_func1, &uctx_func2)\n"); - if (swapcontext(&uctx_func1, &uctx_func2) == -1) { + if (swapcontext(&uctx_func1, &uctx_func2) == -1) handle_error("swapcontext"); - } say("func1: returning\n"); } static void func2(void) { say("func2: started\n"); say("func2: swapcontext(&uctx_func2, &uctx_func1)\n"); - if (swapcontext(&uctx_func2, &uctx_func1) == -1) { + if (swapcontext(&uctx_func2, &uctx_func1) == -1) handle_error("swapcontext"); - } say("func2: returning\n"); } @@ -52,17 +47,15 @@ int main(int argc, char *argv[]) { char func1_stack[8192]; char func2_stack[8192]; - if (getcontext(&uctx_func1) == -1) { + if (getcontext(&uctx_func1) == -1) handle_error("getcontext"); - } uctx_func1.uc_stack.ss_sp = func1_stack; uctx_func1.uc_stack.ss_size = sizeof(func1_stack); uctx_func1.uc_link = &uctx_main; makecontext(&uctx_func1, func1, 0); - if (getcontext(&uctx_func2) == -1) { + if (getcontext(&uctx_func2) == -1) handle_error("getcontext"); - } uctx_func2.uc_stack.ss_sp = func2_stack; uctx_func2.uc_stack.ss_size = sizeof(func2_stack); /* Successor context is f1(), unless argc > 1 */ @@ -70,9 +63,8 @@ int main(int argc, char *argv[]) { makecontext(&uctx_func2, func2, 0); say("main: swapcontext(&uctx_main, &uctx_func2)\n"); - if (swapcontext(&uctx_main, &uctx_func2) == -1) { + if (swapcontext(&uctx_main, &uctx_func2) == -1) handle_error("swapcontext"); - } say("main: exiting\n"); exit(EXIT_SUCCESS); diff --git a/examples/setitimer.c b/examples/setitimer.c index 89b291941..6d926bca8 100644 --- a/examples/setitimer.c +++ b/examples/setitimer.c @@ -7,17 +7,15 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/assert.h" -#include "libc/calls/calls.h" -#include "libc/calls/struct/itimerval.h" -#include "libc/calls/struct/sigaction.h" -#include "libc/calls/struct/siginfo.h" -#include "libc/calls/ucontext.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/itimer.h" -#include "libc/sysv/consts/sa.h" -#include "libc/sysv/consts/sig.h" -#include "libc/time.h" +#include +#include +#include +#include +#include + +/** + * @fileoverview interval timer tutorial + */ volatile bool gotalrm; diff --git a/examples/spawn_bench.c b/examples/spawn_bench.c index d4ad9114a..66ccdbc6a 100644 --- a/examples/spawn_bench.c +++ b/examples/spawn_bench.c @@ -7,24 +7,20 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/atomic.h" -#include "libc/calls/calls.h" -#include "libc/calls/struct/timespec.h" -#include "libc/calls/weirdtypes.h" -#include "libc/mem/mem.h" -#include "libc/proc/posix_spawn.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/clock.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/prot.h" +#include +#include +#include +#include +#include +#include +#include +#include #define ITERATIONS 10 -_Alignas(128) int a; -_Alignas(128) int b; -_Alignas(128) atomic_int lock; +alignas(128) int a; +alignas(128) int b; +alignas(128) atomic_int lock; static struct timespec SubtractTime(struct timespec a, struct timespec b) { a.tv_sec -= b.tv_sec; diff --git a/examples/stat.c b/examples/stat.c index dce122cbb..45e17e354 100644 --- a/examples/stat.c +++ b/examples/stat.c @@ -7,19 +7,12 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/struct/stat.h" -#include "libc/assert.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/mem/gc.h" -#include "libc/mem/mem.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/s.h" -#include "libc/time.h" +#include +#include +#include +#include +#include +#include /** * @fileoverview File metadata viewer. @@ -72,9 +65,15 @@ void PrintFileMetadata(const char *pathname, struct stat *st) { printf("\n%s:", pathname); if (numeric) { fd = atoi(pathname); - CHECK_NE(-1, fstat(fd, st), "fd=%d", fd); + if (fstat(fd, st)) { + perror(pathname); + exit(1); + } } else { - CHECK_NE(-1, stat(pathname, st), "pathname=%s", pathname); + if (stat(pathname, st)) { + perror(pathname); + exit(1); + } } printf("\n" "%-32s%,ld\n" diff --git a/examples/statfs.c b/examples/statfs.c index ce6367794..817017d25 100644 --- a/examples/statfs.c +++ b/examples/statfs.c @@ -7,18 +7,19 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/struct/statfs.h" -#include "libc/dce.h" -#include "libc/fmt/conv.h" -#include "libc/log/check.h" #include "libc/nt/enum/statfs.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/st.h" +#include +#include +#include +#include -dontinline void ShowIt(const char *path) { +void ShowIt(const char *path) { char ibuf[21]; struct statfs sf = {0}; - CHECK_NE(-1, statfs(path, &sf)); + if (statfs(path, &sf)) { + perror(path); + exit(1); + } printf("filesystem %s\n", path); printf("f_type = %#x (%s)\n", sf.f_type, sf.f_fstypename); diff --git a/examples/stringbuffer.c b/examples/stringbuffer.c deleted file mode 100644 index 4f965be2f..000000000 --- a/examples/stringbuffer.c +++ /dev/null @@ -1,36 +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/log/check.h" -#include "libc/mem/mem.h" -#include "libc/stdio/append.h" -#include "libc/str/str.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; -} diff --git a/examples/sysconf.c b/examples/sysconf.c index 19a91e6b6..553b3a245 100644 --- a/examples/sysconf.c +++ b/examples/sysconf.c @@ -7,8 +7,8 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/runtime/sysconf.h" -#include "libc/stdio/stdio.h" +#include +#include #define SYSCONF(NAME) printf("%-24s %,ld\n", #NAME, sysconf(NAME)) diff --git a/examples/sysinfo.c b/examples/sysinfo.c index 4892a8183..afd2c5bca 100644 --- a/examples/sysinfo.c +++ b/examples/sysinfo.c @@ -7,19 +7,19 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/struct/sysinfo.h" -#include "libc/calls/struct/timespec.h" -#include "libc/fmt/conv.h" -#include "libc/fmt/itoa.h" -#include "libc/log/check.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/clock.h" +#include +#include +#include +#include int main(int argc, char *argv[]) { int64_t x; char ibuf[21]; struct sysinfo si; - CHECK_NE(-1, sysinfo(&si)); + if (sysinfo(&si)) { + perror("sysinfo"); + exit(1); + } printf("%-16s", "uptime"); x = si.uptime / (24 * 60 * 60); diff --git a/examples/system.c b/examples/system.c index 070665191..dcb2be248 100644 --- a/examples/system.c +++ b/examples/system.c @@ -7,9 +7,7 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" +#include /** * @fileoverview Cosmopolitan Command Interpreter Demo diff --git a/libc/isystem/sys/vfs.h b/libc/isystem/sys/vfs.h index 9d8ac9412..2904d0feb 100644 --- a/libc/isystem/sys/vfs.h +++ b/libc/isystem/sys/vfs.h @@ -1,4 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_ISYSTEM_SYS_VFS_H_ #define COSMOPOLITAN_LIBC_ISYSTEM_SYS_VFS_H_ #include "libc/calls/struct/statfs.h" +#include "libc/sysv/consts/st.h" #endif /* COSMOPOLITAN_LIBC_ISYSTEM_SYS_VFS_H_ */