moved file resolution code to a shared library
This commit is contained in:
		
							parent
							
								
									3a410edddc
								
							
						
					
					
						commit
						7f5e532216
					
				
							
								
								
									
										16
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								Makefile
									
									
									
									
									
								
							| @ -7,10 +7,10 @@ | ||||
| 
 | ||||
| .POSIX: | ||||
| 
 | ||||
| PREFIX=/usr/local/bin | ||||
| CFLAGS=-O3 -s -Wl,-z,noseparate-code,-z,nosectionheader -flto | ||||
| PREFIX=/usr/local | ||||
| CFLAGS=-O3 -s -Wl,-z,noseparate-code,-z,nosectionheader -flto -Lbuild -lyac | ||||
| 
 | ||||
| build: build_dir cat false true | ||||
| build: build_dir lib cat false tail true | ||||
| 
 | ||||
| clean: build_dir | ||||
| 	rm -rf build/ | ||||
| @ -21,12 +21,20 @@ cat: build_dir | ||||
| false: build_dir | ||||
| 	cc $(CFLAGS) -o build/false src/false.c | ||||
| 
 | ||||
| tail: build_dir | ||||
| 	cc $(CFLAGS) -o build/tail src/tail.c | ||||
| 
 | ||||
| true: build_dir | ||||
| 	cc $(CFLAGS) -o build/true src/true.c | ||||
| 
 | ||||
| lib: | ||||
| 	cc -c -fPIC $(CFLAGS) -o build/yac.o src/yac.c | ||||
| 	cc $(CFLAGS) -shared -o build/libyac.so build/yac.o | ||||
| 
 | ||||
| build_dir: | ||||
| 	mkdir -p build | ||||
| 
 | ||||
| install: build | ||||
| 	mkdir -p $(PREFIX) | ||||
| 	cp -f build/* $(PREFIX)/ | ||||
| 	cp -f build/*.so $(PREFIX)/lib/ | ||||
| 	cp -f build/* $(PREFIX)/bin/ | ||||
|  | ||||
							
								
								
									
										56
									
								
								src/cat.c
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								src/cat.c
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | ||||
| /*
 | ||||
|  * Copyright (c) 2023 Emma Tebibyte | ||||
|  * Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media> | ||||
|  * SPDX-License-Identifier: AGPL-3.0-or-later | ||||
|  * | ||||
|  * This file is part of YAC coreutils. | ||||
| @ -25,6 +25,8 @@ | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "yac.h" | ||||
| 
 | ||||
| void cat(FILE *file, bool u) { | ||||
| 	int byte = 0; /* variable for storing bytes as they are read */ | ||||
| 	int p = 0; /* index counter for bytes in buffered reading */ | ||||
| @ -89,55 +91,13 @@ int main(int argc, char *argv[]) { | ||||
| 	} | ||||
| 	 | ||||
| 	FILE *file; | ||||
| 	struct stat stats; | ||||
| 
 | ||||
| 	for (i = optind; i < argc; i++) { | ||||
| 		if (argv[i][0] == '-') { | ||||
| 			switch (argv[i][1]) { | ||||
| 				case '\0': | ||||
| 					file = stdin; | ||||
| 					break; | ||||
| 				default: | ||||
| 					continue; | ||||
| 			} | ||||
| 		} else if (stat(argv[i], &stats) == 0 && S_ISDIR(stats.st_mode)) { | ||||
| 			fprintf(stderr, "%s: %s: Is a directory.\n", argv[0], argv[i]); | ||||
| 			return EX_NOINPUT; | ||||
| 		} else if ((file = fopen(argv[i], "r")) == NULL) { | ||||
| 			switch (errno) { | ||||
| 				case EACCES: | ||||
| 					fprintf(stderr, "%s: %s: Permission denied.\n", argv[0], argv[i]); | ||||
| 					return EX_NOINPUT; | ||||
| 				case EISDIR: | ||||
| 					fprintf(stderr, "%s: %s: Is a directory.\n", argv[0], argv[i]); | ||||
| 					return EX_NOINPUT; | ||||
| 				case ELOOP: | ||||
| 					fprintf( | ||||
| 						stderr, | ||||
| 						"%s: %s: Is a symbolic link loop.\n", | ||||
| 						argv[0], | ||||
| 						argv[i] | ||||
| 					); | ||||
| 					return EX_UNAVAILABLE; | ||||
| 				case EMFILE: | ||||
| 					fprintf(stderr, "%s: Internal error.\n", argv[0]); | ||||
| 					return EX_SOFTWARE; | ||||
| 				case ENOENT: case ENOTDIR: case ENXIO: | ||||
| 					fprintf( | ||||
| 						stderr, | ||||
| 						"%s: %s: No such file or directory.\n", | ||||
| 						argv[0], | ||||
| 						argv[i] | ||||
| 					); | ||||
| 					return EX_NOINPUT; | ||||
| 				default: | ||||
| 					fprintf(stderr, "%s: Unknown error.\n", argv[0]); | ||||
| 					return EX_UNAVAILABLE; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		cat(file, u); | ||||
| 		if (file != stdin) { fclose(file); } | ||||
| 		file = rpath(argv[0], argv[i]); | ||||
| 		if (file != NULL) { | ||||
| 			cat(file, u); | ||||
| 			if (file != stdin) { fclose(file); } | ||||
| 		} else { continue; } | ||||
| 	} | ||||
| 
 | ||||
| 	return EX_OK; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /*
 | ||||
|  * Copyright (c) 2023 Emma Tebibyte | ||||
|  * Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media> | ||||
|  * SPDX-License-Identifier: AGPL-3.0-or-later | ||||
|  * | ||||
|  * This file is part of YAC coreutils. | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /*
 | ||||
|  * Copyright (c) 2023 Emma Tebibyte | ||||
|  * Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media> | ||||
|  * SPDX-License-Identifier: AGPL-3.0-or-later | ||||
|  * | ||||
|  * This file is part of YAC coreutils. | ||||
|  | ||||
							
								
								
									
										77
									
								
								src/yac.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/yac.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| /*
 | ||||
|  * Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media> | ||||
|  * SPDX-License-Identifier: AGPL-3.0-or-later | ||||
|  * | ||||
|  * This file is part of YAC coreutils. | ||||
|  * | ||||
|  * YAC coreutils 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. | ||||
|  *  | ||||
|  * YAC coreutils 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> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <sysexits.h> | ||||
| #include <sys/stat.h> | ||||
| 
 | ||||
| /* Resolve a file from a path */ | ||||
| FILE *rpath(char *argv0, char *path) {  | ||||
| 	struct stat stats; | ||||
| 	FILE *file; | ||||
| 
 | ||||
| 	if (path[0] == '-') { | ||||
| 		switch (path[1]) { | ||||
| 			case '\0': | ||||
| 				file = stdin; | ||||
| 				break; | ||||
| 			default: | ||||
| 				file = NULL; | ||||
| 				break; | ||||
| 		} | ||||
| 	} else if (stat(path, &stats) == 0 && S_ISDIR(stats.st_mode)) { | ||||
| 		fprintf(stderr, "%s: %s: Is a directory.\n", argv0, path); | ||||
| 		exit(EX_NOINPUT); | ||||
| 	} else if ((file = fopen(path, "r")) == NULL) { | ||||
| 		switch (errno) { | ||||
| 			case EACCES: | ||||
| 				fprintf(stderr, "%s: %s: Permission denied.\n", argv0, path); | ||||
| 				exit(EX_NOINPUT); | ||||
| 			case EISDIR: | ||||
| 				fprintf(stderr, "%s: %s: Is a directory.\n", argv0, path); | ||||
| 				exit(EX_NOINPUT); | ||||
| 			case ELOOP: | ||||
| 				fprintf( | ||||
| 					stderr, | ||||
| 					"%s: %s: Is a symbolic link loop.\n", | ||||
| 					argv0, | ||||
| 					path | ||||
| 				); | ||||
| 				exit(EX_UNAVAILABLE); | ||||
| 			case EMFILE: | ||||
| 				fprintf(stderr, "%s: Internal error.\n", argv0); | ||||
| 				exit(EX_SOFTWARE); | ||||
| 			case ENOENT: case ENOTDIR: case ENXIO: | ||||
| 				fprintf( | ||||
| 					stderr, | ||||
| 					"%s: %s: No such path or directory.\n", | ||||
| 					argv0, | ||||
| 					path | ||||
| 				); | ||||
| 				exit(EX_NOINPUT); | ||||
| 			default: | ||||
| 				fprintf(stderr, "%s: Unknown error.\n", argv0); | ||||
| 				exit(EX_UNAVAILABLE); | ||||
| 		} | ||||
| 	} | ||||
| 	return file; | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/yac.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/yac.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| /*
 | ||||
|  * Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media> | ||||
|  * SPDX-License-Identifier: AGPL-3.0-or-later | ||||
|  * | ||||
|  * This file is part of YAC coreutils. | ||||
|  * | ||||
|  * YAC coreutils 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. | ||||
|  *  | ||||
|  * YAC coreutils 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/.
 | ||||
|  */ | ||||
| 
 | ||||
| #ifndef YAC_H | ||||
| #define YAC_H | ||||
| 
 | ||||
| FILE *rpath(char *argv0, char *path); | ||||
| 
 | ||||
| #endif | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user