Use GLib to spawn browser and dmenu
This commit is contained in:
parent
778a6857d8
commit
fe7d82380e
128
src/menu.c
128
src/menu.c
@ -107,44 +107,40 @@ void open_browser(const char *in)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *url = NULL;
|
char *url, *end;
|
||||||
|
|
||||||
// If any, remove leading [ linktext ] from URL
|
// If any, remove leading [ linktext ] from URL
|
||||||
const char *end = strstr(in, "] ");
|
if (*in == '[' && (end = strstr(in, "] ")))
|
||||||
if (*in == '[' && end)
|
|
||||||
url = g_strdup(end + 2);
|
url = g_strdup(end + 2);
|
||||||
else
|
else
|
||||||
url = g_strdup(in);
|
url = g_strdup(in);
|
||||||
|
|
||||||
int browser_pid1 = fork();
|
int argc = 2+g_strv_length(settings.browser_cmd);
|
||||||
|
char **argv = g_malloc_n(argc, sizeof(char*));
|
||||||
|
|
||||||
if (browser_pid1) {
|
memcpy(argv, settings.browser_cmd, argc * sizeof(char*));
|
||||||
g_free(url);
|
argv[argc-2] = url;
|
||||||
int status;
|
argv[argc-1] = NULL;
|
||||||
waitpid(browser_pid1, &status, 0);
|
|
||||||
} else {
|
|
||||||
int browser_pid2 = fork();
|
|
||||||
if (browser_pid2) {
|
|
||||||
exit(0);
|
|
||||||
} else {
|
|
||||||
int argc = 2+g_strv_length(settings.browser_cmd);
|
|
||||||
char **argv = g_malloc_n(argc, sizeof(char*));
|
|
||||||
|
|
||||||
memcpy(argv, settings.browser_cmd, argc * sizeof(char*));
|
GError *err = NULL;
|
||||||
argv[argc-2] = url;
|
g_spawn_async(NULL,
|
||||||
argv[argc-1] = NULL;
|
argv,
|
||||||
|
NULL,
|
||||||
|
G_SPAWN_DEFAULT
|
||||||
|
| G_SPAWN_SEARCH_PATH
|
||||||
|
| G_SPAWN_STDOUT_TO_DEV_NULL
|
||||||
|
| G_SPAWN_STDERR_TO_DEV_NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&err);
|
||||||
|
|
||||||
execvp(argv[0], argv);
|
if (err) {
|
||||||
g_free(argv);
|
LOG_C("Cannot spawn browser: %s", err->message);
|
||||||
|
g_error_free(err);
|
||||||
// execvp won't return if it's successful
|
|
||||||
// so, if we're here, it's definitely an error
|
|
||||||
fprintf(stderr, "Warning: failed to execute '%s': %s\n",
|
|
||||||
settings.browser,
|
|
||||||
strerror(errno));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free(argv);
|
||||||
|
g_free(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -226,57 +222,45 @@ char *invoke_dmenu(const char *dmenu_input)
|
|||||||
if (!dmenu_input || *dmenu_input == '\0')
|
if (!dmenu_input || *dmenu_input == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
char buf[1024] = {0};
|
gint dunst_to_dmenu;
|
||||||
int child_io[2];
|
gint dmenu_to_dunst;
|
||||||
int parent_io[2];
|
GError *err = NULL;
|
||||||
if (pipe(child_io) != 0) {
|
char buf[1024];
|
||||||
LOG_W("pipe(): error in child: %s", strerror(errno));
|
char *ret = NULL;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (pipe(parent_io) != 0) {
|
|
||||||
LOG_W("pipe(): error in parent: %s", strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int pid = fork();
|
|
||||||
|
|
||||||
if (pid == 0) {
|
g_spawn_async_with_pipes(NULL,
|
||||||
close(child_io[1]);
|
settings.dmenu_cmd,
|
||||||
close(parent_io[0]);
|
NULL,
|
||||||
close(0);
|
G_SPAWN_DEFAULT
|
||||||
if (dup(child_io[0]) == -1) {
|
| G_SPAWN_SEARCH_PATH,
|
||||||
LOG_W("dup(): error in child: %s", strerror(errno));
|
NULL,
|
||||||
exit(EXIT_FAILURE);
|
NULL,
|
||||||
}
|
NULL,
|
||||||
close(1);
|
&dunst_to_dmenu,
|
||||||
if (dup(parent_io[1]) == -1) {
|
&dmenu_to_dunst,
|
||||||
LOG_W("dup(): error in parent: %s", strerror(errno));
|
NULL,
|
||||||
exit(EXIT_FAILURE);
|
&err);
|
||||||
}
|
|
||||||
execvp(settings.dmenu_cmd[0], settings.dmenu_cmd);
|
if (err) {
|
||||||
fprintf(stderr, "Warning: failed to execute '%s': %s\n",
|
LOG_C("Cannot spawn dmenu: %s", err->message);
|
||||||
settings.dmenu,
|
g_error_free(err);
|
||||||
strerror(errno));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
} else {
|
} else {
|
||||||
close(child_io[0]);
|
|
||||||
close(parent_io[1]);
|
|
||||||
size_t wlen = strlen(dmenu_input);
|
size_t wlen = strlen(dmenu_input);
|
||||||
if (write(child_io[1], dmenu_input, wlen) != wlen) {
|
if (write(dunst_to_dmenu, dmenu_input, wlen) != wlen) {
|
||||||
LOG_W("write(): error: %s", strerror(errno));
|
LOG_W("Cannot feed dmenu with input: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
close(child_io[1]);
|
close(dunst_to_dmenu);
|
||||||
|
|
||||||
size_t len = read(parent_io[0], buf, 1023);
|
ssize_t rlen = read(dmenu_to_dunst, buf, sizeof(buf));
|
||||||
|
close(dmenu_to_dunst);
|
||||||
|
|
||||||
waitpid(pid, NULL, 0);
|
if (rlen > 0)
|
||||||
|
ret = g_strndup(buf, rlen);
|
||||||
if (len == 0) {
|
else
|
||||||
return NULL;
|
LOG_W("Didn't receive input from dmenu.");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
close(parent_io[0]);
|
|
||||||
|
|
||||||
return g_strdup(buf);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user