mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-16 08:21:20 -04:00
client: quickly implement --auto-server
With a lot of @todos, and a big sleep to wait for the server to launch Factorize connect()s between -s, no -s, and retries for --auto-server
This commit is contained in:
parent
c34f063307
commit
0afbb4cedf
1 changed files with 72 additions and 12 deletions
84
client.c
84
client.c
|
|
@ -83,6 +83,7 @@ print_usage(const char *prog_name)
|
||||||
" -L,--login-shell start shell as a login shell\n"
|
" -L,--login-shell start shell as a login shell\n"
|
||||||
" -D,--working-directory=DIR directory to start in (CWD)\n"
|
" -D,--working-directory=DIR directory to start in (CWD)\n"
|
||||||
" -s,--server-socket=PATH path to the server UNIX domain socket (default=$XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock)\n"
|
" -s,--server-socket=PATH path to the server UNIX domain socket (default=$XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock)\n"
|
||||||
|
" -S,--auto-server run a server if none detected\n"
|
||||||
" -H,--hold remain open after child process exits\n"
|
" -H,--hold remain open after child process exits\n"
|
||||||
" -N,--no-wait detach the client process from the running terminal, exiting immediately\n"
|
" -N,--no-wait detach the client process from the running terminal, exiting immediately\n"
|
||||||
" -o,--override=[section.]key=value override configuration option\n"
|
" -o,--override=[section.]key=value override configuration option\n"
|
||||||
|
|
@ -137,6 +138,55 @@ send_string_list(int fd, const string_list_t *string_list)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
start_server(void)
|
||||||
|
{
|
||||||
|
pid_t pid = fork();
|
||||||
|
|
||||||
|
if (pid > 0) {
|
||||||
|
LOG_DBG("forked a server with PID %d", pid);
|
||||||
|
/* @todo How to wait for the server having initialized itself? */
|
||||||
|
/* @todo Use --server-socket=<fd of the .sock opened here in the client>? */
|
||||||
|
sleep(1);
|
||||||
|
/* @todo Test if the process exited.
|
||||||
|
int status;
|
||||||
|
pid_t pid = waitpid(-1, &status, WNOHANG);
|
||||||
|
if (pid < 0) {
|
||||||
|
LOG_ERRNO("could not tell the server's status");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (pid > 0) {
|
||||||
|
LOG_ERRNO("the server unexpectedly exited with status %d", status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid < 0) {
|
||||||
|
LOG_ERRNO("failed to fork");
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Child */
|
||||||
|
|
||||||
|
/* @todo Does the server do all signaling cleanup, so that we don't have to? */
|
||||||
|
|
||||||
|
char **foot = xmalloc(3 * sizeof(char *));
|
||||||
|
foot[0] = "foot";
|
||||||
|
foot[1] = "--server";
|
||||||
|
foot[2] = NULL;
|
||||||
|
if (execvp(foot[0], foot) < 0)
|
||||||
|
LOG_ERRNO("failed to execvp %s", foot[0]);
|
||||||
|
|
||||||
|
xassert(false);
|
||||||
|
_exit(errno);
|
||||||
|
|
||||||
|
/* @todo Has the server correctly detached itself, so that our client exiting does not abort the server? */
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *const *argv)
|
main(int argc, char *const *argv)
|
||||||
{
|
{
|
||||||
|
|
@ -158,6 +208,7 @@ main(int argc, char *const *argv)
|
||||||
{"login-shell", no_argument, NULL, 'L'},
|
{"login-shell", no_argument, NULL, 'L'},
|
||||||
{"working-directory", required_argument, NULL, 'D'},
|
{"working-directory", required_argument, NULL, 'D'},
|
||||||
{"server-socket", required_argument, NULL, 's'},
|
{"server-socket", required_argument, NULL, 's'},
|
||||||
|
{"auto-server", no_argument, NULL, 'S'},
|
||||||
{"hold", no_argument, NULL, 'H'},
|
{"hold", no_argument, NULL, 'H'},
|
||||||
{"no-wait", no_argument, NULL, 'N'},
|
{"no-wait", no_argument, NULL, 'N'},
|
||||||
{"override", required_argument, NULL, 'o'},
|
{"override", required_argument, NULL, 'o'},
|
||||||
|
|
@ -171,6 +222,7 @@ main(int argc, char *const *argv)
|
||||||
|
|
||||||
const char *custom_cwd = NULL;
|
const char *custom_cwd = NULL;
|
||||||
const char *server_socket_path = NULL;
|
const char *server_socket_path = NULL;
|
||||||
|
bool auto_server = false;
|
||||||
enum log_class log_level = LOG_CLASS_WARNING;
|
enum log_class log_level = LOG_CLASS_WARNING;
|
||||||
enum log_colorize log_colorize = LOG_COLORIZE_AUTO;
|
enum log_colorize log_colorize = LOG_COLORIZE_AUTO;
|
||||||
bool hold = false;
|
bool hold = false;
|
||||||
|
|
@ -197,7 +249,7 @@ main(int argc, char *const *argv)
|
||||||
string_list_t envp = tll_init();
|
string_list_t envp = tll_init();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int c = getopt_long(argc, argv, "+t:T:a:w:W:mFLD:s:HNo:Ed:l::veh", longopts, NULL);
|
int c = getopt_long(argc, argv, "+t:T:a:w:W:mFLD:s:SHNo:Ed:l::veh", longopts, NULL);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -275,6 +327,10 @@ main(int argc, char *const *argv)
|
||||||
server_socket_path = optarg;
|
server_socket_path = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'S':
|
||||||
|
auto_server = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'H':
|
case 'H':
|
||||||
hold = true;
|
hold = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -351,16 +407,13 @@ main(int argc, char *const *argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_un addr = {.sun_family = AF_UNIX};
|
struct sockaddr_un addr = {.sun_family = AF_UNIX};
|
||||||
|
bool connected = false;
|
||||||
|
int retries = 0;
|
||||||
|
|
||||||
|
retry:
|
||||||
if (server_socket_path != NULL) {
|
if (server_socket_path != NULL) {
|
||||||
strncpy(addr.sun_path, server_socket_path, sizeof(addr.sun_path) - 1);
|
strncpy(addr.sun_path, server_socket_path, sizeof(addr.sun_path) - 1);
|
||||||
if (connect(fd, (const struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
|
||||||
LOG_ERR("%s: failed to connect (is 'foot --server' running?)", server_socket_path);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
bool connected = false;
|
|
||||||
|
|
||||||
const char *xdg_runtime = getenv("XDG_RUNTIME_DIR");
|
const char *xdg_runtime = getenv("XDG_RUNTIME_DIR");
|
||||||
if (xdg_runtime != NULL) {
|
if (xdg_runtime != NULL) {
|
||||||
const char *wayland_display = getenv("WAYLAND_DISPLAY");
|
const char *wayland_display = getenv("WAYLAND_DISPLAY");
|
||||||
|
|
@ -379,13 +432,20 @@ main(int argc, char *const *argv)
|
||||||
if (!connected)
|
if (!connected)
|
||||||
LOG_WARN("%s: failed to connect, will now try /tmp/foot.sock", addr.sun_path);
|
LOG_WARN("%s: failed to connect, will now try /tmp/foot.sock", addr.sun_path);
|
||||||
}
|
}
|
||||||
|
if (!connected)
|
||||||
if (!connected) {
|
|
||||||
strncpy(addr.sun_path, "/tmp/foot.sock", sizeof(addr.sun_path) - 1);
|
strncpy(addr.sun_path, "/tmp/foot.sock", sizeof(addr.sun_path) - 1);
|
||||||
if (connect(fd, (const struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
}
|
||||||
LOG_ERRNO("failed to connect (is 'foot --server' running?)");
|
|
||||||
goto err;
|
if (!connected) {
|
||||||
|
if (connect(fd, (const struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
|
if (++retries < 2 && auto_server) {
|
||||||
|
if (start_server() >= 0) /* @todo Pass server_socket_path */
|
||||||
|
goto retry;
|
||||||
}
|
}
|
||||||
|
LOG_ERRNO("%s%sfailed to connect (is 'foot --server' running?)",
|
||||||
|
server_socket_path ? server_socket_path : "",
|
||||||
|
server_socket_path ? ": " : "");
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue