Rizin
unix-like reverse engineering framework and cli tools
rz_subprocess.h File Reference
#include <rz_types.h>
#include <rz_util/rz_strbuf.h>

Go to the source code of this file.

Classes

struct  rz_process_output_t
 
struct  rz_subprocess_opt_t
 

Macros

#define RZ_SUBPROCESS_STDIN   (1 << 0)
 
#define RZ_SUBPROCESS_STDOUT   (1 << 1)
 
#define RZ_SUBPROCESS_STDERR   (1 << 2)
 

Typedefs

typedef enum rz_subprocess_pipe_create_t RzSubprocessPipeCreate
 
typedef enum rz_process_wait_reason_t RzSubprocessWaitReason
 
typedef struct rz_process_output_t RzSubprocessOutput
 
typedef struct rz_subprocess_opt_t RzSubprocessOpt
 
typedef struct rz_subprocess_t RzSubprocess
 

Enumerations

enum  rz_subprocess_pipe_create_t { RZ_SUBPROCESS_PIPE_NONE , RZ_SUBPROCESS_PIPE_CREATE , RZ_SUBPROCESS_PIPE_STDOUT }
 
enum  rz_process_wait_reason_t { RZ_SUBPROCESS_DEAD , RZ_SUBPROCESS_TIMEDOUT , RZ_SUBPROCESS_BYTESREAD }
 

Functions

RZ_API bool rz_subprocess_init (void)
 
RZ_API void rz_subprocess_fini (void)
 
RZ_API RzSubprocessrz_subprocess_start (const char *file, const char *args[], size_t args_size, const char *envvars[], const char *envvals[], size_t env_size)
 
RZ_API RzSubprocessrz_subprocess_start_opt (RzSubprocessOpt *opt)
 
RZ_API void rz_subprocess_free (RzSubprocess *proc)
 
RZ_API RzSubprocessWaitReason rz_subprocess_wait (RzSubprocess *proc, ut64 timeout_ms)
 
RZ_API void rz_subprocess_kill (RzSubprocess *proc)
 
RZ_API int rz_subprocess_ret (RzSubprocess *proc)
 
RZ_API ut8rz_subprocess_out (RzSubprocess *proc, int *length)
 
RZ_API ut8rz_subprocess_err (RzSubprocess *proc, int *length)
 
RZ_API ssize_t rz_subprocess_stdin_write (RzSubprocess *proc, const ut8 *buf, size_t buf_size)
 
RZ_API RzStrBufrz_subprocess_stdout_read (RzSubprocess *proc, size_t n, ut64 timeout_ms)
 
RZ_API RzStrBufrz_subprocess_stdout_readline (RzSubprocess *proc, ut64 timeout_ms)
 
RZ_API RzSubprocessOutputrz_subprocess_drain (RzSubprocess *proc)
 
RZ_API void rz_subprocess_output_free (RzSubprocessOutput *out)
 

Macro Definition Documentation

◆ RZ_SUBPROCESS_STDERR

#define RZ_SUBPROCESS_STDERR   (1 << 2)

Definition at line 28 of file rz_subprocess.h.

◆ RZ_SUBPROCESS_STDIN

#define RZ_SUBPROCESS_STDIN   (1 << 0)

Values passed to rz_subprocess API to mention stdin, stdout, stderr or a combination of those

Definition at line 26 of file rz_subprocess.h.

◆ RZ_SUBPROCESS_STDOUT

#define RZ_SUBPROCESS_STDOUT   (1 << 1)

Definition at line 27 of file rz_subprocess.h.

Typedef Documentation

◆ RzSubprocess

typedef struct rz_subprocess_t RzSubprocess

Definition at line 1 of file rz_subprocess.h.

◆ RzSubprocessOpt

Specify how the new subprocess should be created.

◆ RzSubprocessOutput

Provide results from running a sub-process, like output, return value, etc.

◆ RzSubprocessPipeCreate

Enum used to determine how pipes should be created, if at all, in the subprocess.

◆ RzSubprocessWaitReason

Enumeration Type Documentation

◆ rz_process_wait_reason_t

Enumerator
RZ_SUBPROCESS_DEAD 
RZ_SUBPROCESS_TIMEDOUT 
RZ_SUBPROCESS_BYTESREAD 

Definition at line 30 of file rz_subprocess.h.

30  {
@ RZ_SUBPROCESS_TIMEDOUT
Definition: rz_subprocess.h:32
@ RZ_SUBPROCESS_BYTESREAD
Definition: rz_subprocess.h:33
@ RZ_SUBPROCESS_DEAD
Definition: rz_subprocess.h:31
enum rz_process_wait_reason_t RzSubprocessWaitReason

◆ rz_subprocess_pipe_create_t

Enum used to determine how pipes should be created, if at all, in the subprocess.

Enumerator
RZ_SUBPROCESS_PIPE_NONE 

No pipe should be created. It can be used for stdin, stdout and stderr.

A new pipe should be created. It can be used for stdin, stdout and stderr.

RZ_SUBPROCESS_PIPE_CREATE 

Re-use the same pipe as stdout. It can be used for stderr only.

RZ_SUBPROCESS_PIPE_STDOUT 

Definition at line 14 of file rz_subprocess.h.

14  {
enum rz_subprocess_pipe_create_t RzSubprocessPipeCreate
@ RZ_SUBPROCESS_PIPE_NONE
No pipe should be created. It can be used for stdin, stdout and stderr.
Definition: rz_subprocess.h:16
@ RZ_SUBPROCESS_PIPE_STDOUT
Definition: rz_subprocess.h:20
@ RZ_SUBPROCESS_PIPE_CREATE
Re-use the same pipe as stdout. It can be used for stderr only.
Definition: rz_subprocess.h:18

Function Documentation

◆ rz_subprocess_drain()

RZ_API RzSubprocessOutput* rz_subprocess_drain ( RzSubprocess proc)

Definition at line 1260 of file subprocess.c.

1260  {
1261  subprocess_lock();
1263  if (out) {
1264  out->out = rz_subprocess_out(proc, &out->out_len);
1265  out->err = rz_subprocess_err(proc, &out->err_len);
1266  out->ret = proc->ret;
1267  out->timeout = false;
1268  }
1270  return out;
1271 }
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define RZ_NEW(x)
Definition: rz_types.h:285
RZ_API ut8 * rz_subprocess_out(RzSubprocess *proc, int *length)
Definition: subprocess.c:1301
RZ_API ut8 * rz_subprocess_err(RzSubprocess *proc, int *length)
Definition: subprocess.c:1312
static void subprocess_unlock(void)
Definition: subprocess.c:728
static void subprocess_lock(void)
Definition: subprocess.c:724
struct Proc * proc

References out, proc, RZ_NEW, rz_subprocess_err(), rz_subprocess_out(), subprocess_lock(), and subprocess_unlock().

Referenced by subprocess_runner().

◆ rz_subprocess_err()

RZ_API ut8* rz_subprocess_err ( RzSubprocess proc,
int length 
)

Definition at line 1312 of file subprocess.c.

1312  {
1313  int bin_len = 0;
1314  const ut8 *bin = rz_strbuf_getbin(&proc->err, &bin_len);
1315  ut8 *buf = (ut8 *)rz_str_newlen((const char *)bin, bin_len);
1316  if (length) {
1317  *length = bin_len;
1318  }
1319  rz_strbuf_fini(&proc->err);
1320  return buf;
1321 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
RZ_API char RZ_API char * rz_str_newlen(const char *str, int len)
Definition: str.c:871
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
RZ_API ut8 * rz_strbuf_getbin(RzStrBuf *sb, int *len)
Definition: strbuf.c:326
Definition: malloc.c:26

References length, proc, rz_str_newlen(), rz_strbuf_fini(), and rz_strbuf_getbin().

Referenced by rz_subprocess_drain(), rz_sys_cmd_str_full(), and rz_test_run_asm_test().

◆ rz_subprocess_fini()

RZ_API void rz_subprocess_fini ( void  )

Definition at line 814 of file subprocess.c.

814  {
815  rz_sys_signal(SIGCHLD, SIG_IGN);
816  ut8 b = 0;
817  rz_xwrite(sigchld_pipe[1], &b, 1);
824 }
RZ_API void rz_th_free(RZ_NULLABLE RzThread *th)
Frees a RzThread structure.
Definition: thread.c:246
RZ_API bool rz_th_wait(RZ_NONNULL RzThread *th)
Awaits indefinetely for a thread to join.
Definition: thread.c:231
RZ_API int rz_sys_pipe_close(int fd)
Definition: sys.c:1462
RZ_API int rz_sys_signal(int sig, void(*handler)(int))
Definition: sys.c:178
#define rz_xwrite(fd, buf, count)
Definition: rz_types.h:642
RZ_API void rz_pvector_clear(RzPVector *vec)
Definition: vector.c:326
#define b(i)
Definition: sha256.c:42
static RzThreadLock * subprocs_mutex
Definition: subprocess.c:720
static RzThread * sigchld_thread
Definition: subprocess.c:722
static RzPVector subprocs
Definition: subprocess.c:719
static int sigchld_pipe[2]
Definition: subprocess.c:721
RZ_API void rz_th_lock_free(RZ_NULLABLE RzThreadLock *thl)
Frees a RzThreadLock structure.
Definition: thread_lock.c:89

References b, rz_pvector_clear(), rz_sys_pipe_close(), rz_sys_signal(), rz_th_free(), rz_th_lock_free(), rz_th_wait(), rz_xwrite, sigchld_pipe, sigchld_thread, subprocs, and subprocs_mutex.

Referenced by rz_sys_cmd_str_full(), rz_test_main(), system_exec(), and system_exec_stdin().

◆ rz_subprocess_free()

RZ_API void rz_subprocess_free ( RzSubprocess proc)

Definition at line 1273 of file subprocess.c.

1273  {
1274  if (!proc) {
1275  return;
1276  }
1277  subprocess_lock();
1280  rz_strbuf_fini(&proc->out);
1281  rz_strbuf_fini(&proc->err);
1282  rz_sys_pipe_close(proc->killpipe[0]);
1283  rz_sys_pipe_close(proc->killpipe[1]);
1284  if (proc->stdin_fd != -1) {
1285  rz_sys_pipe_close(proc->stdin_fd);
1286  }
1287  if (proc->stdout_fd != -1) {
1288  rz_sys_pipe_close(proc->stdout_fd);
1289  }
1290  if (proc->stderr_fd != -1 && proc->stderr_fd != proc->stdout_fd) {
1291  rz_sys_pipe_close(proc->stderr_fd);
1292  }
1293  free(proc);
1294 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API void rz_pvector_remove_data(RzPVector *vec, void *x)
Definition: vector.c:362

References free(), proc, rz_pvector_remove_data(), rz_strbuf_fini(), rz_sys_pipe_close(), subprocess_lock(), subprocess_unlock(), and subprocs.

Referenced by rz_sys_cmd_str_full(), rz_test_check_jq_available(), rz_test_check_json_test(), rz_test_run_asm_test(), subprocess_runner(), system_exec(), and system_exec_stdin().

◆ rz_subprocess_init()

RZ_API bool rz_subprocess_init ( void  )

Definition at line 787 of file subprocess.c.

787  {
790  if (!subprocs_mutex) {
791  return false;
792  }
793  if (rz_sys_pipe(sigchld_pipe, true) == -1) {
794  perror("pipe");
796  return false;
797  }
799  if (!sigchld_thread) {
803  return false;
804  }
805  if (rz_sys_signal(SIGCHLD, handle_sigchld) < 0) {
809  return false;
810  }
811  return true;
812 }
#define NULL
Definition: cris-opc.c:27
RZ_API RZ_OWN RzThread * rz_th_new(RZ_NONNULL RzThreadFunction function, RZ_NULLABLE void *user)
Creates and starts a new thread.
Definition: thread.c:198
RZ_API int rz_sys_pipe(int pipefd[2], bool close_on_exec)
Definition: sys.c:1458
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
Definition: vector.c:298
static void * sigchld_th(void *th)
Definition: subprocess.c:737
static void handle_sigchld(int sig)
Definition: subprocess.c:732
RZ_API RZ_OWN RzThreadLock * rz_th_lock_new(bool recursive)
Allocates and initialize a RzThreadLock structure.
Definition: thread_lock.c:14

References handle_sigchld(), NULL, rz_pvector_init(), rz_sys_pipe(), rz_sys_pipe_close(), rz_sys_signal(), rz_th_lock_free(), rz_th_lock_new(), rz_th_new(), sigchld_pipe, sigchld_th(), sigchld_thread, subprocs, and subprocs_mutex.

Referenced by rz_sys_cmd_str_full(), rz_test_main(), system_exec(), and system_exec_stdin().

◆ rz_subprocess_kill()

RZ_API void rz_subprocess_kill ( RzSubprocess proc)

Definition at line 1256 of file subprocess.c.

1256  {
1257  kill(proc->pid, SIGKILL);
1258 }
#define SIGKILL
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc kill
Definition: sflib.h:64

References kill, proc, and SIGKILL.

Referenced by rz_test_run_asm_test(), and subprocess_runner().

◆ rz_subprocess_out()

RZ_API ut8* rz_subprocess_out ( RzSubprocess proc,
int length 
)

Definition at line 1301 of file subprocess.c.

1301  {
1302  int bin_len = 0;
1303  const ut8 *bin = rz_strbuf_getbin(&proc->out, &bin_len);
1304  ut8 *buf = (ut8 *)rz_str_newlen((const char *)bin, bin_len);
1305  if (length) {
1306  *length = bin_len;
1307  }
1308  rz_strbuf_fini(&proc->out);
1309  return buf;
1310 }

References length, proc, rz_str_newlen(), rz_strbuf_fini(), and rz_strbuf_getbin().

Referenced by rz_subprocess_drain(), rz_sys_cmd_str_full(), rz_test_run_asm_test(), system_exec(), and system_exec_stdin().

◆ rz_subprocess_output_free()

RZ_API void rz_subprocess_output_free ( RzSubprocessOutput out)

Definition at line 1323 of file subprocess.c.

1323  {
1324  if (!out) {
1325  return;
1326  }
1327  free(out->out);
1328  free(out->err);
1329  free(out);
1330 }

References free(), and out.

Referenced by rz_test_test_result_info_free().

◆ rz_subprocess_ret()

RZ_API int rz_subprocess_ret ( RzSubprocess proc)

Definition at line 1297 of file subprocess.c.

1297  {
1298  return proc->ret;
1299 }

References proc.

Referenced by rz_test_check_jq_available(), rz_test_check_json_test(), rz_test_run_asm_test(), and system_exec().

◆ rz_subprocess_start()

RZ_API RzSubprocess* rz_subprocess_start ( const char *  file,
const char *  args[],
size_t  args_size,
const char *  envvars[],
const char *  envvals[],
size_t  env_size 
)

Start a program in a new child process with the specified parameters.

Parameters
fileName of the program to start. It is also evaluated against PATH
argsArray of arguments to pass to the new program. It does not include argv[0]
args_sizeNumber of arguments in the args array
envvarsName of environment variables that the newprocess has different from the parent
envvalsValues of environment variables that the newprocess has different from the parent. Elements are evaluated in parallel with envvars, so envvals[0] specifies the value of the environment variable named envvars[0] and so on.
env_sizeNumber of environment variables in arrays envvars and envvals

Definition at line 1345 of file subprocess.c.

1347  {
1348  RzSubprocessOpt opt = {
1349  .file = file,
1350  .args = args,
1351  .args_size = args_size,
1352  .envvars = envvars,
1353  .envvals = envvals,
1354  .env_size = env_size,
1355  .stdin_pipe = RZ_SUBPROCESS_PIPE_CREATE,
1356  .stdout_pipe = RZ_SUBPROCESS_PIPE_CREATE,
1357  .stderr_pipe = RZ_SUBPROCESS_PIPE_CREATE,
1358  };
1359  return rz_subprocess_start_opt(&opt);
1360 }
int args
Definition: mipsasm.c:18
const char * file
< Name of the executable to run. It is searched also in PATH
Definition: rz_subprocess.h:59
RZ_API RzSubprocess * rz_subprocess_start_opt(RzSubprocessOpt *opt)
Definition: subprocess.c:893
static int file
Definition: z80asm.c:58

References args, file, rz_subprocess_opt_t::file, RZ_SUBPROCESS_PIPE_CREATE, and rz_subprocess_start_opt().

Referenced by rz_test_check_jq_available(), rz_test_check_json_test(), rz_test_run_asm_test(), and subprocess_runner().

◆ rz_subprocess_start_opt()

RZ_API RzSubprocess* rz_subprocess_start_opt ( RzSubprocessOpt opt)

Definition at line 893 of file subprocess.c.

893  {
895  char **child_env = NULL;
896  char **argv = calloc(opt->args_size + 2, sizeof(char *));
897  if (!argv) {
898  return NULL;
899  }
900  argv[0] = (char *)opt->file;
901  if (opt->args_size) {
902  memcpy(argv + 1, opt->args, sizeof(char *) * opt->args_size);
903  }
904  // done by calloc: argv[args_size + 1] = NULL;
905  subprocess_lock();
907  if (!proc) {
908  goto error;
909  }
910  proc->killpipe[0] = proc->killpipe[1] = -1;
911  proc->ret = -1;
912  proc->stdin_fd = -1;
913  proc->stdout_fd = -1;
914  proc->stderr_fd = -1;
915  rz_strbuf_init(&proc->out);
916  rz_strbuf_init(&proc->err);
917 
918  if (rz_sys_pipe(proc->killpipe, true) == -1) {
919  perror("pipe");
920  goto error;
921  }
922  if (fcntl(proc->killpipe[1], F_SETFL, O_NONBLOCK) < 0) {
923  perror("fcntl");
924  goto error;
925  }
926 
927  int stdin_pipe[2] = { -1, -1 };
928  int stdout_pipe[2] = { -1, -1 };
929  int stderr_pipe[2] = { -1, -1 };
931  if (rz_sys_pipe(stdin_pipe, true) == -1) {
932  perror("pipe");
933  goto error;
934  }
935  proc->stdin_fd = stdin_pipe[1];
936  }
937 
939  if (rz_sys_pipe(stdout_pipe, true) == -1) {
940  perror("pipe");
941  goto error;
942  }
943  if (fcntl(stdout_pipe[0], F_SETFL, O_NONBLOCK) < 0) {
944  perror("fcntl");
945  goto error;
946  }
947  proc->stdout_fd = stdout_pipe[0];
948  }
949 
951  if (rz_sys_pipe(stderr_pipe, true) == -1) {
952  perror("pipe");
953  goto error;
954  }
955  if (fcntl(stderr_pipe[0], F_SETFL, O_NONBLOCK) < 0) {
956  perror("fcntl");
957  goto error;
958  }
959  proc->stderr_fd = stderr_pipe[0];
960  } else if (opt->stderr_pipe == RZ_SUBPROCESS_PIPE_STDOUT) {
961  stderr_pipe[0] = stdout_pipe[0];
962  stderr_pipe[1] = stdout_pipe[1];
963  proc->stderr_fd = proc->stdout_fd;
964  }
965 
966  // Let's create the environment for the child in the parent, with malloc,
967  // because we can't use functions that lock after fork
968  child_env = create_child_env(opt->envvars, opt->envvals, opt->env_size);
969 
970  proc->pid = rz_sys_fork();
971  if (proc->pid == -1) {
972  // fail
973  perror("fork");
974  goto error;
975  } else if (proc->pid == 0) {
976  // child
977  if (stderr_pipe[1] != -1) {
978  while ((dup2(stderr_pipe[1], STDERR_FILENO) == -1) && (errno == EINTR)) {
979  }
980  if (proc->stderr_fd != proc->stdout_fd) {
981  rz_sys_pipe_close(stderr_pipe[1]);
982  rz_sys_pipe_close(stderr_pipe[0]);
983  }
984  }
985  if (stdout_pipe[1] != -1) {
986  while ((dup2(stdout_pipe[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {
987  }
990  }
991  if (stdin_pipe[0] != -1) {
992  while ((dup2(stdin_pipe[0], STDIN_FILENO) == -1) && (errno == EINTR)) {
993  }
996  }
997 
998  // Use the previously created environment
999  rz_sys_set_environ(child_env);
1000 
1001  rz_sys_execvp(opt->file, argv);
1002  perror("exec");
1003  rz_sys_exit(-1, true);
1004  }
1005  destroy_child_env(child_env);
1006  free(argv);
1007 
1008  if (stdin_pipe[0] != -1) {
1010  }
1011  if (stdout_pipe[1] != -1) {
1013  }
1014  if (stderr_pipe[1] != -1 && proc->stderr_fd != proc->stdout_fd) {
1015  rz_sys_pipe_close(stderr_pipe[1]);
1016  }
1017 
1019 
1021 
1022  return proc;
1023 error:
1024  free(argv);
1025  if (proc && proc->killpipe[0] == -1) {
1026  rz_sys_pipe_close(proc->killpipe[0]);
1027  }
1028  if (proc && proc->killpipe[1] == -1) {
1029  rz_sys_pipe_close(proc->killpipe[1]);
1030  }
1031  free(proc);
1032  if (stderr_pipe[0] != -1 && stderr_pipe[0] != stdout_pipe[0]) {
1033  rz_sys_pipe_close(stderr_pipe[0]);
1034  }
1035  if (stderr_pipe[1] != -1 && stderr_pipe[1] != stdout_pipe[1]) {
1036  rz_sys_pipe_close(stderr_pipe[1]);
1037  }
1038  if (stdout_pipe[0] != -1) {
1040  }
1041  if (stdout_pipe[1] != -1) {
1043  }
1044  if (stdin_pipe[0] != -1) {
1046  }
1047  if (stdin_pipe[1] != -1) {
1049  }
1050  destroy_child_env(child_env);
1052  return NULL;
1053 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags fcntl
Definition: sflib.h:79
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment static handler static getegid char static len static pgid const char static path dup2
Definition: sflib.h:94
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
RZ_API void rz_sys_set_environ(char **e)
Definition: sys.c:1128
RZ_API void rz_sys_exit(int status, bool nocleanup)
Definition: sys.c:183
RZ_API int rz_sys_fork(void)
Definition: sys.c:1679
RZ_API int rz_sys_execvp(const char *file, char *const argv[])
Definition: sys.c:1525
#define RZ_NEW0(x)
Definition: rz_types.h:284
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
#define O_NONBLOCK
Definition: sftypes.h:494
#define EINTR
Definition: sftypes.h:114
#define F_SETFL
Definition: sftypes.h:507
size_t env_size
Specify how to deal with subprocess stdin.
Definition: rz_subprocess.h:69
RzSubprocessPipeCreate stderr_pipe
Definition: rz_subprocess.h:75
RzSubprocessPipeCreate stdout_pipe
Specify how to deal with subprocess stderr.
Definition: rz_subprocess.h:73
size_t args_size
Names of environment variables that subprocess should have differently from parent.
Definition: rz_subprocess.h:63
const char ** envvals
Number of elements contained in both envvars and envvals.
Definition: rz_subprocess.h:67
const char ** args
Number of arguments in args array.
Definition: rz_subprocess.h:61
RzSubprocessPipeCreate stdin_pipe
Specify how to deal with subprocess stdout.
Definition: rz_subprocess.h:71
const char ** envvars
Values of environment variables that subprocess should have differently from parent.
Definition: rz_subprocess.h:65
static char ** create_child_env(const char *envvars[], const char *envvals[], size_t env_size)
Definition: subprocess.c:826
static void destroy_child_env(char **child_env)
Definition: subprocess.c:882
uv_pipe_t stdin_pipe
Definition: main.c:15
uv_pipe_t stdout_pipe
Definition: main.c:16
#define STDOUT_FILENO
Definition: private.h:41
#define STDERR_FILENO
Definition: private.h:45
#define STDIN_FILENO
Definition: private.h:37
void error(const char *msg)
Definition: untgz.c:593
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References rz_subprocess_opt_t::args, rz_subprocess_opt_t::args_size, argv, calloc(), create_child_env(), destroy_child_env(), dup2, EINTR, rz_subprocess_opt_t::env_size, rz_subprocess_opt_t::envvals, rz_subprocess_opt_t::envvars, error(), F_SETFL, fcntl, rz_subprocess_opt_t::file, free(), if(), memcpy(), NULL, O_NONBLOCK, proc, RZ_NEW0, rz_pvector_push(), rz_strbuf_init(), RZ_SUBPROCESS_PIPE_CREATE, RZ_SUBPROCESS_PIPE_STDOUT, rz_sys_execvp(), rz_sys_exit(), rz_sys_fork(), rz_sys_pipe(), rz_sys_pipe_close(), rz_sys_set_environ(), STDERR_FILENO, rz_subprocess_opt_t::stderr_pipe, STDIN_FILENO, rz_subprocess_opt_t::stdin_pipe, stdin_pipe, STDOUT_FILENO, rz_subprocess_opt_t::stdout_pipe, stdout_pipe, subprocess_lock(), subprocess_unlock(), and subprocs.

Referenced by rz_subprocess_start(), rz_sys_cmd_str_full(), system_exec(), and system_exec_stdin().

◆ rz_subprocess_stdin_write()

RZ_API ssize_t rz_subprocess_stdin_write ( RzSubprocess proc,
const ut8 buf,
size_t  buf_size 
)

Sends some data to the stdin of the subprocess and returns the number of bytes sent.

Parameters
procSubprocess to communicate with
bufData that needs to be send to the subprocess stdin
buf_sizeNumber of bytes to send

Definition at line 1206 of file subprocess.c.

1206  {
1207  ssize_t written = -1;
1208  if (proc->stdin_fd == -1) {
1209  return written;
1210  }
1211  rz_sys_signal(SIGPIPE, SIG_IGN);
1212  written = write(proc->stdin_fd, buf, buf_size);
1213  rz_sys_signal(SIGPIPE, SIG_DFL);
1214  return written;
1215 }
static static fork write
Definition: sflib.h:33
static int buf_size
Definition: debug_qnx.c:35
int ssize_t
Definition: sftypes.h:39

References buf_size, proc, rz_sys_signal(), and write.

Referenced by rz_sys_cmd_str_full(), rz_test_check_jq_available(), rz_test_check_json_test(), and system_exec_stdin().

◆ rz_subprocess_stdout_read()

RZ_API RzStrBuf* rz_subprocess_stdout_read ( RzSubprocess proc,
size_t  n,
ut64  timeout_ms 
)

Read some data from the stdout of the subprocess and returns a RzStrBuf containing it. Callers must not free the returned pointer.

Parameters
procSubprocess to communicate with
nNumber of bytes to read from the subprocess' stdout
timeout_msWait for at most this amount of millisecond to read subprocess' stdout

Definition at line 1225 of file subprocess.c.

1225  {
1226  rz_strbuf_fini(&proc->out);
1227  rz_strbuf_init(&proc->out);
1228  if (proc->stdout_fd != -1) {
1229  subprocess_wait(proc, timeout_ms, RZ_SUBPROCESS_STDOUT, n);
1230  }
1231  return &proc->out;
1232 }
int n
Definition: mipsasm.c:19
#define RZ_SUBPROCESS_STDOUT
Definition: rz_subprocess.h:27
static RzSubprocessWaitReason subprocess_wait(RzSubprocess *proc, ut64 timeout_ms, int pipe_fd, size_t n_bytes)
Wait for subprocess to do something, for a maximum of timeout_ms millisecond.
Definition: subprocess.c:1085

References n, proc, rz_strbuf_fini(), rz_strbuf_init(), RZ_SUBPROCESS_STDOUT, and subprocess_wait().

◆ rz_subprocess_stdout_readline()

RZ_API RzStrBuf* rz_subprocess_stdout_readline ( RzSubprocess proc,
ut64  timeout_ms 
)

Read one line from the stdout of the subprocess and returns a RzStrBuf containing it. Callers must not free the returned pointer.

Parameters
procSubprocess to communicate with
timeout_msWait for at most this amount of millisecond to read subprocess' stdout

Definition at line 1241 of file subprocess.c.

1241  {
1242  rz_strbuf_fini(&proc->out);
1243  rz_strbuf_init(&proc->out);
1244  if (proc->stdout_fd != -1) {
1245  char c = '\0';
1246  RzSubprocessWaitReason reason;
1247  // FIXME: the timeout should also be checked globally here
1248  do {
1249  reason = subprocess_wait(proc, timeout_ms, RZ_SUBPROCESS_STDOUT, 1);
1250  c = rz_strbuf_get(&proc->out)[rz_strbuf_length(&proc->out) - 1];
1251  } while (c != '\n' && reason == RZ_SUBPROCESS_BYTESREAD);
1252  }
1253  return &proc->out;
1254 }
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API int rz_strbuf_length(RzStrBuf *sb)
Definition: strbuf.c:28
#define c(i)
Definition: sha256.c:43

References c, proc, rz_strbuf_fini(), rz_strbuf_get(), rz_strbuf_init(), rz_strbuf_length(), RZ_SUBPROCESS_BYTESREAD, RZ_SUBPROCESS_STDOUT, and subprocess_wait().

◆ rz_subprocess_wait()

RZ_API RzSubprocessWaitReason rz_subprocess_wait ( RzSubprocess proc,
ut64  timeout_ms 
)

Wait until process dies or timeout expires and collect stdout + stderr. No more input can be sent after this call.

Parameters
procSubprocess to communicate with
timeout_msWait for at most this amount of millisecond

Definition at line 1185 of file subprocess.c.

1185  {
1186  if (proc->stdin_fd != -1) {
1187  // Close subprocess stdin to tell it that no more input will come from us
1188  rz_sys_pipe_close(proc->stdin_fd);
1189  proc->stdin_fd = -1;
1190  }
1191  // Empty buffers and read everything we can
1192  rz_strbuf_fini(&proc->out);
1193  rz_strbuf_init(&proc->out);
1194  rz_strbuf_fini(&proc->err);
1195  rz_strbuf_init(&proc->err);
1197 }
#define RZ_SUBPROCESS_STDERR
Definition: rz_subprocess.h:28

References proc, rz_strbuf_fini(), rz_strbuf_init(), RZ_SUBPROCESS_STDERR, RZ_SUBPROCESS_STDOUT, rz_sys_pipe_close(), and subprocess_wait().

Referenced by rz_sys_cmd_str_full(), rz_test_check_jq_available(), rz_test_check_json_test(), rz_test_run_asm_test(), subprocess_runner(), system_exec(), and system_exec_stdin().