Compare commits

..

37 Commits
docs ... main

Author SHA1 Message Date
DTB
f1f5ac1788 Bonsix fork 2024-05-08 08:25:34 -06:00
DTB
7f59c3b617 Remove sleep(1)s man page; see the POSIX man page 2024-05-08 07:56:07 -06:00
DTB
9ef6289e00 Merge remote-tracking branch 'origin/sleep' 2024-05-08 07:53:38 -06:00
DTB
ba55c4c8e7
sleep.1: add copyright header 2024-05-03 21:32:10 -06:00
DTB
003f5aeb1f
Makefile: add sleep to the all recipe 2024-05-03 21:30:39 -06:00
DTB
327c71c8ae
sleep.1: import from trinity/src 2024-05-03 21:29:49 -06:00
DTB
b06c1d5488
sleep(1): reduce dependence on sysexits 2024-05-03 21:22:38 -06:00
DTB
82f6c46b64
Makefile: update sleep recipe 2024-05-03 21:22:07 -06:00
DTB
81c657ec3e
Merge branch 'main' into sleep 2024-05-03 21:19:19 -06:00
9093b06166
Merge branch 'manpage-install' 2024-04-27 12:58:50 -06:00
DTB
6132c9bf47
Merge branch 'main' into scrut-sysexits 2024-04-26 19:37:34 -06:00
DTB
919b171400
scrut(1): conditionally include non-POSIX sysexits.h 2024-04-26 19:35:33 -06:00
DTB
8e38db92c7
scrut(1): update copyright header 2024-04-26 19:33:45 -06:00
DTB
adc9dbded5
scrut(1): changed return status 1 to EXIT_FAILURE 2024-04-26 19:30:33 -06:00
488351da39
scrut(1): changed return status 0 to EXIT_SUCCESS 2024-04-25 16:46:05 -06:00
d8b54fdbf5
Makefile: fixes erroneous whitespace 2024-04-25 12:43:31 -06:00
f6aac60aee
Makefile: fixed manpage install location 2024-04-25 12:40:20 -06:00
DTB
61382c34d9
mm(1): error out when given positional arguments 2024-03-31 22:54:03 -06:00
8d9ac33566
Merge branch 'strerror' 2024-03-29 19:23:27 -06:00
b503d97625
Makefile: directory specification changes 2024-03-29 19:22:55 -06:00
b562898a74
copyright 2024-03-27 09:21:19 +05:45
d05d2fae05 Makefile: add a missing build target for npc(1) 2024-03-26 17:19:21 +05:45
DTB
82a941eee3
sleep(1): initial implementation 2024-03-21 20:41:05 -06:00
DTB
e674027b3e
Makefile: add sleep(1) 2024-03-21 20:40:19 -06:00
d87b5d0958
hru(1), fop(1): changed to reflect strerror changes 2024-03-18 21:31:25 -06:00
1891c3e1aa
strerror(3): created strerror() method 2024-03-18 21:30:43 -06:00
b356ac522f
strerror(3): changed panic to 0 2024-03-18 20:45:53 -06:00
b2d56bbc9a
Makefile: even more changes 2024-03-09 22:02:19 -07:00
2ad7140e1e
Makefile: DESTDIR 2024-03-09 11:53:03 -07:00
8193e471f0
changes redundant .unwrap_or_else(panic!()) to .unwrap() 2024-03-03 17:26:40 -07:00
c392dbc680
Makefile: better deps; fop(1), hru(1), strerror(3): changed strerror wrapper function name 2024-03-02 10:16:32 -07:00
898044cd43
Makefile: better macro assignment 2024-03-01 23:51:36 -07:00
ca01ca4074
rpn(1): remove erroneous strerror(3) dependency 2024-03-01 23:14:58 -07:00
3e6dc5cc46
rpn(1): make error messages consistent with other tools 2024-03-01 23:14:18 -07:00
cf1d16f860
hru(1): changed to use strerror(3) 2024-03-01 23:12:44 -07:00
8f956d775c
fop(1): changed to use strerror(3) 2024-03-01 23:10:28 -07:00
e81703c6e1
sterror(3): added library for C-like error messages; Makefile: some efficiency changes 2024-03-01 23:04:53 -07:00
23 changed files with 455 additions and 538 deletions

View File

@ -1,6 +1,7 @@
# Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media>
# Copyright (c) 20232024 DTB <trinity@trinity.moe>
# Copyright (c) 2023 Sasha Koshka <sashakoshka@tebibyte.media>
# Copyright (c) 2024 Aaditya Aryal <aryalaadi123@gmail.com>
# SPDX-License-Identifier: FSFAP
#
# Copying and distribution of this file, with or without modification, are
@ -8,16 +9,28 @@
# notice are preserved. This file is offered as-is, without any warranty.
.POSIX:
# if using BSD make(1), remove these pragmas because they break it
.PRAGMA: posix_202x # future POSIX standard support à la pdpmake(1)
.PRAGMA: command_comment # breaks without this?
PREFIX=/usr/local
DESTDIR ?= dist
PREFIX ?= /usr/local
CC=cc
RUSTC=rustc
MANDIR != [ $(PREFIX) = / ] && printf '/usr/share/man\n' \
|| printf '/share/man\n'
SYSEXITS != printf '\043include <sysexits.h>\n' | cpp -M - | sed 's/ /\n/g' \
| sed -n 's/sysexits\.h//p' || printf 'include\n'
CC ?= cc
RUSTC ?= rustc
RUSTLIBS = --extern getopt=build/o/libgetopt.rlib \
--extern sysexits=build/o/libsysexits.rlib \
--extern strerror=build/o/libstrerror.rlib
CFLAGS += -I$(SYSEXITS)
.PHONY: all
all: dj false fop hru intcmp mm rpn scrut str strcmp swab true
all: dj false fop hru intcmp mm npc rpn scrut sleep str strcmp swab true
build:
# keep build/include until bindgen(1) has stdin support
@ -26,36 +39,40 @@ build:
.PHONY: clean
clean:
rm -rf build/ dist/
rm -rf build dist
dist: all
mkdir -p dist/bin dist/share/man/man1
cp build/bin/* dist/bin/
cp docs/*.1 dist/share/man/man1/
mkdir -p $(DESTDIR)/$(PREFIX)/bin $(DESTDIR)/$(PREFIX)/share/man/man1
cp build/bin/* $(DESTDIR)/$(PREFIX)/bin
cp docs/*.1 $(DESTDIR)/$(PREFIX)/$(MANDIR)/man1
.PHONY: install
install: dist
mkdir -p $(PREFIX)
cp -r dist/* $(PREFIX)/
cp -r $(DESTDIR)/* /
.PHONY: test
test: build
tests/posix-compat.sh
$(RUSTC) --test src/getopt-rs/lib.rs -o build/test/getopt
build/o/libsysexits.rlib: build
.PHONY: rustlibs
rustlibs: build/o/libsysexits.rlib build/o/libgetopt.rlib \
build/o/libstrerror.rlib
build/o/libgetopt.rlib: build src/getopt-rs/lib.rs
$(RUSTC) $(RUSTFLAGS) --crate-type=lib --crate-name=getopt \
-o $@ src/getopt-rs/lib.rs
build/o/libstrerror.rlib: build src/strerror.rs
$(RUSTC) $(RUSTFLAGS) --crate-type=lib -o $@ \
src/strerror.rs
build/o/libsysexits.rlib: build $(SYSEXITS)sysexits.h
# bandage solution until bindgen(1) gets stdin support
printf '#define EXIT_FAILURE 1\n' | cat - include/sysexits.h \
printf '#define EXIT_FAILURE 1\n' | cat - $(SYSEXITS)sysexits.h \
> build/include/sysexits.h
bindgen --default-macro-constant-type signed --use-core --formatter=none \
"$$(printf '#include <sysexits.h>\n' \
| cpp -M -idirafter "build/include" - \
| sed 's/ /\n/g' | grep sysexits.h)" \
| $(RUSTC) $(RUSTFLAGS) --crate-type lib -o build/o/libsysexits.rlib -
build/o/libgetopt.rlib: src/getopt-rs/lib.rs
$(RUSTC) $(RUSTFLAGS) --crate-type=lib --crate-name=getopt \
-o build/o/libgetopt.rlib src/getopt-rs/lib.rs
build/include/sysexits.h | $(RUSTC) $(RUSTFLAGS) --crate-type lib -o $@ -
.PHONY: dj
dj: build/bin/dj
@ -69,17 +86,13 @@ build/bin/false: src/false.c build
.PHONY: fop
fop: build/bin/fop
build/bin/fop: src/fop.rs build build/o/libgetopt.rlib build/o/libsysexits.rlib
$(RUSTC) $(RUSTFLAGS) --extern getopt=build/o/libgetopt.rlib \
--extern sysexits=build/o/libsysexits.rlib \
-o $@ src/fop.rs
build/bin/fop: src/fop.rs build rustlibs
$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/fop.rs
.PHONY: hru
hru: build/bin/hru
build/bin/hru: src/hru.rs build build/o/libgetopt.rlib build/o/libsysexits.rlib
$(RUSTC) $(RUSTFLAGS) --extern getopt=build/o/libgetopt.rlib \
--extern sysexits=build/o/libsysexits.rlib \
-o $@ src/hru.rs
build/bin/hru: src/hru.rs build rustlibs
$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/hru.rs
.PHONY: intcmp
intcmp: build/bin/intcmp
@ -91,18 +104,28 @@ mm: build/bin/mm
build/bin/mm: src/mm.c build
$(CC) $(CFLAGS) -o $@ src/mm.c
.PHONY: npc
npc: build/bin/npc
build/bin/npc: src/npc.c build
$(CC) $(CFLAGAS) -o $@ src/npc.c
.PHONY: rpn
rpn: build/bin/rpn
build/bin/rpn: src/rpn.rs build build/o/libsysexits.rlib
$(RUSTC) $(RUSTFLAGS) \
--extern sysexits=build/o/libsysexits.rlib \
-o $@ src/rpn.rs
build/bin/rpn: src/rpn.rs build rustlibs
$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/rpn.rs
.PHONY: scrut
scrut: build/bin/scrut
build/bin/scrut: src/scrut.c build
$(CC) $(CFLAGS) -o $@ src/scrut.c
.PHONY: sleep
sleep: build/bin/sleep
build/bin/sleep: src/sleep.rs build rustlibs
$(RUSTC) $(RUSTFLAGS) \
--extern sysexits=build/o/libsysexits.rlib \
-o $@ src/sleep.rs
.PHONY: str
str: build/bin/str
build/bin/str: src/str.c build

57
README
View File

@ -1,27 +1,27 @@
“Seek not to walk the path of the masters; seek what they sought.”
Matsuo Basho
For the Bonsai coreutils, a better Unix toolset, please visit
<https://git.tebibyte.media/bonsai/coreutils>.
The Bonsai core utilities are the result of the careful examination of the
current state of POSIX and Unix utilies. The Unix Philosophy, “do one thing and
do it well” is its core but these tools do not cling to the names of the past.
wwwww /
wWWWWWw /_ _____ _ * "It's not a very good tree, but
w|||w / \/ \ / | /\ / /|/ occasionally it bears fruit!"
_,|||._ _/\__/|__// /_/_|_/_//|__
bonsix : "BOHN zix" : "Bonsai" but "POSIX"
The era of the original Unix tools has been long and fruitful, but they have
their flaws. The new, non-POSIX era of this project started with frustration
with the way certain tools work and how other projects that extend POSIX dont
make anything better.
The excellent Bonsai core utilities are the result of the careful examination
of the current state of POSIX and Unix utilities, ironing out wrinkles in the
implementations that ended up being worn by the POSIX standard. Bonsai's
guiding quote is this one from Matsuo Basho:
This project will not follow in the footsteps of GNU; extensions of POSIX will
not be found here. GNU extensions are a gateway to the misuse of the shell. The
Bonsai core utilities will intentionally discourage use of the shell for
purposes beyond its scope.
"Seek not to walk the path of the masters; seek what they sought."
See docs/ for more on the specific utilities currently implemented.
Unlike Bonsai, Bonsix intends to walk the path of the masters, implementing a
POSIX userland under an AGPLv3 license and taking inspiration from the
practices used by Bonsai.
Building
The coreutils require a POSIX-compliant environment to compile, including a C
compiler and preprocessor (cc(1) and cpp(1) by default) with the -idirafter
flag, a Rust compiler (rustc(1) by default), bindgen(1), and a POSIX-compliant
Bonsix requires an existing POSIX-compliant environment to compile, including a
C compiler and preprocessor (cc(1) and cpp(1) by default) and a POSIX-compliant
make(1) utility.
To build and install:
@ -32,29 +32,6 @@ $ make PREFIX="/your/preferred/location" install
To build with a different compiler than the default:
$ make CC=clang
$ make RUSTC=gccrs
To test the utilities:
$ make test
To remove all untracked files:
$ make clean
Read More
An Introduction to the Unix Shell
<https://porkmail.org/era/unix/shell>
Master Foo and the Ten Thousand Lines
<http://www.catb.org/~esr/writings/unix-koans/ten-thousand.html>
Master Foo Discourses on the Unix-Nature
<http://www.catb.org/~esr/writings/unix-koans/unix-nature.html>
Shell Programming!
<https://tldp.org/LDP/abs/html/why-shell.html>
--
Copyright © 20232024 Emma Tebibyte <emma@tebibyte.media>

197
docs/dj.1
View File

@ -1,5 +1,4 @@
.\" Copyright (c) 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@ -45,139 +44,87 @@ dj
.B output offset
.R ])
.SH OPTIONS
.SH USAGE
The
.B -i
.RS
Takes a file path as an argument to open and use as an input.
.RE
.B -b
.RS
Takes a numeric argument as the size in bytes of the input buffer, with the
default being 1024 bytes or one kibibyte (KiB).
.RE
.B -s
.RS
Takes a numeric argument as the number of bytes to skip into the input
before starting to read. If the standard input is used, bytes read to this point
are discarded.
.RE
option takes a path as an argument to open and use in place of standard input.
The
.B -o
.RS
Takes a file path as an argument to open and use as an output.
.RE
.B -B
.RS
Does the same as
option does the same in place of standard output. Dj does not truncate output
files and instead writes over the bytes in the existing file.
.PP
The
.B -b
but for the output buffer.
.RE
option takes a numeric argument as the size in bytes of the input buffer and
the
.B -B
option does the same for the output buffer, the default for both being 1024
bytes, or one kibibyte (KiB).
.PP
The
.B -s
option takes a numeric argument as the number of bytes to skip into the input
before starting to read, and the
.B -S
.RS
Skips a number of bytes through the output before starting to write from
the input. If the output is a stream, null characters are printed.
.RE
option skips a number of bytes through the output before starting to write from
the input. If the input is a stream the bytes are read and discarded. If the
output is a stream, nul characters are printed.
.PP
The
.B -a
.RS
Accepts a single literal byte with which input buffer is padded in the event
of an incomplete read from the input file.
.RE
.B -c
.RS
Specifies a number of reads to make. If set to zero (the default), reading will
continue until a partial or empty read is encountered.
.RE
option takes one argument of one byte in length and pads the input buffer with
that byte in the event that a read doesn't fill the input buffer, and the
.B -A
.RS
If the output is a stream, null bytes are printed. This option is equivalent to
specifying
.B -a
with a null byte instead of a character.
.RE
.B -d
.RS
Prints invocation information before program execution as described in the
DIAGNOSTICS section below. Each invocation increments the debug level of the
program.
.RE
.B -H
.RS
Prints diagnostics messages in a human-readable manner as described in the
DIAGNOSTICS section below.
.RE
.B -n
.RS
Retries failed reads once more before exiting.
.RE
option takes no arguments and pads with nuls.
The
.B -c
option specifies an amount of reads to make, and if 0 (the default) dj will
continue reading until a partial or empty read.
.PP
On a partial or empty read, dj prints a diagnostic message (unless the
.B -q
.RS
Suppresses error messages which print when a read or write is partial or
empty. Each invocation decrements the debug level of the program.
.RE
.SH STANDARD INPUT
The standard input shall be used as an input if no inputs are specified one or
more of the input files is “-”.
option is specified) and exits (unless the
.B -n
option is specified, in which case only two consecutive empty reads will cause
dj to exit).
At exit, usage statistics are printed unless the option
.B -q
is specified a second time. The
.B -H
option will make these diagnostics human-readable.
.SH DIAGNOSTICS
On a partial or empty read, a diagnostic message is printed (unless the
.B -q
option is specified) and the program exits (unless the
.B -n
option is specified.
By default statistics are printed for input and output to the standard error in
the following format:
.RS
The
.B -d
option prints all information, user-specified or otherwise, before program
execution.
.PP
When dj exits, by default statistics are printed for input and output to
standard error in the following format:
.PP
.R {records read} {ASCII unit separator} {partial records read}
.R {ASCII record separator} {records written} {ASCII unit separator}
.R {partial records written} {ASCII group separator} {bytes read}
.R {ASCII record separator} {bytes written} {ASCII file separator}
.RE
This format for diagnostic output is designed to be machine-parseable for
convenience. For a more human-readable format, the
.PP
If the
.B -H
option may be specified. In this event, the following format is used instead:
.RS
option is specified dj instead uses this following format:
.PP
.R {records read} '+' {partial records read} '>' {records written}
.R '+' {partial records written} ';' {bytes read} '>' {bytes written}
.R {ASCII line feed}
.RE
If the
.B -d
option is specified, debug output will be printed at the beginning of execution.
This debug information contains information regarding how the program was
invoked. The following example is the result of running the program with
.B -d
as the only argument:
.RS
.R argv0=dj
.R in=<stdin> ibs=1024 skip=0 align=ff count=0
.R out=<stdout> obs=1024 seek=0 debug= 3 noerror=0
.RE
In non-recoverable errors that dont pertain to the read-write cycle, a
diagnostic message is printed and the program exits with the appropriate
sysexits.h(3) status.
.PP
The
.B -q
option suppresses error messages which print when a read or write is partial or
empty and when used twice suppresses diagnostic output entirely.
.PP
In non-recoverable errors that don't pertain to dj's read-write cycle, a
diagnostic message is printed and dj exits with the appropriate sysexits(3)
status.
.SH BUGS
@ -189,29 +136,25 @@ expected (the product of the count multiplied by the input block size). If the
or
.B -A
options are used this could make data written nonsensical.
.PP
Many lowercase options have capitalized variants and vice-versa which can be
confusing. Capitalized options tend to affect output or are more intense
versions of lowercase options.
.SH CAVEATS
Existing files are not truncated on ouput and are instead overwritten.
.SH RATIONALE
This program was based on the dd(1p) utility as specified in POSIX. While
character conversion may have been the original intent of dd(1p), it is
irrelevant to its modern use. Because of this, it eschews character conversion
and adds typical option formatting, allowing seeks to be specified in bytes
Dj was modeled after the dd utility specified in POSIX but adds additional
features: typical option formatting, allowing seeks to be specified in bytes
rather than in blocks, allowing arbitrary bytes as padding, and printing in a
format thats easy to parse for machines.
format that's easy to parse for machines. It also neglects character
conversion, which may be dd's original intent but is irrelevant to its modern
use.
.SH COPYRIGHT
Copyright © 2023 DTB. License AGPLv3+: GNU AGPL version 3 or later
Copyright (C) 2023 DTB. License AGPLv3+: GNU AGPL version 3 or later
<https://gnu.org/licenses/agpl.html>.
.SH SEE ALSO
dd(1p)
dd(1)

View File

@ -1,5 +1,5 @@
.\" Copyright (c) 2022, 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media>
.\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@ -12,13 +12,14 @@ false \(en do nothing, unsuccessfully
.SH DESCRIPTION
Do nothing regardless of operands or standard input.
An exit code of 1 will always be returned.
False does nothing regardless of operands or standard input.
False will always return an exit code of 1.
.SH RATIONALE
In POSIX.1-2017, false(1p) exists for the construction of control flow and loops
based on a failure. This implementation functions as described in that standard.
False exists for the construction of control flow and loops based on a failure.
False functions as described in POSIX.1-2017.
.SH AUTHOR

View File

@ -1,60 +0,0 @@
.\" Copyright (c) 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
.TH fop 1
.SH NAME
fop \(en field operator
.SH SYNOPSIS
fop
.RB ( -d )
.RB [ delimiter ]
.RB index
.RB program...
.SH DESCRIPTION
Performs operations on specified fields in input data.
.SH OPTIONS
.B -d
.RS
Sets a delimiter by which the input data will be split into fields. The default
is an ASCII record separator (␞).
.RE
.SH STANDARD INPUT
Data will be read from the standard input.
.SH CAVEATS
Field indices are zero-indexed, which may be unexpected behavior for some users.
.SH RATIONALE
With the assumption that tools will output data separated with ASCII field
separators, there is
The idea for this utility originated in the fact that GNU ls(1) utility contains
a
.B -h
option which enables human-readable units in file size outputs. This
functionality was broken out into hru(1), but there was no easy way to modify
the field in the ouput of ls(1p) without a new tool.
.SH COPYRIGHT
Copyright © 2024 Emma Tebibyte. License AGPLv3+: GNU AGPL version 3 or later
<https://gnu.org/licenses/agpl.html>.
.SH SEE ALSO
sed(1p)

View File

@ -3,7 +3,7 @@
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
.TH hru 1
.TH rpn 1
.SH NAME
@ -15,20 +15,18 @@ hru
.SH DESCRIPTION
Convert counts to higher units.
The program will read byte counts in the form of whole numbers from the standard
input and write to the standard output the same number converted to a higher
unit of data as defined by the International System of Units.
Hru reads byte counts in the form of whole numbers from the standard input and
writes to the standard output the same number converted one of the units of data
defined by the International System of Units.
The program will convert the byte count to the highest unit possible where the
value is greater than one.
.SH DIAGNOSTICS
If encountering non-integer characters in the standard input, the program will
exit with the appropriate error code as defined by sysexits.h(3) and print an
error message.
If encountering non-integer characters in the standard input, hru will exit with
the appropriate error code as defined by sysexits.h(3) and print an error
message.
.SH RATIONALE
@ -41,9 +39,9 @@ program.
.SH STANDARDS
The standard unit prefixes as specified by the Bureau International des Poids
et Mesures (BIPM) in the ninth edition of The International System of Units
(SI) are utilized for the ouput of conversions.
Hru follows the standard unit prefixes as specified by the Bureau International
des Poids et Mesures (BIPM) in the ninth edition of The International System of
Units (SI).
.SH AUTHOR

View File

@ -1,5 +1,5 @@
.\" Copyright (c) 20232024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media>
.\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@ -13,59 +13,45 @@ intcmp \(en compare integers
.SH SYNOPSIS
intcmp
.RB ( -egl )
.RB ( -eghl )
.RB [ integer ]
.RB [ integer... ]
.SH DESCRIPTION
Compare integers to each other.
Intcmp compares integers.
.SH USAGE
.B -e
.RS
Permits given integers to be equal to each other.
.RE
.B -g
.RS
Permits a given integer to be greater than the following integer.
.RE
.B -l
.RS
Permits a given integer to be less than the following integer.
.RE
.SH EXAMPLES
The -e option permits given integers to be equal to each other. If combined
with -g or -l, only adjacent integers in the argument sequence can be equal.
.PP
The -g option permits a given integer to be greater than the following integer.
.PP
The -l option permits a given integer to be less than the following integer.
.PP
It may help to think of the -e, -g, and -l options as equivalent to the
infix algebraic “=”, “>”, and “<” operators respectively, with each option
putting its symbol between every given integer. The following example is
equivalent to evaluating “1 < 2 < 3”:
.RS
putting its symbol between every given integer. For example,
.R intcmp -l 1 2 3
.RE
is equivalent to evaluating "1 < 2 < 3".
.SH DIAGNOSTICS
The program will exit with a status code of 0 for a valid expression and with a
code of 1 for an invalid expression.
In the event of an error, a debug message will be printed and the program will
exit with the appropriate sysexits.h(3) error code.
Intcmp exits 0 for a valid expression and 1 for an invalid expression.
.PP
Intcmp prints a debug message and exits with the appropriate sysexits(3) error
code in the event of an error.
.SH BUGS
There are multiple ways to express compound comparisons; “less than or equal
to” can be -le or -el, for example.
.PP
The inequality comparison is -gl or -lg for “less than or greater than”; this
is elegant but unintuitive.
-egl, “equal to or less than or greater than”, exits 0 no matter what for valid
.PP
-egl, "equal to or less than or greater than", exits 0 no matter what for valid
program usage and may be abused to function as an integer validator.
Use str(1) instead.
@ -75,7 +61,7 @@ The traditional tool for integer comparisons in POSIX and other Unix shells has
been test(1). This tool also handles string comparisons and file scrutiny.
These parts of its functionality have been broken out into multiple utilities.
This programs functionality may be performed on a POSIX-compliant system with
Strcmps functionality may be performed on a POSIX-compliant system with
test(1p).
.SH AUTHOR

View File

@ -20,63 +20,51 @@ mm
.SH DESCRIPTION
Catenate input files and write them to the start of each output file or stream.
Mm catenates input files and writes them to the start of each output file.
.SH OPTIONS
Mm, upon receiving the
.B -a
.RS
Opens subsequent outputs for appending rather than updating.
.RE
.B -e
.RS
Use the standard error as an output.
.RE
option, will open subsequent outputs for appending rather than updating.
.PP
The
.B -i
.RS
Opens a path as an input. Without any inputs specified mm will use the
standard input. The standard input shall be used as an input if one or more of
the input files is “-”.
.RE
option opens a path as an input. Without any inputs specified mm will use
standard input. Standard input itself can be specified by giving the path '-'.
.PP
The
.B -o
.RS
Opens a path as an output. Without any outputs specified mm will use the
standard output. The standard output shall be used as an output if one or more
of the output files is “-”.
.RE
option opens a path as an output. Without any outputs specified mm will use
standard output. Standard output itself can be specified by giving the
path '-'. Standard error itself can be specified with the
.B -e
option.
.PP
The
.B -u
.RS
Ensures neither input or output will be buffered.
.RE
option ensures neither input or output will be buffered.
.PP
The
.B -n
.RS
Causes SIGINT signals to be ignored.
.RE
option tells mm to ignore SIGINT signals.
.SH DIAGNOSTICS
If an output can no longer be written mm prints a diagnostic message, ceases
writing to that particular output, and if there are more outputs specified,
continues, eventually exiting unsuccessfully.
.PP
On error mm prints a diagnostic message and exits with the appropriate
sysexits.h(3) status.
When an error is encountered, diagnostic message is printed and the program
exits with the appropriate sysexits.h(3) status.
.SH BUGS
.SH CAVEATS
Existing files are not truncated on ouput and are instead overwritten.
Mm does not truncate existing files, which may lead to unexpected results.
.SH RATIONALE
The cat(1p) and tee(1p) programs specified in POSIX together provide similar
functionality. The separation of the two sets of functionality into separate
APIs seemed unncessary.
Mm was modeled after the cat and tee utilities specified in POSIX.
.SH COPYRIGHT

View File

@ -1,5 +1,5 @@
.\" Copyright (c) 20232024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media>
.\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@ -13,50 +13,43 @@ npc \(en show non-printing characters
.SH SYNOPSIS
npc
.RB ( -et )
.RB ( -eht )
.SH DESCRIPTION
Print normally non-printing characters.
The program reads from standard input and writes to standard output, replacing
non-printing characters with printable equivalents. Control characters print as
a carat ('^') followed by the character '@' through '_' corresponding to the
character replaced (e.g. control-X becomes '^X'). The delete character (0x7F)
becomes '^?'. Characters with the high bit set (>127) are printed as 'M-'
Npc reads from standard input and writes to standard output, replacing non-
printing characters with printable equivalents. Control characters print as a
carat ('^') followed by the character '@' through '_' corresponding to the
character replaced (e.g. control-X becomes "^X"). The delete character (0x7F)
becomes "^?". Characters with the high bit set (>127) are printed as "M-"
followed by the graphical representation for the same character without the
high bit set.
.SH USAGE
.PP
The
.B -e
.RS
Prints a currency sign ('$') before each line ending.
.RE
option prints a currency sign ('$') before each line ending.
.PP
The
.B -t
.RS
Prints tab characters as '^I' rather than a literal horizontal tab.
.RE
option prints tab characters as "^I" rather than a literal horizontal tab.
.SH DIAGNOSTICS
In the event of an error, a debug message will be printed and the program will
exit with the appropriate sysexits.h(3) error code.
Npc prints a debug message and exits with the appropriate sysexits(3) error
code in the event of an error, otherwise it exits successfully.
.SH BUGS
The program operates in single-byte chunks regardless of intended encoding.
Npc operates in single-byte chunks regardless of intended encoding.
.SH RATIONALE
POSIX currently lacks a way to display non-printing characters in the terminal
using a standard tool. A popular extension to cat(1p), the
.B -v
option, is the bandage solution GNU and other software suites use.
using a standard tool. A popular extension to cat(1p), the -v option, is the
bandage solution GNU and other software suites use.
This functionality is a separate tool because its usefulness extends beyond that
of cat(1p).
This functionality should be a separate tool because its usefulness extends
beyond that of cat(1p).
.SH AUTHOR

View File

@ -17,13 +17,10 @@ rpn
.SH DESCRIPTION
Evaluate reverse polish notation.
Rpn evaluates reverse polish notation expressions either read from the standard
input or parsed from provided arguments. See the STANDARD INPUT section.
The program evaluates reverse polish notation expressions either read from the
standard input or parsed from provided arguments. See the STANDARD INPUT
section.
Upon evaluation, the program will print the resulting number on the stack to the
Upon evaluation, rpn will print the resulting number on the stack to the
standard output. Any further specified numbers will be placed at the end of the
stack.
@ -31,16 +28,14 @@ For information on for reverse polish notation syntax, see rpn(7).
.SH STANDARD INPUT
If arguments are passed , they are interpreted as an expression to be evaluated.
Otherwise, it reads whitespace-delimited numbers and operations from the
standard input.
If arguments are passed to rpn, it interprets them as an expression to be
evaluated. Otherwise, it reads whitespace-delimited numbers and operations from
the standard input.
.SH DIAGNOSTICS
In the event of a syntax error, the program will print an
In the event of an error, a debug message will be printed and the program will
exit with the appropriate sysexits.h(3) error code.
If encountering a syntax error, rpn will exit with the appropriate error code
as defined by sysexits.h(3) and print an error message.
.SH CAVEATS
@ -49,7 +44,7 @@ with the IEEE Standard for Floating Point Arithmetic (IEEE 754), floating-point
arithmetic has rounding errors. This is somewhat curbed by using the
machine epsilon as provided by the Rust standard library to which to round
numbers. Because of this, variation is expected in the number of decimal places
the program can handle based on the platform and hardware of any given machine.
rpn can handle based on the platform and hardware of any given machine.
.SH RATIONALE

View File

@ -1,5 +1,4 @@
.\" Copyright (c) 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@ -18,92 +17,62 @@ scrut
.SH DESCRIPTION
Determine if files comply with requirements.
Scrut determines if given files comply with the opted requirements.
.SH OPTIONS
.B -L
.RS
Requires the given files to exist and be symbolic links.
.RE
.B -S
.RS
Requires the given files to exist and be sockets.
.RE
.B -b
.RS
Requires the given files to exist and be block special files.
.RE
requires the given files to exist and be block special files.
.PP
.B -c
.RS
Requires the given files to exist and be character special files.
.RE
requires the given files to exist and be character special files.
.PP
.B -d
.RS
Requires the given files to exist and be directories.
.RE
requires the given files to exist and be directories.
.PP
.B -e
.RS
Requires the given files to exist, and is redundant to any other option.
.RE
requires the given files to exist, and is redundant to any other option.
.PP
.B -e
.RS
Requires the given files to exist and be regular files.
.RE
requires the given files to exist and be regular files.
.PP
.B -g
.RS
Requires the given files to exist and have their set group ID flags set.
.RE
requires the given files to exist and have their set group ID flags set.
.PP
.B -k
.RS
Requires the given files to exist and have their sticky bit set.
.RE
requires the given files to exist and have their sticky bit set.
.PP
.B -p
.RS
Requires the given files to exist and be named pipes.
.RE
requires the given files to exist and be named pipes.
.PP
.B -r
.RS
Requires the given files to exist and be readable.
.RE
requires the given files to exist and be readable.
.PP
.B -u
.RS
Requires the given files to exist and have their set user ID flags set.
.RE
requires the given files to exist and have their set user ID flags set.
.PP
.B -w
.RS
Requires the given files to exist and be writable.
.RE
requires the given files to exist and be writable.
.PP
.B -x
.RS
Requires the given files to exist and be executable.
.RE
requires the given files to exist and be executable.
.PP
.B -L
requires the given files to exist and be symbolic links.
.PP
.B -S
requires the given files to exist and be sockets.
.SH EXIT STATUS
If the given files comply with the specified requirements, the program will exit
successfully. If not, it exits unsuccessfully.
When invoked incorrectly, a debug message will be printed and the program will
exit with the appropriate sysexits.h(3) error code.
Scrut prints a debug message and exits unsuccessfully with the appropriate
sysexits.h(3) error code if invoked incorrectly. Scrut exits successfully if
the given files comply with their requirements and unsuccessfully otherwise.
.SH STANDARDS
The test(1p) utility contains functionality that was broken out into separate
programs. Thus, the scope of this program is narrower than it. Notably, the
Scrut is nearly compatible with POSIX's test utility though it is narrower in
scope. Notably, the
.B -h
option is now invalid and therefore shows usage information instead of being an
alias to the modern

View File

@ -1,5 +1,5 @@
.\" Copyright (c) 20232024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media>
.\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@ -18,27 +18,30 @@ str
.SH DESCRIPTION
Test string arguments.
The tests in this program are equivalent to the functions with the same names in
ctype.h(0p) and are the methods by which string arguments are tested.
Str tests each character in an arbitrary quantity of string arguments against
the function of the same name within ctype(3).
.SH DIAGNOSTICS
If all tests pass, the program will exit with an exit code of 0. If any of the
tests fail, the program will exit unsuccessfully with an error code of 1.
Str exits successfully if all tests pass and unsuccessfully if a test failed.
.PP
Str will exit unsuccessfully if a string is empty, as none of its contents
passed the test.
.PP
Str will print a message to standard error and exit unsuccessfully if used
improperly.
An empty string will cause an unsuccessful exit as none of its contents pass any
tests.
.SH DEPRECATED FEATURES
When invoked incorrectly, a debug message will be printed and the program will
exit with the appropriate sysexits.h(3) error code.
Str used to have an "isvalue" type as an extension to ctype(3). This was
removed in favor of using strcmp(1) to compare strings against the empty string
('').
.SH BUGS
Theres no way of knowing which argument failed the test without re-testing
There's no way of knowing which argument failed the test without re-testing
arguments individually.
.PP
If a character in a string isn't valid ASCII str will exit unsuccessfully.
.SH AUTHOR

View File

@ -1,5 +1,5 @@
.\" Copyright (c) 20232024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media>
.\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@ -18,27 +18,26 @@ strcmp
.SH DESCRIPTION
Check whether string arguments are the same.
.SH DIAGNOSTICS
The program will exit successfully if the strings are identical. Otherwise, it
exits with the value 1 if an earlier string has a greater byte value than a
later string (e.g.
Strcmp checks whether the given strings are the same.
Strcmp exits successfully if the strings are identical. Otherwise, strcmp exits
with the value 1 if an earlier string has a greater byte value than a later
string (e.g.
.R strcmp b a
)
and 255 if an earlier string has a lesser byte value (e.g.
.R strcmp a b
).
When invoked incorrectly, a debug message will be printed and the program will
exit with the appropriate sysexits.h(3) error code.
.SH DIAGNOSTICS
Strcmp will print an error message and exit unsuccessfully with a status
described in sysexits(3) if used incorrectly (given less than two operands).
.SH UNICODE
The program will exit unsuccessfully if the given strings are not identical;
therefore, Unicode strings may need to be normalized if the intent is to check
visual similarity and not byte similarity.
Strcmp will exit unsuccessfully if the given strings are not identical;
Unicode strings may need to be normalized if the intent is to check visual
similarity and not byte similarity.
.SH RATIONALE
@ -46,7 +45,7 @@ The traditional tool for string comparisons in POSIX and other Unix shells has
been test(1). This tool also handles integer comparisons and file scrutiny.
These parts of its functionality have been broken out into multiple utilities.
This programs functionality may be performed on a POSIX-compliant system with
Strcmps functionality may be performed on a POSIX-compliant system with
test(1p).
.SH AUTHOR

View File

@ -1,5 +1,4 @@
.\" Copyright (c) 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@ -21,51 +20,46 @@ swab
.SH USAGE
Swap the latter and former halves of a block of bytes.
.SH OPTIONS
.B -f
.RS
Ignore system call interruptions.
.RE
.B -w
.RS
Configures the word size; that is, the size in bytes of the block size
on which to operate. By default the word size is 2. The word size must be
cleanly divisible by 2, otherwise the block of bytes being processed can't be
halved.
.RE
Swab swaps the latter and former halves of a block of bytes.
.SH EXAMPLES
The following sh(1p) line:
.RS
.R printf 'hello world!\n' | swab
.RE
Produces the following output:
.RS
.R ehll oowlr!d
.RE
.SH OPTIONS
The
.B -f
option ignores system call interruptions.
.PP
The
.B -w
option configures the word size; that is, the size in bytes of the block size
on which to operate. By default the word size is 2. The word size must be
cleanly divisible by 2, otherwise the block of bytes being processed can't be
halved.
.SH DIAGNOSTICS
In the event of an error, a debug message will be printed and the program will
exit with the appropriate sysexits.h(3) error code.
If an error is encountered in input, output, or invocation, a diagnostic
message will be written to standard error and swab will exit with the
appropriate status from sysexits.h(3).
.SH RATIONALE
This program was modeled and named after the
Swab was modeled after the
.R conv=swab
functionality specified in the dd(1p) utility. It additionally allows the word
size to be configured.
This functionality is useful for fixing the endianness of binary files produced
on other machines.
functionality specified in the POSIX dd utility but additionally allows the
word size to be configured.
.PP
Swab is useful for fixing the endianness of binary files produced on other
machines.
.SH COPYRIGHT

View File

@ -1,5 +1,5 @@
.\" Copyright (c) 2022, 2024 DTB <trinity@trinity.moe>
.\" Copyright (c) 20232024 Emma Tebibyte <emma@tebibyte.media>
.\" Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
.\"
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
@ -12,13 +12,14 @@ true \(en do nothing, successfully
.SH DESCRIPTION
Do nothing regardless of operands or standard input.
An exit code of 0 will always be returned.
True does nothing regardless of operands or standard input.
True will always return an exit code of 0.
.SH RATIONALE
In POSIX.1-2017, true(1p) exists for the construction of control flow and loops
based on a success. This implementation functions as described in that standard.
True exists for the construction of control flow and loops based on a success.
True functions as described in POSIX.1-2017.
.SH AUTHOR

View File

@ -22,10 +22,12 @@ use std::{
process::{ Command, exit, Stdio },
};
extern crate sysexits;
extern crate getopt;
extern crate strerror;
extern crate sysexits;
use getopt::{ Opt, Parser };
use strerror::StrError;
use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE };
fn main() {
@ -55,7 +57,7 @@ fn main() {
});
let index = argv[index_arg].parse::<usize>().unwrap_or_else(|e| {
eprintln!("{}: {}: {}.", argv[0], argv[1], e);
eprintln!("{}: {}: {}", argv[0], argv[1], e);
exit(EX_DATAERR);
});
@ -75,13 +77,13 @@ fn main() {
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else( |e| {
eprintln!("{}: {}: {}.", argv[0], argv[command_arg], e);
eprintln!("{}: {}: {}", argv[0], argv[command_arg], e.strerror());
exit(EX_UNAVAILABLE);
});
let field = fields.get(index).unwrap_or_else(|| {
eprintln!(
"{}: {}: No such index in input.",
"{}: {}: No such index in input",
argv[0],
index.to_string(),
);
@ -94,7 +96,7 @@ fn main() {
}
let output = spawned.wait_with_output().unwrap_or_else(|e| {
eprintln!("{}: {}: {}.", argv[0], argv[command_arg], e);
eprintln!("{}: {}: {}", argv[0], argv[command_arg], e.strerror());
exit(EX_IOERR);
});
@ -103,7 +105,7 @@ fn main() {
if replace.pop() != Some(b'\n') { replace = output.stdout; }
let new_field = String::from_utf8(replace).unwrap_or_else(|e| {
eprintln!("{}: {}: {}.", argv[0], argv[command_arg], e);
eprintln!("{}: {}: {}", argv[0], argv[command_arg], e);
exit(EX_IOERR);
});
@ -111,8 +113,8 @@ fn main() {
stdout().write_all(
fields.join(&d.to_string()).as_bytes()
).unwrap_or_else(|e|{
eprintln!("{}: {}.", argv[0], e);
).unwrap_or_else(|e| {
eprintln!("{}: {}", argv[0], e.strerror());
exit(EX_IOERR);
});
}

View File

@ -23,8 +23,10 @@ use std::{
process::{ ExitCode, exit },
};
extern crate strerror;
extern crate sysexits;
use strerror::StrError;
use sysexits::{ EX_DATAERR, EX_IOERR, EX_SOFTWARE };
const LIST: [(u32, &str); 10] = [
@ -49,7 +51,7 @@ fn convert(input: u128) -> Result<(f64, (u32, &'static str)), String> {
let c = match 10_u128.checked_pow(n) {
Some(c) => c,
None => {
return Err(format!("10^{}: Integer overflow.", n.to_string()));
return Err(format!("10^{}: Integer overflow", n.to_string()));
},
};
@ -79,7 +81,7 @@ fn main() -> ExitCode {
f
},
Err(err) => {
eprintln!("{}: {}.", argv[0], err);
eprintln!("{}: {}", argv[0], err);
return ExitCode::from(EX_DATAERR as u8);
},
};
@ -87,7 +89,7 @@ fn main() -> ExitCode {
let (number, prefix) = match convert(n) {
Ok(x) => x,
Err(err) => {
eprintln!("{}: {}.", argv[0], err);
eprintln!("{}: {}", argv[0], err);
return ExitCode::from(EX_SOFTWARE as u8);
},
};
@ -98,7 +100,7 @@ fn main() -> ExitCode {
stdout().write_all(format!("{} {}\n", out, si_prefix).as_bytes())
.unwrap_or_else(|e| {
eprintln!("{}: {}.", argv[0], e);
eprintln!("{}: {}", argv[0], e.strerror());
exit(EX_IOERR);
});
}

View File

@ -106,6 +106,15 @@ oserr(char *s, char *r){
} \
return retval
/* Prints a usage text, in which s is the program being run (i.e. argv[0]), and
* returns an exit status appropriate for a usage error. */
int usage(char *s){
fprintf(stderr, "Usage: %s (-aenu) (-i [input])... (-o [output])...\n", s);
return EX_USAGE;
}
int main(int argc, char *argv[]){
int c;
struct Files files[2]; /* {read, write} */
@ -178,9 +187,12 @@ int main(int argc, char *argv[]){
k = 1;
break;
default:
fprintf(stderr, "Usage: %s (-aenu) (-i [input])..."
" (-o [output])...\n", argv[0]);
retval = EX_USAGE;
retval = usage(argv[0]);
terminate;
}
if(optind != argc){
retval = usage(argv[0]);
terminate;
}

View File

@ -172,7 +172,7 @@ fn eval(
};
} else {
return Err(EvaluationError {
message: format!("{}: Unexpected operation.", op),
message: format!("{}: Unexpected operation", op),
code: EX_DATAERR,
})
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2023 DTB <trinity@trinity.moe>
* Copyright (c) 20232024 DTB <trinity@trinity.moe>
* Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
@ -17,13 +18,15 @@
*/
#include <stdio.h> /* fprintf(3), stderr, NULL */
#include <stdlib.h> /* EXIT_FAILURE */
#include <stdlib.h> /* EXIT_FAILURE, EXIT_SUCCESS */
#include <string.h> /* memset(3), strchr(3) */
#ifndef EX_USAGE
# include <sysexits.h>
#endif
#include <unistd.h> /* access(3), getopt(3), F_OK, R_OK, W_OK, X_OK */
#include <sys/stat.h> /* lstat(3), stat struct, S_ISBLK, S_ISCHR, S_ISDIR,
* S_ISFIFO, S_ISGID, S_ISREG, S_ISLNK, S_ISSOCK,
* S_ISUID, S_ISVTX */
#include <sysexits.h>
static char args[] = "bcdefghkprsuwxLS";
static char ops[(sizeof args) / (sizeof *args)];
@ -57,7 +60,7 @@ int main(int argc, char *argv[]){
argv += optind;
do{ if(access(*argv, F_OK) != 0 || lstat(*argv, &buf) == -1)
return 1; /* doesn't exist or isn't stattable */
return EXIT_FAILURE; /* doesn't exist or isn't stattable */
for(i = 0; ops[i] != '\0'; ++i)
if(ops[i] == 'e')
@ -97,8 +100,8 @@ usage: fprintf(stderr, "Usage: %s (-%s) [file...]\n",
&& !S_ISLNK(buf.st_mode))
|| (ops[i] == 'S'
&& !S_ISSOCK(buf.st_mode)))
return 1;
return EXIT_FAILURE;
}while(*++argv != NULL);
return 0;
return EXIT_SUCCESS;
}

47
src/sleep.rs Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2024 DTB <trinity@trinity.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
use std::{
env::args,
process::ExitCode,
thread::sleep,
time::Duration
};
extern crate sysexits;
use sysexits::EX_USAGE;
fn usage(s: &str) -> ExitCode {
eprintln!("Usage: {} [seconds]", s);
ExitCode::from(EX_USAGE as u8)
}
fn main() -> ExitCode {
let argv = args().collect::<Vec<String>>();
if argv.len() == 2 {
if let Ok(s) = argv[1].parse::<u64>() {
sleep(Duration::from_secs(s));
ExitCode::SUCCESS
} else {
usage(&argv[0])
}
} else {
usage(&argv[0])
}
}

31
src/strerror.rs Normal file
View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
* SPDX-License-Identifier: FSFAP
*
* Copying and distribution of this file, with or without modification, are
* permitted in any medium without royalty provided the copyright notice and
* this notice are preserved. This file is offered as-is, without any warranty.
*/
use std::ffi::{ c_int, c_char, CStr };
pub trait StrError { fn strerror(&self) -> String; }
impl StrError for std::io::Error {
/* wrapper function for use in Rust */
fn strerror(&self) -> String {
/* Get the raw OS error. If its None, what the hell is going on‽ */
let errno = self.raw_os_error().unwrap_or(0) as c_int;
/* Get a CStr from the error message so that its referenced and then
* convert it to an owned value. If the string is not valid UTF-8,
* return that error instead. */
match unsafe { CStr::from_ptr(strerror(errno)) }.to_str() {
Ok(s) => s.to_owned(), // yay!! :D
Err(e) => e.to_string(), // awww :(
}
}
}
/* binding to strerror(3p) */
extern "C" { fn strerror(errnum: c_int) -> *mut c_char; }

10
src/test.rs Normal file
View File

@ -0,0 +1,10 @@
extern crate strerror;
use strerror::raw_message;
fn main() {
stdout.write_all(b"meow\n").unwrap_or_else(|e| {
eprintln!("{}", raw_message(e));
std::process::exit(1);
});
}