#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>

#define DEST_SOCKET "/tmp/test"
#define CONNECT_FIRST 1
#define DEBUG 0

void sender()
{
	int fd;
	struct sockaddr_un addr;
	int addr_len;
	char datagram[1];
	fd_set set;

	fd = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (fd < 0)
		perror("sender's socket() failed");

	addr.sun_family = AF_UNIX;
	strcpy(addr.sun_path, DEST_SOCKET);
	addr_len = sizeof(addr.sun_family) + strlen(addr.sun_path);

	sleep(1);

#if CONNECT_FIRST
	if (connect(fd, (struct sockaddr*)&addr, addr_len) < 0)
		perror("sender's connect failed");
#endif
	while(1) {
		FD_ZERO(&set);
		FD_SET(fd, &set);

		if (select(fd + 1, NULL, &set, NULL, NULL) < 0)
			perror("sender's select() failed");
		if (FD_ISSET(fd, &set)) {
#if DEBUG
			fprintf(stderr, "Sending...");
#endif
#if CONNECT_FIRST
			if (send(fd, &datagram, sizeof(datagram), 0) < 0)
				perror("\nsend() failed");
#else
			if (sendto(fd, &datagram, sizeof(datagram), 0,
				   (struct sockaddr*)&addr, addr_len) < 0)
				perror("\nsendto() failed");
#endif
#if DEBUG
			fprintf(stderr, "\n");
#endif
		}
	}
}


void receiver()
{

	int fd;
	struct sockaddr_un addr;
	int addr_len;
	char datagram[2000];

	fd = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (fd < 0)
		perror("socket failed");

	addr.sun_family = AF_UNIX;
	strcpy(addr.sun_path, DEST_SOCKET);
	addr_len = sizeof(addr.sun_family) + strlen(addr.sun_path);
	if (bind(fd, (struct sockaddr*)&addr, addr_len) < 0)
		perror("receiver's bind() failed");

	while(1) {
		int i, size;
		sleep(10);

		for (i = 0; i < 5; i++) {
			size = recvfrom(fd, &datagram, sizeof(datagram), 0,
					NULL, NULL);
			if (size < 0)
				perror("recv failed");
#if DEBUG
			else
				fprintf(stderr, "recv %i byte(s)\n", size);
#endif
		}
	}
}


int main()
{
	unlink(DEST_SOCKET);

	int result = fork();
	if (result < 0) {
		perror("fork failed");
		exit(1);
	} else if (result == 0)
		receiver();
	else
		sender();

	exit(0);
}

