diff --git a/include/ntux/ntux.h b/include/ntux/ntux.h index e6bfbd3..ff7d504 100644 --- a/include/ntux/ntux.h +++ b/include/ntux/ntux.h @@ -115,6 +115,7 @@ ntux_api void ntux_free_driver_ctx (struct ntux_driver_ctx *); /* cmd api */ ntux_api int ntux_cmd_stat (const struct ntux_driver_ctx *, const char *); ntux_api int ntux_cmd_spawn (const struct ntux_driver_ctx *); +ntux_api int ntux_cmd_strace (const struct ntux_driver_ctx *); /* utility api */ ntux_api int ntux_main (int, char **, char **); diff --git a/project/common.mk b/project/common.mk index f847b6c..c1f3080 100644 --- a/project/common.mk +++ b/project/common.mk @@ -21,6 +21,7 @@ INTERNAL_SRCS = \ CMD_SRCS = \ src/cmds/ntux_cmd_spawn.c \ src/cmds/ntux_cmd_stat.c \ + src/cmds/ntux_cmd_strace.c \ OUTPUT_SRCS = \ src/output/ntux_output_error.c \ diff --git a/src/cmds/ntux_cmd_strace.c b/src/cmds/ntux_cmd_strace.c new file mode 100644 index 0000000..08d7eb4 --- /dev/null +++ b/src/cmds/ntux_cmd_strace.c @@ -0,0 +1,137 @@ +/***********************************************************/ +/* ntux: native translation und extension */ +/* Copyright (C) 2016--2018 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */ +/***********************************************************/ + +#include +#include +#include +#include +#include + +#include +#include "ntux_driver_impl.h" +#include "ntux_nolibc_impl.h" +#include "ntux_errinfo_impl.h" + +int ntux_cmd_strace(const struct ntux_driver_ctx * dctx) +{ + int32_t status; + int ret; + pid_t pid; + const char ** argv; + const char ** envp; + unsigned char * program; + unsigned char * logfile; + struct __strace strace; + ssize_t rbytes; + ssize_t wbytes; + char * ch; + char buf[2048]; + int fdlog[2]; + int i; + + /* init */ + ntux_driver_set_ectx( + dctx,0, + dctx->cctx->sargv[0]); + + argv = (const char **)dctx->cctx->sargv; + envp = (const char **)dctx->cctx->senvp; + program = (unsigned char *)dctx->cctx->sargv[0]; + logfile = (unsigned char *)dctx->cctx->logfile; + + /* fdlog */ + if (logfile) { + if ((fdlog[1] = __sys_open(logfile,O_CREAT|O_WRONLY,0)) < 0) + if (ntux_errno_set(dctx,fdlog[1])) + return NTUX_SYSTEM_ERROR(dctx); + } else { + if ((ret = __sys_pipe(fdlog)) < 0) + if (ntux_errno_set(dctx,ret)) + return NTUX_SYSTEM_ERROR(dctx); + } + + /* strace */ + strace.size = sizeof(strace); + strace.loader = dctx->cctx->loader; + strace.fdlog = fdlog[1]; + strace.flags = 0; + + for (i=0; i<16; i++) + strace.sysmask[i] = 0xFFFFFFFF; + + for (i=0; i<16; i++) + strace.dbgmask[i] = 0; + + for (i=0; i<32; i++) + strace.osmask[i] = 0; + + /* spawn */ + pid = __sys_vfork(); + + /* failed? */ + if (pid < 0) + if (ntux_errno_set(dctx,pid)) + return NTUX_SYSTEM_ERROR(dctx); + + /* child */ + if (pid == 0) + if ((status = __sys_strace(program,argv,envp,&strace))) + if (ntux_errno_set(dctx,status)) + if (NTUX_SYSTEM_ERROR(dctx)) + __sys_exit(0); + + /* parent */ + __sys_close(fdlog[1]); + + if (dctx->cctx->logfile) { + __sys_wait4( + pid,&status, + 0,0); + + return 0; + } + + /* piped strace output */ + rbytes = __sys_read(fdlog[0],buf,sizeof(buf)); + + while (rbytes == -EINTR) + rbytes = __sys_read(fdlog[0],buf,sizeof(buf)); + + while (rbytes > 0) { + for (ch=buf; rbytes; ch += wbytes) { + wbytes = __sys_write(2,ch,rbytes); + + while (wbytes == -EINTR) + wbytes = __sys_write(2,buf,rbytes); + + if (wbytes < 0) { + __sys_close(fdlog[0]); + ntux_errno_set(dctx,wbytes); + return NTUX_SYSTEM_ERROR(dctx); + } + + rbytes -= wbytes; + } + + rbytes = __sys_read(fdlog[0],buf,sizeof(buf)); + + while (rbytes == -EINTR) + rbytes = __sys_read(fdlog[0],buf,sizeof(buf)); + } + + __sys_close(fdlog[0]); + + if (rbytes < 0) + if (ntux_errno_set(dctx,rbytes)) + return NTUX_SYSTEM_ERROR(dctx); + + /* wait */ + __sys_wait4( + pid,&status, + 0,0); + + return 0; +} diff --git a/src/driver/ntux_amain.c b/src/driver/ntux_amain.c index 9a1d9e1..5ecc267 100644 --- a/src/driver/ntux_amain.c +++ b/src/driver/ntux_amain.c @@ -80,6 +80,9 @@ int ntux_main(int argc, char ** argv, char ** envp) if (dctx->cctx->cmd == NTUX_CMD_SPAWN) ntux_cmd_spawn(dctx); + if (dctx->cctx->cmd == NTUX_CMD_STRACE) + ntux_cmd_strace(dctx); + for (unit=dctx->units; *unit; unit++) ntux_perform_unit_actions(dctx,*unit);