Rewrite how rz_cons_pipe_open/close behave to remove globals (#4223)
This commit is contained in:
parent
fa455f8b52
commit
2886608d59
4 changed files with 164 additions and 67 deletions
|
|
@ -1,62 +1,151 @@
|
|||
// SPDX-FileCopyrightText: 2009-2020 pancake <pancake@nopcode.org>
|
||||
// SPDX-FileCopyrightText: 2024 RizinOrg <info@rizin.re>
|
||||
// SPDX-FileCopyrightText: 2024 deroad <wargio@libero.it>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_cons.h>
|
||||
#include <limits.h>
|
||||
|
||||
// TODO: remove globals, and make this stackable
|
||||
// cons_pipe should be using a stack pipe_push, pipe_pop
|
||||
static int backup_fd = -1;
|
||||
static int backup_fdn = 1;
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
static bool __dupDescriptor(int fd, int fdn) {
|
||||
#if __WINDOWS__
|
||||
backup_fd = 2002 - (fd - 2); // windows xp has 2048 as limit fd
|
||||
return _dup2(fdn, backup_fd) != -1;
|
||||
#else
|
||||
backup_fd = sysconf(_SC_OPEN_MAX) - (fd - 2); // portable getdtablesize()
|
||||
if (backup_fd < 2) {
|
||||
backup_fd = 2002 - (fd - 2); // fallback
|
||||
#include <io.h>
|
||||
|
||||
/**
|
||||
* \brief Duplicates a file descriptor and returns the new one.
|
||||
*
|
||||
* \param old_fd File descriptor to duplicate
|
||||
* \return On success is a positive integer, otherwise -1
|
||||
*/
|
||||
static int pipe_dup_fd(int old_fd) {
|
||||
int new_fd = _dup(old_fd);
|
||||
if (new_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
return dup2(fdn, backup_fd) != -1;
|
||||
#endif
|
||||
return new_fd;
|
||||
}
|
||||
|
||||
RZ_API int rz_cons_pipe_open(const char *file, int fdn, int append) {
|
||||
if (fdn < 1) {
|
||||
return -1;
|
||||
/**
|
||||
* \brief Duplicates a file descriptor by assigning a given one.
|
||||
*
|
||||
* \param old_fd Old file descriptor to duplicate
|
||||
* \param new_fd New file descriptor
|
||||
* \return true on success, otherwise false.
|
||||
*/
|
||||
static bool pipe_dup2_fd(int old_fd, int new_fd) {
|
||||
if (!_dup2(old_fd, new_fd)) {
|
||||
return true;
|
||||
}
|
||||
const int fd_flags = O_BINARY | O_RDWR | O_CREAT | (append ? O_APPEND : O_TRUNC);
|
||||
int fd = rz_sys_open(file, fd_flags, 0644);
|
||||
if (fd == -1) {
|
||||
eprintf("rz_cons_pipe_open: Cannot open file '%s'\n", file);
|
||||
return -1;
|
||||
}
|
||||
if (backup_fd != -1) {
|
||||
close(backup_fd);
|
||||
// already set in __dupDescriptor // backup_fd = -1;
|
||||
}
|
||||
backup_fdn = fdn;
|
||||
if (!__dupDescriptor(fd, fdn)) {
|
||||
eprintf("Cannot dup stdout to %d\n", fdn);
|
||||
return -1;
|
||||
}
|
||||
close(fdn);
|
||||
dup2(fd, fdn);
|
||||
return fd;
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API void rz_cons_pipe_close(int fd) {
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
if (backup_fd != -1) {
|
||||
dup2(backup_fd, backup_fdn);
|
||||
close(backup_fd);
|
||||
backup_fd = -1;
|
||||
}
|
||||
#else /* !__WINDOWS__ */
|
||||
|
||||
/**
|
||||
* \brief Duplicates a file descriptor and returns the new one.
|
||||
*
|
||||
* \param old_fd File descriptor to duplicate
|
||||
* \return On success is a positive integer, otherwise -1
|
||||
*/
|
||||
static int pipe_dup_fd(int old_fd) {
|
||||
int new_fd = dup(old_fd);
|
||||
if (new_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
return new_fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Duplicates a file descriptor by assigning a given one.
|
||||
*
|
||||
* \param old_fd Old file descriptor to duplicate
|
||||
* \param new_fd New file descriptor
|
||||
* \return true on success, otherwise false.
|
||||
*/
|
||||
static bool pipe_dup2_fd(int old_fd, int new_fd) {
|
||||
if (dup2(old_fd, new_fd) == new_fd) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* __WINDOWS__ */
|
||||
|
||||
struct rz_cons_pipe_t {
|
||||
int fd; ///< File descriptor number to override.
|
||||
int copy_fd; ///< Copy of the file descriptor.
|
||||
int file_fd; ///< File descriptor of the opened file.
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Redirects the data flow from a file descriptor to a file.
|
||||
*
|
||||
* \param file File name to open where to redirect the file descriptor.
|
||||
* \param fd The file descriptor to pipe
|
||||
* \param append When true, the data written to the file is appended.
|
||||
* \return On success a valid pointer, otherwise NULL.
|
||||
*/
|
||||
RZ_API RZ_OWN RzConsPipe *rz_cons_pipe_open(RZ_NONNULL const char *file, int fd, bool append) {
|
||||
rz_return_val_if_fail(RZ_STR_ISNOTEMPTY(file), NULL);
|
||||
|
||||
if (fd < 1) {
|
||||
RZ_LOG_ERROR("cpipe: invalid file descriptor '%d'\n", fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RzConsPipe *cpipe = RZ_NEW0(RzConsPipe);
|
||||
if (!cpipe) {
|
||||
RZ_LOG_ERROR("cpipe: cannot allocate RzConsPipe\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// open file to which we pipe all the data from fd
|
||||
const int file_flags = O_BINARY | O_RDWR | O_CREAT | (append ? O_APPEND : O_TRUNC);
|
||||
int file_fd = rz_sys_open(file, file_flags, 0644);
|
||||
if (file_fd < 0) {
|
||||
RZ_LOG_ERROR("cpipe: Cannot open file '%s'\n", file);
|
||||
free(cpipe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// save the original file descriptor by making a copy
|
||||
int copy_fd = pipe_dup_fd(fd);
|
||||
if (copy_fd < 0) {
|
||||
RZ_LOG_ERROR("cpipe: Cannot duplicate %d\n", fd);
|
||||
close(file_fd);
|
||||
free(cpipe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// override file descriptor with the opened file one.
|
||||
if (!pipe_dup2_fd(file_fd, fd)) {
|
||||
RZ_LOG_ERROR("cpipe: Cannot duplicate %d to %d\n", file_fd, fd);
|
||||
close(copy_fd);
|
||||
close(file_fd);
|
||||
free(cpipe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cpipe->fd = fd;
|
||||
cpipe->copy_fd = copy_fd;
|
||||
cpipe->file_fd = file_fd;
|
||||
return cpipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Closes a given RzConsPipe and restores the file descriptor.
|
||||
*
|
||||
* \param cpipe The console pipe to close.
|
||||
*/
|
||||
RZ_API void rz_cons_pipe_close(RZ_NULLABLE RzConsPipe *cpipe) {
|
||||
if (!cpipe) {
|
||||
return;
|
||||
}
|
||||
|
||||
// restore file descriptor from copy.
|
||||
if (!pipe_dup2_fd(cpipe->copy_fd, cpipe->fd)) {
|
||||
RZ_LOG_ERROR("cpipe: Cannot duplicate %d to %d\n", cpipe->copy_fd, cpipe->fd);
|
||||
}
|
||||
|
||||
// close the opened file descriptors
|
||||
close(cpipe->copy_fd);
|
||||
close(cpipe->file_fd);
|
||||
free(cpipe);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1442,7 +1442,8 @@ static int rz_core_cmd_subst_i(RzCore *core, char *cmd, char *colon, bool *tmpse
|
|||
char *grep = NULL;
|
||||
RzIODesc *tmpdesc = NULL;
|
||||
int pamode = !core->io->va;
|
||||
int i, ret = 0, pipefd;
|
||||
int i, ret = 0;
|
||||
RzConsPipe *cpipe = NULL;
|
||||
bool usemyblock = false;
|
||||
int scr_html = -1;
|
||||
int scr_color = -1;
|
||||
|
|
@ -1482,7 +1483,7 @@ static int rz_core_cmd_subst_i(RzCore *core, char *cmd, char *colon, bool *tmpse
|
|||
break;
|
||||
case '"':
|
||||
for (; *cmd;) {
|
||||
int pipefd = -1;
|
||||
RzConsPipe *cpipe = NULL;
|
||||
ut64 oseek = UT64_MAX;
|
||||
char *line, *p;
|
||||
haveQuote = *cmd == '"';
|
||||
|
|
@ -1543,7 +1544,8 @@ static int rz_core_cmd_subst_i(RzCore *core, char *cmd, char *colon, bool *tmpse
|
|||
str = (char *)rz_str_trim_head_ro(str);
|
||||
rz_cons_flush();
|
||||
const bool append = p[2] == '>';
|
||||
pipefd = rz_cons_pipe_open(str, 1, append);
|
||||
/* pipe stdout */
|
||||
cpipe = rz_cons_pipe_open(str, 1, append);
|
||||
}
|
||||
}
|
||||
line = strdup(cmd);
|
||||
|
|
@ -1558,9 +1560,10 @@ static int rz_core_cmd_subst_i(RzCore *core, char *cmd, char *colon, bool *tmpse
|
|||
if (oseek != UT64_MAX) {
|
||||
rz_core_seek(core, oseek, true);
|
||||
}
|
||||
if (pipefd != -1) {
|
||||
if (cpipe) {
|
||||
rz_cons_flush();
|
||||
rz_cons_pipe_close(pipefd);
|
||||
rz_cons_pipe_close(cpipe);
|
||||
cpipe = NULL;
|
||||
}
|
||||
if (!p) {
|
||||
break;
|
||||
|
|
@ -1813,14 +1816,14 @@ escape_pipe:
|
|||
free(o);
|
||||
} else if (fdn > 0) {
|
||||
// pipe to file (or append)
|
||||
pipefd = rz_cons_pipe_open(str, fdn, appendResult);
|
||||
if (pipefd != -1) {
|
||||
cpipe = rz_cons_pipe_open(str, fdn, appendResult);
|
||||
if (cpipe) {
|
||||
if (!pipecolor) {
|
||||
rz_config_set_i(core->config, "scr.color", COLOR_MODE_DISABLED);
|
||||
}
|
||||
ret = rz_core_cmd_subst(core, cmd);
|
||||
rz_cons_flush();
|
||||
rz_cons_pipe_close(pipefd);
|
||||
rz_cons_pipe_close(cpipe);
|
||||
}
|
||||
}
|
||||
rz_cons_set_last_interactive();
|
||||
|
|
@ -3884,17 +3887,17 @@ DEFINE_HANDLE_TS_FCN_AND_SYMBOL(redirect_stmt) {
|
|||
} else {
|
||||
rz_cons_flush();
|
||||
RZ_LOG_DEBUG("redirect_stmt: fdn = %d, is_append = %d\n", fdn, is_append);
|
||||
int pipefd = rz_cons_pipe_open(arg_str, fdn, is_append);
|
||||
if (pipefd != -1) {
|
||||
RzConsPipe *cpipe = rz_cons_pipe_open(arg_str, fdn, is_append);
|
||||
if (cpipe) {
|
||||
if (!pipecolor) {
|
||||
rz_config_set_i(state->core->config, "scr.color", COLOR_MODE_DISABLED);
|
||||
}
|
||||
TSNode command = ts_node_child_by_field_name(node, "command", strlen("command"));
|
||||
res = handle_ts_stmt(state, command);
|
||||
rz_cons_flush();
|
||||
rz_cons_pipe_close(pipefd);
|
||||
rz_cons_pipe_close(cpipe);
|
||||
} else {
|
||||
RZ_LOG_WARN("Could not open pipe to %d", fdn);
|
||||
RZ_LOG_WARN("Could not open pipe to %d\n", fdn);
|
||||
}
|
||||
}
|
||||
free(arg_str);
|
||||
|
|
@ -5533,8 +5536,8 @@ RZ_API char *rz_core_cmd_str_pipe(RzCore *core, const char *cmd) {
|
|||
}
|
||||
rz_cons_reset();
|
||||
if (rz_file_mkstemp("cmd", &tmp) != -1) {
|
||||
int pipefd = rz_cons_pipe_open(tmp, 1, 0);
|
||||
if (pipefd == -1) {
|
||||
RzConsPipe *cpipe = rz_cons_pipe_open(tmp, 1, 0);
|
||||
if (!cpipe) {
|
||||
rz_file_rm(tmp);
|
||||
free(tmp);
|
||||
return rz_core_cmd_str(core, cmd);
|
||||
|
|
@ -5542,7 +5545,7 @@ RZ_API char *rz_core_cmd_str_pipe(RzCore *core, const char *cmd) {
|
|||
char *_cmd = strdup(cmd);
|
||||
rz_core_cmd(core, _cmd, 0);
|
||||
rz_cons_flush();
|
||||
rz_cons_pipe_close(pipefd);
|
||||
rz_cons_pipe_close(cpipe);
|
||||
if (rz_file_exists(tmp)) {
|
||||
char *s = rz_file_slurp(tmp, NULL);
|
||||
rz_file_rm(tmp);
|
||||
|
|
|
|||
|
|
@ -50,10 +50,14 @@ static int __rap_detach(RzDebug *dbg, int pid) {
|
|||
|
||||
static char *__rap_reg_profile(RzDebug *dbg) {
|
||||
char *out, *tf = rz_file_temp("rap.XXXXXX");
|
||||
int fd = rz_cons_pipe_open(tf, 1, 0);
|
||||
RzConsPipe *cpipe = rz_cons_pipe_open(tf, 1, 0);
|
||||
if (!cpipe) {
|
||||
rz_file_rm(tf);
|
||||
return NULL;
|
||||
}
|
||||
rz_io_system(dbg->iob.io, "drp");
|
||||
rz_cons_flush();
|
||||
rz_cons_pipe_close(fd);
|
||||
rz_cons_pipe_close(cpipe);
|
||||
out = rz_file_slurp(tf, NULL);
|
||||
rz_file_rm(tf);
|
||||
free(tf);
|
||||
|
|
|
|||
|
|
@ -904,8 +904,9 @@ RZ_API void rz_cons_break_end(void);
|
|||
RZ_API void rz_cons_break_timeout(int timeout);
|
||||
|
||||
/* pipe */
|
||||
RZ_API int rz_cons_pipe_open(const char *file, int fdn, int append);
|
||||
RZ_API void rz_cons_pipe_close(int fd);
|
||||
typedef struct rz_cons_pipe_t RzConsPipe;
|
||||
RZ_API RZ_OWN RzConsPipe *rz_cons_pipe_open(RZ_NONNULL const char *file, int old_fd, bool append);
|
||||
RZ_API void rz_cons_pipe_close(RZ_NULLABLE RzConsPipe *cpipe);
|
||||
|
||||
#if __WINDOWS__
|
||||
RZ_API RzVirtTermMode rz_cons_detect_vt_mode(void);
|
||||
|
|
|
|||
Loading…
Reference in a new issue