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
|
|
|
|
|
|
|
#include <stdio.h>
|
1995-08-17 14:36:05 +00:00
|
|
|
#include <stdarg.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"
|
|
|
|
|
|
|
|
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>");
|
|
|
|
}
|
|
|
|
|