Skip to content

Instantly share code, notes, and snippets.

@KaiserKatze
Last active August 31, 2018 11:42
Show Gist options
  • Select an option

  • Save KaiserKatze/e57d12b7df2283cb0d7cd5cafc67f3f7 to your computer and use it in GitHub Desktop.

Select an option

Save KaiserKatze/e57d12b7df2283cb0d7cd5cafc67f3f7 to your computer and use it in GitHub Desktop.
Linux Inter-process Communication Demo
/***************************************************
*
* Linux Inter-process Communication Demo
*
***************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
// my inter-process communication socket path
#define MY_SOCK_PATH "/run/myipcsp"
#define LISTEN_BACKLOG 50
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); goto end; } while (0)
// @see https://linux.die.net/man/7/unix
#define MY_DOMAIN AF_UNIX
#define MY_TYPE SOCK_STREAM
#define MY_PROTOCOL (0)
int main(int argc, char ** argv)
{
// socket
int sfd = 0, cfd = 0;
struct sockaddr_un my_addr = { 0 }, peer_addr = { 0 };
socklen_t peer_addr_size = 0;
// process
int flag = 1;
pid_t pid = 0;
// IO
const static size_t buflen = 1024;
const char buffer [buflen] = { 0 };
ssize_t size = 0;
////////////////////////////////////////////////////////////////////////////
my_addr.sun_family = MY_DOMAIN;
strncpy(my_addr.sun_path, MY_SOCK_PATH, sizeof(my_addr.sun_path) - 1);
pid = fork();
if (pid < 0)
handle_error("fork");
if (pid == 0)
{
// child process
cfd = socket(MY_DOMAIN, MY_TYPE, MY_PROTOCOL);
if (connect(cfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_un)) == -1)
handle_error("connect");
for (int i = 10; i > 0 && flag; i--)
{
strncpy((char *) buffer, "Hello world!", buflen - 1);
if (send(cfd, buffer, buflen, 0) == -1)
handle_error("send");
}
stop:
flag = 0;
strncpy((char *) buffer, "stop", buflen - 1);
if (send(cfd, buffer, buflen, 0) == -1)
handle_error("send");
}
else
{
// parent process
sfd = socket(MY_DOMAIN, MY_TYPE, MY_PROTOCOL);
if (sfd == -1)
handle_error("socket");
if (bind(sfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_un)) == -1)
handle_error("bind");
if (listen(sfd, LISTEN_BACKLOG) == -1)
handle_error("listen");
peer_addr_size = sizeof(struct sockaddr_un);
while (flag)
{
cfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_size);
if (cfd == -1)
handle_error("accept");
while (flag)
{
memset((void *) buffer, 0, buflen);
size = recv(cfd, (void *) buffer, buflen, 0);
if (size < 0)
handle_error("recv");
printf("%s\n", buffer, buflen);
if (strcoll("stop", buffer) == 0)
{
flag = 0;
goto end;
}
}
close(cfd);
}
}
end:
if (pid == 0)
{
if (flag)
goto stop;
}
else
{
unlink(MY_SOCK_PATH);
}
if (sfd)
{
close(sfd);
sfd = 0;
}
if (cfd)
{
close(cfd);
cfd = 0;
}
flag = 0;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment