1/* $NetBSD: unix_connect.c,v 1.2 2017/02/14 01:16:49 christos Exp $ */ 2 3/*++ 4/* NAME 5/* unix_connect 3 6/* SUMMARY 7/* connect to UNIX-domain listener 8/* SYNOPSIS 9/* #include <connect.h> 10/* 11/* int unix_connect(addr, block_mode, timeout) 12/* const char *addr; 13/* int block_mode; 14/* int timeout; 15/* DESCRIPTION 16/* unix_connect() connects to a listener in the UNIX domain at the 17/* specified address, and returns the resulting file descriptor. 18/* 19/* Arguments: 20/* .IP addr 21/* Null-terminated string with connection destination. 22/* .IP block_mode 23/* Either NON_BLOCKING for a non-blocking socket, or BLOCKING for 24/* blocking mode. 25/* .IP timeout 26/* Bounds the number of seconds that the operation may take. Specify 27/* a value <= 0 to disable the time limit. 28/* DIAGNOSTICS 29/* The result is -1 in case the connection could not be made. 30/* Fatal errors: other system call failures. 31/* LICENSE 32/* .ad 33/* .fi 34/* The Secure Mailer license must be distributed with this software. 35/* AUTHOR(S) 36/* Wietse Venema 37/* IBM T.J. Watson Research 38/* P.O. Box 704 39/* Yorktown Heights, NY 10598, USA 40/*--*/ 41 42/* System interfaces. */ 43 44#include <sys_defs.h> 45#include <sys/socket.h> 46#include <sys/un.h> 47#include <string.h> 48#include <unistd.h> 49#include <errno.h> 50 51/* Utility library. */ 52 53#include "msg.h" 54#include "iostuff.h" 55#include "sane_connect.h" 56#include "connect.h" 57#include "timed_connect.h" 58 59/* unix_connect - connect to UNIX-domain listener */ 60 61int unix_connect(const char *addr, int block_mode, int timeout) 62{ 63#undef sun 64 struct sockaddr_un sun; 65 ssize_t len = strlen(addr); 66 int sock; 67 68 /* 69 * Translate address information to internal form. 70 */ 71 if (len >= sizeof(sun.sun_path)) 72 msg_fatal("unix-domain name too long: %s", addr); 73 memset((void *) &sun, 0, sizeof(sun)); 74 sun.sun_family = AF_UNIX; 75#ifdef HAS_SUN_LEN 76 sun.sun_len = len + 1; 77#endif 78 memcpy(sun.sun_path, addr, len + 1); 79 80 /* 81 * Create a client socket. 82 */ 83 if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 84 return (-1); 85 86 /* 87 * Timed connect. 88 */ 89 if (timeout > 0) { 90 non_blocking(sock, NON_BLOCKING); 91 if (timed_connect(sock, (struct sockaddr *) &sun, sizeof(sun), timeout) < 0) { 92 close(sock); 93 return (-1); 94 } 95 if (block_mode != NON_BLOCKING) 96 non_blocking(sock, block_mode); 97 return (sock); 98 } 99 100 /* 101 * Maybe block until connected. 102 */ 103 else { 104 non_blocking(sock, block_mode); 105 if (sane_connect(sock, (struct sockaddr *) &sun, sizeof(sun)) < 0 106 && errno != EINPROGRESS) { 107 close(sock); 108 return (-1); 109 } 110 return (sock); 111 } 112} 113