mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Added program_invocation_name(3), error(3), and perror(3) and used them.
This commit is contained in:
parent
867627c085
commit
d4231b2027
15 changed files with 110 additions and 36 deletions
|
@ -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 \
|
||||
|
|
|
@ -32,6 +32,8 @@ __BEGIN_DECLS
|
|||
@include(errno_decl.h)
|
||||
@include(errno_values.h)
|
||||
|
||||
extern char* program_invocation_name;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
36
libmaxsi/c/hsrc/error.h
Normal file
36
libmaxsi/c/hsrc/error.h
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
error.h
|
||||
Error reporting functions.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _ERROR_H
|
||||
#define _ERROR_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
void error(int status, int errnum, const char *format, ...);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#include "string.h"
|
||||
#include <sys/readdirents.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <error.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <libmaxsi/sortix-keyboard.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
13
utils/cp.cpp
13
utils/cp.cpp
|
@ -2,6 +2,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <string.h>
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <libmaxsi/platform.h>
|
||||
#include <libmaxsi/sortix-keyboard.h>
|
||||
|
||||
|
@ -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++ )
|
||||
{
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <libmaxsi/platform.h>
|
||||
#include <libmaxsi/process.h>
|
||||
|
||||
|
@ -12,5 +14,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
Maxsi::Process::Execute(programname, 2, newargv);
|
||||
|
||||
error(1, errno, "%s", programname);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <fcntl.h>
|
||||
#include <libmaxsi/platform.h>
|
||||
#include <libmaxsi/process.h>
|
||||
|
@ -23,6 +24,8 @@ int child()
|
|||
|
||||
Process::Execute(programname, 1, newargv);
|
||||
|
||||
error(0, errno, "%s", programname);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -36,12 +39,7 @@ int main(int argc, char* argv[])
|
|||
printf("\r\e[m\e[J");
|
||||
|
||||
pid_t childpid = Process::Fork();
|
||||
|
||||
if ( childpid < 0 )
|
||||
{
|
||||
printf("init: fork: %s\n", strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
if ( childpid < 0 ) { perror("fork"); return 2; }
|
||||
|
||||
return ( childpid == 0 ) ? child() : parent(childpid);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <sys/readdirents.h>
|
||||
#include <libmaxsi/platform.h>
|
||||
#include <libmaxsi/process.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <fcntl.h>
|
||||
#include <libmaxsi/platform.h>
|
||||
#include <libmaxsi/process.h>
|
||||
|
@ -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[])
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue