1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h>
|
32 33/* UDS - UNIX Domain Socket */ 34 35#include <sys/types.h> 36#include <sys/un.h> 37 38#include <errno.h> 39#include <stdbool.h> 40#include <stdint.h> 41#include <stdio.h> 42#include <string.h> 43#include <unistd.h> 44 45#include "hast.h" 46#include "pjdlog.h" 47#include "proto_impl.h" 48 49#define UDS_CTX_MAGIC 0xd541c 50struct uds_ctx { 51 int uc_magic; 52 struct sockaddr_un uc_sun; 53 int uc_fd; 54 int uc_side; 55#define UDS_SIDE_CLIENT 0 56#define UDS_SIDE_SERVER_LISTEN 1 57#define UDS_SIDE_SERVER_WORK 2 58 pid_t uc_owner; 59}; 60 61static void uds_close(void *ctx); 62 63static int 64uds_addr(const char *addr, struct sockaddr_un *sunp) 65{ 66 67 if (addr == NULL) 68 return (-1); 69 70 if (strncasecmp(addr, "uds://", 6) == 0) 71 addr += 6; 72 else if (strncasecmp(addr, "unix://", 7) == 0) 73 addr += 7; 74 else if (addr[0] == '/' && /* If it starts from /... */ 75 strstr(addr, "://") == NULL)/* ...and there is no prefix... */ 76 ; /* ...we assume its us. */ 77 else 78 return (-1); 79 80 sunp->sun_family = AF_UNIX; 81 if (strlcpy(sunp->sun_path, addr, sizeof(sunp->sun_path)) >= 82 sizeof(sunp->sun_path)) { 83 return (ENAMETOOLONG); 84 } 85 sunp->sun_len = SUN_LEN(sunp); 86 87 return (0); 88} 89 90static int 91uds_common_setup(const char *addr, void **ctxp, int side) 92{ 93 struct uds_ctx *uctx; 94 int ret; 95 96 uctx = malloc(sizeof(*uctx)); 97 if (uctx == NULL) 98 return (errno); 99 100 /* Parse given address. */ 101 if ((ret = uds_addr(addr, &uctx->uc_sun)) != 0) { 102 free(uctx); 103 return (ret); 104 } 105 106 uctx->uc_fd = socket(AF_UNIX, SOCK_STREAM, 0); 107 if (uctx->uc_fd == -1) { 108 ret = errno; 109 free(uctx); 110 return (ret); 111 } 112 113 uctx->uc_side = side; 114 uctx->uc_owner = 0; 115 uctx->uc_magic = UDS_CTX_MAGIC; 116 *ctxp = uctx; 117 118 return (0); 119} 120 121static int
| 32 33/* UDS - UNIX Domain Socket */ 34 35#include <sys/types.h> 36#include <sys/un.h> 37 38#include <errno.h> 39#include <stdbool.h> 40#include <stdint.h> 41#include <stdio.h> 42#include <string.h> 43#include <unistd.h> 44 45#include "hast.h" 46#include "pjdlog.h" 47#include "proto_impl.h" 48 49#define UDS_CTX_MAGIC 0xd541c 50struct uds_ctx { 51 int uc_magic; 52 struct sockaddr_un uc_sun; 53 int uc_fd; 54 int uc_side; 55#define UDS_SIDE_CLIENT 0 56#define UDS_SIDE_SERVER_LISTEN 1 57#define UDS_SIDE_SERVER_WORK 2 58 pid_t uc_owner; 59}; 60 61static void uds_close(void *ctx); 62 63static int 64uds_addr(const char *addr, struct sockaddr_un *sunp) 65{ 66 67 if (addr == NULL) 68 return (-1); 69 70 if (strncasecmp(addr, "uds://", 6) == 0) 71 addr += 6; 72 else if (strncasecmp(addr, "unix://", 7) == 0) 73 addr += 7; 74 else if (addr[0] == '/' && /* If it starts from /... */ 75 strstr(addr, "://") == NULL)/* ...and there is no prefix... */ 76 ; /* ...we assume its us. */ 77 else 78 return (-1); 79 80 sunp->sun_family = AF_UNIX; 81 if (strlcpy(sunp->sun_path, addr, sizeof(sunp->sun_path)) >= 82 sizeof(sunp->sun_path)) { 83 return (ENAMETOOLONG); 84 } 85 sunp->sun_len = SUN_LEN(sunp); 86 87 return (0); 88} 89 90static int 91uds_common_setup(const char *addr, void **ctxp, int side) 92{ 93 struct uds_ctx *uctx; 94 int ret; 95 96 uctx = malloc(sizeof(*uctx)); 97 if (uctx == NULL) 98 return (errno); 99 100 /* Parse given address. */ 101 if ((ret = uds_addr(addr, &uctx->uc_sun)) != 0) { 102 free(uctx); 103 return (ret); 104 } 105 106 uctx->uc_fd = socket(AF_UNIX, SOCK_STREAM, 0); 107 if (uctx->uc_fd == -1) { 108 ret = errno; 109 free(uctx); 110 return (ret); 111 } 112 113 uctx->uc_side = side; 114 uctx->uc_owner = 0; 115 uctx->uc_magic = UDS_CTX_MAGIC; 116 *ctxp = uctx; 117 118 return (0); 119} 120 121static int
|
126} 127 128static int 129uds_connect(void *ctx, int timeout) 130{ 131 struct uds_ctx *uctx = ctx; 132 133 PJDLOG_ASSERT(uctx != NULL); 134 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 135 PJDLOG_ASSERT(uctx->uc_side == UDS_SIDE_CLIENT); 136 PJDLOG_ASSERT(uctx->uc_fd >= 0); 137 PJDLOG_ASSERT(timeout >= -1); 138 139 if (connect(uctx->uc_fd, (struct sockaddr *)&uctx->uc_sun, 140 sizeof(uctx->uc_sun)) < 0) { 141 return (errno); 142 } 143 144 return (0); 145} 146 147static int 148uds_connect_wait(void *ctx, int timeout) 149{ 150 struct uds_ctx *uctx = ctx; 151 152 PJDLOG_ASSERT(uctx != NULL); 153 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 154 PJDLOG_ASSERT(uctx->uc_side == UDS_SIDE_CLIENT); 155 PJDLOG_ASSERT(uctx->uc_fd >= 0); 156 PJDLOG_ASSERT(timeout >= 0); 157 158 return (0); 159} 160 161static int 162uds_server(const char *addr, void **ctxp) 163{ 164 struct uds_ctx *uctx; 165 int ret; 166 167 ret = uds_common_setup(addr, ctxp, UDS_SIDE_SERVER_LISTEN); 168 if (ret != 0) 169 return (ret); 170 171 uctx = *ctxp; 172 173 (void)unlink(uctx->uc_sun.sun_path); 174 if (bind(uctx->uc_fd, (struct sockaddr *)&uctx->uc_sun, 175 sizeof(uctx->uc_sun)) < 0) { 176 ret = errno; 177 uds_close(uctx); 178 return (ret); 179 } 180 uctx->uc_owner = getpid(); 181 if (listen(uctx->uc_fd, 8) < 0) { 182 ret = errno; 183 uds_close(uctx); 184 return (ret); 185 } 186 187 return (0); 188} 189 190static int 191uds_accept(void *ctx, void **newctxp) 192{ 193 struct uds_ctx *uctx = ctx; 194 struct uds_ctx *newuctx; 195 socklen_t fromlen; 196 int ret; 197 198 PJDLOG_ASSERT(uctx != NULL); 199 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 200 PJDLOG_ASSERT(uctx->uc_side == UDS_SIDE_SERVER_LISTEN); 201 PJDLOG_ASSERT(uctx->uc_fd >= 0); 202 203 newuctx = malloc(sizeof(*newuctx)); 204 if (newuctx == NULL) 205 return (errno); 206 207 fromlen = sizeof(newuctx->uc_sun); 208 newuctx->uc_fd = accept(uctx->uc_fd, 209 (struct sockaddr *)&newuctx->uc_sun, &fromlen); 210 if (newuctx->uc_fd < 0) { 211 ret = errno; 212 free(newuctx); 213 return (ret); 214 } 215 216 newuctx->uc_side = UDS_SIDE_SERVER_WORK; 217 newuctx->uc_magic = UDS_CTX_MAGIC; 218 *newctxp = newuctx; 219 220 return (0); 221} 222 223static int 224uds_send(void *ctx, const unsigned char *data, size_t size, int fd) 225{ 226 struct uds_ctx *uctx = ctx; 227 228 PJDLOG_ASSERT(uctx != NULL); 229 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 230 PJDLOG_ASSERT(uctx->uc_fd >= 0); 231 232 return (proto_common_send(uctx->uc_fd, data, size, fd)); 233} 234 235static int 236uds_recv(void *ctx, unsigned char *data, size_t size, int *fdp) 237{ 238 struct uds_ctx *uctx = ctx; 239 240 PJDLOG_ASSERT(uctx != NULL); 241 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 242 PJDLOG_ASSERT(uctx->uc_fd >= 0); 243 244 return (proto_common_recv(uctx->uc_fd, data, size, fdp)); 245} 246 247static int 248uds_descriptor(const void *ctx) 249{ 250 const struct uds_ctx *uctx = ctx; 251 252 PJDLOG_ASSERT(uctx != NULL); 253 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 254 255 return (uctx->uc_fd); 256} 257 258static void 259uds_local_address(const void *ctx, char *addr, size_t size) 260{ 261 const struct uds_ctx *uctx = ctx; 262 struct sockaddr_un sun; 263 socklen_t sunlen; 264 265 PJDLOG_ASSERT(uctx != NULL); 266 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 267 PJDLOG_ASSERT(addr != NULL); 268 269 sunlen = sizeof(sun); 270 if (getsockname(uctx->uc_fd, (struct sockaddr *)&sun, &sunlen) < 0) { 271 PJDLOG_VERIFY(strlcpy(addr, "N/A", size) < size); 272 return; 273 } 274 PJDLOG_ASSERT(sun.sun_family == AF_UNIX); 275 if (sun.sun_path[0] == '\0') { 276 PJDLOG_VERIFY(strlcpy(addr, "N/A", size) < size); 277 return; 278 } 279 PJDLOG_VERIFY(snprintf(addr, size, "uds://%s", sun.sun_path) < (ssize_t)size); 280} 281 282static void 283uds_remote_address(const void *ctx, char *addr, size_t size) 284{ 285 const struct uds_ctx *uctx = ctx; 286 struct sockaddr_un sun; 287 socklen_t sunlen; 288 289 PJDLOG_ASSERT(uctx != NULL); 290 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 291 PJDLOG_ASSERT(addr != NULL); 292 293 sunlen = sizeof(sun); 294 if (getpeername(uctx->uc_fd, (struct sockaddr *)&sun, &sunlen) < 0) { 295 PJDLOG_VERIFY(strlcpy(addr, "N/A", size) < size); 296 return; 297 } 298 PJDLOG_ASSERT(sun.sun_family == AF_UNIX); 299 if (sun.sun_path[0] == '\0') { 300 PJDLOG_VERIFY(strlcpy(addr, "N/A", size) < size); 301 return; 302 } 303 snprintf(addr, size, "uds://%s", sun.sun_path); 304} 305 306static void 307uds_close(void *ctx) 308{ 309 struct uds_ctx *uctx = ctx; 310 311 PJDLOG_ASSERT(uctx != NULL); 312 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 313 314 if (uctx->uc_fd >= 0) 315 close(uctx->uc_fd); 316 /* 317 * Unlink the socket only if we are the owner and this is descriptor 318 * we listen on. 319 */ 320 if (uctx->uc_side == UDS_SIDE_SERVER_LISTEN && 321 uctx->uc_owner == getpid()) { 322 PJDLOG_ASSERT(uctx->uc_sun.sun_path[0] != '\0'); 323 if (unlink(uctx->uc_sun.sun_path) == -1) { 324 pjdlog_errno(LOG_WARNING, 325 "Unable to unlink socket file %s", 326 uctx->uc_sun.sun_path); 327 } 328 } 329 uctx->uc_owner = 0; 330 uctx->uc_magic = 0; 331 free(uctx); 332} 333 334static struct hast_proto uds_proto = { 335 .hp_name = "uds", 336 .hp_client = uds_client, 337 .hp_connect = uds_connect, 338 .hp_connect_wait = uds_connect_wait, 339 .hp_server = uds_server, 340 .hp_accept = uds_accept, 341 .hp_send = uds_send, 342 .hp_recv = uds_recv, 343 .hp_descriptor = uds_descriptor, 344 .hp_local_address = uds_local_address, 345 .hp_remote_address = uds_remote_address, 346 .hp_close = uds_close 347}; 348 349static __constructor void 350uds_ctor(void) 351{ 352 353 proto_register(&uds_proto, false); 354}
| 133} 134 135static int 136uds_connect(void *ctx, int timeout) 137{ 138 struct uds_ctx *uctx = ctx; 139 140 PJDLOG_ASSERT(uctx != NULL); 141 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 142 PJDLOG_ASSERT(uctx->uc_side == UDS_SIDE_CLIENT); 143 PJDLOG_ASSERT(uctx->uc_fd >= 0); 144 PJDLOG_ASSERT(timeout >= -1); 145 146 if (connect(uctx->uc_fd, (struct sockaddr *)&uctx->uc_sun, 147 sizeof(uctx->uc_sun)) < 0) { 148 return (errno); 149 } 150 151 return (0); 152} 153 154static int 155uds_connect_wait(void *ctx, int timeout) 156{ 157 struct uds_ctx *uctx = ctx; 158 159 PJDLOG_ASSERT(uctx != NULL); 160 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 161 PJDLOG_ASSERT(uctx->uc_side == UDS_SIDE_CLIENT); 162 PJDLOG_ASSERT(uctx->uc_fd >= 0); 163 PJDLOG_ASSERT(timeout >= 0); 164 165 return (0); 166} 167 168static int 169uds_server(const char *addr, void **ctxp) 170{ 171 struct uds_ctx *uctx; 172 int ret; 173 174 ret = uds_common_setup(addr, ctxp, UDS_SIDE_SERVER_LISTEN); 175 if (ret != 0) 176 return (ret); 177 178 uctx = *ctxp; 179 180 (void)unlink(uctx->uc_sun.sun_path); 181 if (bind(uctx->uc_fd, (struct sockaddr *)&uctx->uc_sun, 182 sizeof(uctx->uc_sun)) < 0) { 183 ret = errno; 184 uds_close(uctx); 185 return (ret); 186 } 187 uctx->uc_owner = getpid(); 188 if (listen(uctx->uc_fd, 8) < 0) { 189 ret = errno; 190 uds_close(uctx); 191 return (ret); 192 } 193 194 return (0); 195} 196 197static int 198uds_accept(void *ctx, void **newctxp) 199{ 200 struct uds_ctx *uctx = ctx; 201 struct uds_ctx *newuctx; 202 socklen_t fromlen; 203 int ret; 204 205 PJDLOG_ASSERT(uctx != NULL); 206 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 207 PJDLOG_ASSERT(uctx->uc_side == UDS_SIDE_SERVER_LISTEN); 208 PJDLOG_ASSERT(uctx->uc_fd >= 0); 209 210 newuctx = malloc(sizeof(*newuctx)); 211 if (newuctx == NULL) 212 return (errno); 213 214 fromlen = sizeof(newuctx->uc_sun); 215 newuctx->uc_fd = accept(uctx->uc_fd, 216 (struct sockaddr *)&newuctx->uc_sun, &fromlen); 217 if (newuctx->uc_fd < 0) { 218 ret = errno; 219 free(newuctx); 220 return (ret); 221 } 222 223 newuctx->uc_side = UDS_SIDE_SERVER_WORK; 224 newuctx->uc_magic = UDS_CTX_MAGIC; 225 *newctxp = newuctx; 226 227 return (0); 228} 229 230static int 231uds_send(void *ctx, const unsigned char *data, size_t size, int fd) 232{ 233 struct uds_ctx *uctx = ctx; 234 235 PJDLOG_ASSERT(uctx != NULL); 236 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 237 PJDLOG_ASSERT(uctx->uc_fd >= 0); 238 239 return (proto_common_send(uctx->uc_fd, data, size, fd)); 240} 241 242static int 243uds_recv(void *ctx, unsigned char *data, size_t size, int *fdp) 244{ 245 struct uds_ctx *uctx = ctx; 246 247 PJDLOG_ASSERT(uctx != NULL); 248 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 249 PJDLOG_ASSERT(uctx->uc_fd >= 0); 250 251 return (proto_common_recv(uctx->uc_fd, data, size, fdp)); 252} 253 254static int 255uds_descriptor(const void *ctx) 256{ 257 const struct uds_ctx *uctx = ctx; 258 259 PJDLOG_ASSERT(uctx != NULL); 260 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 261 262 return (uctx->uc_fd); 263} 264 265static void 266uds_local_address(const void *ctx, char *addr, size_t size) 267{ 268 const struct uds_ctx *uctx = ctx; 269 struct sockaddr_un sun; 270 socklen_t sunlen; 271 272 PJDLOG_ASSERT(uctx != NULL); 273 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 274 PJDLOG_ASSERT(addr != NULL); 275 276 sunlen = sizeof(sun); 277 if (getsockname(uctx->uc_fd, (struct sockaddr *)&sun, &sunlen) < 0) { 278 PJDLOG_VERIFY(strlcpy(addr, "N/A", size) < size); 279 return; 280 } 281 PJDLOG_ASSERT(sun.sun_family == AF_UNIX); 282 if (sun.sun_path[0] == '\0') { 283 PJDLOG_VERIFY(strlcpy(addr, "N/A", size) < size); 284 return; 285 } 286 PJDLOG_VERIFY(snprintf(addr, size, "uds://%s", sun.sun_path) < (ssize_t)size); 287} 288 289static void 290uds_remote_address(const void *ctx, char *addr, size_t size) 291{ 292 const struct uds_ctx *uctx = ctx; 293 struct sockaddr_un sun; 294 socklen_t sunlen; 295 296 PJDLOG_ASSERT(uctx != NULL); 297 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 298 PJDLOG_ASSERT(addr != NULL); 299 300 sunlen = sizeof(sun); 301 if (getpeername(uctx->uc_fd, (struct sockaddr *)&sun, &sunlen) < 0) { 302 PJDLOG_VERIFY(strlcpy(addr, "N/A", size) < size); 303 return; 304 } 305 PJDLOG_ASSERT(sun.sun_family == AF_UNIX); 306 if (sun.sun_path[0] == '\0') { 307 PJDLOG_VERIFY(strlcpy(addr, "N/A", size) < size); 308 return; 309 } 310 snprintf(addr, size, "uds://%s", sun.sun_path); 311} 312 313static void 314uds_close(void *ctx) 315{ 316 struct uds_ctx *uctx = ctx; 317 318 PJDLOG_ASSERT(uctx != NULL); 319 PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC); 320 321 if (uctx->uc_fd >= 0) 322 close(uctx->uc_fd); 323 /* 324 * Unlink the socket only if we are the owner and this is descriptor 325 * we listen on. 326 */ 327 if (uctx->uc_side == UDS_SIDE_SERVER_LISTEN && 328 uctx->uc_owner == getpid()) { 329 PJDLOG_ASSERT(uctx->uc_sun.sun_path[0] != '\0'); 330 if (unlink(uctx->uc_sun.sun_path) == -1) { 331 pjdlog_errno(LOG_WARNING, 332 "Unable to unlink socket file %s", 333 uctx->uc_sun.sun_path); 334 } 335 } 336 uctx->uc_owner = 0; 337 uctx->uc_magic = 0; 338 free(uctx); 339} 340 341static struct hast_proto uds_proto = { 342 .hp_name = "uds", 343 .hp_client = uds_client, 344 .hp_connect = uds_connect, 345 .hp_connect_wait = uds_connect_wait, 346 .hp_server = uds_server, 347 .hp_accept = uds_accept, 348 .hp_send = uds_send, 349 .hp_recv = uds_recv, 350 .hp_descriptor = uds_descriptor, 351 .hp_local_address = uds_local_address, 352 .hp_remote_address = uds_remote_address, 353 .hp_close = uds_close 354}; 355 356static __constructor void 357uds_ctor(void) 358{ 359 360 proto_register(&uds_proto, false); 361}
|