Added program_invocation_name(3), error(3), and perror(3) and used them.

This commit is contained in:
Jonas 'Sortie' Termansen 2011-11-26 11:00:45 +01:00
parent 867627c085
commit d4231b2027
15 changed files with 110 additions and 36 deletions

View File

@ -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 \

View File

@ -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
View 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

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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;
}

View File

@ -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; }
}
}

View File

@ -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++ )
{

View File

@ -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;
}

View File

@ -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;
}
@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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[])

View File

@ -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;
}
}