2021-11-21 01:49:30 +00:00
|
|
|
#include "main.h"
|
|
|
|
|
2021-11-21 01:29:09 +00:00
|
|
|
#include "dwm.h"
|
|
|
|
|
2021-11-21 02:03:19 +00:00
|
|
|
#include <locale.h>
|
2021-11-21 04:03:58 +00:00
|
|
|
#include <signal.h>
|
2021-11-21 01:37:38 +00:00
|
|
|
#include <stdarg.h>
|
2021-11-21 02:34:25 +00:00
|
|
|
#include <stddef.h>
|
2021-11-21 01:37:38 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2021-11-21 04:03:58 +00:00
|
|
|
#include <sys/wait.h>
|
2021-11-21 04:47:59 +00:00
|
|
|
#include <unistd.h>
|
2021-11-21 01:37:38 +00:00
|
|
|
|
2021-11-21 22:57:22 +00:00
|
|
|
#define PROGRAM_TITLE "PolytreeWM"
|
|
|
|
#define PROGRAM_NAME "polytreewm"
|
2021-11-21 02:38:12 +00:00
|
|
|
|
2021-11-21 04:47:59 +00:00
|
|
|
static char *program_exe = NULL;
|
|
|
|
|
2021-11-21 04:03:58 +00:00
|
|
|
static void signal_callback(int signo);
|
|
|
|
|
2021-11-21 02:25:19 +00:00
|
|
|
static void logger(const char *level, const char *fmt, ...);
|
|
|
|
static void logger_perror(const char *level, const char *fmt, ...);
|
|
|
|
|
2021-11-21 01:29:09 +00:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2021-11-21 01:37:38 +00:00
|
|
|
if (argc == 2 && strcmp(argv[1], "-v") == 0) {
|
2021-11-21 02:38:12 +00:00
|
|
|
fputs(PROGRAM_NAME"-"VERSION"\n", stderr);
|
2021-11-21 01:52:24 +00:00
|
|
|
exit(EXIT_SUCCESS);
|
2021-11-21 01:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (argc != 1) {
|
2021-11-21 02:38:12 +00:00
|
|
|
fputs("usage: "PROGRAM_NAME" [-v]\n", stderr);
|
2021-11-21 02:25:19 +00:00
|
|
|
exit(EXIT_FAILURE);
|
2021-11-21 01:37:38 +00:00
|
|
|
}
|
|
|
|
|
2021-11-21 04:47:59 +00:00
|
|
|
if (!(program_exe = argv[0])) {
|
|
|
|
fatal("no program executable name");
|
|
|
|
}
|
|
|
|
|
2021-11-21 05:27:41 +00:00
|
|
|
if (!setlocale(LC_CTYPE, "")) {
|
2021-11-21 02:03:19 +00:00
|
|
|
warning("no locale support");
|
|
|
|
}
|
|
|
|
|
2021-11-21 02:34:25 +00:00
|
|
|
#ifdef __OpenBSD__
|
|
|
|
if (pledge("stdio rpath proc exec", NULL) == -1) {
|
|
|
|
fatal("pledge");
|
|
|
|
}
|
|
|
|
#endif // __OpenBSD__
|
|
|
|
|
2021-11-21 04:03:58 +00:00
|
|
|
{
|
|
|
|
struct sigaction action;
|
|
|
|
memset(&action, 0, sizeof(action));
|
|
|
|
action.sa_handler = signal_callback;
|
2021-11-21 04:47:59 +00:00
|
|
|
|
2021-11-21 04:03:58 +00:00
|
|
|
if (sigaction(SIGCHLD, &action, NULL) != 0) {
|
|
|
|
fatal_perror("can't install SIGCHLD handler");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-21 22:57:22 +00:00
|
|
|
exit(dwm_main(PROGRAM_TITLE));
|
2021-11-21 01:29:09 +00:00
|
|
|
}
|
2021-11-21 01:37:38 +00:00
|
|
|
|
2021-11-21 04:03:58 +00:00
|
|
|
void signal_callback(const int signo)
|
|
|
|
{
|
2021-11-21 04:47:59 +00:00
|
|
|
switch (signo) {
|
|
|
|
case SIGCHLD:
|
|
|
|
// Clean up any zombies immediately.
|
|
|
|
while (waitpid(-1, NULL, WNOHANG) > 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-11-21 04:03:58 +00:00
|
|
|
|
2021-11-21 04:47:59 +00:00
|
|
|
void restart()
|
|
|
|
{
|
|
|
|
info("restarting");
|
|
|
|
char *args[] = { program_exe, NULL };
|
|
|
|
execvp(program_exe, args);
|
|
|
|
fatal_perror("restart with `execvp' failed");
|
2021-11-21 04:03:58 +00:00
|
|
|
}
|
|
|
|
|
2021-11-21 02:25:19 +00:00
|
|
|
void logger(const char *const level, const char *const fmt, ...)
|
2021-11-21 01:37:38 +00:00
|
|
|
{
|
2021-11-21 02:38:12 +00:00
|
|
|
fprintf(stderr, PROGRAM_NAME": %s: ", level);
|
2021-11-21 02:25:19 +00:00
|
|
|
|
2021-11-21 01:37:38 +00:00
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vfprintf(stderr, fmt, ap);
|
|
|
|
va_end(ap);
|
2021-11-21 01:49:30 +00:00
|
|
|
|
2021-11-21 01:37:38 +00:00
|
|
|
fputc('\n', stderr);
|
|
|
|
}
|
2021-11-21 01:49:30 +00:00
|
|
|
|
2021-11-21 02:25:19 +00:00
|
|
|
void logger_perror(const char *const level, const char *const fmt, ...)
|
2021-11-21 01:49:30 +00:00
|
|
|
{
|
2021-11-21 02:38:12 +00:00
|
|
|
fprintf(stderr, PROGRAM_NAME": %s: ", level);
|
2021-11-21 02:25:19 +00:00
|
|
|
|
2021-11-21 01:49:30 +00:00
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vfprintf(stderr, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
fprintf(stderr, ": ");
|
|
|
|
perror(NULL);
|
2021-11-21 02:25:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void fatal(const char *const fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
logger("ERROR", fmt, ap);
|
|
|
|
va_end(ap);
|
2021-11-21 01:49:30 +00:00
|
|
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2021-11-21 02:03:19 +00:00
|
|
|
|
2021-11-21 02:25:19 +00:00
|
|
|
void fatal_perror(const char* const fmt, ...)
|
2021-11-21 02:03:19 +00:00
|
|
|
{
|
2021-11-21 02:25:19 +00:00
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
logger_perror("ERROR", fmt, ap);
|
|
|
|
va_end(ap);
|
2021-11-21 02:03:19 +00:00
|
|
|
|
2021-11-21 02:25:19 +00:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void fatal_nodie(const char *const fmt, ...)
|
|
|
|
{
|
2021-11-21 02:03:19 +00:00
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
2021-11-21 02:25:19 +00:00
|
|
|
logger("ERROR", fmt, ap);
|
2021-11-21 02:03:19 +00:00
|
|
|
va_end(ap);
|
2021-11-21 02:25:19 +00:00
|
|
|
}
|
2021-11-21 02:03:19 +00:00
|
|
|
|
2021-11-21 02:25:19 +00:00
|
|
|
void fatal_perror_nodie(const char *const fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
logger_perror("ERROR", fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
void warning(const char *const fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
logger("WARN", fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
void warning_perror(const char *const fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
logger_perror("WARN", fmt, ap);
|
|
|
|
va_end(ap);
|
2021-11-21 02:03:19 +00:00
|
|
|
}
|
2021-11-21 04:47:59 +00:00
|
|
|
|
|
|
|
void info(const char *const fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
logger("INFO", fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
}
|