Files
magic/utils/niceabort.c
T
Patrick Kurth ea03883829 Fixed unused-parameters/unused-variables warnings
Added a ARG_UNUSED macro in utils/magic.h, which
produces a simple cast to void to silence the warnings.
The reasons this is used as opposed to an attribute is
that most compilers should support this.
Besides this, the macro can be easily searched for in
the future to potentially remove (where possible) the
unused parameters.
2025-10-10 22:12:19 +02:00

209 lines
5.7 KiB
C

/*
* niceabort.c --
*
* Nice version of abort which dumps core without actually
* killing the running job.
*
* *********************************************************************
* * Copyright (C) 1985, 1990 Regents of the University of California. *
* * Permission to use, copy, modify, and distribute this *
* * software and its documentation for any purpose and without *
* * fee is hereby granted, provided that the above copyright *
* * notice appear in all copies. The University of California *
* * makes no representations about the suitability of this *
* * software for any purpose. It is provided "as is" without *
* * express or implied warranty. Export of this software outside *
* * of the United States of America may require an export license. *
* *********************************************************************
*/
#ifndef lint
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/utils/niceabort.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h> /* for getpid(), sleep() */
#include <sys/types.h>
#include <sys/stat.h> /* for chmod() */
#include <time.h>
#include "utils/magic.h"
#include "textio/textio.h"
#include "utils/utils.h"
#include "utils/geometry.h"
#include "tiles/tile.h"
#include "utils/hash.h"
#include "database/database.h"
#include "windows/windows.h"
#include "utils/main.h"
#define CRASHDIR "CAD_DIR/lib/magic/crash"
/*
* Command used to mail core dump messages. The '%s' is filled in with the
* name of a file to be mailed.
*/
#define MAIL_COMMAND "/bin/mail magiccrash < %s"
/* The following array is used to hold information about the
* assertion that failed.
*/
char AbortMessage[200];
bool AbortFatal = FALSE;
void
DumpCore()
{
int parentPid = getpid();
int cpid, gcpid;
FILE *commentFile, *crashFile;
time_t now;
char pidString[20], line[150], command[512], tempName[200], *crashDir;
TxPrintf("Please wait while magic generates a core image of itself....\n");
sprintf(pidString, "%d", parentPid);
FORK_f (cpid);
if (cpid < 0)
{
perror("fork");
return;
}
/* Child */
if (cpid == 0)
{
/*
* Suspend the parent to make it as easy as
* possible for gcore to make a core image.
*/
kill(SIGSTOP, parentPid);
FORK_vf(gcpid);
if (gcpid < 0)
perror("vfork");
else
{
if (gcpid == 0)
{
execl(GCORE, "gcore", pidString, NULL);
exit (1);
}
WaitPid (gcpid,0);
/* while ((wpid = wait(0)) != gcpid && wpid != -1) */
/* Nothing */;
}
/*
* Resume the parent
*/
kill(SIGCONT, parentPid);
exit (0);
}
WaitPid (cpid,0);
/* while ((wpid = wait(0)) != cpid && wpid != -1) */
/* Nothing */;
/*
* We use PaOpen merely to to tilde expansion on CRASHDIR,
* to find the real name of the directory into which we want
* to place the crash dump.
*/
if ((crashFile = PaOpen(CRASHDIR, "r", "", ".", "", &crashDir)))
{
(void) fclose(crashFile);
(void) sprintf(command, "mv core.%s %s", pidString, crashDir);
system(command);
TxPrintf(".... done\n");
(void) sprintf(tempName, "%s/core.%s", crashDir, pidString);
(void) chmod(tempName, 0644);
TxPrintf("Please type a description of the problem, so the\n");
TxPrintf("magic maintainers will know what went wrong.\n");
TxPrintf("Terminate your description with a dot on a line\n");
TxPrintf("by itself (\".\"):\n\n");
(void) sprintf(tempName, "%s/comments.%s", crashDir, pidString);
commentFile = fopen(tempName, "w");
if (commentFile == (FILE *) NULL) return;
(void) chmod(tempName, 0644);
time(&now);
fprintf(commentFile, "~s -- Magic crashed %24.24s --\n", ctime(&now));
fputs(MagicVersion, commentFile);
fprintf(commentFile, "%s\n", AbortMessage);
while (TxGetLine(line, sizeof line) != NULL)
{
/*
* We would use EOF to end the message, but there is no EOF when
* magic is running unless it is accepting input from a
* command file.
*/
if (strcmp(line, ".") == 0)
break;
fprintf(commentFile, "%s\n", line);
}
fclose(commentFile);
sprintf(command, MAIL_COMMAND, tempName);
system(command);
TxPrintf("Thank you.\n");
}
}
/*
* ----------------------------------------------------------------------------
*
* niceabort --
*
* Nice version of abort which dumps core (using gcore) without actually
* killing the running job.
*
* Results:
* None.
*
* Side effects:
* The first time we are called, we dump a core image; on successive
* calls, we don't bother to dump core.
* ----------------------------------------------------------------------------
*/
void
niceabort()
{
static int timesCalled = 0;
timesCalled++;
TxPrintf("-------------------- Error #%d\n", timesCalled);
if (timesCalled > 10)
{
TxPrintf("\nAbort called more than 10 times -- things are really hosed!\n");
TxPrintf("Recommendation:\n");
TxPrintf(" 1) Copy all your files to another directory.\n");
TxPrintf(" 2) Send magic a SIGTERM signal and it will ATTEMPT to write out your files.\n");
TxPrintf(" (It might trash them, though.)\n");
TxPrintf("Magic going to sleep now for 10 hours -- please kill me.\n");
sleep(3600);
}
TxPrintf("Magic has encountered a major internal inconsistency:\n\n");
TxPrintf(" %s\n", AbortMessage);
if (AbortFatal) {
TxPrintf("Magic can't recover from this error. Goodbye.\n\n");
} else {
TxPrintf("It will try to recover, but you should save all your\n");
TxPrintf("files as soon as possible and quit magic.\n\n");
}
TxPrintf("--------------------\n");
}