2019-03-17 14:42:00 +00:00
|
|
|
/** @file
|
1988-06-22 16:57:09 +00:00
|
|
|
In and output, error messages, etc.
|
|
|
|
*/
|
|
|
|
|
1994-06-24 11:31:16 +00:00
|
|
|
/* $Id$ */
|
1988-06-22 16:57:09 +00:00
|
|
|
|
2019-03-22 19:15:40 +00:00
|
|
|
#include <fcntl.h>
|
1988-06-22 16:57:09 +00:00
|
|
|
#include <stdio.h>
|
1995-08-17 14:36:05 +00:00
|
|
|
#include <stdarg.h>
|
2019-03-22 19:15:40 +00:00
|
|
|
#include <unistd.h>
|
1988-06-22 16:57:09 +00:00
|
|
|
|
|
|
|
#include "logging.h"
|
|
|
|
#include "global.h"
|
|
|
|
#include "mem.h"
|
2019-03-17 14:42:00 +00:00
|
|
|
#include "io.h"
|
|
|
|
#include "warn.h"
|
|
|
|
#include "log.h"
|
1988-06-22 16:57:09 +00:00
|
|
|
#include "linfil.h"
|
Cut down some clang warnings
Edit C code to reduce warnings from clang. Most warnings are for
implicit declarations of functions, but some warnings want me to add
parentheses or curly braces, or to cast arguments for printf().
Make a few other changes, like declaring float_cst() in h/con_float to
be static, and using C99 bool in ego/ra/makeitems.c and
ego/share/makecldef.c. Such changes don't silence warnings; I make
such changes while I silence warnings in the same file. In
float_cst(), rename parameter `str` to `float_str`, so it doesn't
share a name with the global variable `str`.
Remove `const` from `newmodule(const char *)` in mach/proto/as to
silence a warning. I wrongly added the `const` in d347207.
For warnings about implicit declarations of functions, the fix is to
declare the function before calling it. For example, my OpenBSD
system needs <sys/wait.h> to declare wait().
In util/int, add "whatever.h" to declare more functions. Remove old
declarations from "mem.h", to prefer the newer declarations of the
same functions in "data.h" and "stack.h".
2019-10-23 20:06:36 +00:00
|
|
|
#include "whatever.h"
|
1988-06-22 16:57:09 +00:00
|
|
|
|
|
|
|
extern int running; /* from main.c */
|
|
|
|
extern char *prog_name; /* from main.c */
|
|
|
|
extern char *load_name; /* from init.c */
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
extern void core_dump(void);
|
|
|
|
|
1988-06-22 16:57:09 +00:00
|
|
|
/******** The message file ********/
|
|
|
|
|
|
|
|
extern char mess_file[64]; /* from main.c */
|
|
|
|
long mess_id; /* Id, to determine unique mess file */
|
|
|
|
FILE *mess_fp; /* Filepointer of message file */
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
PRIVATE void do_fatal(FILE *, char *, va_list);
|
1988-06-22 16:57:09 +00:00
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void incr_mess_id(void)
|
1988-06-22 16:57:09 +00:00
|
|
|
{ /* for a new child */
|
|
|
|
mess_id++;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef LOGGING
|
|
|
|
extern long inr; /* from log.c */
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
|
|
|
|
/******** General file handling ********/
|
|
|
|
|
|
|
|
PRIVATE int highestfd();
|
|
|
|
|
|
|
|
int fd_limit = 100; /* first non-available file descriptor */
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
/** Creates an unbuffered FILE with name "fn" on the highest
|
|
|
|
* possible file descriptor.
|
|
|
|
*/
|
|
|
|
FILE *fcreat_high(char *fn)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
register int fd;
|
|
|
|
register FILE *fp;
|
|
|
|
|
|
|
|
if ((fd = creat(fn, 0644)) == -1)
|
|
|
|
return NULL;
|
|
|
|
fd = highestfd(fd);
|
|
|
|
if ((fp = fdopen(fd, "w")) == NULL)
|
|
|
|
return NULL;
|
|
|
|
setbuf(fp, (char *) 0); /* unbuffered! */
|
|
|
|
fd_limit = fd;
|
|
|
|
return fp;
|
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
/** Moves the (open) file descriptor "fd" to the highest available
|
|
|
|
* position and returns the new "fd". Does this without knowing
|
|
|
|
* how many fd-s are available.
|
|
|
|
*/
|
|
|
|
PRIVATE int highestfd(int fd)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
2019-03-17 14:42:00 +00:00
|
|
|
|
1988-06-22 16:57:09 +00:00
|
|
|
register int newfd, higherfd;
|
|
|
|
|
|
|
|
/* try to get a better fd */
|
|
|
|
newfd = dup(fd);
|
|
|
|
if (newfd < 0) {
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
if (newfd > 99) {
|
|
|
|
/* for systems with an unlimited supply of file descriptors */
|
|
|
|
close(newfd);
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* occupying the new fd, try to do even better */
|
|
|
|
higherfd = highestfd(newfd);
|
|
|
|
close(fd);
|
|
|
|
return higherfd; /* this is a deep one */
|
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void init_ofiles(int firsttime)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
if (!firsttime) {
|
|
|
|
fclose(mess_fp); /* old message file */
|
|
|
|
mess_fp = 0;
|
|
|
|
sprintf(mess_file, "%s_%ld", mess_file, mess_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create messagefile */
|
|
|
|
if ((mess_fp = fcreat_high(mess_file)) == NULL)
|
|
|
|
fatal("Cannot create messagefile '%s'", mess_file);
|
|
|
|
init_wmsg();
|
|
|
|
|
|
|
|
mess_id = 1; /* ID of next child */
|
|
|
|
|
|
|
|
#ifdef LOGGING
|
|
|
|
open_log(firsttime);
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
1995-08-17 14:36:05 +00:00
|
|
|
/*VARARGS0*/
|
2019-03-17 14:42:00 +00:00
|
|
|
void fatal(char *fmt, ...)
|
1995-08-17 14:36:05 +00:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
fprintf(stderr, "%s: ", prog_name);
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
{
|
|
|
|
do_fatal(stderr, fmt, ap);
|
|
|
|
}
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
if (mess_fp) {
|
|
|
|
va_start(ap, fmt);
|
|
|
|
{
|
|
|
|
do_fatal(mess_fp, fmt, ap);
|
|
|
|
}
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (running)
|
|
|
|
core_dump();
|
|
|
|
|
|
|
|
close_down(1);
|
|
|
|
}
|
1988-06-22 16:57:09 +00:00
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void close_down(int rc)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* all exits should go through here */
|
|
|
|
if (mess_fp) {
|
|
|
|
fclose(mess_fp);
|
|
|
|
mess_fp = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef LOGGING
|
|
|
|
close_log();
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
|
|
|
|
exit(rc);
|
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
PRIVATE void do_fatal(FILE *fp, char *fmt, va_list ap)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
fprintf(fp, "(Fatal error) ");
|
|
|
|
if (load_name)
|
|
|
|
fprintf(fp, "%s: ", load_name);
|
1991-12-03 11:03:58 +00:00
|
|
|
vfprintf(fp, fmt, ap);
|
1988-06-22 16:57:09 +00:00
|
|
|
fputc('\n', fp);
|
|
|
|
}
|
|
|
|
|
1995-08-17 14:36:05 +00:00
|
|
|
/*VARARGS0*/
|
2019-03-17 14:42:00 +00:00
|
|
|
void message(char *fmt, ...)
|
1995-08-17 14:36:05 +00:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
fprintf(mess_fp, "(Message): ");
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
{
|
|
|
|
vfprintf(mess_fp, fmt, ap);
|
|
|
|
}
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
fprintf(mess_fp, " at %s\n", position());
|
|
|
|
}
|
1988-06-22 16:57:09 +00:00
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
char *position(void) /* transient */
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
static char buff[300];
|
|
|
|
register char *fn = dt_fname(getFIL());
|
|
|
|
|
|
|
|
#ifdef LOGGING
|
|
|
|
sprintf(buff, "\"%s\", line %ld, INR = %ld", fn, getLIN(), inr);
|
1991-12-17 15:28:58 +00:00
|
|
|
#else /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
sprintf(buff, "\"%s\", line %ld", fn, getLIN());
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
return buff;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *dt_fname(p)
|
|
|
|
ptr p;
|
|
|
|
{
|
|
|
|
return (p ? &data_loc(p) : "<unknown>");
|
|
|
|
}
|
|
|
|
|