Skip to content

Instantly share code, notes, and snippets.

@arkt8
Last active June 5, 2023 16:51
Show Gist options
  • Save arkt8/8acb165b36f869c5eb99091f607830f5 to your computer and use it in GitHub Desktop.
Save arkt8/8acb165b36f869c5eb99091f607830f5 to your computer and use it in GitHub Desktop.
C rw pipes

Socketpair pipelines

A set of examples on how to proceed to make process pipelines using Unix C socketpair().

#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
inline static
void assert(int cmp, const char *msg, ...) {
if (!cmp) {
va_list va;
va_start(va, msg);
vprintf(msg, va);
exit(EXIT_FAILURE);
}
}
inline static
void dieif(int cmp) {
if (cmp) {
printf("Error: %s\n",strerror(errno));
exit(EXIT_FAILURE);
}
}
#define BUFSZ 1024
int main() {
int pipe[2], res, pid;
dieif (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe) == -1);
char *cmd[] = { "tr", "a", "c", NULL };
char msg[BUFSZ];
if ((pid = fork()) == 0) {
res = dup2(pipe[1], STDIN_FILENO);
assert(res == STDIN_FILENO, "child stdin: (%d >) %d != %d\n", pipe[1], res, STDIN_FILENO);
res = dup2(pipe[1], STDOUT_FILENO);
assert(res == STDOUT_FILENO, "child/stdout: (%d >) %d != %d\n", pipe[1], res, STDOUT_FILENO);
execvp(cmd[0], cmd);
return 0;
}
strcpy(msg, "ola\n");
write(pipe[0], msg, strlen(msg));
shutdown(pipe[0],SHUT_WR);
res = read(pipe[0], msg, BUFSZ);
msg[ (res > 0 ? res : 0) ] = '\0';
printf("RES (%d): %s\n", res, msg);
return 0;
}
/*
* Process pipilining example using socketpair()
*/
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
inline static
void assert(int cmp, const char *msg, ...) {
if (!cmp) {
va_list va;
va_start(va, msg);
vprintf(msg, va);
exit(EXIT_FAILURE);
}
}
inline static
void dieif(int cmp) {
if (cmp) {
printf("Error: %s\n",strerror(errno));
exit(EXIT_FAILURE);
}
}
#define BUFSZ 1024
int main() {
int pipe[2], res, pid;
dieif (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe) == -1);
char *cmd[] = { "tr", "a", "c", NULL };
char msg[BUFSZ];
if ((pid = fork()) == 0) {
res = dup2(pipe[1], STDIN_FILENO);
assert(res == STDIN_FILENO, "child stdin: (%d >) %d != %d\n", pipe[1], res, STDIN_FILENO);
res = dup2(pipe[1], STDOUT_FILENO);
assert(res == STDOUT_FILENO, "child/stdout: (%d >) %d != %d\n", pipe[1], res, STDOUT_FILENO);
execvp(cmd[0], cmd);
return 0;
}
strcpy(msg, "ola\n");
write(pipe[0], msg, strlen(msg));
shutdown(pipe[0],SHUT_WR);
res = read(pipe[0], msg, BUFSZ);
msg[ (res > 0 ? res : 0) ] = '\0';
printf("RES (%d): %s\n", res, msg);
return 0;
}
/*
* Copyright © 2023 - Thadeu A. C de Paula
* Licensed under MIT License
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment