From 699b60db566aeba8f6265e7d474f2686d5ca5b83 Mon Sep 17 00:00:00 2001 From: Nathan Freitas Date: Wed, 30 Dec 2015 09:52:56 -0500 Subject: [PATCH] add linancillary for badvpn tun2socks update for DNS --- jni/libancillary/API | 139 +++++++++++++++++++++++++++++++++++ jni/libancillary/COPYING | 21 ++++++ jni/libancillary/Makefile | 73 ++++++++++++++++++ jni/libancillary/ancillary.h | 131 +++++++++++++++++++++++++++++++++ jni/libancillary/fd_recv.c | 98 ++++++++++++++++++++++++ jni/libancillary/fd_send.c | 92 +++++++++++++++++++++++ jni/libancillary/test.c | 112 ++++++++++++++++++++++++++++ 7 files changed, 666 insertions(+) create mode 100644 jni/libancillary/API create mode 100644 jni/libancillary/COPYING create mode 100644 jni/libancillary/Makefile create mode 100644 jni/libancillary/ancillary.h create mode 100644 jni/libancillary/fd_recv.c create mode 100644 jni/libancillary/fd_send.c create mode 100644 jni/libancillary/test.c diff --git a/jni/libancillary/API b/jni/libancillary/API new file mode 100644 index 00000000..b558995a --- /dev/null +++ b/jni/libancillary/API @@ -0,0 +1,139 @@ + This library provide an easy interface to the black magic that can be done + on Unix domain sockets, like passing file descriptors from one process to + another. + + Programs that uses this library should include the ancillary.h header file. + Nothing else is required. + + All functions of this library require the following header: + + #include + + At this time, the only ancillary data defined by the Single Unix + Specification (v3) is file descriptors. + +Passing file descriptors + + int ancil_send_fd(socket, file_descriptor) + int socket: the Unix socket + int file_descriptor: the file descriptor + Return value: 0 for success, -1 for failure. + + Sends one file descriptor on a socket. + In case of failure, errno is set; the possible values are the ones of the + sendmsg(2) system call. + + + int ancil_recv_fd(socket, file_descriptor) + int socket: the Unix socket + int *file_descriptor: pointer to the returned file descriptor + Return value: 0 for success, -1 for failure + + Receives one file descriptor from a socket. + In case of success, the file descriptor is stored in the integer pointed + to by file_descriptor. + In case of failure, errno is set; the possible values are the ones of the + recvmsg(2) system call. + The behavior is undefined if the recv_fd does not match a send_fd* on the + other side. + + + int ancil_send_fds(socket, file_descriptors, num_file_descriptors) + int socket: the Unix socket + const int *file_descriptors: array of file descriptors + unsigned num_file_descriptors: number of file descriptors + Return value: 0 for success, -1 for failure + + Sends several file descriptors on a socket. + In case of failure, errno is set; the possible values are the ones of the + sendmsg(2) system call. + The maximum number of file descriptors that can be sent using this + function is ANCIL_MAX_N_FDS; the behavior is undefined in case of + overflow, probably a stack corruption. + + + int ancil_recv_fds(socket, file_descriptors, num_file_descriptors) + int socket: the Unix socket + int *file_descriptors: return array of file descriptors + unsigned num_file_descriptors: number of file descriptors + Return value: number of received fd for success, -1 for failure + + Receives several file descriptors from a socket, no more than + num_file_descriptors. + In case of success, the received file descriptors are stored in the array + pointed to by file_descriptors. + In case of failure, errno is set; the possible values are the ones of the + recvmsg(2) system call. + The maximum number of file descriptors that can be received using this + function is ANCIL_MAX_N_FDS; the behavior is undefined in case of + overflow, probably a stack corruption. + The behavior is undefined if the recv_fds does not match a send_fd* on + the other side, or if the number of received file descriptors is more than + num_file_descriptors. + + + int ancil_send_fds_with_buffer(socket, fds, num, buffer) + int socket: the Unix socket + const int *fds: array of file descriptors + unsigned num: number of file descriptors + void *buffer: buffer to hold the system data structures + Return value: 0 for success, -1 for failure + + Sends several file descriptors on a socket. + In case of failure, errno is set; the possible values are the ones of the + sendmsg(2) system call. + The buffer argument must point to a memory area large enough to hold the + system data structures, see ANCIL_FD_BUFFER. + + + int ancil_send_fds_with_buffer(socket, fds, num, buffer) + int socket: the Unix socket + int *fds: return array of file descriptors + unsigned num: number of file descriptors + void *buffer: buffer to hold the system data structures + Return value: number of received fd for success, -1 for failure + + Receives several file descriptors from a socket, no more than + num_file_descriptors. + In case of success, the received file descriptors are stored in the array + pointed to by file_descriptors. + In case of failure, errno is set; the possible values are the ones of the + recvmsg(2) system call. + The behavior is undefined if the recv_fds does not match a send_fd* on + the other side, or if the number of received file descriptors is more than + num_file_descriptors. + The buffer argument must point to a memory area large enough to hold the + system data structures, see ANCIL_FD_BUFFER. + + + ANCIL_MAX_N_FDS + + Maximum number of file descriptors that can be sent with the sent_fds and + recv_fds functions. If you have to send more at once, use the + *_with_buffer versions. The value is enough to send "quite a few" file + descriptors. + + + ANCIL_FD_BUFFER(n) + int n: number of file descriptors + + Expands to a structure data type large enough to hold the system data + structures for n file descriptors. So the address of a variable declared + of type ANCIL_FD_BUFFER(n) is suitable as the buffer argument for + *_with_buffer on n file descriptors. + To use this macro, you need and . Bevare: with + Solaris, the _XPG4_2 macro must be defined before sys/socket is included. + + +Tuning the compilation + + This library is designed to be included in projects, not installed in + /usr/lib. If your project does not use some of the functions, the + TUNE_OPTS variable in the Makefile allows not to build them. It is a list + of proprocessor options: + + -DNDEBUG: turn assertions off (see assert(3)) + -DSPARE_SEND_FDS: do not build ancil_send_fds + -DSPARE_SEND_FD: do not build ancil_send_fd + -DSPARE_RECV_FDS: do not build ancil_recv_fds + -DSPARE_RECV_FD: do not build ancil_recv_fd diff --git a/jni/libancillary/COPYING b/jni/libancillary/COPYING new file mode 100644 index 00000000..5bcd9c2b --- /dev/null +++ b/jni/libancillary/COPYING @@ -0,0 +1,21 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/jni/libancillary/Makefile b/jni/libancillary/Makefile new file mode 100644 index 00000000..3d32533f --- /dev/null +++ b/jni/libancillary/Makefile @@ -0,0 +1,73 @@ +########################################################################### +# libancillary - black magic on Unix domain sockets +# (C) Nicolas George +# Makefile - guess what +########################################################################### + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +CC=gcc +CFLAGS=-Wall -g -O2 +LDFLAGS= +LIBS= +AR=ar +RANLIB=ranlib +RM=rm +CP=cp +MKDIR=mkdir +TAR=tar +GZIP=gzip -9 + +NAME=libancillary +DISTRIBUTION=API COPYING Makefile ancillary.h fd_send.c fd_recv.c test.c +VERSION=0.9.1 + +OBJECTS=fd_send.o fd_recv.o + +TUNE_OPTS=-DNDEBUG +#TUNE_OPTS=-DNDEBUG \ + -DSPARE_SEND_FDS -DSPARE_SEND_FD -DSPARE_RECV_FDS -DSPARE_RECV_FD + +.c.o: + $(CC) -c $(CFLAGS) $(TUNE_OPTS) $< + +all: libancillary.a + +libancillary.a: $(OBJECTS) + $(AR) cr $@ $(OBJECTS) + $(RANLIB) $@ + +fd_send.o: ancillary.h +fd_recv.o: ancillary.h + +test: test.c libancillary.a + $(CC) -o $@ $(CFLAGS) $(LDFLAGS) -L. test.c -lancillary $(LIBS) + +clean: + -$(RM) -f *.o *.a test + +dist: + $(MKDIR) $(NAME)-$(VERSION) + $(CP) $(DISTRIBUTION) $(NAME)-$(VERSION) + $(TAR) -cf - $(NAME)-$(VERSION) | $(GZIP) > $(NAME)-$(VERSION).tar.gz + $(RM) -rf $(NAME)-$(VERSION) diff --git a/jni/libancillary/ancillary.h b/jni/libancillary/ancillary.h new file mode 100644 index 00000000..636d8677 --- /dev/null +++ b/jni/libancillary/ancillary.h @@ -0,0 +1,131 @@ +/*************************************************************************** + * libancillary - black magic on Unix domain sockets + * (C) Nicolas George + * ancillary.c - public header + ***************************************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ANCILLARY_H__ +#define ANCILLARY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************************************************** + * Start of the readable part. + ***************************************************************************/ + +#define ANCIL_MAX_N_FDS 960 +/* + * Maximum number of fds that can be sent or received using the "esay" + * functions; this is so that all can fit in one page. + */ + +extern int +ancil_send_fds_with_buffer(int, const int *, unsigned, void *); +/* + * ancil_send_fds_with_buffer(sock, n_fds, fds, buffer) + * + * Sends the file descriptors in the array pointed by fds, of length n_fds + * on the socket sock. + * buffer is a writeable memory area large enough to hold the required data + * structures. + * Returns: -1 and errno in case of error, 0 in case of success. + */ + +extern int +ancil_recv_fds_with_buffer(int, int *, unsigned, void *); +/* + * ancil_recv_fds_with_buffer(sock, n_fds, fds, buffer) + * + * Receives *n_fds file descriptors into the array pointed by fds + * from the socket sock. + * buffer is a writeable memory area large enough to hold the required data + * structures. + * Returns: -1 and errno in case of error, the actual number of received fd + * in case of success + */ + +#define ANCIL_FD_BUFFER(n) \ + struct { \ + struct cmsghdr h; \ + int fd[n]; \ + } +/* ANCIL_FD_BUFFER(n) + * + * A structure type suitable to be used as buffer for n file descriptors. + * Requires . + * Example: + * ANCIL_FD_BUFFER(42) buffer; + * ancil_recv_fds_with_buffer(sock, 42, my_fds, &buffer); + */ + +extern int +ancil_send_fds(int, const int *, unsigned); +/* + * ancil_send_fds(sock, n_fds, fds) + * + * Sends the file descriptors in the array pointed by fds, of length n_fds + * on the socket sock. + * n_fds must not be greater than ANCIL_MAX_N_FDS. + * Returns: -1 and errno in case of error, 0 in case of success. + */ + +extern int +ancil_recv_fds(int, int *, unsigned); +/* + * ancil_recv_fds(sock, n_fds, fds) + * + * Receives *n_fds file descriptors into the array pointed by fds + * from the socket sock. + * *n_fds must not be greater than ANCIL_MAX_N_FDS. + * Returns: -1 and errno in case of error, the actual number of received fd + * in case of success. + */ + + +extern int +ancil_send_fd(int, int); +/* ancil_recv_fd(sock, fd); + * + * Sends the file descriptor fd on the socket sock. + * Returns : -1 and errno in case of error, 0 in case of success. + */ + +extern int +ancil_recv_fd(int, int *); +/* ancil_send_fd(sock, &fd); + * + * Receives the file descriptor fd from the socket sock. + * Returns : -1 and errno in case of error, 0 in case of success. + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ANCILLARY_H__ */ diff --git a/jni/libancillary/fd_recv.c b/jni/libancillary/fd_recv.c new file mode 100644 index 00000000..46c2e694 --- /dev/null +++ b/jni/libancillary/fd_recv.c @@ -0,0 +1,98 @@ +/*************************************************************************** + * libancillary - black magic on Unix domain sockets + * (C) Nicolas George + * fd_send.c - receiving file descriptors + ***************************************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _XPG4_2 /* Solaris sucks */ +# define _XPG4_2 +#endif + +#include +#include +#include +#include +#include +#if defined(__FreeBSD__) +# include /* FreeBSD sucks */ +#endif + +#include "ancillary.h" + +int +ancil_recv_fds_with_buffer(int sock, int *fds, unsigned n_fds, void *buffer) +{ + struct msghdr msghdr; + char nothing; + struct iovec nothing_ptr; + struct cmsghdr *cmsg; + int i; + + nothing_ptr.iov_base = ¬hing; + nothing_ptr.iov_len = 1; + msghdr.msg_name = NULL; + msghdr.msg_namelen = 0; + msghdr.msg_iov = ¬hing_ptr; + msghdr.msg_iovlen = 1; + msghdr.msg_flags = 0; + msghdr.msg_control = buffer; + msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int) * n_fds; + cmsg = CMSG_FIRSTHDR(&msghdr); + cmsg->cmsg_len = msghdr.msg_controllen; + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + for(i = 0; i < n_fds; i++) + ((int *)CMSG_DATA(cmsg))[i] = -1; + + if(recvmsg(sock, &msghdr, 0) < 0) + return(-1); + for(i = 0; i < n_fds; i++) + fds[i] = ((int *)CMSG_DATA(cmsg))[i]; + n_fds = (msghdr.msg_controllen - sizeof(struct cmsghdr)) / sizeof(int); + return(n_fds); +} + +#ifndef SPARE_RECV_FDS +int +ancil_recv_fds(int sock, int *fd, unsigned n_fds) +{ + ANCIL_FD_BUFFER(ANCIL_MAX_N_FDS) buffer; + + assert(n_fds <= ANCIL_MAX_N_FDS); + return(ancil_recv_fds_with_buffer(sock, fd, n_fds, &buffer)); +} +#endif /* SPARE_RECV_FDS */ + +#ifndef SPARE_RECV_FD +int +ancil_recv_fd(int sock, int *fd) +{ + ANCIL_FD_BUFFER(1) buffer; + + return(ancil_recv_fds_with_buffer(sock, fd, 1, &buffer) == 1 ? 0 : -1); +} +#endif /* SPARE_RECV_FD */ diff --git a/jni/libancillary/fd_send.c b/jni/libancillary/fd_send.c new file mode 100644 index 00000000..01de87fd --- /dev/null +++ b/jni/libancillary/fd_send.c @@ -0,0 +1,92 @@ +/*************************************************************************** + * libancillary - black magic on Unix domain sockets + * (C) Nicolas George + * fd_send.c - sending file descriptors + ***************************************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _XPG4_2 /* Solaris sucks */ +# define _XPG4_2 +#endif + +#include +#include +#include +#include +#include +#if defined(__FreeBSD__) +# include /* FreeBSD sucks */ +#endif + +#include "ancillary.h" + +int +ancil_send_fds_with_buffer(int sock, const int *fds, unsigned n_fds, void *buffer) +{ + struct msghdr msghdr; + char nothing = '!'; + struct iovec nothing_ptr; + struct cmsghdr *cmsg; + int i; + + nothing_ptr.iov_base = ¬hing; + nothing_ptr.iov_len = 1; + msghdr.msg_name = NULL; + msghdr.msg_namelen = 0; + msghdr.msg_iov = ¬hing_ptr; + msghdr.msg_iovlen = 1; + msghdr.msg_flags = 0; + msghdr.msg_control = buffer; + msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int) * n_fds; + cmsg = CMSG_FIRSTHDR(&msghdr); + cmsg->cmsg_len = msghdr.msg_controllen; + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + for(i = 0; i < n_fds; i++) + ((int *)CMSG_DATA(cmsg))[i] = fds[i]; + return(sendmsg(sock, &msghdr, 0) >= 0 ? 0 : -1); +} + +#ifndef SPARE_SEND_FDS +int +ancil_send_fds(int sock, const int *fds, unsigned n_fds) +{ + ANCIL_FD_BUFFER(ANCIL_MAX_N_FDS) buffer; + + assert(n_fds <= ANCIL_MAX_N_FDS); + return(ancil_send_fds_with_buffer(sock, fds, n_fds, &buffer)); +} +#endif /* SPARE_SEND_FDS */ + +#ifndef SPARE_SEND_FD +int +ancil_send_fd(int sock, int fd) +{ + ANCIL_FD_BUFFER(1) buffer; + + return(ancil_send_fds_with_buffer(sock, &fd, 1, &buffer)); +} +#endif /* SPARE_SEND_FD */ diff --git a/jni/libancillary/test.c b/jni/libancillary/test.c new file mode 100644 index 00000000..d3c1fdac --- /dev/null +++ b/jni/libancillary/test.c @@ -0,0 +1,112 @@ +/*************************************************************************** + * libancillary - black magic on Unix domain sockets + * (C) Nicolas George + * test.c - testing and example program + ***************************************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "ancillary.h" + +void child_process(int sock) +{ + int fd; + int fds[3], nfds; + char b[] = "This is on the received fd!\n"; + + if(ancil_recv_fd(sock, &fd)) { + perror("ancil_recv_fd"); + exit(1); + } else { + printf("Received fd: %d\n", fd); + } + write(fd, b, sizeof(b)); + close(fd); + sleep(2); + + nfds = ancil_recv_fds(sock, fds, 3); + if(nfds < 0) { + perror("ancil_recv_fds"); + exit(1); + } else { + printf("Received %d/3 fds : %d %d %d.\n", nfds, + fds[0], fds[1], fds[2]); + } +} + +void parent_process(int sock) +{ + int fds[2] = { 1, 2 }; + + if(ancil_send_fd(sock, 1)) { + perror("ancil_send_fd"); + exit(1); + } else { + printf("Sent fd.\n"); + } + sleep(1); + + if(ancil_send_fds(sock, fds, 2)) { + perror("ancil_send_fds"); + exit(1); + } else { + printf("Sent two fds.\n"); + } +} + +int main(void) +{ + int sock[2]; + + if(socketpair(PF_UNIX, SOCK_STREAM, 0, sock)) { + perror("socketpair"); + exit(1); + } else { + printf("Established socket pair: (%d, %d)\n", sock[0], sock[1]); + } + + switch(fork()) { + case 0: + close(sock[0]); + child_process(sock[1]); + break; + case -1: + perror("fork"); + exit(1); + default: + close(sock[1]); + parent_process(sock[0]); + wait(NULL); + break; + } + return(0); +}