Skip to content

Instantly share code, notes, and snippets.

@cleoold
Created January 12, 2020 21:41
Show Gist options
  • Save cleoold/c7038e4929ad2066cb8c4a5046546daa to your computer and use it in GitHub Desktop.
Save cleoold/c7038e4929ad2066cb8c4a5046546daa to your computer and use it in GitHub Desktop.
C pipe system call
/**
* write string into pipe, read after
*/
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <strings.h>
#define SIZE 99
const char *msg1 = "hello #1";
const char *msg2 = "hello #2";
const char *msg3 = "hello #3, haha";
int main() {
char inbuff[SIZE];
// 0 for read, 1 for write
int p[2];
assert(pipe(p) == 0);
// write to pipe
write(p[1], msg1, SIZE);
write(p[1], msg2, SIZE);
write(p[1], msg3, SIZE);
//close(p[1]);
// first in first out
for (int _ = 0; _++ < 3;) {
bzero(inbuff, sizeof(inbuff));
read(p[0], inbuff, SIZE);
printf("%s\n", inbuff);
}
return 0;
}
/**
* both processes were created using the same version of compiler
* (for example, they're the same executable which forked), you can
* take advantage of the fact that anything in C can be read or
* written as an array of char
*/
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
struct Test {
int x, y;
char *name;
};
struct Test test = { 10,-6, "haha" };
int main() {
int p[2];
struct Test inbuf;
assert(pipe(p) == 0);
write(p[1], &test, sizeof(struct Test));
read(p[0], &inbuf, sizeof(struct Test));
printf("x: %d, y: %d, name: %s\n", inbuf.x, inbuf.y, inbuf.name);
return 0;
}
/**
* parent process sends strings to child process for printing
*/
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#define SIZE 99
const char *msg1 = "hello #1";
const char *msg2 = "hello #2";
const char *msg3 = "hello #3, haha";
void parent(int *p) {
write(p[1], msg1, SIZE);
write(p[1], msg2, SIZE);
write(p[1], msg3, SIZE);
close(p[1]); // or program hangs
wait(NULL);
}
void child(int *p) {
int bytesread;
close(p[1]); // or program hangs
char inbuf[SIZE];
while ((bytesread = read(p[0], inbuf, SIZE)) > 0)
printf("%s\n", inbuf);
assert(bytesread == 0);
printf("done\n");
}
int main() {
int p[2];
int pid;
assert(pipe(p) == 0);
pid = fork();
assert(pid >= 0);
if (pid > 0)
parent(p);
else
child(p);
return 0;
}
/**
* parent sends input
* child processes input
* child sends back input tp parent for printing
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <sys/wait.h>
#define SIZE 100
const char *hack = "(hacked!)";
void parent(char *input, int *pgo, int *pback) {
char result[SIZE];
close(pgo[0]); // parent->child direction don't need to read
write(pgo[1], input, strlen(input)+1);
close(pgo[1]); // after writing close write
wait(NULL); // wait for child to process
close(pback[1]); // child->parent direction don't need to write
read(pback[0], result, SIZE);
close(pback[0]); // after reading result close read
puts(result);
}
void child(int *pgo, int *pback) {
char result[SIZE];
close(pgo[1]); // parent->child direction don't need to write
read(pgo[0], result, SIZE);
close(pgo[0]); // after reading close read
strcat(result, hack); // process string
close(pback[0]); // child->parent direction don't need to read
write(pback[1], result, strlen(result)+1);
close(pback[1]);
}
int main() {
int pgo[2], pback[2]; // relative to parent process
int pid;
char input[SIZE];
printf("Your input: ");
scanf("%s", input);
assert(pipe(pgo) == 0);
assert(pipe(pback) == 0);
assert((pid = fork()) >= 0);
if (pid > 0)
parent(input, pgo, pback);
else
child(pgo, pback);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment