mirror of
https://github.com/swaywm/sway.git
synced 2026-04-28 06:46:26 -04:00
When running Sway from a display manager, a user's login shell is not used. Because of this, profile scripts are not run and the environment may not be configured. As suggested in #3109, this can be solved by a wrapper that runs sway via the user's configured shell. This is similar to the approach taken by GNOME to source the standard set of profile scripts. This could be accomplished with a shell script, but a dedicated binary avoids dependencies on specific shells. The sway.desktop wayland session file is also updated to call the swayrun wrapper.
71 lines
1.5 KiB
C
71 lines
1.5 KiB
C
#define _POSIX_C_SOURCE 200809L // for getline
|
|
#include <errno.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include "stringop.h"
|
|
|
|
#define SWAY_COMMAND "sway"
|
|
|
|
char allowed_shell(char *shell) {
|
|
FILE *fp;
|
|
char *line = NULL;
|
|
size_t len = 0;
|
|
char allowed = false;
|
|
|
|
if (strstr(shell, "false") != NULL || strstr(shell, "nologin") != NULL) {
|
|
return false;
|
|
}
|
|
|
|
fp = fopen("/etc/shells", "r");
|
|
if (fp == NULL) {
|
|
return true;
|
|
}
|
|
|
|
while (getline(&line, &len, fp) != -1) {
|
|
strip_whitespace(line);
|
|
if (strcmp(shell, line) == 0) {
|
|
allowed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
if (line) {
|
|
free(line);
|
|
}
|
|
return allowed;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
char *shell = getenv("SHELL");
|
|
|
|
if (shell && allowed_shell(shell)) {
|
|
// 3 exec arguments + argc + argv[argc] NULL pointer
|
|
int exec_argc = 4 + argc;
|
|
char **exec_argv = malloc(exec_argc * sizeof(char*));
|
|
|
|
// Prefix - to shell path to indicate login shell
|
|
char *login_shell = malloc(strlen(shell) + 2);
|
|
strcpy(login_shell, "-");
|
|
strcat(login_shell, shell);
|
|
|
|
// Build the argumrnts to exec
|
|
memcpy(exec_argv + 3, argv, (argc + 1) * sizeof(argv));
|
|
exec_argv[0] = login_shell;
|
|
exec_argv[1] = "-c";
|
|
exec_argv[2] = "exec " SWAY_COMMAND " \"$@\"";
|
|
exec_argv[3] = shell;
|
|
|
|
execvp(shell, exec_argv);
|
|
fprintf(stderr, "Could not run %s using login shell: %s\n", SWAY_COMMAND, shell);
|
|
} else {
|
|
argv[0] = SWAY_COMMAND;
|
|
execvp(SWAY_COMMAND, argv);
|
|
fprintf(stderr, "Could not run %s\n", SWAY_COMMAND);
|
|
}
|
|
|
|
return errno;
|
|
}
|