Annotation of src/usr.bin/aucat/listen.c, Revision 1.7
1.7 ! ratchov 1: /* $OpenBSD: listen.c,v 1.6 2009/01/23 17:38:15 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:
22: #include <err.h>
23: #include <errno.h>
24: #include <fcntl.h>
25: #include <poll.h>
26: #include <stdio.h>
27: #include <stdlib.h>
28: #include <string.h>
29: #include <unistd.h>
30:
31: #include "conf.h"
32: #include "sock.h"
33: #include "listen.h"
34:
35: struct fileops listen_ops = {
36: "listen",
37: sizeof(struct listen),
38: listen_close,
39: NULL, /* read */
40: NULL, /* write */
41: NULL, /* start */
42: NULL, /* stop */
43: listen_nfds,
44: listen_pollfd,
45: listen_revents
46: };
47:
48: struct listen *
1.4 ratchov 49: listen_new(struct fileops *ops, char *path,
50: struct aparams *wpar, struct aparams *rpar, int maxweight)
1.1 ratchov 51: {
1.7 ! ratchov 52: int sock, oldumask;
1.1 ratchov 53: struct sockaddr_un sockname;
54: struct listen *f;
55:
56: sock = socket(AF_UNIX, SOCK_STREAM, 0);
57: if (sock < 0) {
58: perror("socket");
59: exit(1);
60: }
61: if (unlink(path) < 0 && errno != ENOENT) {
62: perror("unlink");
63: exit(1);
64: }
65: sockname.sun_family = AF_UNIX;
66: strlcpy(sockname.sun_path, path, sizeof(sockname.sun_path));
1.7 ! ratchov 67: oldumask = umask(0111);
1.6 ratchov 68: if (bind(sock, (struct sockaddr *)&sockname,
69: sizeof(struct sockaddr_un)) < 0) {
1.1 ratchov 70: perror("bind");
71: exit(1);
1.2 ratchov 72: }
1.7 ! ratchov 73: umask(oldumask);
1.1 ratchov 74: if (listen(sock, 1) < 0) {
75: perror("listen");
76: exit(1);
77: }
78: f = (struct listen *)file_new(ops, path, 1);
79: f->path = strdup(path);
80: if (f->path == NULL) {
81: perror("strdup");
82: exit(1);
83: }
84: f->fd = sock;
1.4 ratchov 85: f->wpar = *wpar;
86: f->rpar = *rpar;
1.3 ratchov 87: f->maxweight = maxweight;
1.5 ratchov 88: #ifdef DEBUG
89: if (debug_level > 0) {
90: fprintf(stderr, "listen_new: %s: wpar=", f->path);
91: aparams_print(&f->wpar);
92: fprintf(stderr, ", rpar=");
93: aparams_print(&f->rpar);
94: fprintf(stderr, ", vol=%u\n", f->maxweight);
95: }
96: #endif
1.1 ratchov 97: return f;
98: }
99:
100: int
101: listen_nfds(struct file *f) {
102: return 1;
103: }
104:
105: int
106: listen_pollfd(struct file *file, struct pollfd *pfd, int events)
107: {
108: struct listen *f = (struct listen *)file;
109:
110: pfd->fd = f->fd;
111: pfd->events = POLLIN;
112: return 1;
113: }
114:
115: int
116: listen_revents(struct file *file, struct pollfd *pfd)
117: {
118: struct listen *f = (struct listen *)file;
119: struct sockaddr caddr;
120: socklen_t caddrlen;
121: int sock;
122:
123: if (pfd->revents & POLLIN) {
1.5 ratchov 124: DPRINTF("listen_revents: %s: accepting connection\n", f->path);
1.1 ratchov 125: caddrlen = sizeof(caddrlen);
126: sock = accept(f->fd, &caddr, &caddrlen);
127: if (sock < 0) {
128: perror("accept");
129: return 0;
130: }
131: if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
132: perror("fcntl(sock, O_NONBLOCK)");
133: close(sock);
134: return 0;
135: }
1.4 ratchov 136: (void)sock_new(&sock_ops, sock, "socket",
137: &f->wpar, &f->rpar, f->maxweight);
1.1 ratchov 138: }
139: return 0;
140: }
141:
142: void
143: listen_close(struct file *file)
144: {
145: struct listen *f = (struct listen *)file;
146:
147: (void)unlink(f->path);
148: free(f->path);
149: (void)close(f->fd);
150: }