2019-06-12 20:08:54 +02:00
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include <string.h>
|
2019-09-21 20:01:55 +02:00
|
|
|
|
#include <ctype.h>
|
2019-06-12 20:08:54 +02:00
|
|
|
|
#include <stdbool.h>
|
2019-06-13 21:23:52 +02:00
|
|
|
|
#include <locale.h>
|
2019-07-03 09:46:13 +02:00
|
|
|
|
#include <getopt.h>
|
2019-11-01 20:35:42 +01:00
|
|
|
|
#include <signal.h>
|
2019-07-03 15:16:38 +02:00
|
|
|
|
#include <errno.h>
|
2019-12-21 19:57:28 +01:00
|
|
|
|
#include <unistd.h>
|
2019-06-12 20:08:54 +02:00
|
|
|
|
|
2020-02-05 19:53:50 +01:00
|
|
|
|
#include <sys/types.h>
|
2021-01-19 14:38:45 +00:00
|
|
|
|
#include <sys/stat.h>
|
2020-06-09 20:35:21 +02:00
|
|
|
|
#include <sys/utsname.h>
|
2020-02-05 19:53:50 +01:00
|
|
|
|
#include <fcntl.h>
|
2019-08-12 21:22:38 +02:00
|
|
|
|
|
2019-12-01 14:03:24 +01:00
|
|
|
|
#include <fcft/fcft.h>
|
2019-12-01 13:43:51 +01:00
|
|
|
|
|
2019-06-12 20:08:54 +02:00
|
|
|
|
#define LOG_MODULE "main"
|
2019-10-28 18:35:16 +01:00
|
|
|
|
#define LOG_ENABLE_DBG 0
|
2019-06-12 20:08:54 +02:00
|
|
|
|
#include "log.h"
|
2019-06-13 15:19:10 +02:00
|
|
|
|
|
2019-07-16 11:52:22 +02:00
|
|
|
|
#include "config.h"
|
2020-12-04 18:57:49 +01:00
|
|
|
|
#include "foot-features.h"
|
2019-10-27 11:46:18 +01:00
|
|
|
|
#include "fdm.h"
|
2021-02-11 11:08:18 +00:00
|
|
|
|
#include "macros.h"
|
2020-05-21 20:15:10 +02:00
|
|
|
|
#include "reaper.h"
|
2020-01-04 19:49:26 +01:00
|
|
|
|
#include "render.h"
|
2019-11-01 20:37:22 +01:00
|
|
|
|
#include "server.h"
|
2019-06-12 20:08:54 +02:00
|
|
|
|
#include "shm.h"
|
2019-06-15 22:22:44 +02:00
|
|
|
|
#include "terminal.h"
|
2020-10-20 21:04:47 +02:00
|
|
|
|
#include "util.h"
|
2019-10-19 22:09:52 +02:00
|
|
|
|
#include "version.h"
|
2020-08-08 20:34:30 +01:00
|
|
|
|
#include "xmalloc.h"
|
2021-01-14 21:30:06 +00:00
|
|
|
|
#include "xsnprintf.h"
|
2019-06-19 14:17:43 +02:00
|
|
|
|
|
2021-02-10 16:21:56 +01:00
|
|
|
|
static bool
|
|
|
|
|
|
fdm_sigint(struct fdm *fdm, int signo, void *data)
|
2019-11-01 20:35:42 +01:00
|
|
|
|
{
|
2021-02-10 16:21:56 +01:00
|
|
|
|
*(volatile sig_atomic_t *)data = true;
|
|
|
|
|
|
return true;
|
2019-11-01 20:35:42 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-04 18:57:49 +01:00
|
|
|
|
static const char *
|
|
|
|
|
|
version_and_features(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
static char buf[256];
|
2021-10-23 15:40:54 +02:00
|
|
|
|
snprintf(buf, sizeof(buf), "version: %s %cpgo %cime %cgraphemes %cassertions",
|
2021-03-26 20:30:13 +01:00
|
|
|
|
FOOT_VERSION,
|
2021-06-24 17:50:30 +02:00
|
|
|
|
feature_pgo() ? '+' : '-',
|
2021-03-26 20:30:13 +01:00
|
|
|
|
feature_ime() ? '+' : '-',
|
2021-10-23 15:40:54 +02:00
|
|
|
|
feature_graphemes() ? '+' : '-',
|
|
|
|
|
|
feature_assertions() ? '+' : '-');
|
2020-12-04 18:57:49 +01:00
|
|
|
|
return buf;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-08-11 16:03:29 +02:00
|
|
|
|
static void
|
|
|
|
|
|
print_usage(const char *prog_name)
|
|
|
|
|
|
{
|
2021-09-18 19:44:04 +01:00
|
|
|
|
static const char options[] =
|
|
|
|
|
|
"\nOptions:\n"
|
2021-06-26 22:15:09 +01:00
|
|
|
|
" -c,--config=PATH load configuration from PATH ($XDG_CONFIG_HOME/foot/foot.ini)\n"
|
|
|
|
|
|
" -C,--check-config verify configuration, exit with 0 if ok, otherwise exit with 1\n"
|
|
|
|
|
|
" -o,--override=[section.]key=value override configuration option\n"
|
|
|
|
|
|
" -f,--font=FONT comma separated list of fonts in fontconfig format (monospace)\n"
|
2021-09-18 19:44:04 +01:00
|
|
|
|
" -t,--term=TERM value to set the environment variable TERM to (" FOOT_DEFAULT_TERM ")\n"
|
2021-06-26 22:15:09 +01:00
|
|
|
|
" -T,--title=TITLE initial window title (foot)\n"
|
|
|
|
|
|
" -a,--app-id=ID window application ID (foot)\n"
|
|
|
|
|
|
" -m,--maximized start in maximized mode\n"
|
|
|
|
|
|
" -F,--fullscreen start in fullscreen mode\n"
|
|
|
|
|
|
" -L,--login-shell start shell as a login shell\n"
|
|
|
|
|
|
" -D,--working-directory=DIR directory to start in (CWD)\n"
|
|
|
|
|
|
" -w,--window-size-pixels=WIDTHxHEIGHT initial width and height, in pixels\n"
|
|
|
|
|
|
" -W,--window-size-chars=WIDTHxHEIGHT initial width and height, in characters\n"
|
|
|
|
|
|
" -s,--server[=PATH] run as a server (use 'footclient' to start terminals).\n"
|
|
|
|
|
|
" Without PATH, $XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock will be used.\n"
|
|
|
|
|
|
" -H,--hold remain open after child process exits\n"
|
|
|
|
|
|
" -p,--print-pid=FILE|FD print PID to file or FD (only applicable in server mode)\n"
|
|
|
|
|
|
" -d,--log-level={info|warning|error|none} log level (info)\n"
|
|
|
|
|
|
" -l,--log-colorize=[{never|always|auto}] enable/disable colorization of log output on stderr\n"
|
|
|
|
|
|
" -s,--log-no-syslog disable syslog logging (only applicable in server mode)\n"
|
2021-09-18 23:40:40 +01:00
|
|
|
|
" -v,--version show the version number and quit\n"
|
|
|
|
|
|
" -e ignored (for compatibility with xterm -e)\n";
|
2021-09-18 19:44:04 +01:00
|
|
|
|
|
|
|
|
|
|
printf("Usage: %s [OPTIONS...]\n", prog_name);
|
|
|
|
|
|
printf("Usage: %s [OPTIONS...] command [ARGS...]\n", prog_name);
|
|
|
|
|
|
puts(options);
|
2019-11-01 20:34:32 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-12-19 07:25:05 +01:00
|
|
|
|
bool
|
|
|
|
|
|
locale_is_utf8(void)
|
|
|
|
|
|
{
|
2021-01-16 20:16:00 +00:00
|
|
|
|
xassert(strlen(u8"ö") == 2);
|
2019-12-19 07:25:05 +01:00
|
|
|
|
|
|
|
|
|
|
wchar_t w;
|
|
|
|
|
|
if (mbtowc(&w, u8"ö", 2) != 2)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
if (w != U'ö')
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-01 20:34:32 +01:00
|
|
|
|
struct shutdown_context {
|
|
|
|
|
|
struct terminal **term;
|
|
|
|
|
|
int exit_code;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
term_shutdown_cb(void *data, int exit_code)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct shutdown_context *ctx = data;
|
|
|
|
|
|
*ctx->term = NULL;
|
|
|
|
|
|
ctx->exit_code = exit_code;
|
2019-08-11 16:03:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-02-05 19:53:50 +01:00
|
|
|
|
static bool
|
|
|
|
|
|
print_pid(const char *pid_file, bool *unlink_at_exit)
|
|
|
|
|
|
{
|
|
|
|
|
|
LOG_DBG("printing PID to %s", pid_file);
|
|
|
|
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
|
char *end;
|
|
|
|
|
|
int pid_fd = strtoul(pid_file, &end, 10);
|
|
|
|
|
|
|
|
|
|
|
|
if (errno != 0 || *end != '\0') {
|
|
|
|
|
|
if ((pid_fd = open(pid_file,
|
|
|
|
|
|
O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC,
|
|
|
|
|
|
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
|
|
|
|
|
|
LOG_ERRNO("%s: failed to open", pid_file);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
} else
|
|
|
|
|
|
*unlink_at_exit = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pid_fd >= 0) {
|
|
|
|
|
|
char pid[32];
|
2021-01-14 21:30:06 +00:00
|
|
|
|
size_t n = xsnprintf(pid, sizeof(pid), "%u\n", getpid());
|
2020-02-05 19:53:50 +01:00
|
|
|
|
|
2021-01-14 21:30:06 +00:00
|
|
|
|
ssize_t bytes = write(pid_fd, pid, n);
|
2020-02-05 19:53:50 +01:00
|
|
|
|
close(pid_fd);
|
|
|
|
|
|
|
|
|
|
|
|
if (bytes < 0) {
|
|
|
|
|
|
LOG_ERRNO("failed to write PID to FD=%u", pid_fd);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LOG_DBG("wrote %zd bytes to FD=%d", bytes, pid_fd);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
} else
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-02-02 21:35:39 +01:00
|
|
|
|
static void
|
|
|
|
|
|
sanitize_signals(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
sigset_t mask;
|
|
|
|
|
|
sigemptyset(&mask);
|
|
|
|
|
|
sigprocmask(SIG_SETMASK, &mask, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
struct sigaction dfl = {.sa_handler = SIG_DFL};
|
|
|
|
|
|
sigemptyset(&dfl.sa_mask);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 1; i < SIGRTMAX; i++)
|
|
|
|
|
|
sigaction(i, &dfl, NULL);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-06-12 20:08:54 +02:00
|
|
|
|
int
|
2019-07-03 09:46:13 +02:00
|
|
|
|
main(int argc, char *const *argv)
|
2019-06-12 20:08:54 +02:00
|
|
|
|
{
|
2021-04-30 22:47:16 +02:00
|
|
|
|
/* Custom exit code, to enable users to differentiate between foot
|
|
|
|
|
|
* itself failing, and the client application failiing */
|
2021-05-01 10:46:40 +02:00
|
|
|
|
static const int foot_exit_failure = -26;
|
2021-04-30 22:47:16 +02:00
|
|
|
|
int ret = foot_exit_failure;
|
2019-06-12 20:08:54 +02:00
|
|
|
|
|
2022-02-02 21:35:39 +01:00
|
|
|
|
sanitize_signals();
|
|
|
|
|
|
|
2021-10-28 17:51:44 -07:00
|
|
|
|
/* XDG startup notifications */
|
|
|
|
|
|
const char *token = getenv("XDG_ACTIVATION_TOKEN");
|
|
|
|
|
|
unsetenv("XDG_ACTIVATION_TOKEN");
|
|
|
|
|
|
|
2019-09-26 18:41:39 +02:00
|
|
|
|
/* Startup notifications; we don't support it, but must ensure we
|
|
|
|
|
|
* don't pass this on to programs launched by us */
|
|
|
|
|
|
unsetenv("DESKTOP_STARTUP_ID");
|
|
|
|
|
|
|
2022-01-01 21:11:31 +01:00
|
|
|
|
const char *const prog_name = argc > 0 ? argv[0] : "<nullptr>";
|
2019-08-11 16:03:29 +02:00
|
|
|
|
|
2019-07-03 09:46:13 +02:00
|
|
|
|
static const struct option longopts[] = {
|
2020-09-08 19:17:29 +02:00
|
|
|
|
{"config", required_argument, NULL, 'c'},
|
|
|
|
|
|
{"check-config", no_argument, NULL, 'C'},
|
2021-06-11 04:40:08 -05:00
|
|
|
|
{"override", required_argument, NULL, 'o'},
|
2020-09-08 19:17:29 +02:00
|
|
|
|
{"term", required_argument, NULL, 't'},
|
|
|
|
|
|
{"title", required_argument, NULL, 'T'},
|
|
|
|
|
|
{"app-id", required_argument, NULL, 'a'},
|
|
|
|
|
|
{"login-shell", no_argument, NULL, 'L'},
|
2021-02-12 09:39:44 +01:00
|
|
|
|
{"working-directory", required_argument, NULL, 'D'},
|
2020-09-08 19:17:29 +02:00
|
|
|
|
{"font", required_argument, NULL, 'f'},
|
|
|
|
|
|
{"window-size-pixels", required_argument, NULL, 'w'},
|
|
|
|
|
|
{"window-size-chars", required_argument, NULL, 'W'},
|
|
|
|
|
|
{"server", optional_argument, NULL, 's'},
|
|
|
|
|
|
{"hold", no_argument, NULL, 'H'},
|
|
|
|
|
|
{"maximized", no_argument, NULL, 'm'},
|
|
|
|
|
|
{"fullscreen", no_argument, NULL, 'F'},
|
|
|
|
|
|
{"presentation-timings", no_argument, NULL, 'P'}, /* Undocumented */
|
|
|
|
|
|
{"print-pid", required_argument, NULL, 'p'},
|
2021-02-09 21:04:56 +01:00
|
|
|
|
{"log-level", required_argument, NULL, 'd'},
|
2020-09-08 19:17:29 +02:00
|
|
|
|
{"log-colorize", optional_argument, NULL, 'l'},
|
|
|
|
|
|
{"log-no-syslog", no_argument, NULL, 'S'},
|
|
|
|
|
|
{"version", no_argument, NULL, 'v'},
|
|
|
|
|
|
{"help", no_argument, NULL, 'h'},
|
|
|
|
|
|
{NULL, no_argument, NULL, 0},
|
2019-07-03 09:46:13 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
2020-07-29 17:48:22 +02:00
|
|
|
|
bool check_config = false;
|
2019-12-17 19:08:43 +01:00
|
|
|
|
const char *conf_path = NULL;
|
|
|
|
|
|
const char *conf_term = NULL;
|
2020-04-01 19:59:47 +02:00
|
|
|
|
const char *conf_title = NULL;
|
2020-04-01 18:40:51 +02:00
|
|
|
|
const char *conf_app_id = NULL;
|
2021-02-12 09:39:44 +01:00
|
|
|
|
const char *custom_cwd = NULL;
|
2020-02-20 18:34:23 +01:00
|
|
|
|
bool login_shell = false;
|
2019-12-17 19:08:43 +01:00
|
|
|
|
tll(char *) conf_fonts = tll_init();
|
2020-09-08 19:17:29 +02:00
|
|
|
|
enum conf_size_type conf_size_type = CONF_SIZE_PX;
|
2019-12-17 19:08:43 +01:00
|
|
|
|
int conf_width = -1;
|
|
|
|
|
|
int conf_height = -1;
|
2019-11-01 20:37:22 +01:00
|
|
|
|
bool as_server = false;
|
2019-12-17 19:08:43 +01:00
|
|
|
|
const char *conf_server_socket_path = NULL;
|
2019-12-31 15:39:40 +01:00
|
|
|
|
bool presentation_timings = false;
|
2020-02-03 19:58:32 +01:00
|
|
|
|
bool hold = false;
|
2020-03-26 19:47:00 +01:00
|
|
|
|
bool maximized = false;
|
|
|
|
|
|
bool fullscreen = false;
|
2020-02-05 19:53:50 +01:00
|
|
|
|
bool unlink_pid_file = false;
|
|
|
|
|
|
const char *pid_file = NULL;
|
2021-02-09 21:04:56 +01:00
|
|
|
|
enum log_class log_level = LOG_CLASS_INFO;
|
2020-02-05 19:54:16 +01:00
|
|
|
|
enum log_colorize log_colorize = LOG_COLORIZE_AUTO;
|
|
|
|
|
|
bool log_syslog = true;
|
2020-09-08 19:17:29 +02:00
|
|
|
|
user_notifications_t user_notifications = tll_init();
|
2021-06-11 04:40:08 -05:00
|
|
|
|
config_override_t overrides = tll_init();
|
2019-11-01 20:37:22 +01:00
|
|
|
|
|
2019-07-03 09:46:13 +02:00
|
|
|
|
while (true) {
|
2021-09-18 23:40:40 +01:00
|
|
|
|
int c = getopt_long(argc, argv, "+c:Co:t:T:a:LD:f:w:W:s::HmFPp:d:l::Sveh", longopts, NULL);
|
2021-06-11 04:40:08 -05:00
|
|
|
|
|
2019-07-03 09:46:13 +02:00
|
|
|
|
if (c == -1)
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
switch (c) {
|
2019-12-17 19:08:43 +01:00
|
|
|
|
case 'c':
|
|
|
|
|
|
conf_path = optarg;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2020-07-29 17:48:22 +02:00
|
|
|
|
case 'C':
|
|
|
|
|
|
check_config = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2021-06-11 04:40:08 -05:00
|
|
|
|
case 'o':
|
|
|
|
|
|
tll_push_back(overrides, optarg);
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2019-07-18 14:34:45 +02:00
|
|
|
|
case 't':
|
2019-12-17 19:08:43 +01:00
|
|
|
|
conf_term = optarg;
|
2019-07-18 14:34:45 +02:00
|
|
|
|
break;
|
|
|
|
|
|
|
2020-02-20 18:34:23 +01:00
|
|
|
|
case 'L':
|
|
|
|
|
|
login_shell = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2020-04-01 19:59:47 +02:00
|
|
|
|
case 'T':
|
|
|
|
|
|
conf_title = optarg;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2020-04-01 18:40:51 +02:00
|
|
|
|
case 'a':
|
|
|
|
|
|
conf_app_id = optarg;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2021-02-13 10:48:31 +01:00
|
|
|
|
case 'D': {
|
|
|
|
|
|
struct stat st;
|
|
|
|
|
|
if (stat(optarg, &st) < 0 || !(st.st_mode & S_IFDIR)) {
|
|
|
|
|
|
fprintf(stderr, "error: %s: not a directory\n", optarg);
|
2021-04-30 22:47:16 +02:00
|
|
|
|
return ret;
|
2021-02-13 10:48:31 +01:00
|
|
|
|
}
|
2021-02-12 09:39:44 +01:00
|
|
|
|
custom_cwd = optarg;
|
|
|
|
|
|
break;
|
2021-02-13 10:48:31 +01:00
|
|
|
|
}
|
2021-02-12 09:39:44 +01:00
|
|
|
|
|
2019-07-03 09:46:13 +02:00
|
|
|
|
case 'f':
|
2019-12-17 19:08:43 +01:00
|
|
|
|
tll_free_and_free(conf_fonts, free);
|
2019-09-21 20:01:55 +02:00
|
|
|
|
for (char *font = strtok(optarg, ","); font != NULL; font = strtok(NULL, ",")) {
|
|
|
|
|
|
|
|
|
|
|
|
/* Strip leading spaces */
|
|
|
|
|
|
while (*font != '\0' && isspace(*font))
|
|
|
|
|
|
font++;
|
|
|
|
|
|
|
|
|
|
|
|
/* Strip trailing spaces */
|
|
|
|
|
|
char *end = font + strlen(font);
|
2021-01-16 20:16:00 +00:00
|
|
|
|
xassert(*end == '\0');
|
2019-09-21 20:01:55 +02:00
|
|
|
|
end--;
|
|
|
|
|
|
while (end > font && isspace(*end))
|
|
|
|
|
|
*(end--) = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
if (strlen(font) == 0)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
2020-07-07 10:44:55 +02:00
|
|
|
|
tll_push_back(conf_fonts, font);
|
2019-09-21 20:01:55 +02:00
|
|
|
|
}
|
2019-07-03 09:46:13 +02:00
|
|
|
|
break;
|
|
|
|
|
|
|
2020-09-08 19:17:29 +02:00
|
|
|
|
case 'w': {
|
2019-08-23 17:26:41 +02:00
|
|
|
|
unsigned width, height;
|
|
|
|
|
|
if (sscanf(optarg, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) {
|
2020-09-08 19:17:29 +02:00
|
|
|
|
fprintf(stderr, "error: invalid window-size-pixels: %s\n", optarg);
|
2021-04-30 22:47:16 +02:00
|
|
|
|
return ret;
|
2019-08-23 17:26:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-08 19:17:29 +02:00
|
|
|
|
conf_size_type = CONF_SIZE_PX;
|
|
|
|
|
|
conf_width = width;
|
|
|
|
|
|
conf_height = height;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case 'W': {
|
|
|
|
|
|
unsigned width, height;
|
|
|
|
|
|
if (sscanf(optarg, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) {
|
|
|
|
|
|
fprintf(stderr, "error: invalid window-size-chars: %s\n", optarg);
|
2021-04-30 22:47:16 +02:00
|
|
|
|
return ret;
|
2020-09-08 19:17:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
conf_size_type = CONF_SIZE_CELLS;
|
2019-12-17 19:08:43 +01:00
|
|
|
|
conf_width = width;
|
|
|
|
|
|
conf_height = height;
|
2019-08-23 17:26:41 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-01 20:37:22 +01:00
|
|
|
|
case 's':
|
|
|
|
|
|
as_server = true;
|
2019-12-17 19:08:43 +01:00
|
|
|
|
if (optarg != NULL)
|
|
|
|
|
|
conf_server_socket_path = optarg;
|
2019-11-01 20:37:22 +01:00
|
|
|
|
break;
|
|
|
|
|
|
|
2020-02-05 19:53:50 +01:00
|
|
|
|
case 'P':
|
2019-12-31 15:39:40 +01:00
|
|
|
|
presentation_timings = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2020-02-03 19:58:32 +01:00
|
|
|
|
case 'H':
|
|
|
|
|
|
hold = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2020-03-26 19:47:00 +01:00
|
|
|
|
case 'm':
|
|
|
|
|
|
maximized = true;
|
|
|
|
|
|
fullscreen = false;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 'F':
|
|
|
|
|
|
fullscreen = true;
|
|
|
|
|
|
maximized = false;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2020-02-05 19:53:50 +01:00
|
|
|
|
case 'p':
|
|
|
|
|
|
pid_file = optarg;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2021-02-09 21:04:56 +01:00
|
|
|
|
case 'd': {
|
2021-02-11 11:08:18 +00:00
|
|
|
|
int lvl = log_level_from_string(optarg);
|
|
|
|
|
|
if (unlikely(lvl < 0)) {
|
2021-02-09 21:04:56 +01:00
|
|
|
|
fprintf(
|
2021-02-11 11:08:18 +00:00
|
|
|
|
stderr,
|
|
|
|
|
|
"-d,--log-level: %s: argument must be one of %s\n",
|
|
|
|
|
|
optarg,
|
|
|
|
|
|
log_level_string_hint());
|
2021-04-30 22:47:16 +02:00
|
|
|
|
return ret;
|
2021-02-09 21:04:56 +01:00
|
|
|
|
}
|
2021-02-11 11:08:18 +00:00
|
|
|
|
log_level = lvl;
|
2021-02-09 21:04:56 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-02-05 19:54:16 +01:00
|
|
|
|
case 'l':
|
|
|
|
|
|
if (optarg == NULL || strcmp(optarg, "auto") == 0)
|
|
|
|
|
|
log_colorize = LOG_COLORIZE_AUTO;
|
|
|
|
|
|
else if (strcmp(optarg, "never") == 0)
|
|
|
|
|
|
log_colorize = LOG_COLORIZE_NEVER;
|
|
|
|
|
|
else if (strcmp(optarg, "always") == 0)
|
|
|
|
|
|
log_colorize = LOG_COLORIZE_ALWAYS;
|
|
|
|
|
|
else {
|
|
|
|
|
|
fprintf(stderr, "%s: argument must be one of 'never', 'always' or 'auto'\n", optarg);
|
2021-04-30 22:47:16 +02:00
|
|
|
|
return ret;
|
2020-02-05 19:54:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 'S':
|
|
|
|
|
|
log_syslog = false;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2019-08-11 16:03:29 +02:00
|
|
|
|
case 'v':
|
2020-12-04 18:57:49 +01:00
|
|
|
|
printf("foot %s\n", version_and_features());
|
2019-08-11 16:03:29 +02:00
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
|
|
|
2019-07-03 09:46:13 +02:00
|
|
|
|
case 'h':
|
2019-08-11 16:03:29 +02:00
|
|
|
|
print_usage(prog_name);
|
|
|
|
|
|
return EXIT_SUCCESS;
|
2019-07-03 09:46:13 +02:00
|
|
|
|
|
2021-09-18 23:40:40 +01:00
|
|
|
|
case 'e':
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2019-07-03 09:46:13 +02:00
|
|
|
|
case '?':
|
2021-04-30 22:47:16 +02:00
|
|
|
|
return ret;
|
2019-07-03 09:46:13 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-02-05 19:54:16 +01:00
|
|
|
|
log_init(log_colorize, as_server && log_syslog,
|
2021-02-09 21:04:56 +01:00
|
|
|
|
as_server ? LOG_FACILITY_DAEMON : LOG_FACILITY_USER, log_level);
|
2019-12-17 19:07:28 +01:00
|
|
|
|
|
2021-06-26 22:15:09 +01:00
|
|
|
|
_Static_assert((int)LOG_CLASS_ERROR == (int)FCFT_LOG_CLASS_ERROR,
|
2021-04-17 20:09:39 +02:00
|
|
|
|
"fcft log level enum offset");
|
|
|
|
|
|
_Static_assert((int)LOG_COLORIZE_ALWAYS == (int)FCFT_LOG_COLORIZE_ALWAYS,
|
|
|
|
|
|
"fcft colorize enum mismatch");
|
2021-06-26 22:15:09 +01:00
|
|
|
|
fcft_log_init(
|
|
|
|
|
|
(enum fcft_log_colorize)log_colorize,
|
|
|
|
|
|
as_server && log_syslog,
|
|
|
|
|
|
(enum fcft_log_class)log_level);
|
2021-04-17 19:31:17 +02:00
|
|
|
|
|
2022-01-01 21:11:31 +01:00
|
|
|
|
if (argc > 0) {
|
|
|
|
|
|
argc -= optind;
|
|
|
|
|
|
argv += optind;
|
|
|
|
|
|
}
|
2019-07-17 09:55:36 +02:00
|
|
|
|
|
2020-12-04 18:57:49 +01:00
|
|
|
|
LOG_INFO("%s", version_and_features());
|
2020-03-15 11:41:24 +01:00
|
|
|
|
|
2020-06-09 20:35:21 +02:00
|
|
|
|
{
|
|
|
|
|
|
struct utsname name;
|
|
|
|
|
|
if (uname(&name) < 0)
|
|
|
|
|
|
LOG_ERRNO("uname() failed");
|
|
|
|
|
|
else
|
2021-02-07 10:24:48 +01:00
|
|
|
|
LOG_INFO("arch: %s %s/%zu-bit",
|
|
|
|
|
|
name.sysname, name.machine, sizeof(void *) * 8);
|
2020-06-09 20:35:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-02-13 13:40:39 +01:00
|
|
|
|
srand(time(NULL));
|
|
|
|
|
|
|
2021-11-10 17:29:57 +00:00
|
|
|
|
const char *locale = setlocale(LC_CTYPE, "");
|
|
|
|
|
|
if (locale == NULL) {
|
|
|
|
|
|
LOG_ERR("setlocale() failed");
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
main: present invalid locale errors as a user-notification
Foot does not support running under non-UTF8 locales. If we detect a
non-UTF8 locale, we log this and exit with an error.
However, it appears a fairly common situation is this:
user (knowingly or unknowingly) only configures his/hers locale in
e.g. the shell RC files. These aren’t sourced when the compositor is
started via a display manager.
Thus, compositor key binds will fail to launch, and the user typically
has no way of seeing foot’s output.
So, the user proceeds to start another terminal, and from that one
tries launching foot. And it works... (because the shell in the other
terminal sourced the locale configuration).
User is left confused and often don’t know how to debug.
This patch is somewhat hackish; in addition to logging the locale
error, it also pushes a user notification. For this to be visible, we
need to actually start a terminal window.
So, we ignore the configured shell, and we ignore any custom command
line, and instead spawns “/bin/sh -c ‘’”. This allows us to get
something running (that hopefully doesn’t produce too much output we
can’t decode due to the non-UTF8 locale). But, it will exit
immediately. So we also set the --hold flag.
This works, and may be a good enough “solution”. However, it only
works for standalone foot instances, not footclients.
2022-01-10 20:24:46 +01:00
|
|
|
|
|
2021-11-10 17:29:57 +00:00
|
|
|
|
LOG_INFO("locale: %s", locale);
|
main: present invalid locale errors as a user-notification
Foot does not support running under non-UTF8 locales. If we detect a
non-UTF8 locale, we log this and exit with an error.
However, it appears a fairly common situation is this:
user (knowingly or unknowingly) only configures his/hers locale in
e.g. the shell RC files. These aren’t sourced when the compositor is
started via a display manager.
Thus, compositor key binds will fail to launch, and the user typically
has no way of seeing foot’s output.
So, the user proceeds to start another terminal, and from that one
tries launching foot. And it works... (because the shell in the other
terminal sourced the locale configuration).
User is left confused and often don’t know how to debug.
This patch is somewhat hackish; in addition to logging the locale
error, it also pushes a user notification. For this to be visible, we
need to actually start a terminal window.
So, we ignore the configured shell, and we ignore any custom command
line, and instead spawns “/bin/sh -c ‘’”. This allows us to get
something running (that hopefully doesn’t produce too much output we
can’t decode due to the non-UTF8 locale). But, it will exit
immediately. So we also set the --hold flag.
This works, and may be a good enough “solution”. However, it only
works for standalone foot instances, not footclients.
2022-01-10 20:24:46 +01:00
|
|
|
|
|
|
|
|
|
|
bool bad_locale = !locale_is_utf8();
|
|
|
|
|
|
if (bad_locale) {
|
2022-01-12 15:53:26 +01:00
|
|
|
|
static const char fallback_locales[][12] = {
|
|
|
|
|
|
"C.UTF-8",
|
|
|
|
|
|
"en_US.UTF-8",
|
|
|
|
|
|
};
|
2022-01-11 21:37:03 +01:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Try to force an UTF-8 locale. If we succeed, launch the
|
|
|
|
|
|
* user’s shell as usual, but add a user-notification saying
|
|
|
|
|
|
* the locale has been changed.
|
|
|
|
|
|
*/
|
2022-01-12 15:53:26 +01:00
|
|
|
|
for (size_t i = 0; i < ALEN(fallback_locales); i++) {
|
|
|
|
|
|
const char *const fallback_locale = fallback_locales[i];
|
|
|
|
|
|
|
|
|
|
|
|
if (setlocale(LC_CTYPE, fallback_locale) != NULL) {
|
2022-01-12 18:59:15 +01:00
|
|
|
|
LOG_WARN("locale '%s' is not UTF-8, using '%s' instead",
|
|
|
|
|
|
locale, fallback_locale);
|
|
|
|
|
|
|
2022-01-12 15:53:26 +01:00
|
|
|
|
user_notification_add_fmt(
|
|
|
|
|
|
&user_notifications, USER_NOTIFICATION_WARNING,
|
|
|
|
|
|
"locale '%s' is not UTF-8, using '%s' instead",
|
|
|
|
|
|
locale, fallback_locale);
|
2022-01-12 18:59:15 +01:00
|
|
|
|
|
2022-01-12 15:53:26 +01:00
|
|
|
|
bad_locale = false;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2022-01-11 21:37:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-01-12 15:53:26 +01:00
|
|
|
|
if (bad_locale) {
|
2022-01-12 18:59:15 +01:00
|
|
|
|
LOG_ERR("locale '%s' is not UTF-8, "
|
|
|
|
|
|
"and failed to enable a fallback locale", locale);
|
|
|
|
|
|
|
2022-01-12 15:53:26 +01:00
|
|
|
|
user_notification_add_fmt(
|
|
|
|
|
|
&user_notifications, USER_NOTIFICATION_ERROR,
|
|
|
|
|
|
"locale '%s' is not UTF-8, "
|
|
|
|
|
|
"and failed to enable a fallback locale",
|
|
|
|
|
|
locale);
|
2022-01-11 21:37:03 +01:00
|
|
|
|
}
|
2020-10-09 19:45:26 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-12-17 19:08:43 +01:00
|
|
|
|
struct config conf = {NULL};
|
2021-12-22 20:21:46 +01:00
|
|
|
|
bool conf_successful = config_load(
|
|
|
|
|
|
&conf, conf_path, &user_notifications, &overrides, check_config);
|
|
|
|
|
|
|
2021-06-11 04:40:08 -05:00
|
|
|
|
tll_free(overrides);
|
|
|
|
|
|
if (!conf_successful) {
|
2020-03-09 20:04:25 +01:00
|
|
|
|
config_free(conf);
|
2019-12-17 19:08:43 +01:00
|
|
|
|
return ret;
|
2020-03-09 20:04:25 +01:00
|
|
|
|
}
|
2019-12-17 19:08:43 +01:00
|
|
|
|
|
2020-07-29 17:48:22 +02:00
|
|
|
|
if (check_config) {
|
|
|
|
|
|
config_free(conf);
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-13 17:59:56 +02:00
|
|
|
|
fcft_set_scaling_filter(conf.tweak.fcft_filter);
|
|
|
|
|
|
|
2019-12-17 19:08:43 +01:00
|
|
|
|
if (conf_term != NULL) {
|
|
|
|
|
|
free(conf.term);
|
2020-08-08 20:34:30 +01:00
|
|
|
|
conf.term = xstrdup(conf_term);
|
2019-12-17 19:08:43 +01:00
|
|
|
|
}
|
2020-04-01 19:59:47 +02:00
|
|
|
|
if (conf_title != NULL) {
|
|
|
|
|
|
free(conf.title);
|
2020-08-08 20:34:30 +01:00
|
|
|
|
conf.title = xstrdup(conf_title);
|
2020-04-01 19:59:47 +02:00
|
|
|
|
}
|
2020-04-01 18:40:51 +02:00
|
|
|
|
if (conf_app_id != NULL) {
|
|
|
|
|
|
free(conf.app_id);
|
2020-08-08 20:34:30 +01:00
|
|
|
|
conf.app_id = xstrdup(conf_app_id);
|
2020-04-01 18:40:51 +02:00
|
|
|
|
}
|
2020-02-20 18:35:10 +01:00
|
|
|
|
if (login_shell)
|
|
|
|
|
|
conf.login_shell = true;
|
2019-12-17 19:08:43 +01:00
|
|
|
|
if (tll_length(conf_fonts) > 0) {
|
2021-06-17 18:15:29 +02:00
|
|
|
|
for (size_t i = 0; i < ALEN(conf.fonts); i++)
|
|
|
|
|
|
config_font_list_destroy(&conf.fonts[i]);
|
|
|
|
|
|
|
|
|
|
|
|
struct config_font_list *font_list = &conf.fonts[0];
|
|
|
|
|
|
xassert(font_list->count == 0);
|
|
|
|
|
|
xassert(font_list->arr == NULL);
|
|
|
|
|
|
|
|
|
|
|
|
font_list->arr = xmalloc(
|
|
|
|
|
|
tll_length(conf_fonts) * sizeof(font_list->arr[0]));
|
|
|
|
|
|
|
2020-12-15 18:55:27 +01:00
|
|
|
|
tll_foreach(conf_fonts, it) {
|
|
|
|
|
|
struct config_font font;
|
|
|
|
|
|
if (!config_font_parse(it->item, &font)) {
|
|
|
|
|
|
LOG_ERR("%s: invalid font specification", it->item);
|
|
|
|
|
|
} else
|
2021-06-17 18:15:29 +02:00
|
|
|
|
font_list->arr[font_list->count++] = font;
|
2020-12-15 18:55:27 +01:00
|
|
|
|
}
|
2019-12-17 19:08:43 +01:00
|
|
|
|
tll_free(conf_fonts);
|
|
|
|
|
|
}
|
2020-09-08 19:17:29 +02:00
|
|
|
|
if (conf_width > 0 && conf_height > 0) {
|
|
|
|
|
|
conf.size.type = conf_size_type;
|
2020-11-30 02:24:38 +00:00
|
|
|
|
conf.size.width = conf_width;
|
|
|
|
|
|
conf.size.height = conf_height;
|
2020-09-08 19:17:29 +02:00
|
|
|
|
}
|
2019-12-17 19:08:43 +01:00
|
|
|
|
if (conf_server_socket_path != NULL) {
|
|
|
|
|
|
free(conf.server_socket_path);
|
2020-08-08 20:34:30 +01:00
|
|
|
|
conf.server_socket_path = xstrdup(conf_server_socket_path);
|
2019-12-17 19:08:43 +01:00
|
|
|
|
}
|
2020-03-26 19:47:00 +01:00
|
|
|
|
if (maximized)
|
|
|
|
|
|
conf.startup_mode = STARTUP_MAXIMIZED;
|
|
|
|
|
|
else if (fullscreen)
|
|
|
|
|
|
conf.startup_mode = STARTUP_FULLSCREEN;
|
2019-12-31 15:39:40 +01:00
|
|
|
|
conf.presentation_timings = presentation_timings;
|
2020-02-03 19:58:32 +01:00
|
|
|
|
conf.hold_at_exit = hold;
|
2019-12-17 19:08:43 +01:00
|
|
|
|
|
2021-08-31 19:42:22 +02:00
|
|
|
|
if (conf.tweak.font_monospace_warn && conf.fonts[0].count > 0) {
|
|
|
|
|
|
check_if_font_is_monospaced(
|
|
|
|
|
|
conf.fonts[0].arr[0].pattern, &conf.notifications);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
main: present invalid locale errors as a user-notification
Foot does not support running under non-UTF8 locales. If we detect a
non-UTF8 locale, we log this and exit with an error.
However, it appears a fairly common situation is this:
user (knowingly or unknowingly) only configures his/hers locale in
e.g. the shell RC files. These aren’t sourced when the compositor is
started via a display manager.
Thus, compositor key binds will fail to launch, and the user typically
has no way of seeing foot’s output.
So, the user proceeds to start another terminal, and from that one
tries launching foot. And it works... (because the shell in the other
terminal sourced the locale configuration).
User is left confused and often don’t know how to debug.
This patch is somewhat hackish; in addition to logging the locale
error, it also pushes a user notification. For this to be visible, we
need to actually start a terminal window.
So, we ignore the configured shell, and we ignore any custom command
line, and instead spawns “/bin/sh -c ‘’”. This allows us to get
something running (that hopefully doesn’t produce too much output we
can’t decode due to the non-UTF8 locale). But, it will exit
immediately. So we also set the --hold flag.
This works, and may be a good enough “solution”. However, it only
works for standalone foot instances, not footclients.
2022-01-10 20:24:46 +01:00
|
|
|
|
|
|
|
|
|
|
if (bad_locale) {
|
|
|
|
|
|
static char *const bad_locale_fake_argv[] = {"/bin/sh", "-c", "", NULL};
|
|
|
|
|
|
argc = 1;
|
|
|
|
|
|
argv = bad_locale_fake_argv;
|
|
|
|
|
|
conf.hold_at_exit = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-27 19:08:48 +01:00
|
|
|
|
struct fdm *fdm = NULL;
|
2020-05-21 20:15:10 +02:00
|
|
|
|
struct reaper *reaper = NULL;
|
2019-10-27 19:08:48 +01:00
|
|
|
|
struct wayland *wayl = NULL;
|
2020-01-04 19:49:26 +01:00
|
|
|
|
struct renderer *renderer = NULL;
|
2019-10-28 18:25:19 +01:00
|
|
|
|
struct terminal *term = NULL;
|
2019-11-01 20:37:22 +01:00
|
|
|
|
struct server *server = NULL;
|
2021-04-30 22:47:16 +02:00
|
|
|
|
struct shutdown_context shutdown_ctx = {.term = &term, .exit_code = foot_exit_failure};
|
2019-10-27 19:08:48 +01:00
|
|
|
|
|
2021-02-12 09:39:44 +01:00
|
|
|
|
const char *cwd = custom_cwd;
|
|
|
|
|
|
char *_cwd = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (cwd == NULL) {
|
2020-02-20 18:46:45 +01:00
|
|
|
|
errno = 0;
|
2019-12-21 19:57:28 +01:00
|
|
|
|
size_t buf_len = 1024;
|
|
|
|
|
|
do {
|
2021-02-12 09:39:44 +01:00
|
|
|
|
_cwd = xrealloc(_cwd, buf_len);
|
|
|
|
|
|
if (getcwd(_cwd, buf_len) == NULL && errno != ERANGE) {
|
2020-02-20 18:46:45 +01:00
|
|
|
|
LOG_ERRNO("failed to get current working directory");
|
|
|
|
|
|
goto out;
|
|
|
|
|
|
}
|
2019-12-21 19:57:28 +01:00
|
|
|
|
buf_len *= 2;
|
|
|
|
|
|
} while (errno == ERANGE);
|
2021-02-12 09:39:44 +01:00
|
|
|
|
cwd = _cwd;
|
2019-12-21 19:57:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-03-25 20:48:02 +01:00
|
|
|
|
shm_set_max_pool_size(conf.tweak.max_shm_pool_size);
|
|
|
|
|
|
|
2019-10-27 19:08:48 +01:00
|
|
|
|
if ((fdm = fdm_init()) == NULL)
|
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
2020-05-21 20:15:10 +02:00
|
|
|
|
if ((reaper = reaper_init(fdm)) == NULL)
|
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
2019-12-31 16:12:48 +01:00
|
|
|
|
if ((wayl = wayl_init(&conf, fdm)) == NULL)
|
2019-10-27 19:08:48 +01:00
|
|
|
|
goto out;
|
|
|
|
|
|
|
2020-01-04 19:49:26 +01:00
|
|
|
|
if ((renderer = render_init(fdm, wayl)) == NULL)
|
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
2019-12-21 15:27:17 +01:00
|
|
|
|
if (!as_server && (term = term_init(
|
2021-10-28 17:51:44 -07:00
|
|
|
|
&conf, fdm, reaper, wayl, "foot", cwd, token,
|
|
|
|
|
|
argc, argv,
|
2019-12-21 19:57:28 +01:00
|
|
|
|
&term_shutdown_cb, &shutdown_ctx)) == NULL) {
|
2019-11-01 20:34:32 +01:00
|
|
|
|
goto out;
|
2019-12-21 19:57:28 +01:00
|
|
|
|
}
|
2021-02-12 09:39:44 +01:00
|
|
|
|
free(_cwd);
|
|
|
|
|
|
_cwd = NULL;
|
2019-11-01 20:34:32 +01:00
|
|
|
|
|
2020-05-21 20:17:29 +02:00
|
|
|
|
if (as_server && (server = server_init(&conf, fdm, reaper, wayl)) == NULL)
|
2019-06-12 20:08:54 +02:00
|
|
|
|
goto out;
|
2019-08-12 21:49:17 +02:00
|
|
|
|
|
2021-02-10 16:21:56 +01:00
|
|
|
|
volatile sig_atomic_t aborted = false;
|
|
|
|
|
|
if (!fdm_signal_add(fdm, SIGINT, &fdm_sigint, (void *)&aborted) ||
|
|
|
|
|
|
!fdm_signal_add(fdm, SIGTERM, &fdm_sigint, (void *)&aborted))
|
|
|
|
|
|
{
|
2019-11-01 20:35:42 +01:00
|
|
|
|
goto out;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-05 15:25:26 +01:00
|
|
|
|
const struct sigaction sig_ign = {.sa_handler = SIG_IGN};
|
|
|
|
|
|
if (sigaction(SIGHUP, &sig_ign, NULL) < 0 ||
|
|
|
|
|
|
sigaction(SIGPIPE, &sig_ign, NULL) < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
LOG_ERRNO("failed to ignore SIGHUP+SIGPIPE");
|
2019-11-03 13:23:49 +01:00
|
|
|
|
goto out;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-01 20:37:22 +01:00
|
|
|
|
if (as_server)
|
|
|
|
|
|
LOG_INFO("running as server; launch terminals by running footclient");
|
2019-10-27 19:21:36 +01:00
|
|
|
|
|
2020-02-05 19:53:50 +01:00
|
|
|
|
if (as_server && pid_file != NULL) {
|
|
|
|
|
|
if (!print_pid(pid_file, &unlink_pid_file))
|
|
|
|
|
|
goto out;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-26 18:23:28 +01:00
|
|
|
|
while (likely(!aborted && (as_server || tll_length(wayl->terms) > 0))) {
|
|
|
|
|
|
if (unlikely(!fdm_poll(fdm)))
|
2019-06-12 20:08:54 +02:00
|
|
|
|
break;
|
2019-10-27 11:46:18 +01:00
|
|
|
|
}
|
2019-07-21 19:14:19 +02:00
|
|
|
|
|
2021-04-30 22:47:16 +02:00
|
|
|
|
if (aborted || tll_length(wayl->terms) == 0)
|
|
|
|
|
|
ret = EXIT_SUCCESS;
|
2019-07-21 19:14:19 +02:00
|
|
|
|
|
2019-10-27 11:46:18 +01:00
|
|
|
|
out:
|
2021-02-12 09:39:44 +01:00
|
|
|
|
free(_cwd);
|
2019-11-01 20:34:32 +01:00
|
|
|
|
server_destroy(server);
|
|
|
|
|
|
term_destroy(term);
|
2019-11-05 09:30:24 +01:00
|
|
|
|
|
|
|
|
|
|
shm_fini();
|
2020-01-04 19:49:26 +01:00
|
|
|
|
render_destroy(renderer);
|
2019-10-27 19:08:48 +01:00
|
|
|
|
wayl_destroy(wayl);
|
2020-05-21 20:15:10 +02:00
|
|
|
|
reaper_destroy(reaper);
|
2021-02-10 16:21:56 +01:00
|
|
|
|
fdm_signal_del(fdm, SIGTERM);
|
|
|
|
|
|
fdm_signal_del(fdm, SIGINT);
|
2019-10-27 11:46:18 +01:00
|
|
|
|
fdm_destroy(fdm);
|
2019-10-28 18:25:19 +01:00
|
|
|
|
|
2019-11-02 13:50:40 +01:00
|
|
|
|
config_free(conf);
|
2019-12-19 07:25:05 +01:00
|
|
|
|
|
2020-02-05 19:53:50 +01:00
|
|
|
|
if (unlink_pid_file)
|
|
|
|
|
|
unlink(pid_file);
|
|
|
|
|
|
|
2019-12-19 07:25:05 +01:00
|
|
|
|
LOG_INFO("goodbye");
|
2019-11-20 19:43:31 +01:00
|
|
|
|
log_deinit();
|
2019-11-01 20:34:32 +01:00
|
|
|
|
return ret == EXIT_SUCCESS && !as_server ? shutdown_ctx.exit_code : ret;
|
2019-06-12 20:08:54 +02:00
|
|
|
|
}
|