From f44ba092651aa75055e109e04b4164ea92ae7fdc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 19 Jun 2006 21:53:48 +0000 Subject: big s/polyp/pulse/g git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1033 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/pipe.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 src/pulsecore/pipe.c (limited to 'src/pulsecore/pipe.c') diff --git a/src/pulsecore/pipe.c b/src/pulsecore/pipe.c new file mode 100644 index 00000000..6933e180 --- /dev/null +++ b/src/pulsecore/pipe.c @@ -0,0 +1,160 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with PulseAudio; If not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#include "winsock.h" + +#include "pipe.h" + +#ifndef HAVE_PIPE + +static int set_block(int fd, int blocking) { +#ifdef O_NONBLOCK + + int v; + + assert(fd >= 0); + + if ((v = fcntl(fd, F_GETFL)) < 0) + return -1; + + if (blocking) + v &= ~O_NONBLOCK; + else + v |= O_NONBLOCK; + + if (fcntl(fd, F_SETFL, v) < 0) + return -1; + + return 0; + +#elif defined(OS_IS_WIN32) + + u_long arg; + + arg = !blocking; + + if (ioctlsocket(fd, FIONBIO, &arg) < 0) + return -1; + + return 0; + +#else + + return -1; + +#endif +} + +int pipe(int filedes[2]) { + int listener; + struct sockaddr_in addr, peer; + socklen_t len; + + listener = -1; + filedes[0] = -1; + filedes[1] = -1; + + listener = socket(PF_INET, SOCK_STREAM, 0); + if (listener < 0) + goto error; + + filedes[0] = socket(PF_INET, SOCK_STREAM, 0); + if (filedes[0] < 0) + goto error; + + filedes[1] = socket(PF_INET, SOCK_STREAM, 0); + if (filedes[1] < 0) + goto error; + + /* Make non-blocking so that connect() won't block */ + if (set_block(filedes[0], 0) < 0) + goto error; + + addr.sin_family = AF_INET; + addr.sin_port = 0; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + if (bind(listener, (struct sockaddr*)&addr, sizeof(addr)) < 0) + goto error; + + if (listen(listener, 1) < 0) + goto error; + + len = sizeof(addr); + if (getsockname(listener, (struct sockaddr*)&addr, &len) < 0) + goto error; + + if (connect(filedes[0], (struct sockaddr*)&addr, sizeof(addr)) < 0) { +#ifdef OS_IS_WIN32 + if (WSAGetLastError() != EWOULDBLOCK) +#else + if (errno != EINPROGRESS) +#endif + goto error; + } + + len = sizeof(peer); + filedes[1] = accept(listener, (struct sockaddr*)&peer, &len); + if (filedes[1] < 0) + goto error; + + /* Restore blocking */ + if (set_block(filedes[0], 1) < 0) + goto error; + + len = sizeof(addr); + if (getsockname(filedes[0], (struct sockaddr*)&addr, &len) < 0) + goto error; + + /* Check that someone else didn't steal the connection */ + if ((addr.sin_port != peer.sin_port) || (addr.sin_addr.s_addr != peer.sin_addr.s_addr)) + goto error; + + close(listener); + + return 0; + +error: + if (listener >= 0) + close(listener); + if (filedes[0] >= 0) + close(filedes[0]); + if (filedes[1] >= 0) + close(filedes[0]); + + return -1; +} + +#endif /* HAVE_PIPE */ -- cgit