"Fossies" - the Fresh Open Source Software archive 
Member "links-1.03/af_unix.c" of archive links-1.03.tar.gz:
#include "links.h"
#ifdef DONT_USE_AF_UNIX
int bind_to_af_unix()
{
return -1;
}
void af_unix_close()
{
}
#else
#ifdef USE_AF_UNIX
#include <sys/un.h>
#endif
void af_unix_connection(void *);
struct sockaddr *s_unix_acc = NULL;
struct sockaddr *s_unix = NULL;
socklen_t s_unix_l;
int s_unix_fd = -1;
#ifdef USE_AF_UNIX
int get_address()
{
struct sockaddr_un *su;
unsigned char *path;
if (!links_home) return -1;
path = stracpy(links_home);
su = mem_alloc(sizeof(struct sockaddr_un) + strlen(path) + 1);
s_unix_acc = mem_alloc(sizeof(struct sockaddr_un) + strlen(path) + 1);
memset(su, 0, sizeof(struct sockaddr_un) + strlen(path) + 1);
su->sun_family = AF_UNIX;
add_to_strn(&path, LINKS_SOCK_NAME);
strcpy(su->sun_path, path);
mem_free(path);
s_unix = (struct sockaddr *)su;
s_unix_l = (char *)&su->sun_path - (char *)su + strlen(su->sun_path) + 1;
return PF_UNIX;
}
void unlink_unix()
{
if (unlink(((struct sockaddr_un *)s_unix)->sun_path)) {
/*perror("unlink");
debug("unlink: %s", ((struct sockaddr_un *)s_unix)->sun_path);*/
}
}
#else
int get_address()
{
struct sockaddr_in *sin;
sin = mem_alloc(sizeof(struct sockaddr_in));
s_unix_acc = mem_alloc(sizeof(struct sockaddr_in));
memset(sin, 0, sizeof(struct sockaddr_in));
sin->sin_family = AF_INET;
sin->sin_port = LINKS_PORT;
sin->sin_addr.s_addr = htonl(0x7f000001);
s_unix = (struct sockaddr *)sin;
s_unix_l = sizeof(struct sockaddr_in);
return PF_INET;
}
void unlink_unix()
{
}
#endif
int bind_to_af_unix()
{
int u = 0;
int a1 = 1;
int cnt = 0;
int af;
if ((af = get_address()) == -1) return -1;
again:
if ((s_unix_fd = socket(af, SOCK_STREAM, 0)) == -1) return -1;
#if defined(SOL_SOCKET) && defined(SO_REUSEADDR)
setsockopt(s_unix_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&a1, sizeof a1);
#endif
if (bind(s_unix_fd, s_unix, s_unix_l)) {
/*perror("");
debug("bind: %d", errno);*/
close(s_unix_fd);
if ((s_unix_fd = socket(af, SOCK_STREAM, 0)) == -1) return -1;
#if defined(SOL_SOCKET) && defined(SO_REUSEADDR)
setsockopt(s_unix_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&a1, sizeof a1);
#endif
if (connect(s_unix_fd, s_unix, s_unix_l)) {
/*perror("");
debug("connect: %d", errno);*/
if (++cnt < MAX_BIND_TRIES) {
struct timeval tv = { 0, 100000 };
fd_set dummy;
FD_ZERO(&dummy);
select(0, &dummy, &dummy, &dummy, &tv);
close(s_unix_fd);
goto again;
}
close(s_unix_fd), s_unix_fd = -1;
if (!u) {
unlink_unix();
u = 1;
goto again;
}
mem_free(s_unix), s_unix = NULL;
return -1;
}
mem_free(s_unix), s_unix = NULL;
return s_unix_fd;
}
if (listen(s_unix_fd, 100)) {
error("ERROR: listen failed: %d", errno);
mem_free(s_unix), s_unix = NULL;
close(s_unix_fd), s_unix_fd = -1;
return -1;
}
set_handlers(s_unix_fd, af_unix_connection, NULL, NULL, NULL);
return -1;
}
void af_unix_connection(void *xxx)
{
socklen_t l = s_unix_l;
int ns;
memset(s_unix_acc, 0, l);
ns = accept(s_unix_fd, (struct sockaddr *)s_unix_acc, &l);
if (ns == -1) return;
init_term(ns, ns, win_func);
set_highpri();
}
void af_unix_close()
{
if (s_unix_fd != -1) close(s_unix_fd);
if (s_unix) unlink_unix(), mem_free(s_unix), s_unix = NULL;
if (s_unix_acc) mem_free(s_unix_acc), s_unix_acc = NULL;
}
#endif