Hi ,

what is the behaviour of below pseudo code.

pipe(fd)

if(fork()){
	read(fd[0]);
} else {
	write(fd[1]);
	write(fd[1]);
}

I understand how system calls work , but could not understand the behaviour when used differently.

secondly if a process uses while(1); in side its block, will the entire program struck there or it struck there as long as it is scheduled.


Thanks,

Dani AI

Generated

Short practical summary and fixes (for , with notes to and )

The key points you need to know about pipes + fork:

  • A pipe is a kernel byte-stream and file descriptors are inherited across fork. That means both parent and child initially hold both ends. To see EOF in a reader you must close all writable copies of the pipe; otherwise the reader will block waiting for more data. was right about checking fork() == 0 for the child — always test fork()'s return for >0 / 0 / -1.
  • Reads do not simply “fail” when there are more reads than writes. If no data and at least one writer is still open, read blocks. If no writers are open, read returns 0 (EOF). If the descriptor is nonblocking, read returns -1 with errno EAGAIN/EWOULDBLOCK.
  • Writes are not silently dropped. If the pipe buffer is full, a blocking write will wait; a nonblocking write will return -1 with errno EAGAIN/EWOULDBLOCK. If there are no readers at all, writing raises SIGPIPE (and the call fails with EPIPE unless you ignore SIGPIPE).

A simple safe pattern (close the unused end in each process):

int fd[2];
pipe(fd);
pid_t pid = fork();
if (pid > 0) {
    /* parent: close write end, read until EOF */
    close(fd[1]);
    ssize_t n;
    char buf[1024];
    while ((n = read(fd[0], buf, sizeof buf)) > 0) {
        /* handle n bytes */
    }
    close(fd[0]);
} else if (pid == 0) {
    /* child: close read end, write, close, exit */
    close(fd[0]);
    const char *s = "data";
    write(fd[1], s, strlen(s));
    close(fd[1]);
    _exit(0);
}

About while(1); — it busy-loops the current process/thread and will consume CPU but it does not freeze the whole machine; the OS scheduler still runs other processes. Use blocking syscalls (read, select/poll), sleep(), pause(), or sched_yield() to yield the CPU instead.

Debugging tip: with gdb use set follow-fork-mode child (or parent) and set detach-on-fork off to keep both inferiors. You can also attach <pid> to the child after fork and use info inferiors / inferior N to switch between them. Check that you close unused fds — that is the usual cause of the “read never returns EOF” symptom.

Recommended Answers

All 5 Replies

If there are more reads than writes, any reads beyond the number of writes will fail.
If there are more writes than reads, nothing happens aside from a risk of lost data for the writes that weren't consumed.

Thanks deceptikon for your answer.

Actually i tried to debug program involving fork and read and write.

the control is always entering if part only.

is there any way by which we can debug both child and parent proccess just the normal program.

fork returns two values ,0 for child process, and pid of child for parent process. Hence , your if is always true and it runs for parent. If you want some code to run for child you will have to check

if(fork() == 0){
// your code
}

is there any way by which we can debug both child and parent proccess just the normal program.

Assuming you're debugging with gdb: http://www.delorie.com/gnu/docs/gdb/gdb_26.html

fork returns two values ,0 for child process, and pid of child for parent process. Hence , your if is always true and it runs for parent. If you want some code to run for child you will have to check

if(fork() == 0){
// your code
}

All you did was reverse the test. if (fork()) is equivalent to if (fork() != 0) .

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.