xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/unix_dgram_listen.c (revision 67b9b338a7386232ac596b5fd0cd5a9cc8a03c71)
1 /*	$NetBSD: unix_dgram_listen.c,v 1.3 2022/10/08 16:12:50 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	unix_dgram_listen 3
6 /* SUMMARY
7 /*	listen to UNIX-domain datagram server
8 /* SYNOPSIS
9 /*	#include <listen.h>
10 /*
11 /*	int	unix_dgram_listen(
12 /*	const char *path,
13 /*	int	block_mode)
14 /* DESCRIPTION
15 /*	unix_dgram_listen() binds to the specified UNIX-domain
16 /*	datagram endpoint, and returns the resulting file descriptor.
17 /*
18 /*	Arguments:
19 /* .IP path
20 /*	Null-terminated string with connection destination.
21 /* .IP backlog
22 /*	Either NON_BLOCKING for a non-blocking socket, or BLOCKING for
23 /*	blocking mode.
24 /* DIAGNOSTICS
25 /*	Fatal errors: path too large, can't create socket.
26 /* LICENSE
27 /* .ad
28 /* .fi
29 /*	The Secure Mailer license must be distributed with this software.
30 /* AUTHOR(S)
31 /*	Wietse Venema
32 /*	Google, Inc.
33 /*	111 8th Avenue
34 /*	New York, NY 10011, USA
35 /*--*/
36 
37  /*
38   * System library.
39   */
40 #include <sys_defs.h>
41 #include <sys/socket.h>
42 #include <sys/un.h>
43 #include <sys/stat.h>
44 #include <unistd.h>
45 #include <string.h>
46 #include <errno.h>
47 
48  /*
49   * Utility library.
50   */
51 #include <iostuff.h>
52 #include <listen.h>
53 #include <msg.h>
54 
55 /* unix_dgram_listen - bind to UNIX-domain datagram endpoint */
56 
unix_dgram_listen(const char * path,int block_mode)57 int     unix_dgram_listen(const char *path, int block_mode)
58 {
59     const char myname[] = "unix_dgram_listen";
60 #undef sun
61     struct sockaddr_un sun;
62     ssize_t path_len;
63     int     sock;
64 
65     /*
66      * Translate address information to internal form.
67      */
68     if ((path_len = strlen(path)) >= sizeof(sun.sun_path))
69 	msg_fatal("%s: unix-domain name too long: %s", myname, path);
70     memset((void *) &sun, 0, sizeof(sun));
71     sun.sun_family = AF_UNIX;
72 #ifdef HAS_SUN_LEN
73     sun.sun_len = path_len + 1;
74 #endif
75     memcpy(sun.sun_path, path, path_len + 1);
76 
77     /*
78      * Create a 'server' socket.
79      */
80     if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
81 	msg_fatal("%s: socket: %m", myname);
82     if (unlink(path) < 0 && errno != ENOENT)
83         msg_fatal( "remove %s: %m", path);
84     if (bind(sock, (struct sockaddr *) & sun, sizeof(sun)) < 0)
85         msg_fatal( "bind: %s: %m", path);
86 #ifdef FCHMOD_UNIX_SOCKETS
87     if (fchmod(sock, 0666) < 0)
88         msg_fatal("fchmod socket %s: %m", path);
89 #else
90     if (chmod(path, 0666) < 0)
91         msg_fatal("chmod socket %s: %m", path);
92 #endif
93     non_blocking(sock, block_mode);
94     return (sock);
95 }
96