/***********************************************************/ /* ntux: native translation und extension */ /* Copyright (C) 2016--2021 SysDeer Technologies, LLC */ /* 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) { int ret; int32_t status; 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_openat( ntux_driver_fdcwd(dctx), logfile,O_CREAT|O_TRUNC|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 */ struct ntux_driver_ctx_impl * ictx = ntux_get_driver_ictx(dctx); __sys_wait4( pid, &ictx->cctx.status, 0,0); return 0; }