#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
int main(void){
//Variables, p[2] for each end of the pipe. nbytes to read pipe return value SUCCESS or FAILURE. pid_t to hold pid of fork process.
// buffer to hold response from the child process.
int p[2], nbytes;
pid_t childpid;
char string[] = "Hello, World!\n";
char buffer[80];
//Declaration of pipe
pipe(p);
//Error handling.
if(((childpid = fork()) == -1) || (pipe(p) == -1))
{
perror("fork");
exit(1);
}
//Child process sends message to paprent.
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(p[0]);
/* Send "string" through the output side of pipe */
write(p[1], string, (strlen(string)+1));
exit(0);
}
else
{
/* Parent process closes up output side of pipe */
close(p[1]);
/* Read in a string from the pipe */
nbytes = read(p[0], buffer, sizeof(buffer));
printf("Received string: %s", buffer);
}
return(0);
}
Output > Received string: #�=zJ
The point of the exercise is to have a child process send a message through a pipe to the parent process and the parent returns the result. This exact code worked the first time I ran it, but then when I tried to run it a second time it started to return seemingly random characters each time. I tried to copy my buffer to another variable but then it was empty. Is the pipe actually not function the way I think it is? What am I doing wrong?
You first create a pipe with pipe(p); and then you create another with ... || (pipe(p) == -1)) Is that deliberate?
2nd Pipe was causing an issue.
You have:
pipe(p);
//Error handling.
if(((childpid = fork()) == -1) || (pipe(p) == -1))
{
perror("fork");
exit(1);
}
This creates two pipes — one in the line pipe(p); and the second in the condition if(((childpid = fork()) == -1) || (pipe(p) == -1)). This is wasteful at best. Moreover, the second pipe is after the fork(), so the parent and child processes don't access the same pipe any more — you overwrote the one created before the fork() which they do share. Test the result of pipe() before calling fork() and remove the extra condition in the if test:
if (pipe(p) != 0)
{
perror("pipe");
exit(1);
}
if ((childpid = fork()) < 0)
{
perror("fork");
exit(1);
}
Get used to testing for errors and writing appropriate code to handle them. It will be a major part of your life as a C programmer.
Later on in the code, you have:
{
/* Parent process closes up output side of pipe */
close(p[1]);
/* Read in a string from the pipe */
nbytes = read(p[0], buffer, sizeof(buffer));
printf("Received string: %s", buffer);
}
You need to heed the value of nbytes. Since it is an int, you could use:
printf("Received %d bytes: [%.*s]\n", nbytes, nbytes, buffer);
This limits the output to what was read, and reports 0 if that's what it gets. I suppose you should also check for -1 in nbytes before using it in the printf() statement:
if (nbytes < 0)
{
fprintf(stderr, "failed to read from pipe descriptor %d\n", p[0]);
// Or perror("read");
// Should you exit here with a non-zero status?
}
else
printf("Received %d bytes: [%.*s]\n", nbytes, nbytes, buffer);
Note: errors are reported on stderr; perror() does that automatically.
The problem is that you create two pipes when you really only need to check the first for errors:
// Declaration of pipe
if(pipe(p) == -1) { // check for error here
perror("pipe");
exit(1);
}
// Error handling.
if((childpid = fork()) == -1) { // and don't create another pipe here
perror("fork");
exit(1);
}
You should also check the return values from write and read. They may not write or read the full string in one go.
Related
I am working on a program where the main program forks itself and the child process calls exec. I have set it up so that the parent process has 2 pipes StdOutPipe and StdInPipe, and the child process calls dup so that stdout writes to the StdOutPipe and stdin reads from StdInPipe. Then the parent process calls wait, after which i would like to read the entirety of the StdOutPipe into a buffer. I know you can do so by reading one character at a time, but is there a faster way to do so?
For performance reasons, one typically reads a chunk at a time, not a character at a time.
Loop,
Attempt to enlarge the buffer so it can fit CHUNK_SIZE more bytes.
If an error occurred,
Fail.
Attempt to read CHUNK_SIZE bytes from the pipe into the unused part of the buffer.
If an error occurred,
Fail.
If EOF was reached,
Break.
Increased the total number of bytes read by the number of bytes read.
A pipe is basically a byte stream which means:
There's no concept of messages or message boundaries with pipes
The process reading from a
pipe can read blocks of data of any size, regardless of the size of blocks written by
the writing process
A read from a pipe is usually blocked until atleast a byte is written to the pipe.
That said, here's how i would implement your issue.
Create two pipes, stdinpipe and stdoutpipe
Do a fork
Parent process should close the write end of the pipes and sit in a
loop, waiting until data is written to pipe
Child process should close the read end of the pipes and duplicate
STDOUT to stdoutpipe and STDIN to stdinpipe
Child process can then do an exec.
Sample code:
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#define STDPIPE_BUFFER_SIZE 4096
#define ARGV_SIZE 3
int main()
{
// Stdoutpipe and stdint pipe
int stdoutpipe[2], stdinpipe[2], stdin_char_count, stdout_char_count, stdout_read, stdin_read;
pid_t pid;
char stdinbuffer[STDPIPE_BUFFER_SIZE], stdoutbuffer[STDPIPE_BUFFER_SIZE];
char *argv[ARGV_SIZE]; // arguments to exec
if (pipe(stdinpipe) == -1 || pipe(stdoutpipe) == -1)
exit(1); // error occurred
// Fork and exec
switch (pid = fork())
{
case -1:
exit(1); // error
case 0:
// child close the read end of both pipes
if (close(stdinpipe[0]) == -1 || close(stdoutpipe[0]) == -1)
exit(1);
// have the pipes as the new STDIN and STDOUT
if (dup2(stdinpipe[1], STDIN_FILENO) == -1 || dup2(stdoutpipe[1], STDOUT_FILENO) == -1)
exit(1);
argv[0] = "/usr/bin/ssh"; // replace with your own program [ssh -V in my case]
argv[1] = "-V";
argv[2] = NULL;
execve(argv[0], argv, NULL);
exit(1); // if we get here something horribly bad happened
default:
// parent process
stdin_char_count = 0;
stdout_char_count = 0;
// parent close write end of both pipes
if (close(stdinpipe[1]) == -1 || close(stdoutpipe[1]) == -1)
exit(1);
for (;;)
{
stdin_read = read(stdinpipe[0], stdinbuffer, STDPIPE_BUFFER_SIZE);
stdout_read = read(stdinpipe[0], stdinbuffer, STDPIPE_BUFFER_SIZE);
if (stdin_read == 0 && stdout_read == 0)
{
stdinbuffer[stdin_char_count] = '\0';
stdoutbuffer[stdout_char_count] = '\0';
break;
}
if (stdin_read == -1 && stdout_read == -1)
exit(1); // we cant recover from this
stdin_char_count += stdin_read;
stdout_char_count += stdout_read;
}
printf("%s\n", stdoutbuffer);
wait(NULL);
}
}
source: https://man7.org/linux/man-pages/man2/pipe.2.html
You can convert the pipe into an ordinary stream and then use whatever function you find convenient to read the data. Here, getdelim() can be used to read all text up to a NUL byte which need not be sent over the pipe. Error checking is partially omitted for brevity.
Also be aware that if you want to continue interacting directly with the pipe even after opening the stream, you'll probably want to disable buffering on the stream.
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void) {
int fds[2];
if(pipe(fds) == -1) {
perror("Failed to create pipe");
exit(EXIT_FAILURE);
}
const pid_t pid = fork();
if(pid == -1) {
perror("Failed to fork");
exit(EXIT_FAILURE);
}
if(!pid) {
close(fds[0]);
const char *const msg = "Hello, world!";
if(write(fds[1], msg, strlen(msg)) == -1) {
perror("Failed to write");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
close(fds[1]);
FILE *const stream = fdopen(fds[0], "r");
if(!stream) {
perror("Failed to create stream");
exit(EXIT_FAILURE);
}
char *text = NULL;
assert(wait(NULL) != -1);
getdelim(&text, &(size_t){0}, '\0', stream);
fclose(stream);
assert(text);
puts(text);
free(text);
}
I am trying to understand why my program hangs. The Parent sends input froma
file it reads to the child program, and the child program will send the result of its computation back to it's parent. However, I have trouble sending the message back through a second pipe. The parent seems to hang when reading from the pipe.
From the other posts, I have read it seems to indicate that the parent should wait for the child to finish by using wait or waitpid (which in my case both of them does not resolve my issue).
I have notice by adding print statement that neither the PARENT or the CHILD finishes.. Could someone please explain to me why this is happening?
Why does this not work?
int main(int argc,char** argv) {
char buffer[1];
int i;
int fd1[2]; int fd2[2];
pipe(fd1); pipe(fd2);
pid_t pid;
// FIRST PROCESS.
// -------------------
pid = fork();
if(pid == 0) {
int cnt;
dup2(fd1[0], STDIN_FILENO);
dup2(fd2[1], STDOUT_FILENO);
for (i = 0; i < 2; i++) {
close(fd1[i]);
close(fd2[i]);
}
while(read(STDIN_FILENO, buffer, sizeof(buffer)) > 0) {
fprintf(stderr, "( %s )", buffer);
cnt = cnt + *buffer - 48;
}
write(STDOUT_FILENO, &cnt, sizeof(cnt));
exit(0);
}
// PARENT.
// ------------------------
int file = open(argv[1], O_RDONLY);
// READ THE FILE.
while(read(file, buffer, 1) > 0) {
if (48 <= *buffer && *buffer <= 57) {
// PIPE TO CHILD.
write(fd1[1], buffer, 1);
}
}
// WAIT FOR CHILD TO FINISH SENDING BACK.
// int status = 0;
// waitpid(pid, &status, 0);
// THIS BLOCK DOESN'T RESOLVE ANYTHING. IT HANGS AT WAIT OR WAITPID.
// **** THIS IS THE PART WHERE IT DOESN'T WORK.
while(read(fd2[0], buffer, 1) > 0) {
fprintf(stderr, "RESULT : %s", buffer);
}
// CLOSING PIPES
for (i = 0; i < 2; i++) {
close(fd1[i]);
close(fd2[i]);
}
close(file);
exit(0);
}
You aren't closing enough file descriptors in the parent soon enough.
Rule of thumb: If you
dup2()
one end of a pipe to standard input or standard output, close both of the
original file descriptors returned by
pipe()
as soon as possible.
In particular, you should close them before using any of the
exec*()
family of functions.
The rule also applies if you duplicate the descriptors with either
dup()
or
fcntl()
with F_DUPFD
Now, your child process is following the RoT perfectly. But the corollary for parent processes is that they need to close the unused ends of the pipe, and they must close the write end of a pipe that they use to signal EOF to the reading end of that pipe. This is where your code fails.
Arguably, before reading the file, the parent process should close the read end of the pipe it uses to write to the child, and it should close the write end of the pipe it uses to read from the child.
Then, after reading the whole of the file, it should close the write end of the pipe to the child, before going into the 'read from child' loop. That loop never terminates because the parent still has the write end of the pipe open, so there's a process that could (but won't) write to the pipe.
Also, since the child writes the bytes of an integer onto a pipe, the parent should read the bytes of an integer. Using char buffer[1]; with a %s format is pointless; you need a null terminator for the string, and a single char buffer can't hold both a null byte and any data.
Along with various other improvements ('0' instead of 48, for example), you might end up with:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
int fd1[2];
int fd2[2];
char buffer[1];
pipe(fd1);
pipe(fd2);
pid_t pid = fork();
if (pid == 0) {
int cnt = 0;
dup2(fd1[0], STDIN_FILENO);
dup2(fd2[1], STDOUT_FILENO);
for (int i = 0; i < 2; i++) {
close(fd1[i]);
close(fd2[i]);
}
while (read(STDIN_FILENO, buffer, sizeof(buffer)) > 0) {
fprintf(stderr, "(%c)", buffer[0]); // Changed
cnt = cnt + buffer[0] - '0';
}
putc('\n', stderr); // Aesthetics
write(STDOUT_FILENO, &cnt, sizeof(cnt));
exit(0);
}
int file = open(argv[1], O_RDONLY);
if (file < 0) {
fprintf(stderr, "failed to open file '%s' for reading\n", argv[1]);
exit(EXIT_FAILURE);
}
close(fd1[0]); // Added
close(fd2[1]); // Added
while (read(file, buffer, sizeof(buffer)) > 0) {
if ('0' <= buffer[0] && buffer[0] <= '9') {
write(fd1[1], buffer, sizeof(buffer));
}
}
close(file); // Moved
close(fd1[1]); // Added
// Rewritten
int result;
while (read(fd2[0], &result, sizeof(result)) == sizeof(result)) {
fprintf(stderr, "RESULT : %d\n", result);
}
close(fd2[0]); // Added
// Close loop removed
return 0;
}
If that is stored in file pipe71.c and compiled, I get the following outputs when it is run:
$ ./pipe71 pipe71.c
(2)(0)(1)(2)(2)(2)(1)(1)(2)(0)(0)(2)(1)(0)(2)(2)(1)(0)(2)(1)(2)(0)(0)(0)(0)(0)(1)(0)(1)(1)(0)(2)(1)(0)(0)(0)(0)(9)(1)(1)(1)(1)(2)(0)(2)(0)(0)
RESULT : 49
$ ./pipe71 pipe71
(0)(0)(8)(0)(0)(2)(2)(0)(8)(1)(1)(5)(1)(1)(1)(1)(5)(1)(1)(1)(8)(5)(1)(9)(8)(5)(1)(1)(0)(4)(4)(4)(6)(0)(2)(8)(0)(0)(0)(2)(7)(1)(3)(8)(3)(0)(4)(3)(0)(4)(9)(0)(0)(0)(0)(7)(1)(9)(8)(1)(3)(0)
RESULT : 178
$
I want to do a program that first creates 3 processes (A) and later, creates one process more (B) and these first processes must write in a pipe that the last process read each time that process write.
I tried something but I don't know the way to do that because the process (B) is created after the processes (A)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CHILDREN 3
int main(int argc, char *argv[])
{
pid_t pid;
int fd[2];
char buffer[100];
char str[] = "Hello";
char str2[] = "Hello2";
char str3[] = "Hello3";
for(int num_process = 0; num_process < MAX_CHILDREN; num_process++)
{
if(pipe(fd) == -1)
{
perror( "pipe Failed" );
continue;
}
pid = fork();
if(pid < 0)
{
perror("fork failed");
exit(1);
}
if(pid == 0)
{ //child code
if(num_process == 0){
printf("Child %i (pid= %i) send string %s\n", num_process, getpid(),str);
write(fd[1],str,strlen(str));
}
if(num_process == 1){
printf("Child %i (pid= %i) send string %s\n", num_process, getpid(),str2);
write(fd[1],str2,strlen(str2));
}
if(num_process == 2){
printf("Child %i (pid= %i) send string %s\n", num_process, getpid(),str3);
write(fd[1],str3,strlen(str3));
}
exit(0);
}
else{//parent
printf("Im parent %i\n",getpid());
wait(NULL);
}
}
//Creating another child process from parent, this process recieves string sent from
//childs
pid = fork();
if(pid < 0)
{
perror("fork failed");
exit(1);
}
if(pid == 0){//child
printf("The new process %i read fd pipe\n",getpid());
if( read(fd[0],buffer,sizeof(buffer)) <= 0) //read pipe
{
perror("error read");
exit( EXIT_FAILURE );
}
printf("String readed : %s\n",buffer);
}
else{//parent
wait(NULL);
}
return 0;
}
You need to make a number of changes to the code. The parent shouldn't really wait on its children until after they're all launched. Since you create a new pipe for each of the first three children, you need to keep track of which file descriptors are in use. You should use arrays for that, and for the strings to be sent. Neither the read() nor the write() system calls null-terminates strings, and you don't tell it to write a null byte at the end, so you need to tell printf() to print the correct information.
Those changes and sundry others lead to:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAX_CHILDREN 3
int main(void)
{
pid_t pid;
int fd[MAX_CHILDREN][2];
char buffer[100];
const char *str[MAX_CHILDREN] = { "Hello 1", "Hello 2", "Hello 3" };
for (int i = 0; i < MAX_CHILDREN; i++)
{
if (pipe(fd[i]) == -1)
{
perror("pipe Failed");
exit(1);
}
pid = fork();
if (pid < 0)
{
perror("fork failed");
exit(1);
}
if (pid == 0)
{
printf("Child %i (pid= %i) send string %s\n", i + 1, getpid(), str[i]);
write(fd[i][1], str[i], strlen(str[i]));
exit(i + 1);
}
}
pid = fork();
if (pid < 0)
{
perror("fork failed");
exit(1);
}
if (pid == 0)
{
printf("The new process %i read fd pipe\n", getpid());
for (int i = MAX_CHILDREN; i-- > 0; )
{
int nbytes;
if ((nbytes = read(fd[i][0], buffer, sizeof(buffer))) <= 0)
{
perror("error read");
exit(EXIT_FAILURE);
}
printf("String read: %.*s\n", nbytes, buffer);
}
exit(4);
}
int corpse;
int status;
while ((corpse = wait(&status)) >= 0)
printf("child %d exited with status 0x%.4X\n", corpse, status);
return 0;
}
When run, the output might be:
Child 1 (pid= 91027) send string Hello 1
Child 2 (pid= 91028) send string Hello 2
Child 3 (pid= 91029) send string Hello 3
The new process 91030 read fd pipe
String read: Hello 3
String read: Hello 2
String read: Hello 1
child 91027 exited with status 0x0100
child 91028 exited with status 0x0200
child 91029 exited with status 0x0300
child 91030 exited with status 0x0400
I reversed the order of the elements in the reading loop, mainly just for fun. You can use a conventional for (int i = 0; i < MAX_CHILDREN; i++) loop instead if you prefer.
Although it isn't crucial in this program, you aren't closing enough file descriptors in the children or the parent. The parent should close the write ends of the pipes; it isn't going to be using them. The children should close the read ends of the pipes; they aren't going to be using them. Further, the second and third children should close the pipes opened for the first, and the third should close the pipe for the second, as they aren't going to use those, either. If you don't do this and the fourth child looped waiting for EOF (0 bytes returned), it would hang.
Rule of thumb: If you
dup2()
one end of a pipe to standard input or standard output, close both of the
original file descriptors returned by
pipe()
as soon as possible.
In particular, you should close them before using any of the
exec*()
family of functions.
The rule also applies if you duplicate the descriptors with either
dup()
or
fcntl()
with F_DUPFD
Note that an alternative design for the program would create a single pipe outside the loop and the children would all write to the same pipe. You'd probably want to add a newline to the message strings so that the results are separate. You'd definitely want to think about looping the read in the fourth child, and you'd need to worry about the pipe being closed properly, and so on. It'd be a worthwhile sub-exercise to code that.
I create a function exec_in_child which takes the command arguments, pipe file descriptors (fds), read_flag and write_flag as input. When write_flag is set to 1, the child process should duplicate stdout to fds[1], and then execute the command. When read_flag is set to 1, the child should duplicate the stdin to fds[0] and the execute the command.
Do I have to close one end of the pipe when I'm reading/writing to
the other end?
The code below doesn't work. I'm trying to execute /bin/ls inside a child process, write the stdout to the pipe, and then read
it off in the parent process and print it. I'm not able to read in
the parent process.
Can I read and write to the pipe inside the same process without closing other? This situation arises when I want to child to read
from pipe, execute, and then write to the pipe.
#include <stdio.h> /* printf */
#include <stdlib.h>
#include <string.h> /* strlen, strcpy */
int exec_in_child(char *arguments[], const int temp[], int , int);
int main()
{
ssize_t bytes_read;
char *curr_dir = (char *)malloc(500);
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
char *arguments[] = {"/bin/pwd",0};
exec_in_child(arguments, pipefd, 0, 1);
bytes_read = read(pipefd[0], curr_dir, strlen(curr_dir));
printf("%s = %d\n", "bytes read from pipe" ,(int)bytes_read);
printf("%s: %s\n","character read from the pipe",curr_dir);
return 0;
}
int exec_in_child(char * arguments[], const int fds[], int read_flag, int write_flag) {
pid_t pid;
pid = fork();
if (pid < 0) {
perror("Error: Fork Failed");
}
else if (pid == 0){ /*inside the child process */
if (read_flag == 1) {
dup2(fds[0], 0);
perror("Dup2 stdin");
}
if (write_flag == 1) {
dup2(fds[1], 1);
perror("Dup2 stdout");
}
execv(arguments[0], arguments);
perror("Error in child");
exit(1);
} /* if (pid == 0) */
else {
while(pid != wait(0));
} /* if(pid < 0) */
return 0;
}
I get this result:
hmwk1-skk2142(test) > ./a.out
Dup2 stdout: Success
bytes read from pipe = 0
character read from the pipe:
To answer your questions:
1) You do not need to close either end of the pipe in order to use the other end. However, you generally want to close any end(s) of the pipe you're not using. The biggest reason to do this is that the pipe will only close when all open write file descriptors are closed.
2) Your code isn't working because you're using strlen() improperly. This function calculates the length of a string by searching for the null (0) character. When you malloc() the storage for curr_dir you have no guarantee of what resides there (though it will usually be zeroed, as in this case).
Thus, your call strlen(curr_dir) returns zero, and the read() system call thinks you want to read up to zero bytes of data. Change your read call to the following:
bytes_read = read(pipefd[0], curr_dir, 500);
and your code will work perfectly.
3) You can read and write to any pipe you've got a valid file descriptor to. A single process can absolutely read and write the same pipe.
I'm a bit new to pipes and concurrency, and have been frustrated with this problem for hours. I am struggling to understand why this write operation is constantly failing on my pipe. I am trying to have the child process write data through a pipe that will be received by the parent process. My current code is this:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 4096
int main() {
pid_t status;
int fd[2]; //The array of file descriptors
if (pipe(fd) == -1) {
printf("Error piping");
}
status = fork(); //Begin the fork process
switch (status) {
case -1:
perror("Error forking");
break;
case 0:
//Child process
close(fd[0]); //Only send data
char some_string[15] = "hi there";
if (write(fd[1], some_string, MAXSIZE) == -1) {
printf("Error writing to the pipe");
}
close(fd[1]); //Close write end
exit(1);
default:
close(fd[1]); //Only receive data
char readed[500] = "";
while(read(fd[0], readed, MAXSIZE) != 0) {
printf("read this %s\n", readed);
}
printf("Done reading");
close(fd[0]);
break;
}
return 1;
}
However, I constantly get the message "Error writing to pipe", meaning that the write operation has failed in the child process. Another interesting thing is that if I change some_string to a string literal instead, this code works fine with the exception that it never terminates and instead, the read operation in the parent process reads from STDIN! I don't understand why this could be happening, is it possible that we have a zombie child when parent executes so the pipe is "dead"? Or perhaps that the parent process terminates and we have an orphaned child? How can I avoid this and how does this explain the weird behaviour from the string literal instead? Any insights?
You told write() to read the data from out-of-range of the array and allowed read() to write the data read to out-of-range of the array. That is very bad.
Write only valid data and limit the length to read not to cause out-of-range access.
Try this:
#include <unistd.h>
#include <sys/types.h> /* add this to use pid_t */
#include <sys/wait.h> /* add this to use wait() */
#include <stdio.h>
#include <stdlib.h>
/* remove unused MAXSIZE */
int main() {
pid_t status;
int fd[2]; //The array of file descriptors
int st; /* variable for receiving the status */
if (pipe(fd) == -1) {
printf("Error piping");
return 1; /* return 1 when the execution failed */
}
status = fork(); //Begin the fork process
switch (status) {
case -1:
perror("Error forking");
return 1; /* return 1 when the execution failed */
break;
case 0:
//Child process
close(fd[0]); //Only send data
char some_string[15] = "hi there";
if (write(fd[1], some_string, sizeof(some_string)) == -1) {
printf("Error writing to the pipe");
}
close(fd[1]); //Close write end
exit(0); /* return 0 if the execution finished successfully */
default:
close(fd[1]); //Only receive data
char readed[500] = "";
while(read(fd[0], readed, sizeof(readed) - 1) != 0) { /* -1 for reserving space for terminating null-character */
printf("read this %s\n", readed);
}
printf("Done reading");
close(fd[0]);
wait(&st); /* wait for the child process to exit and release the data of the process */
break;
}
return 0; /* return 0 if the execution finished successfully */
}