Packages
backplane_agent_runtime
1.10.53
1.10.57
1.10.56
1.10.55
1.10.54
1.10.53
1.10.52
1.10.51
1.10.50
1.10.49
1.10.48
1.10.47
1.10.46
1.10.45
1.10.44
1.10.43
1.10.42
1.10.41
1.10.40
1.10.39
1.10.38
1.10.37
1.10.36
1.10.35
1.10.34
1.10.32
1.10.31
1.10.30
1.10.29
1.10.28
1.10.27
1.10.26
1.10.25
1.10.24
1.10.23
1.10.22
1.10.21
1.10.20
1.10.19
1.10.18
1.10.17
1.10.16
1.10.15
1.10.14
1.10.13
1.10.12
1.10.11
1.10.10
1.10.9
1.10.8
1.10.7
1.10.6
1.10.5
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.0
1.8.3
1.8.2
1.8.1
1.8.0
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.0
Embedded Elixir/OTP runtime and opt-in tools for bounded independent agents.
Current section
Files
Jump to
Current section
Files
c_src/local_command_pty.c
#define _GNU_SOURCE
/* Linux-only optional packet4 PTY transport. No policy or sandbox is installed. */
#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#define FRAME_MAX 65536U
#define QUEUE_MAX (262144U)
#define CONTROL_RESERVE 8192U
#define MEMBER_MAX 4096U
#define CHUNK 8192U
struct identity { pid_t pid, parent, group, session; unsigned long long start; char state; };
struct member { struct identity id; int fd; };
struct queue { unsigned char data[QUEUE_MAX]; size_t begin, end; };
struct reader { unsigned char data[FRAME_MAX + 4]; size_t used; };
struct config { const char *token, *owner, *incarnation, *session; int rows, columns, timeout; size_t output_limit; char **command; };
static int64_t now_ms(void) {
struct timespec t;
if (clock_gettime(CLOCK_MONOTONIC, &t) != 0) _exit(111);
return (int64_t)t.tv_sec * 1000 + t.tv_nsec / 1000000;
}
static int nonblock(int fd) { int f = fcntl(fd, F_GETFL); return f < 0 ? -1 : fcntl(fd, F_SETFL, f | O_NONBLOCK); }
static int pidfd_open_(pid_t pid) { return (int)syscall(SYS_pidfd_open, pid, 0); }
static int pidfd_signal(int fd, int sig) { return (int)syscall(SYS_pidfd_send_signal, fd, sig, NULL, 0); }
static bool vanished(void) { return errno == ENOENT || errno == ESRCH; }
/* Read starttime as well as session on both sides of pidfd acquisition. */
static int identity(pid_t pid, struct identity *out) {
char path[80], bytes[4096];
snprintf(path, sizeof(path), "/proc/%d/stat", pid);
int fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0) return vanished() ? 1 : -1;
ssize_t n = read(fd, bytes, sizeof(bytes) - 1);
int saved = errno;
close(fd);
errno = saved;
if (n < 0) return vanished() ? 1 : -1;
if (n == 0 || n >= (ssize_t)sizeof(bytes) - 1) return -1;
bytes[n] = 0;
char *rest = strrchr(bytes, ')');
if (!rest || rest[1] != ' ') return -1;
rest += 2;
char *save = NULL, *field = strtok_r(rest, " ", &save);
struct identity found = {.pid = pid};
for (int number = 3; number <= 22; number++) {
if (!field) return -1;
char *end = NULL;
if (number == 3) found.state = field[0];
if (number == 4) found.parent = (pid_t)strtol(field, &end, 10);
if (number == 5) found.group = (pid_t)strtol(field, &end, 10);
if (number == 6) found.session = (pid_t)strtol(field, &end, 10);
if (number == 22) found.start = strtoull(field, &end, 10);
if (end && *end && *end != '\n') return -1;
field = strtok_r(NULL, " ", &save);
}
*out = found;
return 0;
}
static bool same(const struct identity *a, const struct identity *b) { return a->pid == b->pid && a->start == b->start && a->session == b->session; }
static bool exited(const struct identity *id) { return id->state == 'Z' || id->state == 'X' || id->state == 'x'; }
static bool numeric(const char *text) {
if (*text < '1' || *text > '9') return false;
for (const char *p = text; *p; p++) if (*p < '0' || *p > '9') return false;
return true;
}
static int checked_pidfd(const struct identity *id) {
int fd = pidfd_open_(id->pid);
if (fd < 0) return vanished() ? -2 : -1;
struct identity after;
int result = identity(id->pid, &after);
if (result != 0 || !same(id, &after)) { close(fd); return result == 1 ? -2 : -1; }
return fd;
}
/* Complete census, bounded by MEMBER_MAX. Foreign unreadable entries are errors. */
static int census(pid_t sid, struct member *members, size_t *count) {
DIR *dir = opendir("/proc");
if (!dir) return -1;
struct dirent *entry;
int result = 0;
errno = 0;
while ((entry = readdir(dir))) {
if (!numeric(entry->d_name)) continue;
struct identity id;
int status = identity((pid_t)strtol(entry->d_name, NULL, 10), &id);
if (status == 1) { errno = 0; continue; }
if (status < 0) { result = -1; break; }
if (id.session != sid || exited(&id)) { errno = 0; continue; }
bool known = false;
for (size_t i = 0; i < *count; i++) if (same(&members[i].id, &id)) { known = true; break; }
if (!known) {
if (*count == MEMBER_MAX) { result = -1; break; }
int fd = checked_pidfd(&id);
if (fd == -2) { errno = 0; continue; }
if (fd < 0) { result = -1; break; }
members[*count] = (struct member){.id = id, .fd = fd};
(*count)++;
}
errno = 0;
}
if (!entry && errno != 0) result = -1;
closedir(dir);
return result;
}
static int signal_members(struct member *members, size_t count, int sig) {
for (size_t i = 0; i < count; i++) {
if (pidfd_signal(members[i].fd, sig) < 0 && errno != ESRCH) return -1;
}
return 0;
}
static int live_member(const struct member *member) {
struct pollfd p = {.fd = member->fd, .events = POLLIN};
int ready = poll(&p, 1, 0);
if (ready < 0) return -1;
return ready == 0 ? 1 : 0;
}
static int stopped_threads(pid_t pid) {
char path[80];
snprintf(path, sizeof(path), "/proc/%d/task", pid);
DIR *dir = opendir(path);
if (!dir) return vanished() ? 1 : -1;
int result = 1;
struct dirent *entry;
errno = 0;
while ((entry = readdir(dir))) {
if (!numeric(entry->d_name)) continue;
struct identity id;
int status = identity((pid_t)strtol(entry->d_name, NULL, 10), &id);
if (status < 0) { result = -1; break; }
if (status == 0 && !exited(&id) && id.state != 'T' && id.state != 't') result = 0;
errno = 0;
}
if (!entry && errno != 0) result = -1;
closedir(dir);
return result;
}
static int cleanup_session(pid_t sid, int timeout, const char **error) {
struct member *members = calloc(MEMBER_MAX, sizeof(*members));
if (!members) { *error = "allocation"; return -1; }
size_t count = 0;
int64_t started = now_ms(), deadline = started + timeout;
int result = -1;
while (now_ms() < deadline) {
size_t before = count;
if (census(sid, members, &count) < 0) { *error = "proc_observation"; break; }
if (now_ms() < started + 150) {
if (signal_members(members + before, count - before, SIGTERM) < 0 ||
signal_members(members + before, count - before, SIGCONT) < 0) { *error = "term_signal"; break; }
} else {
if (signal_members(members, count, SIGSTOP) < 0) { *error = "stop_signal"; break; }
bool stopped = true;
for (size_t i = 0; i < count; i++) {
int live = live_member(&members[i]);
if (live < 0) { *error = "pidfd_observation"; goto done; }
if (live) {
int status = stopped_threads(members[i].id.pid);
if (status < 0) { *error = "thread_observation"; goto done; }
if (!status) stopped = false;
}
}
/* A second complete scan after all observed threads stop closes ordinary
* fork admission. Newly discovered members require another stop round. */
size_t stable = count;
if (stopped) {
if (census(sid, members, &count) < 0) { *error = "proc_observation"; break; }
if (stable == count && signal_members(members, count, SIGKILL) < 0) { *error = "kill_signal"; break; }
}
}
bool alive = false;
for (size_t i = 0; i < count; i++) {
int live = live_member(&members[i]);
if (live < 0) { *error = "pidfd_observation"; goto done; }
if (live) alive = true;
}
if (!alive) {
size_t final = count;
if (census(sid, members, &count) < 0) { *error = "final_census"; break; }
if (count == final) { result = 0; *error = "none"; break; }
}
poll(NULL, 0, 5);
}
if (result != 0 && !strcmp(*error, "none")) *error = "cleanup_deadline";
done:
for (size_t i = 0; i < count; i++) close(members[i].fd);
free(members);
return result;
}
static int enqueue(struct queue *q, const void *data, size_t size, bool packet, bool control) {
size_t needed = size + (packet ? 4 : 0);
size_t limit = control ? QUEUE_MAX : QUEUE_MAX - CONTROL_RESERVE;
if (q->end - q->begin + needed > limit) return -1;
if (q->end + needed > QUEUE_MAX) {
memmove(q->data, q->data + q->begin, q->end - q->begin);
q->end -= q->begin; q->begin = 0;
}
if (packet) { uint32_t n = htonl((uint32_t)size); memcpy(q->data + q->end, &n, 4); q->end += 4; }
memcpy(q->data + q->end, data, size); q->end += size;
return 0;
}
static int flush_queue(int fd, struct queue *q) {
if (q->begin == q->end) return 0;
ssize_t n = write(fd, q->data + q->begin, q->end - q->begin);
if (n < 0) return errno == EAGAIN || errno == EINTR ? 0 : -1;
q->begin += (size_t)n;
if (q->begin == q->end) q->begin = q->end = 0;
return 0;
}
static int send_message(int fd, const void *message, size_t length) {
ssize_t n = send(fd, message, length, MSG_NOSIGNAL | MSG_DONTWAIT);
return n == (ssize_t)length ? 0 : -1;
}
static void bounded_message(int fd, const void *message, size_t size, int timeout) {
int64_t deadline = now_ms() + timeout;
while (send_message(fd, message, size) < 0 && now_ms() < deadline) {
struct pollfd p = {.fd = fd, .events = POLLOUT};
if (poll(&p, 1, 5) < 0 || p.revents & (POLLERR | POLLHUP)) break;
}
}
static int terminal_master(char *slave, size_t size, int rows, int columns) {
int fd = posix_openpt(O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0) return -1;
if (grantpt(fd) || unlockpt(fd) || ptsname_r(fd, slave, size)) { close(fd); return -1; }
struct winsize dimensions = {.ws_row = (unsigned short)rows, .ws_col = (unsigned short)columns};
if (ioctl(fd, TIOCSWINSZ, &dimensions)) { close(fd); return -1; }
return fd;
}
static int child_terminal(const char *slave, int rows, int columns) {
if (setsid() < 0) return -1;
int fd = open(slave, O_RDWR | O_CLOEXEC);
struct winsize dimensions = {.ws_row = (unsigned short)rows, .ws_col = (unsigned short)columns};
if (fd < 0 || ioctl(fd, TIOCSCTTY, 0) || ioctl(fd, TIOCSWINSZ, &dimensions)) return -1;
for (int i = 0; i < 3; i++) if (dup2(fd, i) < 0) return -1;
if (fd > 2) close(fd);
if (!isatty(0) || !isatty(1) || !isatty(2) || tcgetsid(0) != getpid()) return -1;
return 0;
}
static void child_run(const struct config *config, const char *slave, int master, int socket_fd, int gate, int ready) {
close(master); close(socket_fd);
pid_t parent = getppid();
if (prctl(PR_SET_PDEATHSIG, SIGKILL) || getppid() != parent || child_terminal(slave, config->rows, config->columns)) _exit(125);
char byte = 'R';
if (write(ready, &byte, 1) != 1) _exit(125);
close(ready);
if (read(gate, &byte, 1) != 1 || byte != 'A') _exit(125);
close(gate);
/* Everything but the three slave descriptors is CLOEXEC or already closed. */
signal(SIGPIPE, SIG_DFL);
execv(config->command[0], config->command);
_exit(127);
}
static void guardian(const struct config *config, int channel, pid_t broker) {
int null_fd = open("/dev/null", O_RDWR | O_CLOEXEC);
if (null_fd < 0) _exit(111);
for (int i = 0; i < 3; i++) if (dup2(null_fd, i) < 0) _exit(111);
if (null_fd > 2) close(null_fd);
char slave[PATH_MAX], evidence[2048];
int master = terminal_master(slave, sizeof(slave), config->rows, config->columns);
int gate[2], ready[2];
if (master < 0 || pipe2(gate, O_CLOEXEC) || pipe2(ready, O_CLOEXEC)) _exit(111);
if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) _exit(111);
pid_t child = fork();
if (child < 0) _exit(111);
if (!child) { close(gate[1]); close(ready[0]); child_run(config, slave, master, channel, gate[0], ready[1]); }
close(gate[0]); close(ready[1]);
struct pollfd setup = {.fd = ready[0], .events = POLLIN};
char byte = 0;
int setup_result = poll(&setup, 1, 1000);
bool setup_ok = setup_result > 0 && read(ready[0], &byte, 1) == 1 && byte == 'R';
close(ready[0]);
struct identity b, g, c;
bool identities_ok = identity(broker, &b) == 0 && identity(getpid(), &g) == 0 && identity(child, &c) == 0;
bool identity_ok = identities_ok && c.parent == getpid() && c.session == child && c.group == child;
if (!setup_ok || !identity_ok) {
close(gate[1]);
/* The pre-exec child either exited or is the exact fork child. pidfd only. */
int fd = pidfd_open_(child);
if (fd >= 0) { (void)pidfd_signal(fd, SIGKILL); close(fd); }
int64_t deadline = now_ms() + 100;
while (waitpid(child, NULL, WNOHANG) == 0 && now_ms() < deadline) poll(NULL, 0, 5);
close(master); _exit(111);
}
snprintf(evidence, sizeof(evidence), "1 %s %d %llu %d %llu %d %llu %d %d %d %s %s %s", config->token, broker, b.start, getpid(), g.start, child, c.start, child, config->rows, config->columns, config->owner, config->incarnation, config->session);
char message[FRAME_MAX];
message[0] = 'R'; memcpy(message + 1, evidence, strlen(evidence));
bounded_message(channel, message, strlen(evidence) + 1, 100);
bool dispatched = false, cancel = false, child_seen = false, limited = false;
int child_status = -1;
size_t output_bytes = 0;
struct queue input = {0};
while (!cancel) {
siginfo_t info = {0};
if (waitid(P_PID, (id_t)child, &info, WEXITED | WNOHANG | WNOWAIT) < 0) { cancel = true; break; }
if (info.si_pid == child) {
child_seen = true;
child_status = info.si_code == CLD_EXITED ? info.si_status : 128 + info.si_status;
int length = snprintf(message, sizeof(message), "X%d", child_status);
bounded_message(channel, message, (size_t)length, 10);
break;
}
struct pollfd fds[2] = {{.fd = channel, .events = POLLIN}, {.fd = master, .events = POLLIN | (input.end > input.begin ? POLLOUT : 0)}};
int polled = poll(fds, 2, 10);
if (polled < 0 && errno != EINTR) { cancel = true; break; }
if (fds[0].revents & (POLLIN | POLLHUP | POLLERR)) {
ssize_t n = recv(channel, message, sizeof(message), MSG_DONTWAIT);
if (n <= 0) { cancel = true; break; }
if (message[0] == 'C') { cancel = true; break; }
if (message[0] == 'A' && !dispatched && (size_t)n == strlen(config->token) + 1 && !memcmp(message + 1, config->token, (size_t)n - 1)) {
byte = 'A';
if (write(gate[1], &byte, 1) != 1) { cancel = true; break; }
close(gate[1]); gate[1] = -1; dispatched = true;
} else if (message[0] == 'I' && dispatched) {
if (enqueue(&input, message + 1, (size_t)n - 1, false, false)) { limited = true; cancel = true; break; }
} else { cancel = true; break; }
}
if ((fds[1].revents & POLLOUT) && flush_queue(master, &input)) { cancel = true; break; }
if (fds[1].revents & POLLIN) {
ssize_t n = read(master, message + 1, CHUNK);
if (n > 0) {
size_t allowed = config->output_limit > output_bytes ? config->output_limit - output_bytes : 0;
if ((size_t)n > allowed) { n = (ssize_t)allowed; limited = true; }
message[0] = 'O';
if (n && send_message(channel, message, (size_t)n + 1)) limited = true;
output_bytes += (size_t)n;
if (limited) { cancel = true; break; }
}
}
}
if (gate[1] >= 0) close(gate[1]);
if (limited) bounded_message(channel, "L", 1, 10);
const char *error = "none";
int clean = cleanup_session(child, config->timeout, &error);
/* Preserve final terminal bytes after normal exit, within the same byte cap. */
for (int i = 0; i < 32; i++) {
ssize_t n = read(master, message + 1, CHUNK);
if (n <= 0) break;
size_t allowed = config->output_limit > output_bytes ? config->output_limit - output_bytes : 0;
if ((size_t)n > allowed) { n = (ssize_t)allowed; limited = true; }
message[0] = 'O';
if (n && send_message(channel, message, (size_t)n + 1)) limited = true;
output_bytes += (size_t)n;
}
if (limited) bounded_message(channel, "L", 1, 10);
if (!child_seen) {
siginfo_t info = {0};
if (waitid(P_PID, (id_t)child, &info, WEXITED | WNOHANG | WNOWAIT) == 0 && info.si_pid == child) {
child_status = info.si_code == CLD_EXITED ? info.si_status : 128 + info.si_status;
child_seen = true;
}
}
/* No unbounded wait on a D-state leader: only reap observed exited children. */
if (child_seen) {
if (waitpid(child, NULL, WNOHANG) != child) { clean = -1; if (!strcmp(error, "none")) error = "leader_reap_unobserved"; }
} else { clean = -1; if (!strcmp(error, "none")) error = "leader_exit_unobserved"; }
while (waitpid(-1, NULL, WNOHANG) > 0) {}
if (close(master) != 0) { clean = -1; if (!strcmp(error, "none")) error = "master_close"; }
int length = snprintf(message, sizeof(message), "K%s|%d|%s|closed|%s|reaped|%s", evidence, child_status, clean == 0 ? "confirmed" : "uncertain", dispatched ? "dispatched" : "never_started", error);
bounded_message(channel, message, (size_t)length, 50);
close(channel);
_exit(clean == 0 ? 0 : 1);
}
/* Broker sole Port endpoint. Both pipes and lifeline are nonblocking. */
static int broker(const struct config *config) {
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, sockets)) return 111;
pid_t guardian_pid = fork();
if (guardian_pid < 0) return 111;
if (!guardian_pid) { close(sockets[0]); guardian(config, sockets[1], getppid()); }
close(sockets[1]);
nonblock(STDIN_FILENO); nonblock(STDOUT_FILENO);
struct queue output = {0};
struct reader input = {0};
unsigned char message[FRAME_MAX];
char ready[2048] = "", proof[4096] = "";
bool cancelling = false, guardian_done = false, final = false;
int guardian_status = -1;
int64_t stop_deadline = INT64_MAX;
for (;;) {
struct pollfd fds[3] = {{.fd = STDIN_FILENO, .events = cancelling ? 0 : POLLIN}, {.fd = STDOUT_FILENO, .events = output.end > output.begin ? POLLOUT : 0}, {.fd = sockets[0], .events = POLLIN}};
if (poll(fds, 3, 5) < 0 && errno != EINTR) break;
if (fds[1].revents & POLLOUT) if (flush_queue(STDOUT_FILENO, &output)) break;
if (fds[0].revents & (POLLIN | POLLHUP | POLLERR)) {
ssize_t n = read(STDIN_FILENO, input.data + input.used, sizeof(input.data) - input.used);
if (n <= 0 && errno != EAGAIN && errno != EINTR) cancelling = true;
if (n == 0) cancelling = true;
if (n > 0) input.used += (size_t)n;
while (input.used >= 4) {
uint32_t length;
memcpy(&length, input.data, 4); length = ntohl(length);
if (!length || length > FRAME_MAX) { cancelling = true; break; }
if (input.used < length + 4U) break;
if (input.data[4] == 'C') cancelling = true;
if (send_message(sockets[0], input.data + 4, length)) cancelling = true;
memmove(input.data, input.data + length + 4, input.used - length - 4);
input.used -= length + 4;
}
}
if (cancelling && stop_deadline == INT64_MAX) {
(void)send_message(sockets[0], "C", 1);
/* SHUT_WR is reliable cancellation even when the bounded socket is full. */
shutdown(sockets[0], SHUT_WR);
stop_deadline = now_ms() + config->timeout + 200;
}
if (fds[2].revents & (POLLIN | POLLHUP | POLLERR)) {
for (int i = 0; i < 64; i++) {
ssize_t n = recv(sockets[0], message, sizeof(message), MSG_DONTWAIT);
if (n <= 0) break;
if (message[0] == 'R' && (size_t)n < sizeof(ready)) { memcpy(ready, message + 1, (size_t)n - 1); ready[n - 1] = 0; }
if (message[0] == 'K') {
if ((size_t)n < sizeof(proof)) { memcpy(proof, message + 1, (size_t)n - 1); proof[n - 1] = 0; }
} else if (enqueue(&output, message, (size_t)n, true, message[0] != 'O')) {
if (!cancelling) (void)enqueue(&output, "L", 1, true, true);
cancelling = true;
}
}
}
if (!guardian_done) {
pid_t waited = waitpid(guardian_pid, &guardian_status, WNOHANG);
if (waited == guardian_pid) guardian_done = true;
}
if (guardian_done && !final) {
/* Drain the result queued immediately before G exited. */
ssize_t n;
while ((n = recv(sockets[0], message, sizeof(message), MSG_DONTWAIT)) > 0) {
if (message[0] == 'K' && (size_t)n < sizeof(proof)) { memcpy(proof, message + 1, (size_t)n - 1); proof[n - 1] = 0; }
else if (message[0] != 'K') (void)enqueue(&output, message, (size_t)n, true, message[0] != 'O');
}
if (proof[0] && WIFEXITED(guardian_status) &&
(WEXITSTATUS(guardian_status) == 0 || (WEXITSTATUS(guardian_status) == 1 && strstr(proof, "|uncertain|")))) {
n = snprintf((char *)message, sizeof(message), "F%s", proof);
} else {
n = snprintf((char *)message, sizeof(message), "F%s|-1|uncertain|unknown|unknown|reaped|guardian_proof_missing", ready);
}
(void)enqueue(&output, message, (size_t)n, true, true);
final = true;
stop_deadline = now_ms() + 100;
}
if (final && output.end == output.begin) { close(sockets[0]); return 0; }
if (now_ms() >= stop_deadline) break;
}
close(sockets[0]);
/* Closing the lifeline asks G to clean; bounded wait never fabricates proof. */
int64_t deadline = now_ms() + config->timeout + 100;
while (!guardian_done && now_ms() < deadline) {
if (waitpid(guardian_pid, &guardian_status, WNOHANG) == guardian_pid) guardian_done = true;
else poll(NULL, 0, 5);
}
return 1;
}
static int probe(void) {
struct identity self;
if (identity(getpid(), &self)) return 1;
struct member *members = calloc(MEMBER_MAX, sizeof(*members));
if (!members) return 1;
size_t count = 0;
int observation = census(-1, members, &count);
free(members);
if (observation < 0) return 1;
int fd = pidfd_open_(getpid());
if (fd < 0 || pidfd_signal(fd, 0)) { if (fd >= 0) close(fd); return 1; }
close(fd);
char slave[PATH_MAX];
int master = terminal_master(slave, sizeof(slave), 24, 80);
if (master < 0) return 1;
pid_t child = fork();
if (child < 0) { close(master); return 1; }
if (!child) { close(master); _exit(child_terminal(slave, 24, 80) == 0 ? 0 : 1); }
int status;
if (waitpid(child, &status, 0) != child) { close(master); return 1; }
close(master);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) return 1;
return write(STDOUT_FILENO, "BACKPLANE_PTY 1\n", 16) == 16 ? 0 : 1;
}
static long number(const char *text, long minimum, long maximum) {
char *end;
errno = 0;
long value = strtol(text, &end, 10);
return errno || *end || value < minimum || value > maximum ? -1 : value;
}
int main(int argc, char **argv) {
signal(SIGPIPE, SIG_IGN);
if (argc == 2 && !strcmp(argv[1], "--probe")) return probe();
if (argc < 11 || strcmp(argv[1], "--run")) return 64;
for (int i = 2; i <= 5; i++) if (!argv[i][0] || strlen(argv[i]) > 256 || strpbrk(argv[i], " |\n\r")) return 64;
struct config config = {.token = argv[2], .owner = argv[3], .incarnation = argv[4], .session = argv[5],
.rows = (int)number(argv[6], 1, 1000), .columns = (int)number(argv[7], 1, 1000),
.timeout = (int)number(argv[8], 1, 4000), .output_limit = (size_t)number(argv[9], 1, LONG_MAX), .command = &argv[10]};
if (config.rows < 0 || config.columns < 0 || config.timeout < 0 || config.output_limit == (size_t)-1 || argv[10][0] != '/') return 64;
return broker(&config);
}