mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-14 08:21:27 -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"
|
||||
" -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,--auto-server run a server if none detected\n"
|
||||
" -H,--hold remain open after child process exits\n"
|
||||
" -N,--no-wait detach the client process from the running terminal, exiting immediately\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;
|
||||
}
|
||||
|
||||
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
|
||||
main(int argc, char *const *argv)
|
||||
{
|
||||
|
|
@ -158,6 +208,7 @@ main(int argc, char *const *argv)
|
|||
{"login-shell", no_argument, NULL, 'L'},
|
||||
{"working-directory", required_argument, NULL, 'D'},
|
||||
{"server-socket", required_argument, NULL, 's'},
|
||||
{"auto-server", no_argument, NULL, 'S'},
|
||||
{"hold", no_argument, NULL, 'H'},
|
||||
{"no-wait", no_argument, NULL, 'N'},
|
||||
{"override", required_argument, NULL, 'o'},
|
||||
|
|
@ -171,6 +222,7 @@ main(int argc, char *const *argv)
|
|||
|
||||
const char *custom_cwd = NULL;
|
||||
const char *server_socket_path = NULL;
|
||||
bool auto_server = false;
|
||||
enum log_class log_level = LOG_CLASS_WARNING;
|
||||
enum log_colorize log_colorize = LOG_COLORIZE_AUTO;
|
||||
bool hold = false;
|
||||
|
|
@ -197,7 +249,7 @@ main(int argc, char *const *argv)
|
|||
string_list_t envp = tll_init();
|
||||
|
||||
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)
|
||||
break;
|
||||
|
||||
|
|
@ -275,6 +327,10 @@ main(int argc, char *const *argv)
|
|||
server_socket_path = optarg;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
auto_server = true;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
hold = true;
|
||||
break;
|
||||
|
|
@ -351,16 +407,13 @@ main(int argc, char *const *argv)
|
|||
}
|
||||
|
||||
struct sockaddr_un addr = {.sun_family = AF_UNIX};
|
||||
bool connected = false;
|
||||
int retries = 0;
|
||||
|
||||
retry:
|
||||
if (server_socket_path != NULL) {
|
||||
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 {
|
||||
bool connected = false;
|
||||
|
||||
const char *xdg_runtime = getenv("XDG_RUNTIME_DIR");
|
||||
if (xdg_runtime != NULL) {
|
||||
const char *wayland_display = getenv("WAYLAND_DISPLAY");
|
||||
|
|
@ -379,13 +432,20 @@ main(int argc, char *const *argv)
|
|||
if (!connected)
|
||||
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);
|
||||
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