Master-slave pair of processes with Unix datagram communication
mainserv.c
- mainserv.c
/*
* Copyright 2011 Oleg Borodin <onborodin@gmail.com>
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
int main(int argc, char **argv) {
pid_t pid = fork();
if (pid == 0){
/* in the child */
char subserv[] = "./subserv";
char* args[] = { subserv, NULL };
int res = execv(subserv, args);
fprintf(stderr, "exec res %d\n", res);
}
if (pid < 0) {
fprintf(stderr, "unable fork, exit\n");
exit(1);
}
int sock = -1;
if((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
fprintf(stderr, "unable create unix socket, exit\n");
exit(1);
}
const char sockpath[] = "unix-socket";
struct sockaddr sockaddr;
memset(&sockaddr, 0, sizeof(struct sockaddr));
struct sockaddr_un* paddr = (struct sockaddr_un*)&sockaddr;
paddr->sun_family = AF_UNIX;
strcpy(paddr->sun_path, sockpath);
socklen_t socklen = sizeof(struct sockaddr_un);
sleep(1);
if (connect(sock, (struct sockaddr*)&sockaddr, socklen) < 0) {
fprintf(stderr, "unable connect to unix socket, exit.\n");
exit(1);
}
fprintf(stderr, "connect to unix socket %d\n", sock);
while(true) {
const char msg[] = "hello, subprocess!";
fprintf(stderr, "try send to subprocess\n");
ssize_t res = send(sock, msg, strlen(msg), 0);
fprintf(stderr, "send %d chars\n", (int)res);
sleep(1);
}
close(sock);
kill(pid, SIGTERM);
int status;
waitpid(pid, &status, 0);
return 0;
}
subserv.c
- subserv.c
/*
* Copyright 2011 Oleg Borodin <onborodin@gmail.com>
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>
#include <string.h>
int main(int argc, char **argv) {
int sock = -1;
if((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
fprintf(stderr, "unable create unix socket, exit\n");
exit(1);
}
const char sockpath[] = "unix-socket";
struct sockaddr sockaddr;
memset(&sockaddr, 0, sizeof(struct sockaddr));
struct sockaddr_un* paddr = (struct sockaddr_un*)&sockaddr;
paddr->sun_family = AF_UNIX;
strcpy(paddr->sun_path, sockpath);
unlink(sockpath);
socklen_t socklen = sizeof(struct sockaddr_un);
if (bind(sock, (struct sockaddr*)paddr, socklen) < 0) {
fprintf(stderr, "unable bind unix socket, exit\n");
close(sock);
exit(1);
}
int backlog = 1024;
if (listen(sock, backlog) < 0) {
fprintf(stderr, "unable listen unix socket, exit\n");
close(sock);
exit(1);
}
fprintf(stderr, "do accept with socket %d\n", sock);
ssize_t res;
const int bufsize = 1024;
char buffer[bufsize];
while ((res = recv(sock, buffer, bufsize, 0)) > 0) {
char str[] = "";
strncat(str, buffer, (int)res);
fprintf(stderr, "subprocess read %d chars: %s\n", (int)res, str);
}
close(sock);
unlink(sockpath);
return 0;
}
out
$ ./mainserv
do accept with socket 3
connect to unix socket 3
try send to subprocess
send 18 chars
subprocess read 18 chars: hello, subprocess!
try send to subprocess
send 18 chars
subprocess read 18 chars: hello, subprocess!
^C