|
|
8ce751 |
/***********************************************************/
|
|
|
8ce751 |
/* ntux: native translation und extension */
|
|
|
8ce751 |
/* Copyright (C) 2016--2018 Z. Gilboa */
|
|
|
8ce751 |
/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */
|
|
|
8ce751 |
/***********************************************************/
|
|
|
8ce751 |
|
|
|
8ce751 |
#include <ntapi/ntapi.h>
|
|
|
8ce751 |
#include <psxabi/sys_sysapi.h>
|
|
|
8ce751 |
#include <psxabi/sys_strace.h>
|
|
|
8ce751 |
#include <psxabi/sys_fcntl.h>
|
|
|
8ce751 |
#include <psxabi/sys_errno.h>
|
|
|
8ce751 |
|
|
|
8ce751 |
#include <ntux/ntux.h>
|
|
|
8ce751 |
#include "ntux_driver_impl.h"
|
|
|
8ce751 |
#include "ntux_nolibc_impl.h"
|
|
|
8ce751 |
#include "ntux_errinfo_impl.h"
|
|
|
8ce751 |
|
|
|
8ce751 |
int ntux_cmd_strace(const struct ntux_driver_ctx * dctx)
|
|
|
8ce751 |
{
|
|
|
8ce751 |
int32_t status;
|
|
|
8ce751 |
int ret;
|
|
|
8ce751 |
pid_t pid;
|
|
|
8ce751 |
const char ** argv;
|
|
|
8ce751 |
const char ** envp;
|
|
|
8ce751 |
unsigned char * program;
|
|
|
8ce751 |
unsigned char * logfile;
|
|
|
8ce751 |
struct __strace strace;
|
|
|
8ce751 |
ssize_t rbytes;
|
|
|
8ce751 |
ssize_t wbytes;
|
|
|
8ce751 |
char * ch;
|
|
|
8ce751 |
char buf[2048];
|
|
|
8ce751 |
int fdlog[2];
|
|
|
8ce751 |
int i;
|
|
|
8ce751 |
|
|
|
8ce751 |
/* init */
|
|
|
8ce751 |
ntux_driver_set_ectx(
|
|
|
8ce751 |
dctx,0,
|
|
|
8ce751 |
dctx->cctx->sargv[0]);
|
|
|
8ce751 |
|
|
|
8ce751 |
argv = (const char **)dctx->cctx->sargv;
|
|
|
8ce751 |
envp = (const char **)dctx->cctx->senvp;
|
|
|
8ce751 |
program = (unsigned char *)dctx->cctx->sargv[0];
|
|
|
8ce751 |
logfile = (unsigned char *)dctx->cctx->logfile;
|
|
|
8ce751 |
|
|
|
8ce751 |
/* fdlog */
|
|
|
8ce751 |
if (logfile) {
|
|
|
8ce751 |
if ((fdlog[1] = __sys_open(logfile,O_CREAT|O_WRONLY,0)) < 0)
|
|
|
8ce751 |
if (ntux_errno_set(dctx,fdlog[1]))
|
|
|
8ce751 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
8ce751 |
} else {
|
|
|
8ce751 |
if ((ret = __sys_pipe(fdlog)) < 0)
|
|
|
8ce751 |
if (ntux_errno_set(dctx,ret))
|
|
|
8ce751 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
8ce751 |
}
|
|
|
8ce751 |
|
|
|
8ce751 |
/* strace */
|
|
|
8ce751 |
strace.size = sizeof(strace);
|
|
|
8ce751 |
strace.loader = dctx->cctx->loader;
|
|
|
8ce751 |
strace.fdlog = fdlog[1];
|
|
|
8ce751 |
strace.flags = 0;
|
|
|
8ce751 |
|
|
|
8ce751 |
for (i=0; i<16; i++)
|
|
|
8ce751 |
strace.sysmask[i] = 0xFFFFFFFF;
|
|
|
8ce751 |
|
|
|
8ce751 |
for (i=0; i<16; i++)
|
|
|
8ce751 |
strace.dbgmask[i] = 0;
|
|
|
8ce751 |
|
|
|
8ce751 |
for (i=0; i<32; i++)
|
|
|
8ce751 |
strace.osmask[i] = 0;
|
|
|
8ce751 |
|
|
|
8ce751 |
/* spawn */
|
|
|
8ce751 |
pid = __sys_vfork();
|
|
|
8ce751 |
|
|
|
8ce751 |
/* failed? */
|
|
|
8ce751 |
if (pid < 0)
|
|
|
8ce751 |
if (ntux_errno_set(dctx,pid))
|
|
|
8ce751 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
8ce751 |
|
|
|
8ce751 |
/* child */
|
|
|
8ce751 |
if (pid == 0)
|
|
|
8ce751 |
if ((status = __sys_strace(program,argv,envp,&strace)))
|
|
|
8ce751 |
if (ntux_errno_set(dctx,status))
|
|
|
8ce751 |
if (NTUX_SYSTEM_ERROR(dctx))
|
|
|
8ce751 |
__sys_exit(0);
|
|
|
8ce751 |
|
|
|
8ce751 |
/* parent */
|
|
|
8ce751 |
__sys_close(fdlog[1]);
|
|
|
8ce751 |
|
|
|
8ce751 |
if (dctx->cctx->logfile) {
|
|
|
8ce751 |
__sys_wait4(
|
|
|
8ce751 |
pid,&status,
|
|
|
8ce751 |
0,0);
|
|
|
8ce751 |
|
|
|
8ce751 |
return 0;
|
|
|
8ce751 |
}
|
|
|
8ce751 |
|
|
|
8ce751 |
/* piped strace output */
|
|
|
8ce751 |
rbytes = __sys_read(fdlog[0],buf,sizeof(buf));
|
|
|
8ce751 |
|
|
|
8ce751 |
while (rbytes == -EINTR)
|
|
|
8ce751 |
rbytes = __sys_read(fdlog[0],buf,sizeof(buf));
|
|
|
8ce751 |
|
|
|
8ce751 |
while (rbytes > 0) {
|
|
|
8ce751 |
for (ch=buf; rbytes; ch += wbytes) {
|
|
|
8ce751 |
wbytes = __sys_write(2,ch,rbytes);
|
|
|
8ce751 |
|
|
|
8ce751 |
while (wbytes == -EINTR)
|
|
|
8ce751 |
wbytes = __sys_write(2,buf,rbytes);
|
|
|
8ce751 |
|
|
|
8ce751 |
if (wbytes < 0) {
|
|
|
8ce751 |
__sys_close(fdlog[0]);
|
|
|
8ce751 |
ntux_errno_set(dctx,wbytes);
|
|
|
8ce751 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
8ce751 |
}
|
|
|
8ce751 |
|
|
|
8ce751 |
rbytes -= wbytes;
|
|
|
8ce751 |
}
|
|
|
8ce751 |
|
|
|
8ce751 |
rbytes = __sys_read(fdlog[0],buf,sizeof(buf));
|
|
|
8ce751 |
|
|
|
8ce751 |
while (rbytes == -EINTR)
|
|
|
8ce751 |
rbytes = __sys_read(fdlog[0],buf,sizeof(buf));
|
|
|
8ce751 |
}
|
|
|
8ce751 |
|
|
|
8ce751 |
__sys_close(fdlog[0]);
|
|
|
8ce751 |
|
|
|
8ce751 |
if (rbytes < 0)
|
|
|
8ce751 |
if (ntux_errno_set(dctx,rbytes))
|
|
|
8ce751 |
return NTUX_SYSTEM_ERROR(dctx);
|
|
|
8ce751 |
|
|
|
8ce751 |
/* wait */
|
|
|
8ce751 |
__sys_wait4(
|
|
|
8ce751 |
pid,&status,
|
|
|
8ce751 |
0,0);
|
|
|
8ce751 |
|
|
|
8ce751 |
return 0;
|
|
|
8ce751 |
}
|