From d4231b2027a4e588b1742c70bd04e4a017e32332 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sat, 26 Nov 2011 11:00:45 +0100 Subject: [PATCH] Added program_invocation_name(3), error(3), and perror(3) and used them. --- libmaxsi/Makefile | 1 + libmaxsi/c/hsrc/errno.h | 2 ++ libmaxsi/c/hsrc/error.h | 36 ++++++++++++++++++++++++++++++++++++ libmaxsi/c/hsrc/stdio.h | 2 +- libmaxsi/init.cpp | 12 +++++++++++- libmaxsi/io.cpp | 22 ++++++++++++++++++++++ utils/cat.cpp | 9 +++++---- utils/cp.cpp | 13 +++++-------- utils/editor.cpp | 11 ++++++----- utils/help.cpp | 4 ++++ utils/init.cpp | 12 +++++------- utils/kill.cpp | 3 ++- utils/ls.cpp | 5 +++-- utils/mxsh.cpp | 11 +++++------ utils/rm.cpp | 3 ++- 15 files changed, 110 insertions(+), 36 deletions(-) create mode 100644 libmaxsi/c/hsrc/error.h diff --git a/libmaxsi/Makefile b/libmaxsi/Makefile index 9e241ce2..9408e50b 100644 --- a/libmaxsi/Makefile +++ b/libmaxsi/Makefile @@ -40,6 +40,7 @@ c/h/wctype.h \ c/h/features.h \ c/h/string.h \ c/h/errno.h \ +c/h/error.h \ c/h/sys/readdirents.h \ c/h/sys/stat.h \ c/h/sys/types.h \ diff --git a/libmaxsi/c/hsrc/errno.h b/libmaxsi/c/hsrc/errno.h index fa35f953..82174679 100644 --- a/libmaxsi/c/hsrc/errno.h +++ b/libmaxsi/c/hsrc/errno.h @@ -32,6 +32,8 @@ __BEGIN_DECLS @include(errno_decl.h) @include(errno_values.h) +extern char* program_invocation_name; + __END_DECLS #endif diff --git a/libmaxsi/c/hsrc/error.h b/libmaxsi/c/hsrc/error.h new file mode 100644 index 00000000..43ad6467 --- /dev/null +++ b/libmaxsi/c/hsrc/error.h @@ -0,0 +1,36 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + This file is part of LibMaxsi. + + LibMaxsi is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + LibMaxsi 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 Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with LibMaxsi. If not, see . + + error.h + Error reporting functions. + +******************************************************************************/ + +#ifndef _ERROR_H +#define _ERROR_H 1 + +#include + +__BEGIN_DECLS + +void error(int status, int errnum, const char *format, ...); + +__END_DECLS + +#endif diff --git a/libmaxsi/c/hsrc/stdio.h b/libmaxsi/c/hsrc/stdio.h index e7e286a5..25aa0a45 100644 --- a/libmaxsi/c/hsrc/stdio.h +++ b/libmaxsi/c/hsrc/stdio.h @@ -76,6 +76,7 @@ extern FILE* stderr; #define stdout stdout #define stderr stderr +extern void perror(const char* s); extern int printf(const char* restrict format, ...); /* TODO: These are not implemented in libmaxsi/sortix yet. */ @@ -141,7 +142,6 @@ extern ssize_t getline(char** restrict lineptr, size_t* restrict n, FILE* restri extern void clearerr(FILE* stream); extern void flockfile(FILE* file); extern void funlockfile(FILE* file); -extern void perror(const char* s); extern void rewind(FILE* stream); extern void setbuf(FILE* restrict stream, char* restrict buf); diff --git a/libmaxsi/init.cpp b/libmaxsi/init.cpp index 7047ec0e..3bf01e2f 100644 --- a/libmaxsi/init.cpp +++ b/libmaxsi/init.cpp @@ -25,13 +25,23 @@ #include "platform.h" #include "signal.h" +#include "string.h" +#include "io.h" namespace Maxsi { + extern "C" { char program_invocation_name_data[256] = ""; } + extern "C" { char* program_invocation_name = program_invocation_name_data; } + extern "C" void init_error_functions(); - extern "C" void initialize_standard_library() + extern "C" void initialize_standard_library(int argc, char* argv[]) { + if ( argc ) + { + String::Copy(program_invocation_name, argv[0]); + } + // Initialize stuff such as errno. init_error_functions(); diff --git a/libmaxsi/io.cpp b/libmaxsi/io.cpp index cd907fe1..db95beb6 100644 --- a/libmaxsi/io.cpp +++ b/libmaxsi/io.cpp @@ -29,6 +29,10 @@ #include "string.h" #include #include +#include +#include +#include +#include namespace Maxsi { @@ -76,6 +80,24 @@ namespace Maxsi return (int) result; } + extern "C" void error(int status, int errnum, const char *format, ...) + { + printf("%s: ", program_invocation_name); + + va_list list; + va_start(list, format); + size_t result = Maxsi::Format::Virtual(PrintCallback, NULL, format, list); + va_end(list); + + printf(": %s\n", strerror(errnum)); + if ( status ) { exit(status); } + } + + extern "C" void perror(const char* s) + { + error(0, errno, "%s", s); + } + extern "C" ssize_t read(int fd, void* buf, size_t count) { return SysRead(fd, buf, count); diff --git a/utils/cat.cpp b/utils/cat.cpp index e98475b5..0b525f8c 100644 --- a/utils/cat.cpp +++ b/utils/cat.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include int cat(int argc, char* argv[]) @@ -10,14 +11,14 @@ int cat(int argc, char* argv[]) int result = 0; int outfd = open("/dev/tty", O_WRONLY | O_APPEND); - if ( outfd < 0 ) { printf("%s: %s: %s\n", argv[0], "/dev/tty", strerror(errno)); return 1; } + if ( outfd < 0 ) { error(0, errno, "%s", "/dev/tty"); return 1; } for ( int i = 1; i < argc; i++ ) { int fd = open(argv[i], O_RDONLY); if ( fd < 0 ) { - printf("%s: %s: %s\n", argv[0], argv[i], strerror(errno)); + error(0, errno, "%s", argv[i]); result = 1; continue; } @@ -30,13 +31,13 @@ int cat(int argc, char* argv[]) if ( bytesread == 0 ) { break; } if ( bytesread < 0 ) { - printf("%s: %s: %s\n", argv[0], argv[i], strerror(errno)); + error(0, errno, "read: %s", argv[i]); result = 1; break; } if ( writeall(outfd, buffer, bytesread) ) { - printf("%s: /dev/tty: %s\n", argv[0], strerror(errno)); + error(0, errno, "write: %s", argv[i]); result = 1; break; } diff --git a/utils/cp.cpp b/utils/cp.cpp index acbbba4f..912bebbd 100644 --- a/utils/cp.cpp +++ b/utils/cp.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include const char* basename(const char* path) @@ -20,7 +21,7 @@ int main(int argc, char* argv[]) char tobuffer[256]; int fromfd = open(frompath, O_RDONLY); - if ( fromfd < 0 ) { printf("%s: %s: %s\n", argv[0], frompath, strerror(errno)); return 1; } + if ( fromfd < 0 ) { error(1, errno, "%s", frompath); return 1; } int tofd = open(topath, O_WRONLY | O_TRUNC | O_CREAT, 0777); if ( tofd < 0 ) @@ -34,11 +35,7 @@ int main(int argc, char* argv[]) tofd = open(topath, O_WRONLY | O_TRUNC | O_CREAT, 0777); } - if ( tofd < 0 ) - { - printf("%s: %s: %s\n", argv[0], topath, strerror(errno)); - return 1; - } + if ( tofd < 0 ) { error(1, errno, "%s", topath); return 1; } } while ( true ) @@ -46,8 +43,8 @@ int main(int argc, char* argv[]) const size_t BUFFER_SIZE = 4096; char buffer[BUFFER_SIZE]; ssize_t bytesread = read(fromfd, buffer, BUFFER_SIZE); - if ( bytesread < 0 ) { printf("%s: %s: %s\n", argv[0], frompath, strerror(errno)); return 1; } + if ( bytesread < 0 ) { error(1, errno, "read: %s", frompath); return 1; } if ( bytesread == 0 ) { return 0; } - if ( writeall(tofd, buffer, bytesread) ) { printf("%s: %s: %s\n", argv[0], topath, strerror(errno)); return 1; } + if ( writeall(tofd, buffer, bytesread) ) { error(1, errno, "write: %s", topath); return 1; } } } diff --git a/utils/editor.cpp b/utils/editor.cpp index 66c325be..bbca7b5c 100644 --- a/utils/editor.cpp +++ b/utils/editor.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -202,7 +203,7 @@ unsigned confirmquit() bool savetofile(const char* path) { int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0777); - if ( fd < 0 ) { printf("%s: %s\n", path, strerror(errno)); return false; } + if ( fd < 0 ) { error(0, errno, "%s", path); return false; } for ( unsigned y = 0; y < numlines; y++ ) { @@ -210,10 +211,10 @@ bool savetofile(const char* path) buffers[y][len] = '\n'; bool result = !writeall(fd, buffers[y], len+1); buffers[y][len] = 0; - if ( !result ) { printf("%s: %s\n", path, strerror(errno)); close(fd); return false; } + if ( !result ) { error(0, errno, "write: %s", path); close(fd); return false; } } - if ( close(fd) ) { printf("%s: %s\n", path, strerror(errno)); return false; } + if ( close(fd) ) { error(0, errno, "close: %s", path); return false; } return true; } @@ -277,7 +278,7 @@ retry: bool loadfromfile(const char* path) { int fd = open(path, O_RDONLY, 0777); - if ( fd < 0 ) { printf("%s: %s\n", path, strerror(errno)); return false; } + if ( fd < 0 ) { error(0, errno, "%s", path); return false; } clearbuffers(); @@ -288,7 +289,7 @@ bool loadfromfile(const char* path) while ( !done ) { ssize_t bytesread = read(fd, buffer, BUFFER_SIZE); - if ( bytesread < 0 ) { printf("%s: %s\n", path, strerror(errno)); close(fd); return false; } + if ( bytesread < 0 ) { error(0, errno, "read: %s", path); close(fd); return false; } if ( bytesread == 0 ) { break; } for ( ssize_t i = 0; i < bytesread; i++ ) { diff --git a/utils/help.cpp b/utils/help.cpp index c34d3b7d..5668541a 100644 --- a/utils/help.cpp +++ b/utils/help.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include @@ -12,5 +14,7 @@ int main(int argc, char* argv[]) Maxsi::Process::Execute(programname, 2, newargv); + error(1, errno, "%s", programname); + return 1; } diff --git a/utils/init.cpp b/utils/init.cpp index b9aaf4c4..d9f0b54f 100644 --- a/utils/init.cpp +++ b/utils/init.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,8 @@ int child() Process::Execute(programname, 1, newargv); + error(0, errno, "%s", programname); + return 2; } @@ -35,13 +38,8 @@ int main(int argc, char* argv[]) // Reset the terminal's color and the rest of it. printf("\r\e[m\e[J"); - pid_t childpid = Process::Fork(); - - if ( childpid < 0 ) - { - printf("init: fork: %s\n", strerror(errno)); - return 2; - } + pid_t childpid = Process::Fork(); + if ( childpid < 0 ) { perror("fork"); return 2; } return ( childpid == 0 ) ? child() : parent(childpid); } diff --git a/utils/kill.cpp b/utils/kill.cpp index 08434401..8d46461a 100644 --- a/utils/kill.cpp +++ b/utils/kill.cpp @@ -3,6 +3,7 @@ #include #include #include +#include int usage() { @@ -29,7 +30,7 @@ int main(int argc, char* argv[]) pid_t pid = atoi(argv[i]); if ( kill(pid, signum) ) { - printf("kill: (%u): %s\n", pid, strerror(errno)); + error(0, errno, "(%u)", pid); result |= 1; } } diff --git a/utils/ls.cpp b/utils/ls.cpp index c903359a..8253deef 100644 --- a/utils/ls.cpp +++ b/utils/ls.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -12,7 +13,7 @@ using namespace Maxsi; int ls(const char* path) { int fd = open(path, O_SEARCH | O_DIRECTORY); - if ( fd < 0 ) { printf("ls: %s: %s\n", path, strerror(errno)); return 2; } + if ( fd < 0 ) { error(2, errno, "%s", path); return 2; } const size_t BUFFER_SIZE = 512; char buffer[BUFFER_SIZE]; @@ -25,7 +26,7 @@ int ls(const char* path) { if ( readdirents(fd, dirent, BUFFER_SIZE) ) { - printf("ls: %s: %s\n", path, strerror(errno)); + error(2, errno, "readdirents: %s", path); return 1; } diff --git a/utils/mxsh.cpp b/utils/mxsh.cpp index ec4915fb..1bb68619 100644 --- a/utils/mxsh.cpp +++ b/utils/mxsh.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -95,14 +96,14 @@ void command() if ( 1 < argc ) { newdir = argv[1]; } if ( chdir(newdir) ) { - printf("sh: cd: %s: %s\n", newdir, strerror(errno)); + error(0, errno, "cd: %s", newdir); status = 1; } return; } pid_t child = fork(); - if ( child < 0 ) { printf("sh: fork failed: %s\n", strerror(errno)); return; } + if ( child < 0 ) { perror("fork"); status = 1; return; } if ( child != 0 ) { pid_t childpid = wait(&status); @@ -115,7 +116,7 @@ void command() { const char* file = argv[argc-1]; int outfd = open(file, O_CREAT | O_WRONLY | O_TRUNC | O_APPEND); - if ( outfd < 0 ) { printf("%s: %s\n", file, strerror(errno)); exit(127); } + if ( outfd < 0 ) { error(127, errno, "%s", file); exit(127); } close(1); dup(outfd); close(outfd); @@ -127,9 +128,7 @@ void command() Process::Execute(argv[0], argc, argv); // This is clever. This only happens if the program didn't change. - printf("%s: %s\n", argv[0], strerror(errno)); - - exit(127); + error(127, errno, "%s", argv[0]); } int main(int argc, char* argv[]) diff --git a/utils/rm.cpp b/utils/rm.cpp index 0ae402c9..0df66688 100644 --- a/utils/rm.cpp +++ b/utils/rm.cpp @@ -2,6 +2,7 @@ #include #include #include +#include int main(int argc, char* argv[]) { @@ -13,7 +14,7 @@ int main(int argc, char* argv[]) { if ( unlink(argv[i]) ) { - printf("%s: cannot remove %s: %s\n", argv[0], argv[i], strerror(errno)); + error(0, errno, "cannot remove %s", argv[i]); result = 1; } }