|
|
b824c9 |
/***********************************************************/
|
|
|
b824c9 |
/* ntux: native translation und extension */
|
|
|
b824c9 |
/* Copyright (C) 2016--2022 SysDeer Technologies, LLC */
|
|
|
b824c9 |
/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */
|
|
|
b824c9 |
/***********************************************************/
|
|
|
b824c9 |
|
|
|
b824c9 |
#include <ntapi/nt_termios.h>
|
|
|
b824c9 |
|
|
|
b824c9 |
#include <psxabi/sys_sysapi.h>
|
|
|
b824c9 |
#include <psxabi/sys_fcntl.h>
|
|
|
b824c9 |
#include <psxabi/sys_errno.h>
|
|
|
b824c9 |
#include <psxabi/sys_process.h>
|
|
|
b824c9 |
#include <psxxfi/xfi_framework.h>
|
|
|
b824c9 |
|
|
|
b824c9 |
#include <ntux/ntux.h>
|
|
|
b824c9 |
#include "ntux_driver_impl.h"
|
|
|
b824c9 |
#include "ntux_nolibc_impl.h"
|
|
|
b824c9 |
#include "ntux_errinfo_impl.h"
|
|
|
b824c9 |
|
|
|
b824c9 |
int ntux_cmd_bridge(const struct ntux_driver_ctx * dctx)
|
|
|
b824c9 |
{
|
|
|
b824c9 |
int ret;
|
|
|
b824c9 |
int val;
|
|
|
b824c9 |
pid_t pid;
|
|
|
b824c9 |
int argc;
|
|
|
b824c9 |
const char ** argv;
|
|
|
b824c9 |
const char ** envp;
|
|
|
b824c9 |
unsigned char * program;
|
|
|
b824c9 |
unsigned char * logfile;
|
|
|
b824c9 |
ssize_t rbytes;
|
|
|
b824c9 |
ssize_t wbytes;
|
|
|
b824c9 |
char * ch;
|
|
|
b824c9 |
char * script;
|
|
|
b824c9 |
char * interp;
|
|
|
b824c9 |
const char * usrscript;
|
|
|
b824c9 |
char ** sargv;
|
|
|
b824c9 |
const char ** pargv;
|
|
|
b824c9 |
const char ** aargv;
|
|
|
b824c9 |
char buf[2048];
|
|
|
b824c9 |
int fdlog[2];
|
|
|
b824c9 |
int32_t status;
|
|
|
b824c9 |
|
|
|
b824c9 |
struct ntux_fd_ctx fdctx;
|
|
|
b824c9 |
|
|
|
b824c9 |
/* init */
|
|
|
b824c9 |
ntux_driver_set_ectx(
|
|
|
b824c9 |
dctx,0,
|
|
|
b824c9 |
dctx->cctx->sargv[0]);
|
|
|
b824c9 |
|
|
|
b824c9 |
if (ntux_get_driver_fdctx(dctx,&fdctx) < 0)
|
|
|
b824c9 |
if (ntux_errno_set(dctx,fdlog[1]))
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
|
|
|
b824c9 |
if (dctx->cctx->interp) {
|
|
|
b824c9 |
ret = __xfi_framework_get_int32_slot_value(
|
|
|
b824c9 |
PSX_RTDATA_UDAT32_ARGV1_IS_OPTARG,
|
|
|
b824c9 |
&val;;
|
|
|
b824c9 |
|
|
|
b824c9 |
if (ret < 0)
|
|
|
b824c9 |
if (ntux_errno_set(dctx,fdlog[1]))
|
|
|
b824c9 |
return NTUX_CUSTOM_ERROR(
|
|
|
b824c9 |
dctx,
|
|
|
b824c9 |
NTUX_ERR_FLOW_ERROR);
|
|
|
b824c9 |
|
|
|
b824c9 |
for (sargv=dctx->cctx->sargv; *sargv; sargv++)
|
|
|
b824c9 |
(void)0;
|
|
|
b824c9 |
|
|
|
b824c9 |
argc = sargv - dctx->cctx->sargv;
|
|
|
b824c9 |
|
|
|
b824c9 |
if (!(aargv = ntux_calloc(argc + 3,sizeof(char *))))
|
|
|
b824c9 |
if (ntux_errno_set(dctx,fdlog[1]))
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
|
|
|
b824c9 |
if (!(script = ntux_calloc(1,NTUX_MAX_PATH)))
|
|
|
b824c9 |
if (ntux_errno_set(dctx,fdlog[1]))
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
|
|
|
b824c9 |
if (!(interp = ntux_calloc(1,NTUX_MAX_PATH)))
|
|
|
b824c9 |
if (ntux_errno_set(dctx,fdlog[1]))
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
|
|
|
b824c9 |
usrscript = val ? dctx->cctx->sargv[2] : dctx->cctx->sargv[1];
|
|
|
b824c9 |
|
|
|
b824c9 |
if (__sys_fs_npath(fdctx.fdcwd,usrscript,0,script,NTUX_MAX_PATH) < 0)
|
|
|
b824c9 |
if (ntux_errno_set(dctx,fdlog[1]))
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
|
|
|
b824c9 |
if (__sys_fs_npath(fdctx.fdcwd,dctx->cctx->interp,0,interp,NTUX_MAX_PATH) < 0)
|
|
|
b824c9 |
if (ntux_errno_set(dctx,fdlog[1]))
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
|
|
|
b824c9 |
if (val) {
|
|
|
b824c9 |
aargv[0] = interp;
|
|
|
b824c9 |
aargv[1] = dctx->cctx->sargv[1];
|
|
|
b824c9 |
aargv[2] = script;
|
|
|
b824c9 |
|
|
|
b824c9 |
sargv = &dctx->cctx->sargv[3];
|
|
|
b824c9 |
pargv = &aargv[3];
|
|
|
b824c9 |
} else {
|
|
|
b824c9 |
aargv[0] = interp;
|
|
|
b824c9 |
aargv[1] = script;
|
|
|
b824c9 |
|
|
|
b824c9 |
sargv = &dctx->cctx->sargv[2];
|
|
|
b824c9 |
pargv = &aargv[2];
|
|
|
b824c9 |
}
|
|
|
b824c9 |
|
|
|
b824c9 |
for (; *sargv; )
|
|
|
b824c9 |
*pargv++ = *sargv++;
|
|
|
b824c9 |
|
|
|
b824c9 |
argv = aargv;
|
|
|
b824c9 |
program = (unsigned char *)interp;
|
|
|
b824c9 |
} else {
|
|
|
b824c9 |
argv = (const char **)dctx->cctx->sargv;
|
|
|
b824c9 |
program = (unsigned char *)dctx->cctx->sargv[0];
|
|
|
b824c9 |
}
|
|
|
b824c9 |
|
|
|
b824c9 |
envp = (const char **)dctx->cctx->senvp;
|
|
|
b824c9 |
logfile = (unsigned char *)dctx->cctx->logfile;
|
|
|
b824c9 |
|
|
|
b824c9 |
/* fdlog */
|
|
|
b824c9 |
if (logfile) {
|
|
|
b824c9 |
if ((fdlog[1] = __sys_openat(
|
|
|
b824c9 |
ntux_driver_fdcwd(dctx),
|
|
|
b824c9 |
logfile,O_CREAT|O_TRUNC|O_WRONLY,0)) < 0)
|
|
|
b824c9 |
if (ntux_errno_set(dctx,fdlog[1]))
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
} else {
|
|
|
b824c9 |
if ((ret = __sys_pipe(fdlog)) < 0)
|
|
|
b824c9 |
if (ntux_errno_set(dctx,ret))
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
}
|
|
|
b824c9 |
|
|
|
b824c9 |
/* spawn */
|
|
|
b824c9 |
pid = __sys_vfork();
|
|
|
b824c9 |
|
|
|
b824c9 |
/* failed? */
|
|
|
b824c9 |
if (pid < 0)
|
|
|
b824c9 |
if (ntux_errno_set(dctx,pid))
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
|
|
|
b824c9 |
/* child */
|
|
|
b824c9 |
if (pid == 0)
|
|
|
b824c9 |
if ((status = __sys_execve(program,argv,envp)))
|
|
|
b824c9 |
if (ntux_errno_set(dctx,status))
|
|
|
b824c9 |
if (NTUX_SYSTEM_ERROR(dctx))
|
|
|
b824c9 |
__sys_exit(0);
|
|
|
b824c9 |
|
|
|
b824c9 |
/* parent */
|
|
|
b824c9 |
__sys_close(fdlog[1]);
|
|
|
b824c9 |
|
|
|
b824c9 |
if (dctx->cctx->logfile) {
|
|
|
b824c9 |
__sys_wait4(
|
|
|
b824c9 |
pid,&status,
|
|
|
b824c9 |
0,0);
|
|
|
b824c9 |
|
|
|
b824c9 |
return 0;
|
|
|
b824c9 |
}
|
|
|
b824c9 |
|
|
|
b824c9 |
/* piped bridge output */
|
|
|
b824c9 |
rbytes = __sys_read(fdlog[0],buf,sizeof(buf));
|
|
|
b824c9 |
|
|
|
b824c9 |
while (rbytes == -EINTR)
|
|
|
b824c9 |
rbytes = __sys_read(fdlog[0],buf,sizeof(buf));
|
|
|
b824c9 |
|
|
|
b824c9 |
while (rbytes > 0) {
|
|
|
b824c9 |
for (ch=buf; rbytes; ch += wbytes) {
|
|
|
b824c9 |
wbytes = __sys_write(2,ch,rbytes);
|
|
|
b824c9 |
|
|
|
b824c9 |
while (wbytes == -EINTR)
|
|
|
b824c9 |
wbytes = __sys_write(2,buf,rbytes);
|
|
|
b824c9 |
|
|
|
b824c9 |
if (wbytes < 0) {
|
|
|
b824c9 |
__sys_close(fdlog[0]);
|
|
|
b824c9 |
ntux_errno_set(dctx,wbytes);
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
}
|
|
|
b824c9 |
|
|
|
b824c9 |
rbytes -= wbytes;
|
|
|
b824c9 |
}
|
|
|
b824c9 |
|
|
|
b824c9 |
rbytes = __sys_read(fdlog[0],buf,sizeof(buf));
|
|
|
b824c9 |
|
|
|
b824c9 |
while (rbytes == -EINTR)
|
|
|
b824c9 |
rbytes = __sys_read(fdlog[0],buf,sizeof(buf));
|
|
|
b824c9 |
}
|
|
|
b824c9 |
|
|
|
b824c9 |
__sys_close(fdlog[0]);
|
|
|
b824c9 |
|
|
|
b824c9 |
if (rbytes < 0)
|
|
|
b824c9 |
if (ntux_errno_set(dctx,rbytes))
|
|
|
b824c9 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
b824c9 |
|
|
|
b824c9 |
/* wait */
|
|
|
b824c9 |
struct ntux_driver_ctx_impl * ictx = ntux_get_driver_ictx(dctx);
|
|
|
b824c9 |
|
|
|
b824c9 |
__sys_wait4(
|
|
|
b824c9 |
pid,
|
|
|
b824c9 |
&ictx->cctx.status,
|
|
|
b824c9 |
0,0);
|
|
|
b824c9 |
|
|
|
b824c9 |
return 0;
|
|
|
b824c9 |
}
|