mirror of
https://github.com/javalsai/lidm.git
synced 2026-02-27 12:00:44 +01:00
feat: wait for X DISPLAY before starting session
Launch X.org with a pipe fd where it will output the DISPLAY number, once ready.
This commit is contained in:
113
src/auth.c
113
src/auth.c
@@ -23,10 +23,11 @@
|
|||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define DEFAULT_XORG_DISPLAY 0
|
|
||||||
// no PATH search for now
|
// no PATH search for now
|
||||||
#define XORG_COMMAND "/usr/bin/X"
|
#define XORG_COMMAND "/usr/bin/X"
|
||||||
|
|
||||||
|
#define XORG_MESSAGE_LENGTH 16
|
||||||
|
|
||||||
static void try_source_file(struct Vector* NNULLABLE vec_envlist,
|
static void try_source_file(struct Vector* NNULLABLE vec_envlist,
|
||||||
char* NNULLABLE filepath) {
|
char* NNULLABLE filepath) {
|
||||||
log_printf("sourcing %s\n", filepath);
|
log_printf("sourcing %s\n", filepath);
|
||||||
@@ -98,62 +99,103 @@ struct child_msg {
|
|||||||
bool err;
|
bool err;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: OR check if xorg_pid fail exited
|
/// block until X returns the display number or an error occurs
|
||||||
static int wait_for_x_ready(const int xorg_pipefd[1], __pid_t xorg_pid) {
|
static bool x_get_display(const int xorg_pipefd[2], int* display) {
|
||||||
// TODO
|
char buffer[XORG_MESSAGE_LENGTH];
|
||||||
UNUSED(xorg_pipefd);
|
bool status;
|
||||||
UNUSED(xorg_pid);
|
|
||||||
sleep(2);
|
close(xorg_pipefd[1]);
|
||||||
return 0;
|
ssize_t bytes_read = read(xorg_pipefd[0], buffer, sizeof(buffer) - 1);
|
||||||
|
buffer[bytes_read] = '\0';
|
||||||
|
|
||||||
|
if (bytes_read > 0) {
|
||||||
|
char* endptr;
|
||||||
|
int val = (int) strtol(buffer, &endptr, 10);
|
||||||
|
if (endptr == buffer) {
|
||||||
|
(void)fputs("failed to parse Xorg display response\n", stderr);
|
||||||
|
status = false;
|
||||||
|
} else {
|
||||||
|
*display = val;
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
} else if (bytes_read == 0) {
|
||||||
|
(void)fputs("Xorg pipe closed\n", stderr);
|
||||||
|
status = false;
|
||||||
|
} else {
|
||||||
|
perror("read");
|
||||||
|
status = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(xorg_pipefd[0]);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// small helper to push dyn arr
|
||||||
|
static void push_dyn_arr(void*** arr, void* item) {
|
||||||
|
struct Vector vec = vec_from_raw(*arr);
|
||||||
|
vec_push(&vec, item);
|
||||||
|
*arr = vec_as_raw(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: properly pass this down
|
// TODO: properly pass this down
|
||||||
extern int vt;
|
extern int vt;
|
||||||
// TODO: add error msgs
|
// TODO: add error msgs
|
||||||
|
/// returns on completion
|
||||||
static void launch_with_xorg_server(struct session_exec* NNULLABLE exec,
|
static void launch_with_xorg_server(struct session_exec* NNULLABLE exec,
|
||||||
struct passwd* pw,
|
struct passwd* pw,
|
||||||
char** NNULLABLE envlist) {
|
char** NNULLABLE envlist) {
|
||||||
int xorg_pipefd[2];
|
int xorg_pipefd[2];
|
||||||
pipe(xorg_pipefd);
|
if (pipe(xorg_pipefd) == -1) _exit(EXIT_FAILURE);
|
||||||
(void)fflush(NULL);
|
|
||||||
__pid_t xorg_pid = fork();
|
__pid_t xorg_pid = fork();
|
||||||
if (xorg_pid == 0) {
|
if (xorg_pid == 0) {
|
||||||
|
close(xorg_pipefd[0]);
|
||||||
if (!pw->pw_dir) _exit(EXIT_FAILURE);
|
if (!pw->pw_dir) _exit(EXIT_FAILURE);
|
||||||
// !!!!!!!!!! ATTENTION: this fails silently, of course add failure msgs but
|
// !!!!!!!!!! ATTENTION: this fails silently, of course add failure msgs but
|
||||||
// for now I can't so be careful
|
// for now I can't so be careful
|
||||||
if (vt == -1) _exit(EXIT_FAILURE);
|
if (vt == -1) _exit(EXIT_FAILURE);
|
||||||
|
|
||||||
char* display_thing;
|
// pass the pipe so Xorg can write the DISPLAY value in there
|
||||||
asprintf(&display_thing, ":%d", DEFAULT_XORG_DISPLAY);
|
char* fd_str;
|
||||||
if (!display_thing) _exit(EXIT_FAILURE);
|
asprintf(&fd_str, "%d", xorg_pipefd[1]);
|
||||||
|
if (!fd_str) _exit(EXIT_FAILURE);
|
||||||
|
|
||||||
char* vt_path;
|
char* vt_path;
|
||||||
asprintf(&vt_path, "vt%d", vt);
|
asprintf(&vt_path, "vt%d", vt);
|
||||||
if (!vt_path) {
|
if (!vt_path) {
|
||||||
free(display_thing);
|
free(fd_str);
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dup2(xorg_pipefd[1], STDERR_FILENO);
|
int exit = execle(XORG_COMMAND, XORG_COMMAND, "-displayfd", fd_str, vt_path,
|
||||||
// dup2(xorg_pipefd[1], STDOUT_FILENO);
|
NULL, envlist);
|
||||||
// close(xorg_pipefd[0]);
|
|
||||||
// close(xorg_pipefd[1]);
|
|
||||||
|
|
||||||
int exit = execle(XORG_COMMAND, XORG_COMMAND, display_thing, vt_path, NULL,
|
|
||||||
envlist);
|
|
||||||
perror("exec");
|
perror("exec");
|
||||||
// execle("X", "X", display_thing, vt_path, "-auth", xauth_path,
|
|
||||||
// "-nolisten", "tcp", "-background", "none", NULL, envlist);
|
|
||||||
|
|
||||||
printf("wtf3\n");
|
|
||||||
(void)fflush(stdout);
|
|
||||||
|
|
||||||
free(vt_path);
|
free(vt_path);
|
||||||
free(display_thing);
|
free(fd_str);
|
||||||
_exit(exit);
|
_exit(exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_for_x_ready(xorg_pipefd, xorg_pid);
|
int display = 0;
|
||||||
|
if (!x_get_display(xorg_pipefd, &display)) {
|
||||||
|
(void)fputs("failed to get X display, aborting\n", stderr);
|
||||||
|
int status;
|
||||||
|
waitpid(xorg_pid, &status, 0);
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* display_env;
|
||||||
|
asprintf(&display_env, "DISPLAY=:%d", display);
|
||||||
|
if (!display_env) {
|
||||||
|
(void)fputs("failure allocating memory for DISPLAY string\n", stderr);
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
// convert back for convenient push-ing
|
||||||
|
push_dyn_arr((void***)&envlist, display_env);
|
||||||
|
if (!envlist) {
|
||||||
|
(void)fputs("failure allocating memory for DISPLAY env\n", stderr);
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
__pid_t xorg_session_pid = fork();
|
__pid_t xorg_session_pid = fork();
|
||||||
if (xorg_session_pid == 0) {
|
if (xorg_session_pid == 0) {
|
||||||
@@ -175,10 +217,6 @@ static void launch_with_xorg_server(struct session_exec* NNULLABLE exec,
|
|||||||
|
|
||||||
kill(pid_to_kill, SIGTERM);
|
kill(pid_to_kill, SIGTERM);
|
||||||
waitpid(pid_to_kill, &status, 0);
|
waitpid(pid_to_kill, &status, 0);
|
||||||
printf("wtf %d, x%d s%d - k%d\n", status, xorg_pid, xorg_session_pid,
|
|
||||||
pid_to_kill);
|
|
||||||
(void)fflush(stdout);
|
|
||||||
sleep(10);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -218,6 +256,7 @@ inline static void forked(int pipefd[2], struct passwd* pw,
|
|||||||
|
|
||||||
if (session->type == XORG) {
|
if (session->type == XORG) {
|
||||||
launch_with_xorg_server(&session->exec, pw, envlist);
|
launch_with_xorg_server(&session->exec, pw, envlist);
|
||||||
|
_exit(EXIT_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
int exit = session_exec_exec(&session->exec, envlist);
|
int exit = session_exec_exec(&session->exec, envlist);
|
||||||
perror("exec error");
|
perror("exec error");
|
||||||
@@ -260,16 +299,6 @@ bool launch(char* user, char* passwd, struct session session, void (*cb)(void),
|
|||||||
|
|
||||||
struct Vector envlist_vec = vec_from_raw((void**)env_ret.envlist);
|
struct Vector envlist_vec = vec_from_raw((void**)env_ret.envlist);
|
||||||
|
|
||||||
if (session.type == XORG) {
|
|
||||||
char* display_env;
|
|
||||||
asprintf(&display_env, "DISPLAY=:%d", DEFAULT_XORG_DISPLAY);
|
|
||||||
if (!display_env) {
|
|
||||||
print_err("alloc error");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
vec_push(&envlist_vec, display_env);
|
|
||||||
}
|
|
||||||
|
|
||||||
source_paths(&envlist_vec, &config->behavior.source, pw->pw_dir,
|
source_paths(&envlist_vec, &config->behavior.source, pw->pw_dir,
|
||||||
&config->behavior.user_source);
|
&config->behavior.user_source);
|
||||||
char** envlist = (char**)vec_as_raw(envlist_vec);
|
char** envlist = (char**)vec_as_raw(envlist_vec);
|
||||||
|
|||||||
5
src/ui.c
5
src/ui.c
@@ -186,6 +186,7 @@ void ui_update_ofield(struct opts_field* NNULLABLE self) {
|
|||||||
ui_update_field(input);
|
ui_update_field(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// draw everything
|
||||||
void scratch_print_ui() {
|
void scratch_print_ui() {
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &window);
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &window);
|
||||||
box_start = (struct uint_point){
|
box_start = (struct uint_point){
|
||||||
@@ -313,6 +314,8 @@ int load(struct Vector* users, struct Vector* sessions) {
|
|||||||
&restore_all, g_config)) {
|
&restore_all, g_config)) {
|
||||||
print_passwd(utf8len(of_passwd.efield.content), true);
|
print_passwd(utf8len(of_passwd.efield.content), true);
|
||||||
ui_update_cursor_focus();
|
ui_update_cursor_focus();
|
||||||
|
} else {
|
||||||
|
scratch_print_ui();
|
||||||
}
|
}
|
||||||
} else if (ansi_key == A_UP || ansi_key == A_DOWN) {
|
} else if (ansi_key == A_UP || ansi_key == A_DOWN) {
|
||||||
st_ch_focus(ansi_key == A_DOWN ? 1 : -1);
|
st_ch_focus(ansi_key == A_DOWN ? 1 : -1);
|
||||||
@@ -336,6 +339,8 @@ int load(struct Vector* users, struct Vector* sessions) {
|
|||||||
&restore_all, g_config)) {
|
&restore_all, g_config)) {
|
||||||
print_passwd(utf8len(of_passwd.efield.content), true);
|
print_passwd(utf8len(of_passwd.efield.content), true);
|
||||||
ui_update_cursor_focus();
|
ui_update_cursor_focus();
|
||||||
|
} else {
|
||||||
|
scratch_print_ui();
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
st_kbd_type(seq, g_config->behavior.include_defshell);
|
st_kbd_type(seq, g_config->behavior.include_defshell);
|
||||||
|
|||||||
Reference in New Issue
Block a user