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