1 /* $NetBSD: unix_connect.c,v 1.1.1.1 2009/06/23 10:09:01 tron 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 61 int unix_connect(const char *addr, int block_mode, int timeout) 62 { 63 #undef sun 64 struct sockaddr_un sun; 65 int len = strlen(addr); 66 int sock; 67 68 /* 69 * Translate address information to internal form. 70 */ 71 if (len >= (int) sizeof(sun.sun_path)) 72 msg_fatal("unix-domain name too long: %s", addr); 73 memset((char *) &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