Skip to content

Instantly share code, notes, and snippets.

@ghedo
Created August 13, 2013 14:22
Show Gist options
  • Save ghedo/6221579 to your computer and use it in GitHub Desktop.
Save ghedo/6221579 to your computer and use it in GitHub Desktop.
Bidirectional pipe
/*
* Bidirectional pipe
*
* Compile:
* $ cc -o bipipe bipipe.c
*
* Examples:
*
* * Unix domain socket chat over SSH:
*
* On host A
* $ bipipe socket -s ./a.sock '<=>' ssh B socket -s ./b.sock
* $ socket ./a.sock
*
* On host B
* $ socket ./b.sock
*
* Then write on the terminals to chat.
*
* Copyright (C) 2013 Alessandro Ghedini <alessandro@ghedini.me>
* --------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Alessandro Ghedini wrote this file. As long as you retain this
* notice you can do whatever you want with this stuff. If we
* meet some day, and you think this stuff is worth it, you can
* buy me a beer in return.
* --------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[]) {
int i, rc;
int split = argc;
int pipe1[2], pipe2[2];
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "<=>") == 0) {
argv[i] = '\0';
split = i + 1;
}
}
rc = pipe(pipe1);
if (rc < 0) {
fprintf(stderr, "ERROR: Can't create pipe: %d: %s\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
rc = pipe(pipe2);
if (rc < 0) {
fprintf(stderr, "ERROR: Can't create pipe: %d: %s\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
switch (fork()) {
case -1:
fprintf(stderr, "ERROR: Can't fork(): %d: %s\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
case 0:
close(pipe1[0]);
close(pipe2[1]);
dup2(pipe2[0], STDIN_FILENO);
dup2(pipe1[1], STDOUT_FILENO);
close(pipe1[1]);
close(pipe2[0]);
puts(argv[split]);
printf("%d\n", split);
rc = execvp(argv[split], (argv + split));
if (rc < 0) {
fprintf(stderr,
"ERROR: Can't exec command: %d: %s\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
break;
default:
close(pipe1[1]);
close(pipe2[0]);
dup2(pipe1[0], STDIN_FILENO);
dup2(pipe2[1], STDOUT_FILENO);
close(pipe1[0]);
close(pipe2[1]);
puts(argv[1]);
rc = execvp(argv[1], (argv + 1));
if (rc < 0) {
fprintf(stderr,
"ERROR: Can't exec command: %d: %s\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
break;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment