diff --git a/binr/r2r/load.c b/binr/r2r/load.c index 16f60dcd16..d849f8408b 100644 --- a/binr/r2r/load.c +++ b/binr/r2r/load.c @@ -132,16 +132,6 @@ R_API RPVector *r2r_load_cmd_test_file(const char *file) { if (val) { *val = '\0'; val++; - // Strip comment - char *cmt = strchr (val, '#'); - if (cmt) { - *cmt = '\0'; - cmt--; - while (cmt > val && *cmt == ' ') { - *cmt = '\0'; - cmt--; - } - } } // RUN is the only cmd without value @@ -180,6 +170,16 @@ R_API RPVector *r2r_load_cmd_test_file(const char *file) { eprintf (LINEFMT "Warning: Duplicate key \"%s\"\n", file, linenum, key); \ } \ test->field.set = true; \ + /* Strip comment */ \ + char *cmt = strchr (val, '#'); \ + if (cmt) { \ + *cmt = '\0'; \ + cmt--; \ + while (cmt > val && *cmt == ' ') { \ + *cmt = '\0'; \ + cmt--; \ + } \ + } \ if (!strcmp (val, "1")) { \ test->field.value = true; \ } else if (!strcmp (val, "0")) { \ diff --git a/binr/r2r/r2r.c b/binr/r2r/r2r.c index 37553fa4a7..792b070d59 100644 --- a/binr/r2r/r2r.c +++ b/binr/r2r/r2r.c @@ -23,18 +23,23 @@ static RThreadFunctionRet worker_th(RThread *th); static void print_state(R2RState *state, ut64 prev_completed); static int help(bool verbose) { - printf ("Usage: r2r [test]\n"); + printf ("Usage: r2r [-vh] [-j threads] [test path]\n"); if (verbose) { - printf (" TODO: verbose help\n"); + printf ( + " -h print this help\n" + " -v verbose\n" + " -j [threads] how many threads to use for running tests concurrently (default is 4)\n"); } return 1; } int main(int argc, char **argv) { - int c, workers_count = 4; // TODO: read from arg + int workers_count = 4; bool verbose = false; + RGetopt opt; - r_getopt_init (&opt, argc, (const char **)argv, "hv"); + r_getopt_init (&opt, argc, (const char **)argv, "hvj:"); + int c; while ((c = r_getopt_next (&opt)) != -1) { switch (c) { case 'h': @@ -42,6 +47,14 @@ int main(int argc, char **argv) { case 'v': verbose = true; break; + case 'j': { + workers_count = atoi (opt.arg); + if (workers_count <= 0) { + eprintf ("Invalid thread count\n"); + return help (false); + } + break; + } default: return help (false); } @@ -254,9 +267,12 @@ static void print_result_diff(R2RRunConfig *config, R2RTestResultInfo *result) { print_diff (result->proc_out->out, expect); } expect = result->test->cmd_test->expect_err.value; - if (expect && strcmp (result->proc_out->err, expect)) { + const char *err = result->proc_out->err; + if (expect && strcmp (err, expect)) { printf ("-- stderr\n"); - print_diff (result->proc_out->err, expect); + print_diff (err, expect); + } else if (*err) { + printf ("-- stderr\n%s\n", err); } if (result->proc_out->ret != 0) { printf ("-- exit status: "Color_RED"%d"Color_RESET"\n", result->proc_out->ret); diff --git a/binr/r2r/run.c b/binr/r2r/run.c index 1af28a5907..33446314cf 100644 --- a/binr/r2r/run.c +++ b/binr/r2r/run.c @@ -41,6 +41,7 @@ R_API void r2r_subprocess_free(R2RSubprocess *proc) {} struct r2r_subprocess_t { pid_t pid; + int stdin_fd; int stdout_fd; int stderr_fd; int killpipe[2]; @@ -174,6 +175,13 @@ R_API R2RSubprocess *r2r_subprocess_start( goto error; } + int stdin_pipe[2] = { -1, -1 }; + if (pipe (stdin_pipe) == -1) { + perror ("pipe"); + goto error; + } + proc->stdin_fd = stdin_pipe[1]; + int stdout_pipe[2] = { -1, -1 }; if (pipe (stdout_pipe) == -1) { perror ("pipe"); @@ -207,6 +215,9 @@ R_API R2RSubprocess *r2r_subprocess_start( return NULL; } else if (proc->pid == 0) { // child + while ((dup2(stdin_pipe[0], STDIN_FILENO) == -1) && (errno == EINTR)) {} + close (stdin_pipe[0]); + close (stdin_pipe[1]); while ((dup2(stdout_pipe[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {} close (stdout_pipe[1]); close (stdout_pipe[0]); @@ -225,6 +236,7 @@ R_API R2RSubprocess *r2r_subprocess_start( free (argv); // parent + close (stdin_pipe[0]); close (stdout_pipe[1]); close (stderr_pipe[1]); @@ -254,6 +266,12 @@ error: if (stdout_pipe[1] == -1) { close (stdout_pipe[1]); } + if (stdin_pipe[0] == -1) { + close (stdin_pipe[0]); + } + if (stdin_pipe[1] == -1) { + close (stdin_pipe[1]); + } return NULL; } @@ -345,9 +363,10 @@ R_API void r2r_subprocess_free(R2RSubprocess *proc) { r_pvector_remove_data (&subprocs, proc); r_th_lock_leave (subprocs_mutex); r_strbuf_fini (&proc->out); - r_strbuf_fini (&proc->err);; - close (proc->killpipe[0]);; + r_strbuf_fini (&proc->err); + close (proc->killpipe[0]); close (proc->killpipe[1]); + close (proc->stdin_fd); close (proc->stdout_fd); close (proc->stderr_fd); free (proc); @@ -397,7 +416,9 @@ static R2RProcessOutput *run_r2_test(R2RRunConfig *config, const char *cmds, RLi "1" }; size_t env_size = load_plugins ? 0 : 1; - return runner (config->r2_cmd, args.v.a, r_pvector_len (&args), envvars, envvals, env_size); + R2RProcessOutput *out = runner (config->r2_cmd, args.v.a, r_pvector_len (&args), envvars, envvals, env_size); + r_pvector_clear (&args); + return out; } R_API R2RProcessOutput *r2r_run_cmd_test(R2RRunConfig *config, R2RCmdTest *test, R2RCmdRunner runner) { @@ -411,6 +432,14 @@ R_API R2RProcessOutput *r2r_run_cmd_test(R2RRunConfig *config, R2RCmdTest *test, r_list_delete (files, it); } } + if (r_list_empty (files)) { + if (!files) { + files = r_list_new (); + } else { + files->free = NULL; + } + r_list_push (files, "-"); + } R2RProcessOutput *out = run_r2_test (config, test->cmds.value, files, extra_args, test->load_plugins, runner); r_list_free (extra_args); r_list_free (files); diff --git a/libr/bin/bfile.c b/libr/bin/bfile.c index 6afff554eb..ff5c6974a5 100644 --- a/libr/bin/bfile.c +++ b/libr/bin/bfile.c @@ -355,7 +355,7 @@ static int string_scan_range(RList *list, RBinFile *bf, int min, pj_end (pj); RIO *io = bin->iob.io; if (io) { - io->cb_printf ("%s", pj_string (pj)); + io->cb_printf ("%s\n", pj_string (pj)); } pj_free (pj); } diff --git a/libr/core/cbin.c b/libr/core/cbin.c index 520ff8cf46..bed542f6bc 100644 --- a/libr/core/cbin.c +++ b/libr/core/cbin.c @@ -417,7 +417,7 @@ static void _print_strings(RCore *r, RList *list, int mode, int va) { R_FREE (b64.string); if (IS_MODE_JSON (mode)) { pj_end (pj); - r_cons_printf ("%s", pj_string (pj)); + r_cons_printf ("%s\n", pj_string (pj)); pj_free (pj); pj = NULL; } else if (IS_MODE_SET (mode)) { @@ -502,7 +502,7 @@ static bool bin_strings(RCore *r, int mode, int va) { if (plugin->info && plugin->name) { if (strcmp (plugin->name, "any") == 0 && !rawstr) { if (IS_MODE_JSON (mode)) { - r_cons_print ("[]"); + r_cons_print ("[]\n"); return true; } return false; @@ -621,7 +621,7 @@ static int bin_info(RCore *r, int mode, ut64 laddr) { RBinFile *bf = r_bin_cur (r->bin); if (!bf) { if (IS_MODE_JSON (mode)) { - r_cons_printf ("{}"); + r_cons_printf ("{}\n"); } return false; } @@ -631,7 +631,7 @@ static int bin_info(RCore *r, int mode, ut64 laddr) { if (!bf || !info || !obj) { if (mode & R_MODE_JSON) { - r_cons_printf ("{}"); + r_cons_printf ("{}\n"); return true; } return false; @@ -863,7 +863,7 @@ static int bin_info(RCore *r, int mode, ut64 laddr) { } } if (IS_MODE_JSON (mode)) { - r_cons_printf ("}"); + r_cons_printf ("}\n"); } } const char *dir_prefix = r_config_get (r->config, "dir.prefix"); @@ -2085,7 +2085,7 @@ static int bin_symbols(RCore *r, int mode, ut64 laddr, int va, ut64 at, const ch bool bin_demangle = r_config_get_i (r->config, "bin.demangle"); if (!info) { if (IS_MODE_JSON (mode)) { - r_cons_printf (printHere? "{}": "[]"); + r_cons_printf (printHere? "{}": "[]\n"); } r_table_free (table); return 0; @@ -2336,7 +2336,7 @@ next: pj_end (pj); } const char *js = pj_string (pj); - r_cons_printf ("%s", (js && *js)? js: "{}"); + r_cons_printf ("%s\n", (js && *js)? js: "{}"); } pj_free (pj); @@ -3127,7 +3127,7 @@ static int bin_classes(RCore *r, int mode) { RList *cs = r_bin_get_classes (r->bin); if (!cs) { if (IS_MODE_JSON (mode)) { - r_cons_print ("[]"); + r_cons_print ("[]\n"); return true; } return false; @@ -3286,7 +3286,7 @@ static int bin_classes(RCore *r, int mode) { free (name); } if (IS_MODE_JSON (mode)) { - r_cons_print ("]"); + r_cons_print ("]\n"); } return true; @@ -3778,7 +3778,7 @@ static void bin_pe_resources(RCore *r, int mode) { r_cons_printf ("%s\n", pj_string (pj)); pj_free (pj); } else if (IS_MODE_RAD (mode)) { - r_cons_printf ("fs *"); + r_cons_println ("fs *"); } } @@ -3825,7 +3825,7 @@ static int bin_signature(RCore *r, int mode) { if (plg && plg->signature) { const char *signature = plg->signature (cur, IS_MODE_JSON (mode)); if (IS_MODE_JSON (mode)) { - r_cons_printf ("{\"signature\":%s}", signature); + r_cons_printf ("{\"signature\":%s}\n", signature); } else { r_cons_println (signature); } diff --git a/libr/core/cmd_info.c b/libr/core/cmd_info.c index fb74ff0d89..a8319a922e 100644 --- a/libr/core/cmd_info.c +++ b/libr/core/cmd_info.c @@ -651,7 +651,7 @@ static int cmd_info(void *data, const char *input) { } } pj_end (pj); - r_cons_printf ("%s", pj_string (pj)); + r_cons_printf ("%s\n", pj_string (pj)); pj_free (pj); } else { // "it" if (!equal) { diff --git a/libr/core/cmd_print.c b/libr/core/cmd_print.c index b2316dcede..390297f73c 100644 --- a/libr/core/cmd_print.c +++ b/libr/core/cmd_print.c @@ -4287,7 +4287,7 @@ static void func_walk_blocks(RCore *core, RAnalFunction *f, char input, char typ } } pj_end (pj); - r_cons_printf ("%s", pj_string (pj)); + r_cons_printf ("%s\n", pj_string (pj)); pj_free (pj); } else { bool asm_lines = r_config_get_i (core->config, "asm.lines.bb"); diff --git a/libr/debug/dreg.c b/libr/debug/dreg.c index 444fc4de32..bee993a52e 100644 --- a/libr/debug/dreg.c +++ b/libr/debug/dreg.c @@ -280,7 +280,7 @@ beach: dbg->cb_printf ("}\n"); } else if (rad == 'J') { // do nothing - } else if (n > 0 && rad == 2 && ((n%cols))) { + } else if (n > 0 && (rad == 2 || rad == '=') && ((n%cols))) { dbg->cb_printf ("\n"); } return n; diff --git a/libr/util/thread.c b/libr/util/thread.c index ad0fde6251..b115e90d1c 100644 --- a/libr/util/thread.c +++ b/libr/util/thread.c @@ -39,6 +39,7 @@ static void *_r_th_launcher(void *_th) { th->running = false; r_th_lock_enter (th->lock); } while (ret); + r_th_lock_leave (th->lock); #if HAVE_PTHREAD pthread_exit (&ret); #endif diff --git a/test/new/db/anal/x86_64 b/test/new/db/anal/x86_64 index de0c84eede..c8b4f83ff9 100644 --- a/test/new/db/anal/x86_64 +++ b/test/new/db/anal/x86_64 @@ -2371,7 +2371,9 @@ s 0x2254d agf~invalid echo end EOF -EXPECT=end +EXPECT=< /dev/null agCj~{0} EOF -EXPECT={"name":"entry0", "size":46,"imports":["reloc.__libc_start_main"]} +EXPECT=< /dev/null agC~unk. echo end EOF -EXPECT=end +EXPECT=<