pschdir(1): rewrite in Rust
This commit is contained in:
		
							parent
							
								
									f4514592bd
								
							
						
					
					
						commit
						e34e4fad3f
					
				
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
								
							@ -124,8 +124,8 @@ build/bin/npc: src/npc.c build
 | 
			
		||||
 | 
			
		||||
.PHONY: pschdir
 | 
			
		||||
pschdir: build/bin/pschdir
 | 
			
		||||
build/bin/pschdir: src/pschdir.c build
 | 
			
		||||
	$(CC) $(CFLAGS) -o $@ src/pschdir.c
 | 
			
		||||
build/bin/pschdir: src/pschdir.rs build
 | 
			
		||||
	$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/pschdir.rs
 | 
			
		||||
 | 
			
		||||
.PHONY: rpn
 | 
			
		||||
rpn: build/bin/rpn
 | 
			
		||||
 | 
			
		||||
@ -1,48 +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 <errno.h> /* EACCESS, ELOOP, ENAMETOOLONG, ENOENT, ENOTDIR, errno */
 | 
			
		||||
#include <stdio.h> /* fprintf(3), stderr */
 | 
			
		||||
#include <string.h> /* strerror(3) */
 | 
			
		||||
#include <sysexits.h> /* EX_OSERR, EX_NOPERM, EX_NOINPUT, EX_UNAVAILABLE,
 | 
			
		||||
                       * EX_USAGE */
 | 
			
		||||
#include <unistd.h> /* chdir(2) */
 | 
			
		||||
 | 
			
		||||
char *program_name = "pschdir";
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]){
 | 
			
		||||
	if (argc < 3) {
 | 
			
		||||
		fprintf(stderr, "Usage: %s directory command [argument...]\n",
 | 
			
		||||
			argv[0] == NULL ? program_name : argv[0]);
 | 
			
		||||
		return EX_USAGE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(chdir(argv[1]) != 0){
 | 
			
		||||
		fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1], strerror(errno));
 | 
			
		||||
 | 
			
		||||
		switch (errno) {
 | 
			
		||||
			case ENAMETOOLONG:	return EX_OSERR;
 | 
			
		||||
			case EACCES:      	return EX_NOPERM;
 | 
			
		||||
			case ENOENT:
 | 
			
		||||
			case ENOTDIR:     	return EX_NOINPUT;
 | 
			
		||||
			default:          	return EX_UNAVAILABLE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	execvp(argv[2], &argv[2]);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								src/pschdir.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/pschdir.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user