5 Commits

Author SHA1 Message Date
DTB
e0f9641e93 run(1) works 2024-07-24 23:39:47 -06:00
DTB
f7e0cb5c14 simexec(1): rename to run(1) 2024-07-24 19:04:02 -06:00
DTB
653576b35d simexec(1): Merge in pschdir(1) functionality 2024-07-24 19:02:23 -06:00
DTB
87845ba5bd Merge branch 'pschdir' into simexec 2024-07-24 18:47:09 -06:00
DTB
427e1b9d36 simexec(1): non-functional Rust rewrite 2024-07-24 18:46:05 -06:00
8 changed files with 106 additions and 278 deletions

View File

@@ -31,8 +31,8 @@ RUSTLIBS = --extern getopt=build/o/libgetopt.rlib \
--extern strerror=build/o/libstrerror.rlib
CFLAGS += -I$(SYSEXITS)
all: argued dj false fop hru intcmp mm npc pschdir retval rpn scrut simexec \
str strcmp swab true
.PHONY: all
all: dj false fop hru intcmp mm npc rpn run scrut str strcmp swab true
# keep build/include until bindgen(1) has stdin support
# https://github.com/rust-lang/rust-bindgen/issues/2703
@@ -87,11 +87,6 @@ build/o/libsysexits.rlib: build/include/sysexits.h
build/include/sysexits.h: build $(SYSEXITS)sysexits.h
printf '\043define EXIT_FAILURE 1\n' | cat - $(SYSEXITS)sysexits.h > $@
.PHONY: argued
argued: build/bin/argued
build/bin/argued: src/argued.rs build
$(RUSTC) $(RUSTFLAGS) -o $@ src/argued.rs
.PHONY: dj
dj: build/bin/dj
build/bin/dj: src/dj.c build
@@ -127,31 +122,21 @@ npc: build/bin/npc
build/bin/npc: src/npc.c build
$(CC) $(CFLAGAS) -o $@ src/npc.c
.PHONY: pschdir
pschdir: build/bin/pschdir
build/bin/pschdir: src/pschdir.rs build
$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/pschdir.rs
.PHONY: retval
retval: build/bin/retval
build/bin/retval: src/retval.rs build rustlibs
$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/retval.rs
.PHONY: rpn
rpn: build/bin/rpn
build/bin/rpn: src/rpn.rs build rustlibs
$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/rpn.rs
.PHONY: run
run: build/bin/run
build/bin/run: src/run.rs build
$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/run.rs
.PHONY: scrut
scrut: build/bin/scrut
build/bin/scrut: src/scrut.c build
$(CC) $(CFLAGS) -o $@ src/scrut.c
.PHONY: simexec
simexec: build/bin/simexec
build/bin/simexec: src/simexec.c build
$(CC) $(CFLAGS) -o $@ src/simexec.c
.PHONY: str
str: build/bin/str
build/bin/str: src/str.c build
@@ -171,8 +156,3 @@ 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

View File

@@ -1,28 +0,0 @@
.\" Copyright (c) 20222024 DTB <trinity@trinity.moe>
.\"
.\" 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 ARGUED 1 2024-07-23 "Harakit-overgrown X.X.X"
.SH NAME
argued \(en check for arguments
.\"
.SH DESCRIPTION
.BR argued (1)
exits successfully if any arguments are provided, and unsuccessfully
otherwise.
.\"
.SH AUTHOR
Written by DTB
.MT trinity@trinity.moe
.ME .
.\"
.SH COPYRIGHT
This work is marked with CC0 1.0. To see a copy of this license, visit
<http://creativecommons.org/publicdomain/zero/1.0>.
.\"
.SH SEE ALSO
.BR test (1)

View File

@@ -1,28 +0,0 @@
/*
* Copyright (c) 2022_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 };
fn main() -> ExitCode {
let argv = args().collect::<Vec<String>>();
match argv.len() {
0 | 1 => ExitCode::FAILURE,
_ => ExitCode::SUCCESS
}
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright (c) 2023_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, io::Error, process::{ Command, ExitCode } };
extern crate strerror;
use strerror::StrError;
extern crate sysexits;
use sysexits::{ EX_UNAVAILABLE, EX_USAGE };
fn error(p: &str, n: &str, e: Error) -> ExitCode {
eprintln!("{}: {}: {}", p, n, e.strerror());
ExitCode::from(EX_UNAVAILABLE as u8)
}
fn main() -> ExitCode {
let argv = args().collect::<Vec<String>>();
if argv.len() < 3 {
eprintln!("Usage: {} directory command [argument]", argv[0]);
return ExitCode::from(EX_USAGE as u8);
}
let cmdargs = argv.iter().clone().skip(3).collect::<Vec<&String>>();
match Command::new(argv[2].clone())
.current_dir(argv[1].clone())
.args(cmdargs)
.spawn() {
Ok(mut child) => match child.wait() {
Ok(status) => {
match status.code() {
Some(code) => ExitCode::from(code as u8),
None => {
eprintln!("{}: {}: process terminated by signal",
argv[0], argv[2]);
ExitCode::FAILURE
}
}
},
Err(e) => error(&argv[0], &argv[2], e)
},
Err(e) => error(&argv[0], &argv[2], e)
}
}

View File

@@ -1,39 +0,0 @@
/*
* 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 };
extern crate sysexits;
use sysexits::EX_USAGE;
fn usage(s: &str) -> ExitCode {
eprintln!("Usage: {} status", s);
ExitCode::from(EX_USAGE)
}
fn main() -> ExitCode {
let argv = args().collect::<Vec<String>>();
match argv.len() {
2 => match argv[1].parse::<u8>() {
Ok(e) => ExitCode::from(e),
_ => usage(&argv[0])
},
_ => usage(&argv[0])
}
}

99
src/run.rs Normal file
View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 20222024 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,
io::Error,
os::unix::process::CommandExt,
process::{ Command, ExitCode }
};
extern crate getopt;
use getopt::GetOpt;
extern crate strerror;
use strerror::StrError;
extern crate sysexits;
use sysexits::{ EX_UNAVAILABLE, EX_USAGE };
fn error(p: &str, n: &str, e: Error) -> ExitCode {
eprintln!("{}: {}: {}", p, n, e.strerror());
ExitCode::from(EX_UNAVAILABLE as u8)
}
fn usage(s: &str) -> ExitCode {
eprintln!("Usage: {} command [argument...]", s);
ExitCode::from(EX_USAGE as u8)
}
fn main() -> ExitCode {
let argv = args().collect::<Vec<String>>();
let mut optind = 1;
/* arg0 is None if no argv[0] is meant to be given (argc will be 0),
* however I don't know how to do this in Rust, so the option is currently
* meaningless. -z will set this to None. */
let mut arg0: Option<String> = Some(String::default());
let mut dir = String::from("."); // $PWD for command
while let Some(opt) = argv.getopt("C:n:z") {
match opt.opt() {
// Consistent with precedent; git, make, tar, etc.
Ok("C") => dir = opt.arg().unwrap(),
Ok("n") => arg0 = Some(opt.arg().unwrap()),
// Ok("z") => arg0 = None,
_ => { return usage(&argv[0]); }
}
optind = opt.ind();
}
if argv.len() - optind < 1 { return usage(&argv[0]); }
let mut cmd = Command::new(argv[optind].clone());
cmd.current_dir(dir.clone());
match arg0 {
Some(a) if a != String::default() => { cmd.arg0(a); },
_ => () // TODO: argv[0]==NULL support
}
if argv.len() - optind > 1 { // there are arguments
let cmdargs = argv
.iter()
.clone()
.skip(optind + 1)
.collect::<Vec<&String>>();
cmd.args(cmdargs);
}
match cmd.spawn() {
Ok(mut child) => match child.wait() {
Ok(status) => match status.code() {
Some(code) => ExitCode::from(code as u8),
None => {
eprintln!("{}: {}: process terminated by signal",
argv[0], argv[2]);
ExitCode::FAILURE
}
},
Err(e) => error(&argv[0], &argv[optind], e)
},
Err(e) => error(&argv[0], &argv[optind], e)
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright (c) 20222024 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 <stdio.h> /* fprintf(3), NULL */
#include <unistd.h> /* execv(3), */
#include <sysexits.h> /* EX_USAGE */
char *program_name = "simexec";
int main(int argc, char *argv[]){
if (argc < 2) {
fprintf(stderr, "Usage: %s binary argv...\n",
argv[0] == NULL ? program_name : argv[0]
);
return EX_USAGE;
}
execv(argv[1], &argv[2]);
}

View File

@@ -1,61 +0,0 @@
/*
* 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);
}
}
}