"Fossies" - the Fresh Open Source Software Archive

Member "pulseaudio-13.0/src/pulsecore/pipe.c" (13 Jul 2018, 3413 Bytes) of package /linux/misc/pulseaudio-13.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pipe.c" see the Fossies "Dox" file reference documentation.

    1 /***
    2   This file is part of PulseAudio.
    3 
    4   Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
    5 
    6   PulseAudio is free software; you can redistribute it and/or modify
    7   it under the terms of the GNU Lesser General Public License as published
    8   by the Free Software Foundation; either version 2.1 of the License,
    9   or (at your option) any later version.
   10 
   11   PulseAudio is distributed in the hope that it will be useful, but
   12   WITHOUT ANY WARRANTY; without even the implied warranty of
   13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   14   General Public License for more details.
   15 
   16   You should have received a copy of the GNU Lesser General Public License
   17   along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
   18 ***/
   19 
   20 #ifdef HAVE_CONFIG_H
   21 #include <config.h>
   22 #endif
   23 
   24 #include <errno.h>
   25 #include <unistd.h>
   26 #include <fcntl.h>
   27 
   28 #include <sys/types.h>
   29 
   30 #include <pulsecore/socket.h>
   31 #include <pulsecore/core-util.h>
   32 
   33 #include "pipe.h"
   34 
   35 #ifndef HAVE_PIPE
   36 
   37 static int set_block(int fd, int blocking) {
   38 #ifdef O_NONBLOCK
   39 
   40     int v;
   41 
   42     pa_assert(fd >= 0);
   43 
   44     if ((v = fcntl(fd, F_GETFL)) < 0)
   45         return -1;
   46 
   47     if (blocking)
   48         v &= ~O_NONBLOCK;
   49     else
   50         v |= O_NONBLOCK;
   51 
   52     if (fcntl(fd, F_SETFL, v) < 0)
   53         return -1;
   54 
   55     return 0;
   56 
   57 #elif defined(OS_IS_WIN32)
   58 
   59     u_long arg;
   60 
   61     arg = !blocking;
   62 
   63     if (ioctlsocket(fd, FIONBIO, &arg) < 0)
   64         return -1;
   65 
   66     return 0;
   67 
   68 #else
   69 
   70     return -1;
   71 
   72 #endif
   73 }
   74 
   75 int pipe(int filedes[2]) {
   76     int listener;
   77     struct sockaddr_in addr, peer;
   78     socklen_t len;
   79 
   80     listener = -1;
   81     filedes[0] = -1;
   82     filedes[1] = -1;
   83 
   84     listener = socket(PF_INET, SOCK_STREAM, 0);
   85     if (listener < 0)
   86         goto error;
   87 
   88     filedes[0] = socket(PF_INET, SOCK_STREAM, 0);
   89     if (filedes[0] < 0)
   90         goto error;
   91 
   92     filedes[1] = socket(PF_INET, SOCK_STREAM, 0);
   93     if (filedes[1] < 0)
   94         goto error;
   95 
   96     /* Make non-blocking so that connect() won't block */
   97     if (set_block(filedes[0], 0) < 0)
   98         goto error;
   99 
  100     addr.sin_family = AF_INET;
  101     addr.sin_port = 0;
  102     addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  103 
  104     if (bind(listener, (struct sockaddr*)&addr, sizeof(addr)) < 0)
  105         goto error;
  106 
  107     if (listen(listener, 1) < 0)
  108         goto error;
  109 
  110     len = sizeof(addr);
  111     if (getsockname(listener, (struct sockaddr*)&addr, &len) < 0)
  112         goto error;
  113 
  114     if (connect(filedes[0], (struct sockaddr*)&addr, sizeof(addr)) < 0) {
  115 #ifdef OS_IS_WIN32
  116         if (WSAGetLastError() != EWOULDBLOCK)
  117 #else
  118         if (errno != EINPROGRESS)
  119 #endif
  120             goto error;
  121     }
  122 
  123     len = sizeof(peer);
  124     filedes[1] = accept(listener, (struct sockaddr*)&peer, &len);
  125     if (filedes[1] < 0)
  126         goto error;
  127 
  128     /* Restore blocking */
  129     if (set_block(filedes[0], 1) < 0)
  130         goto error;
  131 
  132     len = sizeof(addr);
  133     if (getsockname(filedes[0], (struct sockaddr*)&addr, &len) < 0)
  134         goto error;
  135 
  136     /* Check that someone else didn't steal the connection */
  137     if ((addr.sin_port != peer.sin_port) || (addr.sin_addr.s_addr != peer.sin_addr.s_addr))
  138         goto error;
  139 
  140     pa_close(listener);
  141 
  142     return 0;
  143 
  144 error:
  145         if (listener >= 0)
  146                 pa_close(listener);
  147         if (filedes[0] >= 0)
  148                 pa_close(filedes[0]);
  149         if (filedes[1] >= 0)
  150                 pa_close(filedes[1]);
  151 
  152         return -1;
  153 }
  154 
  155 #endif /* HAVE_PIPE */