source: neercs/trunk/src/mini-socket.c @ 4380

Last change on this file since 4380 was 4380, checked in by Sam Hocevar, 10 years ago

Implement bidirectional communication in mini-neercs.

  • Property svn:keywords set to Id
File size: 2.9 KB
Line 
1/*
2 *  neercs        console-based window manager
3 *  Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
4 *                2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
5 *                2008-2010 Pascal Terjan <pterjan@linuxfr.org>
6 *                All Rights Reserved
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15#if defined HAVE_CONFIG_H
16#   include "config.h"
17#endif
18
19#include <stdio.h> /* perror() */
20#include <stdlib.h> /* malloc(), free() */
21#include <unistd.h> /* unlink() */
22#include <fcntl.h> /* fcntl() */
23#include <string.h> /* memcpy() */
24#include <sys/select.h> /* select() */
25#include <sys/types.h> /* bind(), connect() */
26#include <sys/socket.h> /* bind(), connect() */
27#include <sys/un.h> /* AF_UNIX */
28
29#include "mini-neercs.h"
30#include "mini-socket.h"
31
32#define SIZEOF_SUN_PATH (sizeof(((struct sockaddr_un *)NULL)->sun_path))
33
34struct nrx_socket
35{
36#if 1
37    /* Linux sockets */
38    int fd;
39    int server;
40    char path[SIZEOF_SUN_PATH];
41#else
42#   error No socket implementation
43#endif
44};
45
46nrx_socket_t * socket_open(char const *path, int server)
47{
48    nrx_socket_t * sock;
49    struct sockaddr_un addr;
50    int ret, fd;
51
52    fd = socket(AF_UNIX, SOCK_DGRAM, 0);
53    if (fd < 0)
54    {
55        perror("socket creation");
56        return NULL;
57    }
58
59    memset(&addr, 0, sizeof(struct sockaddr_un));
60    addr.sun_family = AF_UNIX;
61    strncpy(addr.sun_path, path, SIZEOF_SUN_PATH - 1);
62
63    if (server)
64    {
65        unlink(path);
66        ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
67    }
68    else
69    {
70        ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
71    }
72
73    if (ret < 0)
74    {
75        perror(server ? "socket binding" : "socket connection");
76        close(fd);
77        return NULL;
78    }
79
80    fcntl(fd, F_SETFL, O_NONBLOCK);
81
82    sock = malloc(sizeof(*sock));
83    sock->fd = fd;
84    sock->server = server;
85    strncpy(sock->path, path, SIZEOF_SUN_PATH - 1);
86
87    return sock;
88}
89
90int socket_select(nrx_socket_t *sock, int usecs)
91{
92    fd_set rfds;
93    struct timeval tv;
94    int ret;
95
96    FD_ZERO(&rfds);
97    FD_SET(sock->fd, &rfds);
98
99    tv.tv_sec = usecs / 1000000;
100    tv.tv_usec = usecs % 1000000;
101
102    ret = select(sock->fd + 1, &rfds, NULL, NULL, &tv);
103    if (ret < 0)
104        return -1;
105
106    if (FD_ISSET(sock->fd, &rfds))
107        return 1;
108
109    return 0;
110}
111
112int socket_puts(nrx_socket_t *sock, char const *str)
113{
114    int ret;
115    ret = write(sock->fd, str, strlen(str));
116    return ret;
117}
118
119ssize_t socket_read(nrx_socket_t *sock, void *buf, size_t count)
120{
121    int ret;
122    ret = read(sock->fd, buf, count);
123    return ret;
124}
125
126void socket_close(nrx_socket_t *sock)
127{
128    close(sock->fd);
129    if (sock->server)
130        unlink(sock->path);
131    free(sock);
132}
133
Note: See TracBrowser for help on using the repository browser.