2020-06-15 11:24:43 +02:00
|
|
|
/* radare - LGPL - Copyright 2009-2020 - pancake */
|
2009-02-05 22:08:46 +01:00
|
|
|
|
|
|
|
#include <r_cons.h>
|
2011-11-16 02:06:46 +01:00
|
|
|
#include <limits.h>
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2019-06-09 18:50:36 +02:00
|
|
|
// TODO: kill globals, and make this stackable
|
|
|
|
// cons_pipe should be using a stack pipe_push, pipe_pop
|
2011-11-16 00:44:18 +01:00
|
|
|
static int backup_fd = -1;
|
2013-11-29 17:27:46 +01:00
|
|
|
static int backup_fdn = 1;
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2011-11-29 12:28:02 +01:00
|
|
|
#ifndef O_BINARY
|
|
|
|
#define O_BINARY 0
|
|
|
|
#endif
|
|
|
|
|
2019-06-09 18:50:36 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
return dup2 (fdn, backup_fd) != -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-11-29 17:27:46 +01:00
|
|
|
R_API int r_cons_pipe_open(const char *file, int fdn, int append) {
|
2016-09-19 17:44:22 +02:00
|
|
|
if (fdn < 1) {
|
|
|
|
return -1;
|
|
|
|
}
|
2019-06-09 18:50:36 +02:00
|
|
|
char *targetFile = (!strncmp (file, "~/", 2) || !strncmp (file, "~\\", 2))
|
|
|
|
? r_str_home (file + 2): strdup (file);
|
|
|
|
const int fd_flags = O_BINARY | O_RDWR | O_CREAT | (append? O_APPEND: O_TRUNC);
|
|
|
|
int fd = r_sandbox_open (targetFile, fd_flags, 0644);
|
|
|
|
if (fd == -1) {
|
2012-09-06 12:47:32 +02:00
|
|
|
eprintf ("r_cons_pipe_open: Cannot open file '%s'\n", file);
|
2016-11-22 00:28:15 +01:00
|
|
|
free (targetFile);
|
2009-02-05 22:08:46 +01:00
|
|
|
return -1;
|
2019-06-09 18:50:36 +02:00
|
|
|
}
|
2016-09-21 11:00:52 +02:00
|
|
|
if (backup_fd != -1) {
|
2011-11-16 00:44:18 +01:00
|
|
|
close (backup_fd);
|
2019-09-16 14:25:37 +02:00
|
|
|
// already set in __dupDescriptor // backup_fd = -1;
|
2016-09-21 11:00:52 +02:00
|
|
|
}
|
|
|
|
backup_fdn = fdn;
|
2019-06-09 18:50:36 +02:00
|
|
|
if (!__dupDescriptor (fd, fdn)) {
|
2019-09-16 14:25:37 +02:00
|
|
|
eprintf ("Cannot dup stdout to %d\n", fdn);
|
2016-11-22 00:28:15 +01:00
|
|
|
free (targetFile);
|
2011-04-04 18:33:27 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2013-11-29 17:27:46 +01:00
|
|
|
close (fdn);
|
|
|
|
dup2 (fd, fdn);
|
2016-11-22 00:28:15 +01:00
|
|
|
free (targetFile);
|
2009-02-05 22:08:46 +01:00
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2010-07-12 21:37:40 +02:00
|
|
|
R_API void r_cons_pipe_close(int fd) {
|
2019-06-09 18:50:36 +02:00
|
|
|
if (fd != -1) {
|
|
|
|
close (fd);
|
|
|
|
if (backup_fd != -1) {
|
|
|
|
dup2 (backup_fd, backup_fdn);
|
|
|
|
close (backup_fd);
|
|
|
|
backup_fd = -1;
|
|
|
|
}
|
2011-11-16 00:44:18 +01:00
|
|
|
}
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|