/*
 * Copyright (c) 2006 Claus Assmann
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the license/LICENSE.3C file which can be found at the
 * top level of this source code distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: exit2txt_r.c,v 1.4 2007/09/29 02:15:43 ca Exp $")

#include "sm/assert.h"
#include "sm/io.h"
#include "sm/wait.h"
#include "sm/sysexits.h"
#include "sm/signal.h"
#include "smerr2txt.h"

static e2s_T
e_exit[] = {
#ifdef EX_USAGE
	{ EX_USAGE,	"command line usage error"	},
#endif
#ifdef EX_DATAERR
	{ EX_DATAERR,	"data format error"	},
#endif
#ifdef EX_NOINPUT
	{ EX_NOINPUT,	"cannot open input"	},
#endif
#ifdef EX_NOUSER
	{ EX_NOUSER,	"addressee unknown"	},
#endif
#ifdef EX_NOHOST
	{ EX_NOHOST,	"host name unknown"	},
#endif
#ifdef EX_UNAVAILABLE
	{ EX_UNAVAILABLE,	"service unavailable"	},
#endif
#ifdef EX_SOFTWARE
	{ EX_SOFTWARE,	"internal software error"	},
#endif
#ifdef EX_OSERR
	{ EX_OSERR,	"system error (e.g., can't fork)"	},
#endif
#ifdef EX_OSFILE
	{ EX_OSFILE,	"critical OS file missing"	},
#endif
#ifdef EX_CANTCREAT
	{ EX_CANTCREAT,	"can't create (user) output file"	},
#endif
#ifdef EX_IOERR
	{ EX_IOERR,	"input/output error"	},
#endif
#ifdef EX_TEMPFAIL
	{ EX_TEMPFAIL,	"temp failure; user is invited to retry"	},
#endif
#ifdef EX_PROTOCOL
	{ EX_PROTOCOL,	"remote error in protocol"	},
#endif
#ifdef EX_NOPERM
	{ EX_NOPERM,	"permission denied"	},
#endif
#ifdef EX_CONFIG
	{ EX_CONFIG,	"configuration error"	},
#endif
#ifdef EX_RESTARTDEP
	{ EX_RESTARTDEP,	"restart depending on"	},
#endif
#ifdef EX_RESTARTALL
	{ EX_RESTARTALL,	"restart all"	},
#endif
}
;

static e2s_T
e_signal[] = {
#ifdef SIGHUP
	{ SIGHUP,	"hangup"	},
#endif
#ifdef SIGINT
	{ SIGINT,	"interrupt"	},
#endif
#ifdef SIGQUIT
	{ SIGQUIT,	"quit"	},
#endif
#ifdef SIGILL
	{ SIGILL,	"illegal instr"	},
#endif
#ifdef SIGTRAP
	{ SIGTRAP,	"trace trap"	},
#endif
#ifdef SIGABRT
	{ SIGABRT,	"abort"	},
#endif
#ifdef SIGIOT
	{ SIGIOT,	"compatibility"	},
#endif
#ifdef SIGEMT
	{ SIGEMT,	"EMT instruction"	},
#endif
#ifdef SIGFPE
	{ SIGFPE,	"floating point exception"	},
#endif
#ifdef SIGKILL
	{ SIGKILL,	"kill"	},
#endif
#ifdef SIGBUS
	{ SIGBUS,	"bus error"	},
#endif
#ifdef SIGSEGV
	{ SIGSEGV,	"segmentation violation"	},
#endif
#ifdef SIGSYS
	{ SIGSYS,	"non-existent system call invoked"	},
#endif
#ifdef SIGPIPE
	{ SIGPIPE,	"write on a pipe with no one to read it"	},
#endif
#ifdef SIGALRM
	{ SIGALRM,	"alarm clock"	},
#endif
#ifdef SIGTERM
	{ SIGTERM,	"software termination signal from kill"	},
#endif
#ifdef SIGURG
	{ SIGURG,	"urgent condition on IO channel"	},
#endif
#ifdef SIGSTOP
	{ SIGSTOP,	"sendable stop signal not from tty"	},
#endif
#ifdef SIGTSTP
	{ SIGTSTP,	"stop signal from tty"	},
#endif
#ifdef SIGCONT
	{ SIGCONT,	"continue a stopped process"	},
#endif
#ifdef SIGCHLD
	{ SIGCHLD,	"to parent on child stop or exit"	},
#endif
#ifdef SIGTTIN
	{ SIGTTIN,	"to readers pgrp upon background tty read"	},
#endif
#ifdef SIGTTOU
	{ SIGTTOU,	"like TTIN"	},
#endif
#ifdef SIGIO
	{ SIGIO,	"input/output possible signal"	},
#endif
#ifdef SIGXCPU
	{ SIGXCPU,	"exceeded CPU time limit"	},
#endif
#ifdef SIGXFSZ
	{ SIGXFSZ,	"exceeded file size limit"	},
#endif
#ifdef SIGVTALRM
	{ SIGVTALRM,	"virtual time alarm"	},
#endif
#ifdef SIGPROF
	{ SIGPROF,	"profiling time alarm"	},
#endif
#ifdef SIGWINCH
	{ SIGWINCH,	"window size changes"	},
#endif
#ifdef SIGINFO
	{ SIGINFO,	"information request"	},
#endif
#ifdef SIGUSR1
	{ SIGUSR1,	"user defined signal 1"	},
#endif
#ifdef SIGUSR2
	{ SIGUSR2,	"user defined signal 2"	},
#endif
};


int
exit2txt_r(int status, char *errbuf, size_t buflen)
{
	int r;
	char *txt;

	SM_REQUIRE(errbuf != NULL);
	SM_REQUIRE(buflen > 0);

	if (WIFEXITED(status)) {
		r = WEXITSTATUS(status);
		txt = finde(r, e_exit);
		if (txt != NULL)
			sm_snprintf(errbuf, buflen, "exit=%s", txt);
		else
			sm_snprintf(errbuf, buflen, "exit=%d", r);
	}
	else if (WIFSTOPPED(status))
		(void) strlcpy(errbuf, "stopped", buflen);
	else if (WIFSIGNALED(status)) {
		r = WTERMSIG(status);
		txt = finde(r, e_signal);
		if (txt != NULL)
			sm_snprintf(errbuf, buflen, "%s=%s", WCOREDUMP(status) ? "core" : "signal", txt);
		else
			sm_snprintf(errbuf, buflen, "%s=%d", WCOREDUMP(status) ? "core" : "signal", r);
	}
	return SM_SUCCESS;
}


syntax highlighted by Code2HTML, v. 0.9.1