Compare commits

..

1 Commits

Author SHA1 Message Date
DTB
a28542e5e5
zn(1): proof of concept 2024-07-29 22:32:13 -06:00
3 changed files with 121 additions and 3 deletions

View File

@ -171,3 +171,8 @@ build/bin/swab: src/swab.rs build rustlibs
true: build/bin/true
build/bin/true: src/true.c build
$(CC) $(CFLAGS) -o $@ src/true.c
.PHONY: zn
zn: build/bin/zn
build/bin/zn: src/zn.c build
$(CC) $(CFLAGS) -o $@ src/zn.c

58
README
View File

@ -1,9 +1,61 @@
overgrown - trinity's harakit workshop
“Seek not to walk the path of the masters; seek what they sought.”
Matsuo Basho
simple build, no dependencies except rust
The Bonsai harakit utilities are a replacement for standard POSIX utilities
which aim to fill its niche while expanding on their capabilities. These new
tools are the result of the careful examination of the current state of POSIX
and Unix utilies. The Unix Philosophy of “do one thing and do it well” are their
core but they avoid clinging to the past.
The era of the original Unix tools has been long and fruitful, but they have
their flaws. This project originated from frustrations with the way certain
tools work and how other projects that extend POSIX dont make anything better.
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
harakit utilities will intentionally discourage use of the shell for purposes
beyond its scope.
See docs/ for more on the specific utilities currently implemented.
Building
Harakit utilities require a POSIX-compliant environment to compile, including a
C compiler and preprocessor (cc(1) and cpp(1) by default), an edition 2023 Rust
compiler (rustc(1) by default), bindgen(1), and a POSIX-compliant make(1)
utility.
To build and install:
# pkg_add rust rust-bindgen
$ make
$ 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 build and distributable 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>

61
src/zn.c Normal file
View File

@ -0,0 +1,61 @@
/*
* 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/.
*/
#include <limits.h> /* _POSIX_MAX_CANON */
#include <stdio.h> /* fgets(3) */
#include <string.h> /* strtok(3) */
#include <sysexits.h> /* EX_OSERR */
#include <unistd.h> /* fork(2) */
#include <sys/wait.h> /* wait(2), WIFEXITED, WEXITSTATUS */
static char *sep = " \t\v\n";
static char **
get_args(char *s) {
size_t c = 0;
static char *v[10];
if ((v[c] = strtok(s, sep)) == NULL) { return NULL; }
while (++c < sizeof v / sizeof *v) {
if ((v[c] = strtok(NULL, sep)) == NULL) { return v; }
}
return v;
}
static char *
get_line(FILE *stream) {
static char buffer[_POSIX_MAX_CANON];
return fgets(buffer, sizeof *buffer * MAX_CANON, stream);
}
int main(int argc, char *argv[]) {
char **a;
char *s;
while ((s = get_line(stdin)) != NULL) {
a = get_args(s);
switch (fork()) {
case -1: perror(argv[0]); return EX_OSERR;
case 0: execvp(a[0], a);
default: (void)wait(NULL);
}
}
}