@@ -66,6 +66,15 @@ _Noreturn void exec_am_broadcast(int argc, char** argv, char* input_address_stri
6666 exit (1 );
6767}
6868
69+ _Noreturn void exec_callback (int fd )
70+ {
71+ char * fds ;
72+ if (asprintf (& fds , "%d" , fd ) == -1 ) { perror ("asprintf" ); }
73+ execl ("/data/data/com.termux/files/usr/libexec/termux-callback" , "termux-callback" , fds , NULL );
74+ perror ("execl(\"/data/data/com.termux/files/usr/libexec/termux-callback\")" );
75+ exit (1 );
76+ }
77+
6978void generate_uuid (char * str ) {
7079 sprintf (str , "%x%x-%x-%x-%x-%x%x%x" ,
7180 arc4random (), arc4random (), // Generates a 64-bit Hex number
@@ -93,13 +102,32 @@ void* transmit_stdin_to_socket(void* arg) {
93102}
94103
95104// Main thread function which reads from input socket and writes to stdout.
96- void transmit_socket_to_stdout (int input_socket_fd ) {
105+ int transmit_socket_to_stdout (int input_socket_fd ) {
97106 ssize_t len ;
98107 char buffer [1024 ];
99- while ((len = read (input_socket_fd , & buffer , sizeof (buffer ))) > 0 ) {
108+ char cbuf [256 ];
109+ struct iovec io = { .iov_base = buffer , .iov_len = sizeof (buffer ) };
110+ struct msghdr msg = { 0 };
111+ int fd = -1 ; // An optional file descriptor received through the socket
112+ msg .msg_iov = & io ;
113+ msg .msg_iovlen = 1 ;
114+ msg .msg_control = cbuf ;
115+ msg .msg_controllen = sizeof (cbuf );
116+ while ((len = recvmsg (input_socket_fd , & msg , 0 )) > 0 ) {
117+ struct cmsghdr * cmsg = CMSG_FIRSTHDR (& msg );
118+ if (cmsg && cmsg -> cmsg_len == CMSG_LEN (sizeof (int ))) {
119+ if (cmsg -> cmsg_type == SCM_RIGHTS ) {
120+ fd = * ((int * ) CMSG_DATA (cmsg ));
121+ }
122+ }
123+ // A file descriptor must be accompanied by a non-empty message,
124+ // so we use "@" when we don't want any output.
125+ if (fd != -1 && len == 1 && buffer [0 ] == '@' ) { len = 0 ; }
100126 write (STDOUT_FILENO , buffer , len );
127+ msg .msg_controllen = sizeof (cbuf );
101128 }
102- if (len < 0 ) perror ("read()" );
129+ if (len < 0 ) perror ("recvmsg()" );
130+ return fd ;
103131}
104132
105133int main (int argc , char * * argv ) {
@@ -149,7 +177,9 @@ int main(int argc, char** argv) {
149177 pthread_t transmit_thread ;
150178 pthread_create (& transmit_thread , NULL , transmit_stdin_to_socket , & output_server_socket );
151179
152- transmit_socket_to_stdout (input_client_socket );
180+ int fd = transmit_socket_to_stdout (input_client_socket );
181+ close (input_client_socket );
182+ if (fd != -1 ) { exec_callback (fd ); }
153183
154184 return 0 ;
155185}
0 commit comments