1 /* radare - LGPL - Copyright 2009-2020 - pancake */
2
3 #include <r_cons.h>
4 #include <limits.h>
5
6 // TODO: kill globals, and make this stackable
7 // cons_pipe should be using a stack pipe_push, pipe_pop
8 static int backup_fd = -1;
9 static int backup_fdn = 1;
10
11 #ifndef O_BINARY
12 #define O_BINARY 0
13 #endif
14
__dupDescriptor(int fd,int fdn)15 static bool __dupDescriptor(int fd, int fdn) {
16 #if __WINDOWS__
17 backup_fd = 2002 - (fd - 2); // windows xp has 2048 as limit fd
18 return _dup2 (fdn, backup_fd) != -1;
19 #else
20 backup_fd = sysconf (_SC_OPEN_MAX) - (fd - 2); // portable getdtablesize()
21 if (backup_fd < 2) {
22 backup_fd = 2002 - (fd - 2); // fallback
23 }
24 return dup2 (fdn, backup_fd) != -1;
25 #endif
26 }
27
r_cons_pipe_open(const char * file,int fdn,int append)28 R_API int r_cons_pipe_open(const char *file, int fdn, int append) {
29 if (fdn < 1) {
30 return -1;
31 }
32 char *targetFile = (!strncmp (file, "~/", 2) || !strncmp (file, "~\\", 2))
33 ? r_str_home (file + 2): strdup (file);
34 const int fd_flags = O_BINARY | O_RDWR | O_CREAT | (append? O_APPEND: O_TRUNC);
35 int fd = r_sandbox_open (targetFile, fd_flags, 0644);
36 if (fd == -1) {
37 eprintf ("r_cons_pipe_open: Cannot open file '%s'\n", file);
38 free (targetFile);
39 return -1;
40 }
41 if (backup_fd != -1) {
42 close (backup_fd);
43 // already set in __dupDescriptor // backup_fd = -1;
44 }
45 backup_fdn = fdn;
46 if (!__dupDescriptor (fd, fdn)) {
47 eprintf ("Cannot dup stdout to %d\n", fdn);
48 free (targetFile);
49 return -1;
50 }
51 close (fdn);
52 dup2 (fd, fdn);
53 free (targetFile);
54 return fd;
55 }
56
r_cons_pipe_close(int fd)57 R_API void r_cons_pipe_close(int fd) {
58 if (fd != -1) {
59 close (fd);
60 if (backup_fd != -1) {
61 dup2 (backup_fd, backup_fdn);
62 close (backup_fd);
63 backup_fd = -1;
64 }
65 }
66 }
67