1 /* radare - LGPL - Copyright 2007-2012 - pancake */
2 
3 /* XXX : move to r_util??? rename method names.. to long? */
4 /* proc IO is not related to socket io.. this is shitty!! */
5 
6 #include <r_socket.h>
7 #include <r_util.h>
8 #include <signal.h>
9 
10 #if __UNIX__
11 #include <sys/wait.h>
12 #endif
13 
14 #define BUFFER_SIZE 4096
15 
r_socket_proc_open(char * const argv[])16 R_API struct r_socket_proc_t *r_socket_proc_open(char* const argv[]) {
17 #if __UNIX__ && LIBC_HAVE_FORK
18 	RSocketProc *sp = R_NEW (RSocketProc);
19 #ifdef O_CLOEXEC
20 	const int flags = O_CLOEXEC; //O_NONBLOCK|O_CLOEXEC;
21 #else
22 	const int flags = 0; //O_NONBLOCK|O_CLOEXEC;
23 #endif
24 
25 	if (!sp) {
26 		return NULL;
27 	}
28 
29 	if (pipe (sp->fd0)==-1) {
30 		perror ("pipe");
31 		goto error;
32 	}
33 	if (fcntl (sp->fd0[0], flags) < 0) {
34 		goto error;
35 	}
36 	if (fcntl (sp->fd0[1], flags) < 0) {
37 		goto error;
38 	}
39 
40 	if (pipe (sp->fd1)==-1) {
41 		perror ("pipe");
42 		goto error;
43 	}
44 	if (fcntl (sp->fd1[0], flags) < 0) {
45 		goto error;
46 	}
47 	if (fcntl (sp->fd1[1], flags) < 0) {
48 		goto error;
49 	}
50 
51 	sp->pid = r_sys_fork ();
52 	switch (sp->pid) {
53 	case 0:
54 		close (0);
55 		dup2 (sp->fd0[0], 0);
56 		close (1);
57 		dup2 (sp->fd1[1], 1);
58 		execv (argv[0], argv);
59 		exit (1);
60 		break;
61 	case -1:
62 		perror ("fork");
63 		r_socket_proc_close (sp);
64 		goto error;
65 		//r_socket_block_time (sp, false, 0);
66 	}
67 	return sp;
68 error:
69 	free (sp);
70 	return NULL;
71 #else
72 	return NULL;
73 #endif
74 }
75 
r_socket_proc_close(struct r_socket_proc_t * sp)76 R_API int r_socket_proc_close(struct r_socket_proc_t *sp) {
77 #if __UNIX__
78 	/* this is wrong */
79 	kill (sp->pid, SIGKILL);
80 	waitpid (sp->pid, NULL, 0); //WNOHANG);
81 	close (sp->fd0[0]);
82 	close (sp->fd0[1]);
83 	//close(sp->fd1[0]);
84 	close (sp->fd1[1]);
85 	//sp->fd[0] = -1;
86 	//sp->fd[1] = -1;
87 #endif
88 	return 0;
89 }
90 
r_socket_proc_read(RSocketProc * sp,unsigned char * buf,int len)91 R_API int r_socket_proc_read (RSocketProc *sp, unsigned char *buf, int len) {
92 	RSocket s;
93 	s.is_ssl = false;
94 	s.fd = sp->fd1[0];
95 	return r_socket_read (&s, buf, len);
96 }
97 
r_socket_proc_gets(RSocketProc * sp,char * buf,int size)98 R_API int r_socket_proc_gets (RSocketProc *sp, char *buf, int size) {
99 	RSocket s;
100 	s.is_ssl = false;
101 	s.fd = sp->fd1[0];
102 	return r_socket_gets (&s, buf, size);
103 }
104 
r_socket_proc_write(RSocketProc * sp,void * buf,int len)105 R_API int r_socket_proc_write (RSocketProc *sp, void *buf, int len) {
106 	RSocket s;
107 	s.is_ssl = false;
108 	s.fd = sp->fd0[1];
109 	return r_socket_write (&s, buf, len);
110 }
111 
r_socket_proc_printf(RSocketProc * sp,const char * fmt,...)112 R_API void r_socket_proc_printf (RSocketProc *sp, const char *fmt, ...) {
113 	RSocket s;
114 	char buf[BUFFER_SIZE];
115 	va_list ap;
116 	s.is_ssl = false;
117 	s.fd = sp->fd0[1];
118 	if (s.fd != R_INVALID_SOCKET) {
119 		va_start (ap, fmt);
120 		vsnprintf (buf, BUFFER_SIZE, fmt, ap);
121 		r_socket_write (&s, buf, strlen(buf));
122 		va_end (ap);
123 	}
124 }
125 
r_socket_proc_ready(RSocketProc * sp,int secs,int usecs)126 R_API int r_socket_proc_ready (RSocketProc *sp, int secs, int usecs) {
127 	RSocket s;
128 	s.is_ssl = false;
129 	s.fd = sp->fd1[0];
130 	return r_socket_ready (&s, secs, usecs);
131 }
132