mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-14 00:38:55 +00:00
Refactor r2pipe API into r_socket and fix w32 build
This commit is contained in:
parent
19f1e78c5c
commit
967067ea9c
@ -349,7 +349,8 @@ static int r_debug_native_step(RDebug *dbg) {
|
|||||||
regs.EFlags |= 0x100;
|
regs.EFlags |= 0x100;
|
||||||
r_debug_native_reg_write (dbg, R_REG_TYPE_GPR, (ut8 *)®s, sizeof (regs));
|
r_debug_native_reg_write (dbg, R_REG_TYPE_GPR, (ut8 *)®s, sizeof (regs));
|
||||||
r_debug_native_continue (dbg, pid, dbg->tid, dbg->signum);
|
r_debug_native_continue (dbg, pid, dbg->tid, dbg->signum);
|
||||||
ret=R_TRUE;
|
ret = R_TRUE;
|
||||||
|
r_debug_handle_signals (dbg);
|
||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
//debug_arch_x86_trap_set (dbg, 1);
|
//debug_arch_x86_trap_set (dbg, 1);
|
||||||
// TODO: not supported in all platforms. need dbg.swstep=
|
// TODO: not supported in all platforms. need dbg.swstep=
|
||||||
@ -375,6 +376,7 @@ static int r_debug_native_step(RDebug *dbg) {
|
|||||||
eprintf ("mach-error: %d, %s\n", ret, MACH_ERROR_STRING (ret));
|
eprintf ("mach-error: %d, %s\n", ret, MACH_ERROR_STRING (ret));
|
||||||
ret = R_FALSE; /* do not wait for events */
|
ret = R_FALSE; /* do not wait for events */
|
||||||
} else ret = R_TRUE;
|
} else ret = R_TRUE;
|
||||||
|
r_debug_handle_signals (dbg);
|
||||||
#endif
|
#endif
|
||||||
#elif __BSD__
|
#elif __BSD__
|
||||||
ret = ptrace (PT_STEP, pid, (caddr_t)1, 0);
|
ret = ptrace (PT_STEP, pid, (caddr_t)1, 0);
|
||||||
@ -477,7 +479,6 @@ static int r_debug_native_continue_syscall(RDebug *dbg, int pid, int num) {
|
|||||||
/* TODO: specify thread? */
|
/* TODO: specify thread? */
|
||||||
/* TODO: must return true/false */
|
/* TODO: must return true/false */
|
||||||
static int r_debug_native_continue(RDebug *dbg, int pid, int tid, int sig) {
|
static int r_debug_native_continue(RDebug *dbg, int pid, int tid, int sig) {
|
||||||
void *data = (void*)(size_t)((sig != -1)?sig: dbg->signum);
|
|
||||||
#if __WINDOWS__ && !__CYGWIN__
|
#if __WINDOWS__ && !__CYGWIN__
|
||||||
eprintf("r_debug_native_continue: pid=%08x tid=%08x\n",pid,tid);
|
eprintf("r_debug_native_continue: pid=%08x tid=%08x\n",pid,tid);
|
||||||
if (ContinueDebugEvent (pid, tid, DBG_CONTINUE) == 0) {
|
if (ContinueDebugEvent (pid, tid, DBG_CONTINUE) == 0) {
|
||||||
@ -519,12 +520,14 @@ static int r_debug_native_continue(RDebug *dbg, int pid, int tid, int sig) {
|
|||||||
(int)(size_t)data) == 0;
|
(int)(size_t)data) == 0;
|
||||||
#endif
|
#endif
|
||||||
#elif __BSD__
|
#elif __BSD__
|
||||||
|
void *data = (void*)(size_t)((sig != -1)?sig: dbg->signum);
|
||||||
ut64 pc = r_debug_reg_get (dbg, "pc");
|
ut64 pc = r_debug_reg_get (dbg, "pc");
|
||||||
return ptrace (PTRACE_CONT, pid, (void*)(size_t)pc, (int)data) == 0;
|
return ptrace (PTRACE_CONT, pid, (void*)(size_t)pc, (int)data) == 0;
|
||||||
#elif __CYGWIN__
|
#elif __CYGWIN__
|
||||||
#warning "r_debug_native_continue not supported on this platform"
|
#warning "r_debug_native_continue not supported on this platform"
|
||||||
return -1;
|
return -1;
|
||||||
#else
|
#else
|
||||||
|
void *data = (void*)(size_t)((sig != -1)?sig: dbg->signum);
|
||||||
//eprintf ("SIG %d\n", dbg->signum);
|
//eprintf ("SIG %d\n", dbg->signum);
|
||||||
return ptrace (PTRACE_CONT, pid, NULL, data) == 0;
|
return ptrace (PTRACE_CONT, pid, NULL, data) == 0;
|
||||||
#endif
|
#endif
|
||||||
@ -1743,13 +1746,13 @@ static RDebugMap* r_debug_native_map_alloc(RDebug *dbg, ut64 addr, int size) {
|
|||||||
if (!dbg->process_handle) {
|
if (!dbg->process_handle) {
|
||||||
dbg->process_handle = tid2handler (dbg->pid, dbg->tid);
|
dbg->process_handle = tid2handler (dbg->pid, dbg->tid);
|
||||||
}
|
}
|
||||||
base = VirtualAllocEx (dbg->process_handle, (LPVOID)addr, (SIZE_T)size, MEM_COMMIT, PAGE_READWRITE);
|
base = VirtualAllocEx (dbg->process_handle, (LPVOID)(size_t)addr, (SIZE_T)size, MEM_COMMIT, PAGE_READWRITE);
|
||||||
if (!base) {
|
if (!base) {
|
||||||
eprintf("Failed to allocate memory\n");
|
eprintf("Failed to allocate memory\n");
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
r_debug_map_sync (dbg);
|
r_debug_map_sync (dbg);
|
||||||
map = r_debug_map_get (dbg, (ut64)base);
|
map = r_debug_map_get (dbg, (ut64)(size_t)base);
|
||||||
return map;
|
return map;
|
||||||
#else
|
#else
|
||||||
// malloc not implemented for this platform
|
// malloc not implemented for this platform
|
||||||
@ -1772,7 +1775,7 @@ static int r_debug_native_map_dealloc(RDebug *dbg, ut64 addr, int size) {
|
|||||||
if (!dbg->process_handle) {
|
if (!dbg->process_handle) {
|
||||||
dbg->process_handle = tid2handler (dbg->pid, dbg->tid);
|
dbg->process_handle = tid2handler (dbg->pid, dbg->tid);
|
||||||
}
|
}
|
||||||
if (!VirtualFreeEx (dbg->process_handle, (LPVOID)addr, (SIZE_T)size, MEM_DECOMMIT)) {
|
if (!VirtualFreeEx (dbg->process_handle, (LPVOID)(size_t)addr, (SIZE_T)size, MEM_DECOMMIT)) {
|
||||||
eprintf("Failed to free memory\n");
|
eprintf("Failed to free memory\n");
|
||||||
return R_FALSE;
|
return R_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,8 @@ return (0);
|
|||||||
//BOOL WINAPI DebugActiveProcessStop(DWORD dwProcessId);
|
//BOOL WINAPI DebugActiveProcessStop(DWORD dwProcessId);
|
||||||
|
|
||||||
BOOL WINAPI DebugBreakProcess(
|
BOOL WINAPI DebugBreakProcess(
|
||||||
_In_ HANDLE Process
|
HANDLE Process
|
||||||
|
//_In_ HANDLE Process
|
||||||
);
|
);
|
||||||
static void (*gmbn)(HANDLE, HMODULE, LPTSTR, int) = NULL;
|
static void (*gmbn)(HANDLE, HMODULE, LPTSTR, int) = NULL;
|
||||||
static int (*gmi)(HANDLE, HMODULE, LPMODULEINFO, int) = NULL;
|
static int (*gmi)(HANDLE, HMODULE, LPMODULEINFO, int) = NULL;
|
||||||
@ -186,9 +187,9 @@ static int w32_dbg_init() {
|
|||||||
"DebugActiveProcessStop");
|
"DebugActiveProcessStop");
|
||||||
w32_openthread = (HANDLE WINAPI (*)(DWORD, BOOL, DWORD))
|
w32_openthread = (HANDLE WINAPI (*)(DWORD, BOOL, DWORD))
|
||||||
GetProcAddress (GetModuleHandle ("kernel32"), "OpenThread");
|
GetProcAddress (GetModuleHandle ("kernel32"), "OpenThread");
|
||||||
w32_openprocess=(HANDLE WINAPI (*)(DWORD, BOOL, DWORD))
|
w32_openprocess = (HANDLE WINAPI (*)(DWORD, BOOL, DWORD))
|
||||||
GetProcAddress (GetModuleHandle ("kernel32"), "OpenProcess");
|
GetProcAddress (GetModuleHandle ("kernel32"), "OpenProcess");
|
||||||
w32_dbgbreak = (HANDLE WINAPI (*)(HANDLE))
|
w32_dbgbreak = (BOOL WINAPI (*)(HANDLE))
|
||||||
GetProcAddress (GetModuleHandle ("kernel32"),
|
GetProcAddress (GetModuleHandle ("kernel32"),
|
||||||
"DebugBreakProcess");
|
"DebugBreakProcess");
|
||||||
// only windows vista :(
|
// only windows vista :(
|
||||||
@ -221,8 +222,8 @@ static int w32_dbg_init() {
|
|||||||
return R_TRUE;
|
return R_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HANDLE w32_t2h(pid_t tid) {
|
|
||||||
#if 0
|
#if 0
|
||||||
|
static HANDLE w32_t2h(pid_t tid) {
|
||||||
TH_INFO *th = get_th (tid);
|
TH_INFO *th = get_th (tid);
|
||||||
if(th == NULL) {
|
if(th == NULL) {
|
||||||
/* refresh thread list */
|
/* refresh thread list */
|
||||||
@ -233,9 +234,8 @@ static HANDLE w32_t2h(pid_t tid) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return th->ht;
|
return th->ht;
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
inline static int w32_h2t(HANDLE h) {
|
inline static int w32_h2t(HANDLE h) {
|
||||||
if (w32_getthreadid != NULL) // >= Windows Vista
|
if (w32_getthreadid != NULL) // >= Windows Vista
|
||||||
@ -426,10 +426,9 @@ static RList *w32_dbg_maps(RDebug *dbg) {
|
|||||||
MODULEENTRY32 me32;
|
MODULEENTRY32 me32;
|
||||||
RDebugMap *mr;
|
RDebugMap *mr;
|
||||||
ut8 PeHeader[1024];
|
ut8 PeHeader[1024];
|
||||||
DWORD cbNeeded=0;
|
|
||||||
char *mapname = NULL;
|
char *mapname = NULL;
|
||||||
int NumSections, i;
|
int NumSections, i;
|
||||||
int tid = dbg->tid;
|
//int tid = dbg->tid;
|
||||||
int pid = dbg->pid;
|
int pid = dbg->pid;
|
||||||
RList *list = r_list_new ();
|
RList *list = r_list_new ();
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ R_LIB_VERSION_HEADER(r_socket);
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_LIB_SSL
|
#if HAVE_LIB_SSL
|
||||||
@ -27,6 +28,18 @@ R_LIB_VERSION_HEADER(r_socket);
|
|||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int magic;
|
||||||
|
int child;
|
||||||
|
#if __WINDOWS__
|
||||||
|
HANDLE pipe;
|
||||||
|
#else
|
||||||
|
int input[2];
|
||||||
|
int output[2];
|
||||||
|
#endif
|
||||||
|
} R2Pipe;
|
||||||
|
|
||||||
|
|
||||||
typedef struct r_socket_t {
|
typedef struct r_socket_t {
|
||||||
int fd;
|
int fd;
|
||||||
int is_ssl;
|
int is_ssl;
|
||||||
@ -189,6 +202,13 @@ R_API int r_run_start(RRunProfile *p);
|
|||||||
R_API void r_run_reset(RRunProfile *p);
|
R_API void r_run_reset(RRunProfile *p);
|
||||||
R_API int r_run_parsefile (RRunProfile *p, const char *b);
|
R_API int r_run_parsefile (RRunProfile *p, const char *b);
|
||||||
|
|
||||||
|
/* r2pipe */
|
||||||
|
R_API int r2p_close(R2Pipe *r2p);
|
||||||
|
R_API R2Pipe *r2p_open(const char *cmd);
|
||||||
|
R_API int r2p_write(R2Pipe *r2p, const char *str);
|
||||||
|
R_API char *r2p_read(R2Pipe *r2p);
|
||||||
|
R_API void r2p_free (R2Pipe *r2p);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
26
libr/io/p/io_r2pipe-test.js
Normal file
26
libr/io/p/io_r2pipe-test.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
var fs = require ('fs');
|
||||||
|
|
||||||
|
var nfd_in = +process.env.R2PIPE_IN;
|
||||||
|
var nfd_out = +process.env.R2PIPE_OUT;
|
||||||
|
|
||||||
|
if (!nfd_in || !nfd_out) {
|
||||||
|
console.error ("Only from r2");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fd_in = fs.createReadStream(null, {fd: nfd_in});
|
||||||
|
var fd_out = fs.createWriteStream(null, {fd: nfd_out});
|
||||||
|
|
||||||
|
console.log ("Running r2pipe io using fds: ", nfd_in, nfd_out);
|
||||||
|
|
||||||
|
fd_in.on('data', function(data) {
|
||||||
|
data = data.slice(0,-1);
|
||||||
|
var obj_in = JSON.parse (data);
|
||||||
|
console.log ("got data(",obj_in,")");
|
||||||
|
var obj = {result:obj_in.count, data:[1,2,3]};
|
||||||
|
fd_out.write (JSON.stringify (obj)+"\x00");
|
||||||
|
});
|
||||||
|
|
||||||
|
fd_in.on('end', function() {
|
||||||
|
console.log ("--> THE END");
|
||||||
|
});
|
@ -2,94 +2,11 @@
|
|||||||
|
|
||||||
#include "r_io.h"
|
#include "r_io.h"
|
||||||
#include "r_lib.h"
|
#include "r_lib.h"
|
||||||
|
#include "r_socket.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int magic;
|
|
||||||
int child;
|
|
||||||
int input[2];
|
|
||||||
int output[2];
|
|
||||||
} R2Pipe;
|
|
||||||
|
|
||||||
#define R2P_MAGIC 0x329193
|
|
||||||
#define R2P_PID(x) (((R2Pipe*)x->data)->pid)
|
|
||||||
#define R2P_INPUT(x) (((R2Pipe*)x->data)->input[0])
|
|
||||||
#define R2P_OUTPUT(x) (((R2Pipe*)x->data)->output[1])
|
|
||||||
|
|
||||||
static void env(const char *s, int f) {
|
|
||||||
char *a = r_str_newf ("%d", f);
|
|
||||||
r_sys_setenv (s, a);
|
|
||||||
free (a);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r2p_close(R2Pipe *r2p) {
|
|
||||||
if (r2p->input[0] != -1) {
|
|
||||||
close (r2p->input[0]);
|
|
||||||
close (r2p->input[1]);
|
|
||||||
r2p->input[0] = -1;
|
|
||||||
r2p->input[1] = -1;
|
|
||||||
}
|
|
||||||
if (r2p->output[0] != -1) {
|
|
||||||
close (r2p->output[0]);
|
|
||||||
close (r2p->output[1]);
|
|
||||||
r2p->output[0] = -1;
|
|
||||||
r2p->output[1] = -1;
|
|
||||||
}
|
|
||||||
if (r2p->child != -1) {
|
|
||||||
kill (r2p->child, SIGINT);
|
|
||||||
r2p->child = -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static R2Pipe *r2p_open(const char *cmd) {
|
|
||||||
R2Pipe *r2p = R_NEW0 (R2Pipe);
|
|
||||||
r2p->magic = R2P_MAGIC;
|
|
||||||
pipe (r2p->input);
|
|
||||||
pipe (r2p->output);
|
|
||||||
r2p->child = fork ();
|
|
||||||
if (r2p->child == -1) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
env ("R2PIPE_IN", r2p->input[0]);
|
|
||||||
env ("R2PIPE_OUT", r2p->output[1]);
|
|
||||||
|
|
||||||
if (r2p->child) {
|
|
||||||
eprintf ("Child is %d\n", r2p->child);
|
|
||||||
} else {
|
|
||||||
int rc;
|
|
||||||
rc = r_sandbox_system (cmd, 1);
|
|
||||||
eprintf ("Child was %d with %d\n", r2p->child, rc);
|
|
||||||
r2p_close (r2p);
|
|
||||||
exit (0);
|
|
||||||
}
|
|
||||||
return r2p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r2p_write(R2Pipe *r2p, const char *str) {
|
|
||||||
int len = strlen (str)+1; /* include \x00 */
|
|
||||||
return write (r2p->input[1], str, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: add timeout here ? */
|
|
||||||
static char *r2p_read(R2Pipe *r2p) {
|
|
||||||
char buf[1024];
|
|
||||||
int i, rv;
|
|
||||||
for (i=0; i<sizeof (buf)-1; i++) {
|
|
||||||
rv = read (r2p->output[0], buf+i, 1);
|
|
||||||
if (rv != 1 || !buf[i]) break;
|
|
||||||
}
|
|
||||||
buf[i] = 0;
|
|
||||||
return strdup (buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void r2p_free (R2Pipe *r2p) {
|
|
||||||
r2p->magic = 0;
|
|
||||||
free (r2p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------- */
|
/* --------------------------------------------------------- */
|
||||||
#define R2P(x) ((R2Pipe*)x->data)
|
#define R2P(x) ((R2Pipe*)x->data)
|
||||||
|
|
||||||
@ -104,12 +21,12 @@ static int __write(RIO *io, RIODesc *fd, const ut8 *buf, int count) {
|
|||||||
snprintf (fmt, sizeof (fmt),
|
snprintf (fmt, sizeof (fmt),
|
||||||
"{\"op\":\"write\",\"address\":%"PFMT64d",\"data\":%s}",
|
"{\"op\":\"write\",\"address\":%"PFMT64d",\"data\":%s}",
|
||||||
io->off, "[]");
|
io->off, "[]");
|
||||||
rv = r2p_write (R2P(fd), fmt);
|
rv = r2p_write (R2P (fd), fmt);
|
||||||
if (rv <1) {
|
if (rv <1) {
|
||||||
eprintf ("r2p_write: error\n");
|
eprintf ("r2p_write: error\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
res = r2p_read (R2P(fd));
|
res = r2p_read (R2P (fd));
|
||||||
/* TODO: parse json back */
|
/* TODO: parse json back */
|
||||||
r = strstr (res, "result");
|
r = strstr (res, "result");
|
||||||
if (r) { count = atoi (r+6+1); }
|
if (r) { count = atoi (r+6+1); }
|
||||||
@ -127,12 +44,12 @@ static int __read(RIO *io, RIODesc *fd, ut8 *buf, const int count) {
|
|||||||
snprintf (fmt, sizeof (fmt),
|
snprintf (fmt, sizeof (fmt),
|
||||||
"{\"op\":\"read\",\"address\":%"PFMT64d",\"count\":%d}",
|
"{\"op\":\"read\",\"address\":%"PFMT64d",\"count\":%d}",
|
||||||
io->off, count);
|
io->off, count);
|
||||||
rv = r2p_write (R2P(fd), fmt);
|
rv = r2p_write (R2P (fd), fmt);
|
||||||
if (rv <1) {
|
if (rv <1) {
|
||||||
eprintf ("r2p_write: error\n");
|
eprintf ("r2p_write: error\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
res = r2p_read (R2P(fd));
|
res = r2p_read (R2P (fd));
|
||||||
/* TODO: parse json back */
|
/* TODO: parse json back */
|
||||||
r = strstr (res, "result");
|
r = strstr (res, "result");
|
||||||
if (r) { rescount = atoi (r+6+2); }
|
if (r) { rescount = atoi (r+6+2); }
|
||||||
@ -223,7 +140,7 @@ static int __system(RIO *io, RIODesc *fd, const char *msg) {
|
|||||||
|
|
||||||
RIOPlugin r_io_plugin_r2pipe = {
|
RIOPlugin r_io_plugin_r2pipe = {
|
||||||
.name = "r2pipe",
|
.name = "r2pipe",
|
||||||
.desc = "r2pipe exec",
|
.desc = "r2pipe io plugin",
|
||||||
.license = "MIT",
|
.license = "MIT",
|
||||||
.open = __open,
|
.open = __open,
|
||||||
.close = __close,
|
.close = __close,
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
include ../config.mk
|
include ../config.mk
|
||||||
|
|
||||||
NAME=r_socket
|
NAME=r_socket
|
||||||
OBJS=socket.o proc.o http.o http_server.o rap_server.o run.o
|
OBJS=socket.o proc.o http.o http_server.o
|
||||||
|
OBJS+=rap_server.o run.o r2pipe.o
|
||||||
DEPS=r_util
|
DEPS=r_util
|
||||||
|
|
||||||
ifneq (,$(findstring mingw32,${OSTYPE}))
|
ifneq (,$(findstring mingw32,${OSTYPE}))
|
||||||
|
158
libr/socket/r2pipe.c
Normal file
158
libr/socket/r2pipe.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/* radare - LGPL - Copyright 2015 - pancake */
|
||||||
|
|
||||||
|
#include <r_util.h>
|
||||||
|
#include <r_socket.h>
|
||||||
|
|
||||||
|
#define R2P_MAGIC 0x329193
|
||||||
|
#define R2P_PID(x) (((R2Pipe*)x->data)->pid)
|
||||||
|
#define R2P_INPUT(x) (((R2Pipe*)x->data)->input[0])
|
||||||
|
#define R2P_OUTPUT(x) (((R2Pipe*)x->data)->output[1])
|
||||||
|
|
||||||
|
static void env(const char *s, int f) {
|
||||||
|
char *a = r_str_newf ("%d", f);
|
||||||
|
r_sys_setenv (s, a);
|
||||||
|
free (a);
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API int r2p_close(R2Pipe *r2p) {
|
||||||
|
#if __WINDOWS__
|
||||||
|
if (r2p->pipe) {
|
||||||
|
CloseHandle (r2p->pipe);
|
||||||
|
r2p->pipe = NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (r2p->input[0] != -1) {
|
||||||
|
close (r2p->input[0]);
|
||||||
|
close (r2p->input[1]);
|
||||||
|
r2p->input[0] = -1;
|
||||||
|
r2p->input[1] = -1;
|
||||||
|
}
|
||||||
|
if (r2p->output[0] != -1) {
|
||||||
|
close (r2p->output[0]);
|
||||||
|
close (r2p->output[1]);
|
||||||
|
r2p->output[0] = -1;
|
||||||
|
r2p->output[1] = -1;
|
||||||
|
}
|
||||||
|
if (r2p->child != -1) {
|
||||||
|
kill (r2p->child, SIGTERM);
|
||||||
|
waitpid (r2p->child, NULL, 0);
|
||||||
|
r2p->child = -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __WINDOWS__
|
||||||
|
static int w32_createChildProcess(const char * szCmdline) {
|
||||||
|
PROCESS_INFORMATION piProcInfo;
|
||||||
|
STARTUPINFO siStartInfo;
|
||||||
|
BOOL bSuccess = FALSE;
|
||||||
|
DWORD dwWritten;
|
||||||
|
ZeroMemory (&piProcInfo, sizeof (PROCESS_INFORMATION));
|
||||||
|
ZeroMemory (&siStartInfo, sizeof (STARTUPINFO));
|
||||||
|
siStartInfo.cb = sizeof (STARTUPINFO);
|
||||||
|
bSuccess = CreateProcess (NULL, szCmdline, NULL, NULL,
|
||||||
|
TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo);
|
||||||
|
if (!bSuccess)
|
||||||
|
return R_FALSE;
|
||||||
|
CloseHandle (piProcInfo.hProcess);
|
||||||
|
CloseHandle (piProcInfo.hThread);
|
||||||
|
return R_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int w32_createPipe(R2Pipe *r2p, const char *cmd) {
|
||||||
|
DWORD dwRead, dwWritten;
|
||||||
|
CHAR buf[1024];
|
||||||
|
BOOL bSuccess = FALSE;
|
||||||
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
|
int res = 0;
|
||||||
|
r2p->pipe = CreateNamedPipe ("\\\\.\\pipe\\R2PIPE_IN",
|
||||||
|
PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE | \
|
||||||
|
PIPE_READMODE_MESSAGE | \
|
||||||
|
PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
|
||||||
|
sizeof (buf), sizeof (buf), 0, NULL);
|
||||||
|
if (w32_createChildProcess (cmd) != R_TRUE) {
|
||||||
|
//eprintf("Error spawning process: %s\n",code);
|
||||||
|
return R_TRUE;
|
||||||
|
}
|
||||||
|
bSuccess = ConnectNamedPipe (r2p->pipe, NULL);
|
||||||
|
if (!bSuccess) {
|
||||||
|
//eprintf("Error connecting pipe.\n");
|
||||||
|
return R_TRUE;
|
||||||
|
}
|
||||||
|
return R_TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
R_API R2Pipe *r2p_open(const char *cmd) {
|
||||||
|
R2Pipe *r2p = R_NEW0 (R2Pipe);
|
||||||
|
r2p->magic = R2P_MAGIC;
|
||||||
|
#if __WINDOWS__
|
||||||
|
w32_createPipe (r2p, cmd);
|
||||||
|
r2p->child = (int)(r2p->pipe);
|
||||||
|
#else
|
||||||
|
pipe (r2p->input);
|
||||||
|
pipe (r2p->output);
|
||||||
|
r2p->child = fork ();
|
||||||
|
if (r2p->child == -1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
env ("R2PIPE_IN", r2p->input[0]);
|
||||||
|
env ("R2PIPE_OUT", r2p->output[1]);
|
||||||
|
|
||||||
|
if (r2p->child) {
|
||||||
|
eprintf ("Child is %d\n", r2p->child);
|
||||||
|
} else {
|
||||||
|
int rc;
|
||||||
|
rc = r_sandbox_system (cmd, 1);
|
||||||
|
eprintf ("Child was %d with %d\n", r2p->child, rc);
|
||||||
|
r2p_close (r2p);
|
||||||
|
exit (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return r2p;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API int r2p_write(R2Pipe *r2p, const char *str) {
|
||||||
|
int len = strlen (str)+1; /* include \x00 */
|
||||||
|
#if __WINDOWS__
|
||||||
|
DWORD dwWritten = -1;
|
||||||
|
WriteFile (r2p->pipe, str, len, &dwWritten, NULL);
|
||||||
|
return dwWritten;
|
||||||
|
#else
|
||||||
|
return write (r2p->input[1], str, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: add timeout here ? */
|
||||||
|
R_API char *r2p_read(R2Pipe *r2p) {
|
||||||
|
char buf[1024];
|
||||||
|
#if __WINDOWS__
|
||||||
|
BOOL bSuccess = FALSE;
|
||||||
|
DWORD dwRead = 0;
|
||||||
|
memset (buf, 0, sizeof (buf));
|
||||||
|
bSuccess = ReadFile (r2p->pipe, buf, sizeof (buf), &dwRead, NULL);
|
||||||
|
if (!bSuccess || !buf[0]) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (dwRead>0) {
|
||||||
|
buf[dwRead] = 0;
|
||||||
|
}
|
||||||
|
buf[sizeof (buf)-1] = 0;
|
||||||
|
#else
|
||||||
|
int i, rv;
|
||||||
|
for (i=0; i<sizeof (buf)-1; i++) {
|
||||||
|
rv = read (r2p->output[0], buf+i, 1);
|
||||||
|
if (rv != 1 || !buf[i]) break;
|
||||||
|
}
|
||||||
|
buf[i] = 0;
|
||||||
|
#endif
|
||||||
|
return strdup (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API void r2p_free (R2Pipe *r2p) {
|
||||||
|
r2p_close (r2p);
|
||||||
|
r2p->magic = 0;
|
||||||
|
free (r2p);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user