User Tools

Site Tools


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