#include <sys/cdefs.h>
__RCSID("$NetBSD: execregs.c,v 1.1 2025/02/27 00:55:32 riastradh Exp $");
#include "execregs.h"
#include <errno.h>
#include <spawn.h>
#include <stddef.h>
#include <unistd.h>
extern char **environ;
static unsigned long
nonnull(unsigned long x)
{
x |= x << 8;
x |= x << 16;
return x;
}
int
execregschild(char *path)
{
register long r0 __asm("r0") = nonnull(0x10);
register long r1 __asm("r1") = nonnull(1);
register long r2 __asm("r2") = nonnull(2);
register long r3 __asm("r3") = nonnull(3);
register long r4 __asm("r4") = nonnull(4);
register long r5 __asm("r5") = nonnull(5);
register long r6 __asm("r6") = nonnull(6);
register long r7 __asm("r7") = nonnull(7);
register long r8 __asm("r8") = nonnull(8);
register long r9 __asm("r9") = nonnull(9);
register long r10 __asm("r10") = nonnull(10);
register long r11 __asm("r11") = nonnull(11);
char *argv[] = {path, NULL};
char **envp = environ;
__asm volatile("" :
"+r"(r0),
"+r"(r1),
"+r"(r2),
"+r"(r3),
"+r"(r4),
"+r"(r5),
"+r"(r6),
"+r"(r7),
"+r"(r8),
"+r"(r9),
"+r"(r10),
"+r"(r11)
:: "memory");
return execve(path, argv, envp);
}
pid_t
spawnregschild(char *path, int fd)
{
register long r0 __asm("r0") = nonnull(0x10);
register long r1 __asm("r1") = nonnull(1);
register long r2 __asm("r2") = nonnull(2);
register long r3 __asm("r3") = nonnull(3);
register long r4 __asm("r4") = nonnull(4);
register long r5 __asm("r5") = nonnull(5);
register long r6 __asm("r6") = nonnull(6);
register long r7 __asm("r7") = nonnull(7);
register long r8 __asm("r8") = nonnull(8);
register long r9 __asm("r9") = nonnull(9);
register long r10 __asm("r10") = nonnull(10);
register long r11 __asm("r11") = nonnull(11);
char *argv[] = {path, NULL};
char **envp = environ;
posix_spawn_file_actions_t fileacts;
posix_spawnattr_t attr;
pid_t pid;
int error;
error = posix_spawn_file_actions_init(&fileacts);
if (error)
goto out;
error = posix_spawn_file_actions_adddup2(&fileacts, fd, STDOUT_FILENO);
if (error)
goto out;
error = posix_spawnattr_init(&attr);
if (error)
goto out;
__asm volatile("" :
"+r"(r0),
"+r"(r1),
"+r"(r2),
"+r"(r3),
"+r"(r4),
"+r"(r5),
"+r"(r6),
"+r"(r7),
"+r"(r8),
"+r"(r9),
"+r"(r10),
"+r"(r11)
:: "memory");
error = posix_spawn(&pid, path, &fileacts, &attr, argv, envp);
if (error)
goto out;
out: posix_spawnattr_destroy(&attr);
posix_spawn_file_actions_destroy(&fileacts);
if (error) {
errno = error;
return -1;
}
return 0;
}