[BACK]Return to listen.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / aucat

Annotation of src/usr.bin/aucat/listen.c, Revision 1.1

1.1     ! ratchov     1: /*     $OpenBSD$       */
        !             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>
        !            19: #include <sys/un.h>
        !            20:
        !            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"
        !            31: #include "sock.h"
        !            32: #include "listen.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:
        !            47: struct listen *
        !            48: listen_new(struct fileops *ops, char *path)
        !            49: {
        !            50:        int sock;
        !            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");
        !            57:                exit(1);
        !            58:        }
        !            59:        if (unlink(path) < 0 && errno != ENOENT) {
        !            60:                perror("unlink");
        !            61:                exit(1);
        !            62:        }
        !            63:        sockname.sun_family = AF_UNIX;
        !            64:        strlcpy(sockname.sun_path, path, sizeof(sockname.sun_path));
        !            65:        if (bind(sock, (struct sockaddr *)&sockname,
        !            66:                sizeof(struct sockaddr_un)) < 0) {
        !            67:                perror("bind");
        !            68:                exit(1);
        !            69:        }
        !            70:        if (listen(sock, 1) < 0) {
        !            71:                perror("listen");
        !            72:                exit(1);
        !            73:        }
        !            74:        f = (struct listen *)file_new(ops, path, 1);
        !            75:        f->path = strdup(path);
        !            76:        if (f->path == NULL) {
        !            77:                perror("strdup");
        !            78:                exit(1);
        !            79:        }
        !            80:        f->fd = sock;
        !            81:        return f;
        !            82: }
        !            83:
        !            84: int
        !            85: listen_nfds(struct file *f) {
        !            86:        return 1;
        !            87: }
        !            88:
        !            89: int
        !            90: listen_pollfd(struct file *file, struct pollfd *pfd, int events)
        !            91: {
        !            92:        struct listen *f = (struct listen *)file;
        !            93:
        !            94:        pfd->fd = f->fd;
        !            95:        pfd->events = POLLIN;
        !            96:        return 1;
        !            97: }
        !            98:
        !            99: int
        !           100: listen_revents(struct file *file, struct pollfd *pfd)
        !           101: {
        !           102:        struct listen *f = (struct listen *)file;
        !           103:        struct sockaddr caddr;
        !           104:        socklen_t caddrlen;
        !           105:        int sock;
        !           106:
        !           107:        if (pfd->revents & POLLIN) {
        !           108:                DPRINTF("listen_revents: accepting connection\n");
        !           109:                caddrlen = sizeof(caddrlen);
        !           110:                sock = accept(f->fd, &caddr, &caddrlen);
        !           111:                if (sock < 0) {
        !           112:                        perror("accept");
        !           113:                        return 0;
        !           114:                }
        !           115:                if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
        !           116:                        perror("fcntl(sock, O_NONBLOCK)");
        !           117:                        close(sock);
        !           118:                        return 0;
        !           119:                }
        !           120:                (void)sock_new(&sock_ops, sock, "socket");
        !           121:        }
        !           122:        return 0;
        !           123: }
        !           124:
        !           125: void
        !           126: listen_close(struct file *file)
        !           127: {
        !           128:        struct listen *f = (struct listen *)file;
        !           129:
        !           130:        (void)unlink(f->path);
        !           131:        free(f->path);
        !           132:        (void)close(f->fd);
        !           133: }