Home | History | Annotate | Line # | Download | only in util
      1 /*	$NetBSD: unix_listen.c,v 1.2 2017/02/14 01:16:49 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	unix_listen 3
      6 /* SUMMARY
      7 /*	start UNIX-domain listener
      8 /* SYNOPSIS
      9 /*	#include <listen.h>
     10 /*
     11 /*	int	unix_listen(addr, backlog, block_mode)
     12 /*	const char *addr;
     13 /*	int	backlog;
     14 /*	int	block_mode;
     15 /*
     16 /*	int	unix_accept(fd)
     17 /*	int	fd;
     18 /* DESCRIPTION
     19 /*	The \fBunix_listen\fR() routine starts a listener in the UNIX domain
     20 /*	on the specified address, with the specified backlog, and returns
     21 /*	the resulting file descriptor.
     22 /*
     23 /*	unix_accept() accepts a connection and sanitizes error results.
     24 /*
     25 /*	Arguments:
     26 /* .IP addr
     27 /*	Null-terminated string with connection destination.
     28 /* .IP backlog
     29 /*	This argument is passed on to the \fIlisten(2)\fR routine.
     30 /* .IP block_mode
     31 /*	Either NON_BLOCKING for a non-blocking socket, or BLOCKING for
     32 /*	blocking mode.
     33 /* .IP fd
     34 /*	File descriptor returned by unix_listen().
     35 /* DIAGNOSTICS
     36 /*	Fatal errors: unix_listen() aborts upon any system call failure.
     37 /*	unix_accept() leaves all error handling up to the caller.
     38 /* LICENSE
     39 /* .ad
     40 /* .fi
     41 /*	The Secure Mailer license must be distributed with this software.
     42 /* AUTHOR(S)
     43 /*	Wietse Venema
     44 /*	IBM T.J. Watson Research
     45 /*	P.O. Box 704
     46 /*	Yorktown Heights, NY 10598, USA
     47 /*--*/
     48 
     49 /* System interfaces. */
     50 
     51 #include <sys_defs.h>
     52 #include <sys/socket.h>
     53 #include <sys/un.h>
     54 #include <string.h>
     55 #include <unistd.h>
     56 #include <sys/stat.h>
     57 #include <errno.h>
     58 
     59 /* Utility library. */
     60 
     61 #include "msg.h"
     62 #include "iostuff.h"
     63 #include "listen.h"
     64 #include "sane_accept.h"
     65 
     66 /* unix_listen - create UNIX-domain listener */
     67 
     68 int     unix_listen(const char *addr, int backlog, int block_mode)
     69 {
     70 #undef sun
     71     struct sockaddr_un sun;
     72     ssize_t len = strlen(addr);
     73     int     sock;
     74 
     75     /*
     76      * Translate address information to internal form.
     77      */
     78     if (len >= sizeof(sun.sun_path))
     79 	msg_fatal("unix-domain name too long: %s", addr);
     80     memset((void *) &sun, 0, sizeof(sun));
     81     sun.sun_family = AF_UNIX;
     82 #ifdef HAS_SUN_LEN
     83     sun.sun_len = len + 1;
     84 #endif
     85     memcpy(sun.sun_path, addr, len + 1);
     86 
     87     /*
     88      * Create a listener socket. Do whatever we can so we don't run into
     89      * trouble when this process is restarted after crash.
     90      */
     91     if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
     92 	msg_fatal("socket: %m");
     93     if (unlink(addr) < 0 && errno != ENOENT)
     94 	msg_fatal("remove %s: %m", addr);
     95     if (bind(sock, (struct sockaddr *) &sun, sizeof(sun)) < 0)
     96 	msg_fatal("bind: %s: %m", addr);
     97 #ifdef FCHMOD_UNIX_SOCKETS
     98     if (fchmod(sock, 0666) < 0)
     99 	msg_fatal("fchmod socket %s: %m", addr);
    100 #else
    101     if (chmod(addr, 0666) < 0)
    102 	msg_fatal("chmod socket %s: %m", addr);
    103 #endif
    104     non_blocking(sock, block_mode);
    105     if (listen(sock, backlog) < 0)
    106 	msg_fatal("listen: %m");
    107     return (sock);
    108 }
    109 
    110 /* unix_accept - accept connection */
    111 
    112 int     unix_accept(int fd)
    113 {
    114     return (sane_accept(fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0));
    115 }
    116