Annotation of src/usr.bin/aucat/listen.c, Revision 1.12
1.12 ! ratchov 1: /* $OpenBSD: listen.c,v 1.11 2009/09/27 11:51:20 ratchov Exp $ */
1.1 ratchov 2: /*
3: * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17: #include <sys/types.h>
18: #include <sys/socket.h>
1.2 ratchov 19: #include <sys/stat.h>
1.1 ratchov 20: #include <sys/un.h>
21: #include <err.h>
22: #include <errno.h>
23: #include <fcntl.h>
24: #include <poll.h>
25: #include <stdio.h>
26: #include <stdlib.h>
27: #include <string.h>
28: #include <unistd.h>
29:
30: #include "conf.h"
1.10 ratchov 31: #include "listen.h"
1.1 ratchov 32: #include "sock.h"
33:
34: struct fileops listen_ops = {
35: "listen",
36: sizeof(struct listen),
37: listen_close,
38: NULL, /* read */
39: NULL, /* write */
40: NULL, /* start */
41: NULL, /* stop */
42: listen_nfds,
43: listen_pollfd,
44: listen_revents
45: };
46:
1.12 ! ratchov 47: void
! 48: listen_new_un(char *path)
1.1 ratchov 49: {
1.7 ratchov 50: int sock, oldumask;
1.1 ratchov 51: struct sockaddr_un sockname;
52: struct listen *f;
53:
54: sock = socket(AF_UNIX, SOCK_STREAM, 0);
55: if (sock < 0) {
56: perror("socket");
1.12 ! ratchov 57: exit(1);
1.1 ratchov 58: }
59: if (unlink(path) < 0 && errno != ENOENT) {
60: perror("unlink");
1.8 ratchov 61: goto bad_close;
1.1 ratchov 62: }
63: sockname.sun_family = AF_UNIX;
64: strlcpy(sockname.sun_path, path, sizeof(sockname.sun_path));
1.7 ratchov 65: oldumask = umask(0111);
1.6 ratchov 66: if (bind(sock, (struct sockaddr *)&sockname,
67: sizeof(struct sockaddr_un)) < 0) {
1.1 ratchov 68: perror("bind");
1.8 ratchov 69: goto bad_close;
1.2 ratchov 70: }
1.7 ratchov 71: umask(oldumask);
1.1 ratchov 72: if (listen(sock, 1) < 0) {
73: perror("listen");
1.8 ratchov 74: goto bad_close;
1.1 ratchov 75: }
1.12 ! ratchov 76: f = (struct listen *)file_new(&listen_ops, path, 1);
1.8 ratchov 77: if (f == NULL)
78: goto bad_close;
1.1 ratchov 79: f->path = strdup(path);
80: if (f->path == NULL) {
81: perror("strdup");
82: exit(1);
83: }
84: f->fd = sock;
1.12 ! ratchov 85: return;
1.8 ratchov 86: bad_close:
87: close(sock);
1.12 ! ratchov 88: exit(1);
1.1 ratchov 89: }
90:
91: int
92: listen_nfds(struct file *f) {
93: return 1;
94: }
95:
96: int
97: listen_pollfd(struct file *file, struct pollfd *pfd, int events)
98: {
99: struct listen *f = (struct listen *)file;
100:
101: pfd->fd = f->fd;
102: pfd->events = POLLIN;
103: return 1;
104: }
105:
106: int
107: listen_revents(struct file *file, struct pollfd *pfd)
108: {
109: struct listen *f = (struct listen *)file;
110: struct sockaddr caddr;
111: socklen_t caddrlen;
112: int sock;
113:
114: if (pfd->revents & POLLIN) {
115: caddrlen = sizeof(caddrlen);
116: sock = accept(f->fd, &caddr, &caddrlen);
117: if (sock < 0) {
1.12 ! ratchov 118: /* XXX: should we kill the socket here ? */
1.1 ratchov 119: perror("accept");
120: return 0;
121: }
122: if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
123: perror("fcntl(sock, O_NONBLOCK)");
124: close(sock);
125: return 0;
126: }
1.9 ratchov 127: if (sock_new(&sock_ops, sock) == NULL) {
1.8 ratchov 128: close(sock);
129: return 0;
130: }
1.1 ratchov 131: }
132: return 0;
133: }
134:
135: void
136: listen_close(struct file *file)
137: {
138: struct listen *f = (struct listen *)file;
139:
1.12 ! ratchov 140: if (f->path != NULL) {
! 141: unlink(f->path);
! 142: free(f->path);
! 143: }
1.10 ratchov 144: close(f->fd);
1.12 ! ratchov 145: }
! 146:
! 147: void
! 148: listen_closeall(void)
! 149: {
! 150: struct file *f, *fnext;
! 151:
! 152: for (f = LIST_FIRST(&file_list); f != NULL; f = fnext) {
! 153: fnext = LIST_NEXT(f, entry);
! 154: if (f->ops == &listen_ops)
! 155: file_close(f);
! 156: }
1.1 ratchov 157: }