aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-14 15:20:06 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-14 15:20:06 +0000
commitea03f11cfac38afdad7ea45b3a7787bd9b4f4711 (patch)
treef167b9eb1fe57eab105475cfc78555fde74a9fc8 /src/util
parentdbc46fb04fb3e1257b2473aee609c06c5b56f3c9 (diff)
downloadgnunet-ea03f11cfac38afdad7ea45b3a7787bd9b4f4711.tar.gz
gnunet-ea03f11cfac38afdad7ea45b3a7787bd9b4f4711.zip
LRN: new pipe creation function GNUNET_DISK_pipe_from_fd to wrap existing file descriptor pair
Diffstat (limited to 'src/util')
-rw-r--r--src/util/disk.c158
1 files changed, 144 insertions, 14 deletions
diff --git a/src/util/disk.c b/src/util/disk.c
index 430d9cc46..8d1fe3c12 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -2037,6 +2037,116 @@ GNUNET_DISK_pipe (int blocking, int inherit_read, int inherit_write)
2037 return p; 2037 return p;
2038} 2038}
2039 2039
2040/**
2041 * Creates a pipe object from a couple of file descriptors.
2042 * Useful for wrapping existing pipe FDs.
2043 *
2044 * @param blocking creates an asynchronous pipe if set to GNUNET_NO
2045 * @param fd an array of two fd values. One of them may be -1 for read-only or write-only pipes
2046 *
2047 * @return handle to the new pipe, NULL on error
2048 */
2049struct GNUNET_DISK_PipeHandle *
2050GNUNET_DISK_pipe_from_fd (int blocking, int fd[2])
2051{
2052 struct GNUNET_DISK_PipeHandle *p;
2053 struct GNUNET_DISK_FileHandle *fds;
2054
2055 p = GNUNET_malloc (sizeof (struct GNUNET_DISK_PipeHandle) +
2056 2 * sizeof (struct GNUNET_DISK_FileHandle));
2057 fds = (struct GNUNET_DISK_FileHandle *) &p[1];
2058 p->fd[0] = &fds[0];
2059 p->fd[1] = &fds[1];
2060#ifndef MINGW
2061 int ret;
2062 int flags;
2063 int eno;
2064
2065 p->fd[0]->fd = fd[0];
2066 p->fd[1]->fd = fd[1];
2067 ret = 0;
2068 if (fd[0] >= 0)
2069 {
2070 flags = fcntl (fd[0], F_GETFL);
2071 if (!blocking)
2072 flags |= O_NONBLOCK;
2073 if (0 > fcntl (fd[0], F_SETFL, flags))
2074 ret = -1;
2075 flags = fcntl (fd[0], F_GETFD);
2076 flags |= FD_CLOEXEC;
2077 if (0 > fcntl (fd[0], F_SETFD, flags))
2078 ret = -1;
2079 }
2080
2081 if (fd[1] >= 0)
2082 {
2083 flags = fcntl (fd[1], F_GETFL);
2084 if (!blocking)
2085 flags |= O_NONBLOCK;
2086 if (0 > fcntl (fd[1], F_SETFL, flags))
2087 ret = -1;
2088 flags = fcntl (fd[1], F_GETFD);
2089 flags |= FD_CLOEXEC;
2090 if (0 > fcntl (fd[1], F_SETFD, flags))
2091 ret = -1;
2092 }
2093 if (ret == -1)
2094 {
2095 eno = errno;
2096 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fcntl");
2097 if (p->fd[0]->fd >= 0)
2098 GNUNET_break (0 == close (p->fd[0]->fd));
2099 if (p->fd[1]->fd >= 0)
2100 GNUNET_break (0 == close (p->fd[1]->fd));
2101 GNUNET_free (p);
2102 errno = eno;
2103 return NULL;
2104 }
2105#else
2106 BOOL ret;
2107
2108 if (fd[0] >= 0)
2109 p->fd[0]->h = _get_osfhandle (fd[0]);
2110 else
2111 p->fd[0]->h = INVALID_HANDLE_VALUE;
2112 if (fd[1] >= 0)
2113 p->fd[1]->h = _get_osfhandle (fd[1]);
2114 else
2115 p->fd[1]->h = INVALID_HANDLE_VALUE;
2116
2117 if (!blocking)
2118 {
2119 DWORD mode;
2120
2121 mode = PIPE_NOWAIT;
2122 if (p->fd[0]->h != INVALID_HANDLE_VALUE)
2123 SetNamedPipeHandleState (p->fd[0]->h, &mode, NULL, NULL);
2124 if (p->fd[1]->h != INVALID_HANDLE_VALUE)
2125 SetNamedPipeHandleState (p->fd[1]->h, &mode, NULL, NULL);
2126 /* this always fails on Windows 95, so we don't care about error handling */
2127 }
2128
2129 if (p->fd[0]->h != INVALID_HANDLE_VALUE)
2130 {
2131 p->fd[0]->type = GNUNET_PIPE;
2132 p->fd[0]->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED));
2133 p->fd[0]->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED));
2134 p->fd[0]->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
2135 p->fd[0]->oOverlapWrite->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
2136 }
2137
2138 if (p->fd[1]->h != INVALID_HANDLE_VALUE)
2139 {
2140 p->fd[1]->type = GNUNET_PIPE;
2141 p->fd[1]->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED));
2142 p->fd[1]->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED));
2143 p->fd[1]->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
2144 p->fd[1]->oOverlapWrite->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
2145 }
2146#endif
2147 return p;
2148}
2149
2040 2150
2041/** 2151/**
2042 * Closes an interprocess channel 2152 * Closes an interprocess channel
@@ -2055,21 +2165,31 @@ GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p,
2055#ifdef MINGW 2165#ifdef MINGW
2056 if (end == GNUNET_DISK_PIPE_END_READ) 2166 if (end == GNUNET_DISK_PIPE_END_READ)
2057 { 2167 {
2058 if (!CloseHandle (p->fd[0]->h)) 2168 if (p->fd[0]->h != INVALID_HANDLE_VALUE)
2059 { 2169 {
2060 SetErrnoFromWinError (GetLastError ()); 2170 if (!CloseHandle (p->fd[0]->h))
2061 ret = GNUNET_SYSERR; 2171 {
2172 SetErrnoFromWinError (GetLastError ());
2173 ret = GNUNET_SYSERR;
2174 }
2175 GNUNET_free (p->fd[0]->oOverlapRead);
2176 GNUNET_free (p->fd[0]->oOverlapWrite);
2177 p->fd[0]->h = INVALID_HANDLE_VALUE;
2062 } 2178 }
2063 p->fd[0]->h = INVALID_HANDLE_VALUE;
2064 } 2179 }
2065 else if (end == GNUNET_DISK_PIPE_END_WRITE) 2180 else if (end == GNUNET_DISK_PIPE_END_WRITE)
2066 { 2181 {
2067 if (!CloseHandle (p->fd[1]->h)) 2182 if (p->fd[0]->h != INVALID_HANDLE_VALUE)
2068 { 2183 {
2069 SetErrnoFromWinError (GetLastError ()); 2184 if (!CloseHandle (p->fd[1]->h))
2070 ret = GNUNET_SYSERR; 2185 {
2186 SetErrnoFromWinError (GetLastError ());
2187 ret = GNUNET_SYSERR;
2188 }
2189 GNUNET_free (p->fd[1]->oOverlapRead);
2190 GNUNET_free (p->fd[1]->oOverlapWrite);
2191 p->fd[1]->h = INVALID_HANDLE_VALUE;
2071 } 2192 }
2072 p->fd[1]->h = INVALID_HANDLE_VALUE;
2073 } 2193 }
2074 save = errno; 2194 save = errno;
2075#else 2195#else
@@ -2110,15 +2230,25 @@ GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p)
2110 int save; 2230 int save;
2111 2231
2112#ifdef MINGW 2232#ifdef MINGW
2113 if (!CloseHandle (p->fd[0]->h)) 2233 if (p->fd[0]->h != INVALID_HANDLE_VALUE)
2114 { 2234 {
2115 SetErrnoFromWinError (GetLastError ()); 2235 if (!CloseHandle (p->fd[0]->h))
2116 ret = GNUNET_SYSERR; 2236 {
2237 SetErrnoFromWinError (GetLastError ());
2238 ret = GNUNET_SYSERR;
2239 }
2240 GNUNET_free (p->fd[0]->oOverlapRead);
2241 GNUNET_free (p->fd[0]->oOverlapWrite);
2117 } 2242 }
2118 if (!CloseHandle (p->fd[1]->h)) 2243 if (p->fd[1]->h != INVALID_HANDLE_VALUE)
2119 { 2244 {
2120 SetErrnoFromWinError (GetLastError ()); 2245 if (!CloseHandle (p->fd[1]->h))
2121 ret = GNUNET_SYSERR; 2246 {
2247 SetErrnoFromWinError (GetLastError ());
2248 ret = GNUNET_SYSERR;
2249 }
2250 GNUNET_free (p->fd[1]->oOverlapRead);
2251 GNUNET_free (p->fd[1]->oOverlapWrite);
2122 } 2252 }
2123 save = errno; 2253 save = errno;
2124#else 2254#else