mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
Set up pseudo terminal and fork slave
This commit is contained in:
parent
4de6a8ad38
commit
acda4d2d31
4 changed files with 127 additions and 7 deletions
62
main.c
62
main.c
|
|
@ -2,7 +2,9 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
|
|
@ -12,7 +14,9 @@
|
|||
#define LOG_MODULE "main"
|
||||
#define LOG_ENABLE_DBG 1
|
||||
#include "log.h"
|
||||
|
||||
#include "shm.h"
|
||||
#include "slave.h"
|
||||
|
||||
struct wayland {
|
||||
struct wl_display *display;
|
||||
|
|
@ -27,6 +31,7 @@ struct wayland {
|
|||
|
||||
struct context {
|
||||
bool quit;
|
||||
int ptmx;
|
||||
struct wayland wl;
|
||||
};
|
||||
|
||||
|
|
@ -71,7 +76,7 @@ static void
|
|||
handle_global(void *data, struct wl_registry *registry,
|
||||
uint32_t name, const char *interface, uint32_t version)
|
||||
{
|
||||
LOG_DBG("global: %s", interface);
|
||||
//LOG_DBG("global: %s", interface);
|
||||
struct context *c = data;
|
||||
|
||||
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||
|
|
@ -144,7 +149,7 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
|
|||
int32_t width, int32_t height, struct wl_array *states)
|
||||
{
|
||||
//struct context *c = data;
|
||||
LOG_DBG("xdg-toplevel: configure: %dx%d", width, height);
|
||||
//LOG_DBG("xdg-toplevel: configure: %dx%d", width, height);
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
|
|
@ -169,7 +174,7 @@ static void
|
|||
xdg_surface_configure(void *data, struct xdg_surface *xdg_surface,
|
||||
uint32_t serial)
|
||||
{
|
||||
LOG_DBG("xdg-surface: configure");
|
||||
//LOG_DBG("xdg-surface: configure");
|
||||
xdg_surface_ack_configure(xdg_surface, serial);
|
||||
}
|
||||
|
||||
|
|
@ -196,9 +201,15 @@ main(int argc, const char *const *argv)
|
|||
|
||||
struct context c = {
|
||||
.quit = false,
|
||||
.ptmx = posix_openpt(O_RDWR | O_NOCTTY),
|
||||
.wl = {0},
|
||||
};
|
||||
|
||||
if (c.ptmx == -1) {
|
||||
LOG_ERRNO("failed to open pseudo terminal");
|
||||
goto out;
|
||||
}
|
||||
|
||||
c.wl.display = wl_display_connect(NULL);
|
||||
if (c.wl.display == NULL) {
|
||||
LOG_ERR("failed to connect to wayland; no compositor running?");
|
||||
|
|
@ -252,23 +263,57 @@ main(int argc, const char *const *argv)
|
|||
|
||||
wl_display_dispatch_pending(c.wl.display);
|
||||
|
||||
pid_t pid = fork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
LOG_ERRNO("failed to fork");
|
||||
goto out;
|
||||
|
||||
case 0:
|
||||
/* Child */
|
||||
slave_spawn(c.ptmx);
|
||||
assert(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_DBG("slave has PID %d", pid);
|
||||
break;
|
||||
}
|
||||
|
||||
while (!c.quit) {
|
||||
struct pollfd fds[] = {
|
||||
{.fd = wl_display_get_fd(c.wl.display), .events = POLLIN},
|
||||
{.fd = c.ptmx, .events = POLLIN},
|
||||
};
|
||||
|
||||
wl_display_flush(c.wl.display);
|
||||
poll(fds, 1, -1);
|
||||
poll(fds, sizeof(fds) / sizeof(fds[0]), -1);
|
||||
|
||||
if (fds[0].revents & POLLIN) {
|
||||
wl_display_dispatch(c.wl.display);
|
||||
}
|
||||
|
||||
if (fds[0].revents & POLLHUP) {
|
||||
LOG_WARN("disconnected from wayland");
|
||||
break;
|
||||
}
|
||||
|
||||
wl_display_dispatch(c.wl.display);
|
||||
}
|
||||
if (fds[1].revents & POLLIN) {
|
||||
char data[1024];
|
||||
ssize_t count = read(c.ptmx, data, sizeof(data));
|
||||
if (count < 0) {
|
||||
LOG_ERRNO("failed to read from pseudo terminal");
|
||||
break;
|
||||
}
|
||||
|
||||
ret = EXIT_SUCCESS;
|
||||
LOG_DBG("%.*s", (int)count, data);
|
||||
}
|
||||
|
||||
if (fds[1].revents & POLLHUP) {
|
||||
ret = EXIT_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
shm_fini();
|
||||
|
|
@ -289,6 +334,9 @@ out:
|
|||
if (c.wl.display != NULL)
|
||||
wl_display_disconnect(c.wl.display);
|
||||
|
||||
if (c.ptmx != -1)
|
||||
close(c.ptmx);
|
||||
|
||||
cairo_debug_reset_static_data();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ executable(
|
|||
'log.c', 'log.h',
|
||||
'main.c',
|
||||
'shm.c', 'shm.h',
|
||||
'slave.c', 'slave.h',
|
||||
'tllist.h',
|
||||
wl_proto_src + wl_proto_headers,
|
||||
dependencies: [cairo, cairo_ft, fontconfig, wayland_client, wayland_cursor, xkb],
|
||||
|
|
|
|||
67
slave.c
Normal file
67
slave.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#define _XOPEN_SOURCE 500
|
||||
#include "slave.h"
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define LOG_MODULE "slave"
|
||||
#define LOG_ENABLE_DBG 1
|
||||
#include "log.h"
|
||||
|
||||
void
|
||||
slave_spawn(int ptmx)
|
||||
{
|
||||
int pts = -1;
|
||||
const char *pts_name = ptsname(ptmx);
|
||||
|
||||
if (grantpt(ptmx) == -1) {
|
||||
LOG_ERRNO("failed to grantpt()");
|
||||
goto err;
|
||||
}
|
||||
if (unlockpt(ptmx) == -1) {
|
||||
LOG_ERRNO("failed to unlockpt()");
|
||||
goto err;
|
||||
}
|
||||
|
||||
close(ptmx);
|
||||
ptmx = -1;
|
||||
|
||||
if (setsid() == -1) {
|
||||
LOG_ERRNO("failed to setsid()");
|
||||
goto err;
|
||||
}
|
||||
|
||||
pts = open(pts_name, O_RDWR);
|
||||
if (pts == -1) {
|
||||
LOG_ERRNO("failed to open pseudo terminal slave device");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (dup2(pts, STDIN_FILENO) == -1 ||
|
||||
dup2(pts, STDOUT_FILENO) == -1 ||
|
||||
dup2(pts, STDERR_FILENO) == -1)
|
||||
{
|
||||
LOG_ERRNO("failed to dup stdin/stdout/stderr");
|
||||
goto err;
|
||||
}
|
||||
|
||||
close(pts);
|
||||
pts = -1;
|
||||
|
||||
/* TODO: exec() */
|
||||
const char *s = "hello world\n";
|
||||
write(STDOUT_FILENO, s, strlen(s));
|
||||
|
||||
sleep(1000);
|
||||
|
||||
err:
|
||||
if (pts != -1)
|
||||
close(pts);
|
||||
if (ptmx != -1)
|
||||
close(ptmx);
|
||||
_exit(errno);
|
||||
}
|
||||
4
slave.h
Normal file
4
slave.h
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include <stdbool.h>
|
||||
|
||||
void slave_spawn(int ptmx);
|
||||
Loading…
Add table
Add a link
Reference in a new issue