Rizin
unix-like reverse engineering framework and cli tools
rzpipe.c File Reference
#include <rz_util.h>
#include <rz_lib.h>
#include <rz_socket.h>

Go to the source code of this file.

Macros

#define RZP_PID(x)   (((RzPipe *)(x)->data)->pid)
 
#define RZP_INPUT(x)   (((RzPipe *)(x)->data)->input[0])
 
#define RZP_OUTPUT(x)   (((RzPipe *)(x)->data)->output[1])
 

Functions

static void env (const char *s, int f)
 
RZ_API int rzpipe_write (RzPipe *rzpipe, const char *str)
 
RZ_API char * rzpipe_read (RzPipe *rzpipe)
 
RZ_API int rzpipe_close (RzPipe *rzpipe)
 
static RzPiperzp_open_spawn (RzPipe *rzp, const char *cmd)
 
static RzPiperzpipe_new (void)
 
RZ_API RzPiperzpipe_open_corebind (RzCoreBind *coreb)
 
RZ_API RzPiperzpipe_open_dl (const char *libr_path)
 
RZ_API RzPiperzpipe_open (const char *cmd)
 
RZ_API char * rzpipe_cmd (RzPipe *rzp, const char *str)
 
RZ_API char * rzpipe_cmdf (RzPipe *rzp, const char *fmt,...)
 

Macro Definition Documentation

◆ RZP_INPUT

#define RZP_INPUT (   x)    (((RzPipe *)(x)->data)->input[0])

Definition at line 25 of file rzpipe.c.

◆ RZP_OUTPUT

#define RZP_OUTPUT (   x)    (((RzPipe *)(x)->data)->output[1])

Definition at line 26 of file rzpipe.c.

◆ RZP_PID

#define RZP_PID (   x)    (((RzPipe *)(x)->data)->pid)

Definition at line 24 of file rzpipe.c.

Function Documentation

◆ env()

static void env ( const char *  s,
int  f 
)
static

Definition at line 29 of file rzpipe.c.

29  {
30  char *a = rz_str_newf("%d", f);
31  rz_sys_setenv(s, a);
32  free(a);
33 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static RzSocket * s
Definition: rtr.c:28
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API int rz_sys_setenv(const char *key, const char *value)
Set an environment variable in the calling process.
Definition: sys.c:405
#define f(i)
Definition: sha256.c:46
#define a(i)
Definition: sha256.c:41

References a, f, free(), rz_str_newf(), rz_sys_setenv(), and s.

Referenced by rzpipe_open().

◆ rzp_open_spawn()

static RzPipe* rzp_open_spawn ( RzPipe rzp,
const char *  cmd 
)
static

Definition at line 169 of file rzpipe.c.

169  {
171 #if __UNIX__ || defined(__CYGWIN__)
172  char *out = rz_sys_getenv("RZ_PIPE_IN");
173  char *in = rz_sys_getenv("RZ_PIPE_OUT");
174  int done = false;
175  if (in && out) {
176  int i_in = atoi(in);
177  int i_out = atoi(out);
178  if (i_in >= 0 && i_out >= 0) {
179  rzp->input[0] = rzp->input[1] = i_in;
180  rzp->output[0] = rzp->output[1] = i_out;
181  done = true;
182  }
183  }
184  if (!done) {
185  eprintf("Cannot find RZ_PIPE_IN or RZ_PIPE_OUT environment\n");
186  RZ_FREE(rzp);
187  }
188  free(in);
189  free(out);
190  return rzp;
191 #else
192  eprintf("rzpipe_open(NULL) not supported on windows\n");
193  return NULL;
194 #endif
195 }
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define NULL
Definition: cris-opc.c:27
struct tab * done
Definition: enough.c:233
#define eprintf(x, y...)
Definition: rlcc.c:7
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API char * rz_sys_getenv(const char *key)
Get the value of an environment variable named key or NULL if none exists.
Definition: sys.c:483
#define RZ_FREE(x)
Definition: rz_types.h:369
int input[2]
Definition: rz_socket.h:56
int output[2]
Definition: rz_socket.h:57

References done, eprintf, free(), in, RzPipe::input, NULL, out, RzPipe::output, RZ_FREE, rz_return_val_if_fail, and rz_sys_getenv().

Referenced by rzpipe_open().

◆ rzpipe_close()

RZ_API int rzpipe_close ( RzPipe rzpipe)

Definition at line 110 of file rzpipe.c.

110  {
111  if (!rzpipe) {
112  return 0;
113  }
114  /*
115  if (rzpipe->coreb.core && !rzpipe->coreb.puts) {
116  void (*rfre)(void *c) = rz_lib_dl_sym (librz, "rz_core_free");
117  if (rfre) {
118  rfre (rzpipe->coreb.core);
119  }
120  }
121  */
122 #if __WINDOWS__
123  if (rzpipe->pipe) {
124  CloseHandle(rzpipe->pipe);
125  rzpipe->pipe = NULL;
126  }
127 #else
128  if (rzpipe->input[0] != -1) {
129  rz_sys_pipe_close(rzpipe->input[0]);
130  rzpipe->input[0] = -1;
131  }
132  if (rzpipe->input[1] != -1) {
133  rz_sys_pipe_close(rzpipe->input[1]);
134  rzpipe->input[1] = -1;
135  }
136  if (rzpipe->output[0] != -1) {
137  rz_sys_pipe_close(rzpipe->output[0]);
138  rzpipe->output[0] = -1;
139  }
140  if (rzpipe->output[1] != -1) {
141  rz_sys_pipe_close(rzpipe->output[1]);
142  rzpipe->output[1] = -1;
143  }
144  if (rzpipe->child != -1) {
145  kill(rzpipe->child, SIGTERM);
146  waitpid(rzpipe->child, NULL, 0);
147  rzpipe->child = -1;
148  }
149 #endif
150  free(rzpipe);
151  return 0;
152 }
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
RZ_API int rz_sys_pipe_close(int fd)
Definition: sys.c:1462
int child
Definition: rz_socket.h:52

References RzPipe::child, free(), RzPipe::input, kill, NULL, RzPipe::output, and rz_sys_pipe_close().

Referenced by __close(), and rzpipe_open().

◆ rzpipe_cmd()

RZ_API char* rzpipe_cmd ( RzPipe rzp,
const char *  str 
)

Definition at line 316 of file rzpipe.c.

316  {
317  rz_return_val_if_fail(rzp && str, NULL);
318  if (!*str || !rzpipe_write(rzp, str)) {
319  perror("rzpipe_write");
320  return NULL;
321  }
322  return rzpipe_read(rzp);
323 }
RZ_API char * rzpipe_read(RzPipe *rzpipe)
Definition: rzpipe.c:61
RZ_API int rzpipe_write(RzPipe *rzpipe, const char *str)
Definition: rzpipe.c:36

References NULL, rz_return_val_if_fail, rzpipe_read(), rzpipe_write(), and cmd_descs_generate::str.

Referenced by rzpipe_cmdf().

◆ rzpipe_cmdf()

RZ_API char* rzpipe_cmdf ( RzPipe rzp,
const char *  fmt,
  ... 
)

Definition at line 325 of file rzpipe.c.

325  {
326  int ret, ret2;
327  char *p, string[1024];
328  va_list ap, ap2;
329  va_start(ap, fmt);
330  va_start(ap2, fmt);
331  ret = vsnprintf(string, sizeof(string) - 1, fmt, ap);
332  if (ret < 1 || ret >= sizeof(string)) {
333  p = malloc(ret + 2);
334  if (!p) {
335  va_end(ap2);
336  va_end(ap);
337  return NULL;
338  }
339  ret2 = vsnprintf(p, ret + 1, fmt, ap2);
340  if (ret2 < 1 || ret2 > ret + 1) {
341  free(p);
342  va_end(ap2);
343  va_end(ap);
344  return NULL;
345  }
346  fmt = rzpipe_cmd(rzp, p);
347  free(p);
348  } else {
349  fmt = rzpipe_cmd(rzp, string);
350  }
351  va_end(ap2);
352  va_end(ap);
353  return (char *)fmt;
354 }
vsnprintf
Definition: kernel.h:366
void * p
Definition: libc.cpp:67
void * malloc(size_t size)
Definition: malloc.c:123
RZ_API char * rzpipe_cmd(RzPipe *rzp, const char *str)
Definition: rzpipe.c:316

References free(), malloc(), NULL, p, rzpipe_cmd(), and vsnprintf.

◆ rzpipe_new()

static RzPipe* rzpipe_new ( void  )
static

Definition at line 197 of file rzpipe.c.

197  {
198  RzPipe *rzpipe = RZ_NEW0(RzPipe);
199  if (rzpipe) {
200 #if __UNIX__
201  rzpipe->input[0] = rzpipe->input[1] = -1;
202  rzpipe->output[0] = rzpipe->output[1] = -1;
203 #endif
204  rzpipe->child = -1;
205  }
206  return rzpipe;
207 }
#define RZ_NEW0(x)
Definition: rz_types.h:284

References RzPipe::child, RzPipe::input, RzPipe::output, and RZ_NEW0.

Referenced by rzpipe_open(), rzpipe_open_corebind(), and rzpipe_open_dl().

◆ rzpipe_open()

RZ_API RzPipe* rzpipe_open ( const char *  cmd)

Definition at line 235 of file rzpipe.c.

235  {
236  RzPipe *rzp = rzpipe_new();
237  if (!rzp) {
238  return NULL;
239  }
240  if (RZ_STR_ISEMPTY(cmd)) {
241  rzp->child = -1;
242  return rzp_open_spawn(rzp, cmd);
243  }
244 #if __WINDOWS__
245  w32_createPipe(rzp, cmd);
246  rzp->child = (int)(rzp->pipe);
247 #else
248  int r = rz_sys_pipe(rzp->input, false);
249  if (r != 0) {
250  eprintf("pipe failed on input\n");
251  rzpipe_close(rzp);
252  return NULL;
253  }
254  r = rz_sys_pipe(rzp->output, false);
255  if (r != 0) {
256  eprintf("pipe failed on output\n");
257  rzpipe_close(rzp);
258  return NULL;
259  }
260  rzp->child = rz_sys_fork();
261  if (rzp->child == -1) {
262  rzpipe_close(rzp);
263  return NULL;
264  }
265  env("RZ_PIPE_IN", rzp->input[0]);
266  env("RZ_PIPE_OUT", rzp->output[1]);
267 
268  if (rzp->child) {
269  signed char ch = -1;
270  // eprintf ("[+] rzpipeipe child is %d\n", rzpipe->child);
271  if (read(rzp->output[0], &ch, 1) != 1) {
272  eprintf("Failed to read 1 byte\n");
273  rzpipe_close(rzp);
274  return NULL;
275  }
276  if (ch == -1) {
277  eprintf("[+] rzpipe link error.\n");
278  rzpipe_close(rzp);
279  return NULL;
280  }
281  // Close parent's end of pipes
282  rz_sys_pipe_close(rzp->input[0]);
283  rz_sys_pipe_close(rzp->output[1]);
284  rzp->input[0] = -1;
285  rzp->output[1] = -1;
286  } else {
287  int rc = 0;
288  if (cmd && *cmd) {
289  close(0);
290  close(1);
291  dup2(rzp->input[0], 0);
292  dup2(rzp->output[1], 1);
293  rz_sys_pipe_close(rzp->input[1]);
294  rz_sys_pipe_close(rzp->output[0]);
295  rzp->input[1] = -1;
296  rzp->output[0] = -1;
297  rc = rz_sys_system(cmd);
298  if (rc != 0) {
299  eprintf("return code %d for %s\n", rc, cmd);
300  }
301  // trigger the blocking read
302  rz_xwrite(1, "\xff", 1);
303  rz_sys_pipe_close(rzp->output[1]);
304  close(0);
305  close(1);
306  }
307  rzp->child = -1;
308  rzpipe_close(rzp);
309  exit(rc);
310  return NULL;
311  }
312 #endif
313  return rzp;
314 }
#define r
Definition: crypto_rc6.c:12
static static fork const void static count close
Definition: sflib.h:33
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 cmd
Definition: sflib.h:79
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
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API int rz_sys_pipe(int pipefd[2], bool close_on_exec)
Definition: sys.c:1458
RZ_API int rz_sys_fork(void)
Definition: sys.c:1679
RZ_API int rz_sys_system(const char *command)
Definition: sys.c:1658
#define rz_xwrite(fd, buf, count)
Definition: rz_types.h:642
static RzPipe * rzpipe_new(void)
Definition: rzpipe.c:197
RZ_API int rzpipe_close(RzPipe *rzpipe)
Definition: rzpipe.c:110
static void env(const char *s, int f)
Definition: rzpipe.c:29
static RzPipe * rzp_open_spawn(RzPipe *rzp, const char *cmd)
Definition: rzpipe.c:169
static int
Definition: sfsocketcall.h:114
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115

References RzPipe::child, close, cmd, dup2, env(), eprintf, test-lz4-list::exit, RzPipe::input, int, NULL, RzPipe::output, r, read(), RZ_STR_ISEMPTY, rz_sys_fork(), rz_sys_pipe(), rz_sys_pipe_close(), rz_sys_system(), rz_xwrite, rzp_open_spawn(), rzpipe_close(), and rzpipe_new().

Referenced by __open().

◆ rzpipe_open_corebind()

RZ_API RzPipe* rzpipe_open_corebind ( RzCoreBind coreb)

Definition at line 209 of file rzpipe.c.

209  {
210  RzPipe *rzpipe = rzpipe_new();
211  if (rzpipe) {
212  memcpy(&rzpipe->coreb, coreb, sizeof(RzCoreBind));
213  }
214  return rzpipe;
215 }
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
RzCoreBind coreb
Definition: rz_socket.h:59

References RzPipe::coreb, memcpy(), and rzpipe_new().

◆ rzpipe_open_dl()

RZ_API RzPipe* rzpipe_open_dl ( const char *  libr_path)

Definition at line 217 of file rzpipe.c.

217  {
218  void *librz = rz_lib_dl_open(libr_path);
219  void *(*rnew)() = rz_lib_dl_sym(librz, "rz_core_new");
220  char *(*rcmd)(void *c, const char *cmd) = rz_lib_dl_sym(librz, "rz_core_cmd_str");
221 
222  if (rnew && rcmd) {
223  RzPipe *rzpipe = rzpipe_new();
224  if (rzpipe) {
225  rzpipe->coreb.core = rnew();
226  rzpipe->coreb.cmdstr = rcmd;
227  // rzpipe->coreb.free = rfre;
228  }
229  return rzpipe;
230  }
231  eprintf("Cannot resolve rz_core_cmd, rz_core_cmd_str, rz_core_free\n");
232  return NULL;
233 }
RZ_API void * rz_lib_dl_sym(void *handler, const char *name)
Definition: lib.c:90
RZ_API void * rz_lib_dl_open(const char *libname)
Definition: lib.c:54
#define c(i)
Definition: sha256.c:43
RzCoreCmdStr cmdstr
Definition: rz_bind.h:34
void * core
Definition: rz_bind.h:31

References c, cmd, rz_core_bind_t::cmdstr, rz_core_bind_t::core, RzPipe::coreb, eprintf, NULL, rz_lib_dl_open(), rz_lib_dl_sym(), and rzpipe_new().

◆ rzpipe_read()

RZ_API char* rzpipe_read ( RzPipe rzpipe)

Definition at line 61 of file rzpipe.c.

61  {
62  int bufsz = 0;
63  char *buf = NULL;
64  if (!rzpipe) {
65  return NULL;
66  }
67  bufsz = 4096;
68  buf = calloc(1, bufsz);
69  if (!buf) {
70  return NULL;
71  }
72 #if __WINDOWS__
73  BOOL bSuccess = FALSE;
74  DWORD dwRead = 0;
75  // TODO: handle > 4096 buffers here
76  bSuccess = ReadFile(rzpipe->pipe, buf, bufsz, &dwRead, NULL);
77  if (!bSuccess || !buf[0]) {
78  return NULL;
79  }
80  if (dwRead > 0) {
81  buf[dwRead] = 0;
82  }
83  buf[bufsz - 1] = 0;
84 #else
85  char *newbuf;
86  int i, rv;
87  for (i = 0; i < bufsz; i++) {
88  rv = read(rzpipe->output[0], buf + i, 1);
89  if (i + 2 >= bufsz) {
90  bufsz += 4096;
91  newbuf = realloc(buf, bufsz);
92  if (!newbuf) {
93  RZ_FREE(buf);
94  break;
95  }
96  buf = newbuf;
97  }
98  if (rv != 1 || !buf[i]) {
99  break;
100  }
101  }
102  if (buf) {
103  int zpos = (i < bufsz) ? i : i - 1;
104  buf[zpos] = 0;
105  }
106 #endif
107  return buf;
108 }
lzma_index ** i
Definition: index.h:629
voidpf void * buf
Definition: ioapi.h:138
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
#define FALSE
Definition: mybfd.h:102
DWORD

References calloc(), DWORD, FALSE, i, NULL, RzPipe::output, read(), realloc(), and RZ_FREE.

Referenced by __read(), __system(), __write(), and rzpipe_cmd().

◆ rzpipe_write()

RZ_API int rzpipe_write ( RzPipe rzpipe,
const char *  str 
)

Definition at line 36 of file rzpipe.c.

36  {
37  char *cmd;
38  int ret, len;
39  if (!rzpipe || !str) {
40  return -1;
41  }
42  len = strlen(str) + 2; /* include \n\x00 */
43  cmd = malloc(len + 2);
44  if (!cmd) {
45  return 0;
46  }
47  memcpy(cmd, str, len - 1);
48  strcpy(cmd + len - 2, "\n");
49 #if __WINDOWS__
50  DWORD dwWritten = -1;
51  WriteFile(rzpipe->pipe, cmd, len, &dwWritten, NULL);
52  ret = (dwWritten == len);
53 #else
54  ret = (write(rzpipe->input[1], cmd, len) == len);
55 #endif
56  free(cmd);
57  return ret;
58 }
size_t len
Definition: 6502dis.c:15
static static fork write
Definition: sflib.h:33

References cmd, DWORD, free(), RzPipe::input, len, malloc(), memcpy(), NULL, cmd_descs_generate::str, and write.

Referenced by __read(), __system(), __write(), and rzpipe_cmd().