1748117 Members
3603 Online
108758 Solutions
New Discussion юеВ

Pipes' program problem

 
Ron Barak
Advisor

Pipes' program problem

Hi Gurus,

A CS student asked me to help him with a two-ways pipe assignment (on Linux).

I wrote the program below which is supposed to be creating a ring of processes (parents spawning children, and communications flows from parents to children and vice-versa).

However, as you see from the output below the listing, I get "write: Bad file descriptor" and "Broken pipe" errors.

I spent quite some time trying to debug this program: anyone could point me in the correct direction to eliminate these errors ?

Thanks,
Ron.

--------------------------------------------------------------------------------

[rbarakX@ROSH005 /tmp/ring]$ ################################################
[rbarakX@ROSH005 /tmp/ring]$ ##### This is the working "one way pipe" program ######
[rbarakX@ROSH005 /tmp/ring]$ ################################################
[rbarakX@ROSH005 /tmp/ring]$ cat one_way_pipes_ring.c
#include
#include
#include
#include
#include
#include
#include

int main(int argc, char *argv[ ]) {
pid_t childpid; /* indicates process should spawn another */
int error; /* return value from dup2 call */
int fd[2]; /* file descriptors returned by pipe */
int i; /* number of this process (starting with 1) */
int k; /* counter of ID array */
int nprocs; /* total number of processes in ring */
int icount; /* iteration count */
char buf[BUFSIZ]; /* input buffer */
int next_ID; /* next process id */
int *ID_list; /* pointer to list of process id's */

/* check command line for a valid number of processes to generate */
if ( (argc != 2) || ((nprocs = atoi (argv[1])) <= 0) ) {
fprintf (stderr, "Usage: %s nprocs\n", argv[0]);
return 1;
}
if (pipe (fd) == -1) { /* connect std input to std output via a pipe */
perror("Failed to create starting pipe");
return 1;
}
if ((dup2(fd[0], STDIN_FILENO) == -1) ||
(dup2(fd[1], STDOUT_FILENO) == -1)) {
perror("Failed to connect pipe");
return 1;
}
if ((close(fd[0]) == -1) || (close(fd[1]) == -1)) {
perror("Failed to close extra descriptors");
return 1;
}

for (i = 1; i < nprocs; i++) { /* create the remaining processes */
if (pipe (fd) == -1) {
fprintf(stderr, "[%ld]:failed to create pipe %d: %s\n",
(long)getpid(), i, strerror(errno));
return 1;
}
if ((childpid = fork()) == -1) {
fprintf(stderr, "[%ld]:failed to create child %d: %s\n",
(long)getpid(), i, strerror(errno));
return 1;
}
if (childpid > 0) /* for parent process, reassign stdout */
error = dup2(fd[1], STDOUT_FILENO);
else /* for child process, reassign stdin */
error = dup2(fd[0], STDIN_FILENO);
if (error == -1) {
fprintf(stderr, "[%ld]:failed to dup pipes for iteration %d: %s\n",
(long)getpid(), i, strerror(errno));
return 1;
}
if ((close(fd[0]) == -1) || (close(fd[1]) == -1)) {
fprintf(stderr, "[%ld]:failed to close extra descriptors %d: %s\n",
(long)getpid(), i, strerror(errno));
return 1;
}
if (childpid)
break;
}

icount = i; /* save which iteration this is - in a global */
if (NULL == (ID_list = malloc(i * sizeof(int) ))) {
perror("Out of memory!");
return 2;
}
ID_list[0] = next_ID = getpid();

/* read data from this process's parent... */
for (k = 1; k < icount; ++k) {
fgets(buf, sizeof (buf), stdin);
next_ID = ID_list[k] = atoi(buf);
}

/* a parent sends data to its child process */
for (k = 0; (icount != nprocs) && (k < icount); ++k) {
printf("%d\n", ID_list[k]);
fflush(stdout); /* flushing output so child could get input */
}

/* and then wait for the child to expire */
wait(NULL) ;
/* say hello to the world */
fprintf(stderr, "\nThis is process %d with ID %ld and parent id %ld\nID array: ",
i, (long)getpid(), (long)getppid());

for (k = 0; k < icount; ++k) {
fprintf(stderr,"%c%d", k % 10 ? ' ' : '\n', ID_list[k]);
}

fprintf(stderr,"\n");
return 0;
}
[rbarakX@ROSH005 /tmp/ring]$ ##########################################################
[rbarakX@ROSH005 /tmp/ring]$ ##### executing the "one way pipe" program with 3 processes ######
[rbarakX@ROSH005 /tmp/ring]$ ##########################################################
[rbarakX@ROSH005 /tmp/ring]$ ./one_way_pipes_ring 3

This is process 3 with ID 184 and parent id 3724
ID array:
184 3724 4068

This is process 2 with ID 3724 and parent id 4068
ID array:
3724 4068

This is process 1 with ID 4068 and parent id 172
ID array:
4068
[rbarakX@ROSH005 /tmp/ring]$ ################################################
[rbarakX@ROSH005 /tmp/ring]$ ##### This is the crashing "two ways pipe" program #####
[rbarakX@ROSH005 /tmp/ring]$ ################################################
[rbarakX@ROSH005 /tmp/ring]$ cat two_way_pipes_ring.c
#include
#include
#include
#include
#include
#include
#include
#include /* defines isascii(), toupper(), and other */
/* character manipulation routines. */

/* function executed by the user-interacting process. */
int p2c(int input_pipe[], int output_pipe[], int i)
{
int c; /* user input - must be 'int', to recognize EOF (= -1). */
char ch; /* the same - as a char. */
int rc; /* return values of functions. */
// pid_t childpid; /* indicates process should spawn another */
int error; /* return value from dup2 call */
int writepipe[2]; /* parent -> child */
int readpipe [2]; /* child -> parent */
int fd[2]; /* file descriptors returned by pipe */
int k; /* counter of ID array */
int nprocs; /* total number of processes in ring */
int icount; /* iteration count */
char buf[BUFSIZ]; /* input buffer */
int next_ID; /* next process id */
int *ID_list; /* pointer to list of process id's */

fprintf(stderr, "(%d) start: p2c \n", 38) ;
/* first, close unnecessary file descriptors */
close(input_pipe[1]); /* we don't need to write to this pipe. */
close(output_pipe[0]); /* we don't need to read from this pipe. */


icount = i; /* save which iteration this is - in a global */
if (NULL == (ID_list = malloc(i * sizeof(int) ))) {
perror("Out of memory!");
exit(2);
}
ID_list[0] = next_ID = getpid();

/* read data from this process's parent... */
for (k = 1; k < icount; ++k) {
rc = (int)fgets(buf, sizeof (buf), (FILE *)input_pipe[0]);
if (rc <= 0) { /* fgets failed */
perror("p2c: read");
close(input_pipe[0]);
close(output_pipe[1]);
exit (1);
}
next_ID = ID_list[k] = atoi(buf);
}

fprintf(stderr, "(%d) c2p \n", 63) ;
/* a parent sends data to its child process */
for (k = 0; (icount != nprocs) && (k < icount); ++k) {
fprintf(stderr, "(%d) c2p: i=%d ; k=%d ; ID_list[%d]=%d\n", 66,k,i,k,ID_list[k]) ;
sprintf(buf, "%d\0", ID_list[k]) ;
rc = (int)write(output_pipe[1], buf, sizeof(buf));
// rc = (int)fprintf((FILE *)input_pipe[1], "%d\n", ID_list[k]);
fprintf(stderr, "(%d) p2c: k=%d ; buf=|%s| ; rc=%d\n", 70,k,buf,rc) ;
fflush(NULL); /* flushing output so child could get input */
if (rc == -1) { /* fprintf failed */
perror("(73 error) p2c: write");
close(input_pipe[0]);
close(output_pipe[1]);
exit (1);
}
fflush(NULL); /* flushing output so child could get input */
}

/* and then wait for the child to expire */
// wait(NULL) ;
/* say hello to the world */
fprintf(stderr, "\nThis is process %d with ID %ld and parent id %ld\nID array: ",
i, (long)getpid(), (long)getppid());

for (k = 0; k < icount; ++k) {
fprintf(stderr,"%c%d", k % 10 ? ' ' : '\n', ID_list[k]);
}

/* close pipes and return. */
close(input_pipe[0]);
close(output_pipe[1]);
fprintf(stderr,"\n");
return (0);

}

/* now comes the function executed by the translator process. */
int c2p(int input_pipe[], int output_pipe[], int i)
{
int rc; /* return values of functions. */
// pid_t childpid; /* indicates process should spawn another */
int error; /* return value from dup2 call */
int k; /* counter of ID array */
int nprocs; /* total number of processes in ring */
int icount; /* iteration count */
char buf[BUFSIZ]; /* input buffer */
int next_ID; /* next process id */
int *ID_list; /* pointer to list of process id's */


fprintf(stderr, "(%d) start: c2p \n", 112) ;
/* first, close unnecessary file descriptors */
close(input_pipe[0]); /* we don't need to read from this pipe. */
close(output_pipe[1]); /* we don't need to write to this pipe. */

icount = i; /* save which iteration this is - in a global */
if (NULL == (ID_list = malloc(i * sizeof(int) ))) {
perror("Out of memory!");
exit(2);
}
ID_list[0] = next_ID = getpid();

fprintf(stderr, "(%d) c2p \n", 124) ;
/* read data from this process's parent... */
for (k = 1; k < icount; ++k) {
rc = (int)read(output_pipe[0], buf, sizeof (buf));
// rc = (int)fgets(buf, sizeof (buf), (FILE *)output_pipe[0]);
fprintf(stderr, "(%d) c2p: k=%d ; buf=|%s| ; rc=%d\n", 130,k,buf, rc) ;
if (rc <= 0) { /* fgets failed */
perror("c2p: read");
close(input_pipe[1]);
close(output_pipe[0]);
exit (1);
}
next_ID = ID_list[k] = atoi(buf);
}

fprintf(stderr, "(%d) c2p \n", 137) ;
/* a parent sends data to its child process */
for (k = 0; (icount != nprocs) && (k < icount); ++k) {
fprintf(stderr, "(%d) c2p: i=%d ; k=%d ; ID_list[%d]=%d\n", 140,k,i,k,ID_list[k]) ;
sprintf(buf, "%d\0", ID_list[k]) ;
rc = (int)write(input_pipe[1], buf, sizeof(buf));
// rc = (int)fprintf((FILE *)input_pipe[1], "%d\n", ID_list[k]);
fprintf(stderr, "(%d) c2p: k=%d ; buf=|%s|\n", 142,k,buf) ;
fflush(NULL); /* flushing output so child could get input */
if (rc == -1) { /* fprintf failed */
perror("(144 error) c2p: write");
close(input_pipe[1]);
close(output_pipe[0]);
exit (1);
}
fflush(NULL); /* flushing output so child could get input */
}

fprintf(stderr, "(%d) c2p \n", 150) ;
/* and then wait for the child to expire */
// wait(NULL) ;
/* say hello to the world */
fprintf(stderr, "\nThis is process %d with ID %ld and parent id %ld\nID array: ",
i, (long)getpid(), (long)getppid());

for (k = 0; k < icount; ++k) {
fprintf(stderr,"%c%d", k % 10 ? ' ' : '\n', ID_list[k]);
}
fprintf(stderr, "(%d) c2p \n", 168) ;

/* close pipes and return. */
close(input_pipe[1]);
close(output_pipe[0]);
fprintf(stderr,"\n");
fprintf(stderr, "(%d) c2p \n", 165) ;
return (0) ;
}



int main(int argc, char *argv[ ]) {
pid_t childpid; /* indicates process should spawn another */
int error; /* return value from dup2 call */
int writepipe[2]; /* parent -> child */
int readpipe [2]; /* child -> parent */
int fd[2]; /* file descriptors returned by pipe */
int i; /* number of this process (starting with 1) */
int k; /* counter of ID array */
int nprocs; /* total number of processes in ring */
int icount; /* iteration count */
char buf[BUFSIZ]; /* input buffer */
int next_ID; /* next process id */
int *ID_list; /* pointer to list of process id's */
/* 2 arrays to contain file descriptors, for two pipes. */
int p2cpipe[2];
int c2ppipe[2];
// int pid; /* pid of child process, or 0, as returned via fork. */
int rc; /* stores return values of various routines. */


/* check command line for a valid number of processes to generate */
if ( (argc != 2) || ((nprocs = atoi (argv[1])) <= 0) ) {
fprintf (stderr, "Usage: %s nprocs\n", argv[0]);
return 1;
}
fprintf(stderr, "(%d)\n", 190) ;
if (pipe (p2cpipe) == -1) { /* connect std input to std output via a pipe */
perror("Failed to create p2cpipe pipe");
return 1;
}
if (pipe (c2ppipe) == -1) { /* connect std input to std output via a pipe */
perror("Failed to create c2ppipe pipe");
return 1;
}

fprintf(stderr, "(%d)\n", 200) ;
for (i = 1; i < nprocs; i++) { /* create the remaining processes */
if (pipe (p2cpipe) == -1) {
fprintf(stderr, "[%ld]:failed to create p2cpipe pipe %d: %s\n",
(long)getpid(), i, strerror(errno));
return 1;
}
if (pipe (c2ppipe) == -1) {
fprintf(stderr, "[%ld]:failed to create c2ppipe pipe %d: %s\n",
(long)getpid(), i, strerror(errno));
return 1;
}

fprintf(stderr, "(%d)\n", 214) ;
switch (childpid = fork()) {
case -1: /* fork failed. */
{
fprintf(stderr, "[%ld]:failed to create child %d: %s\n",
(long)getpid(), i, strerror(errno));
return 1;
}
case 0: /* inside child process. */
c2p(p2cpipe, c2ppipe, i); /* line 'A' */
/* NOT REACHED */
default: /* inside parent process. */
{
wait(NULL) ;
p2c(c2ppipe, p2cpipe, i); /* line 'B' */
}
/* NOT REACHED */
}
}

fprintf(stderr, "(%d)\n", 231) ;
fprintf(stderr,"\n");
return 0;
}
[rbarakX@ROSH005 /tmp/ring]$ ##########################################################
[rbarakX@ROSH005 /tmp/ring]$ ##### executing the "two ways pipe" program with 3 processes #####
[rbarakX@ROSH005 /tmp/ring]$ ##### Note the two errors: "write: Bad file descriptor", and #####
[rbarakX@ROSH005 /tmp/ring]$ ##### Broken pipe, and as consqunce, the output of only one #####
[rbarakX@ROSH005 /tmp/ring]$ ##### output block, namely: #####
[rbarakX@ROSH005 /tmp/ring]$ ##### This is process 1 with ID 1264 and parent id 1896 #####
[rbarakX@ROSH005 /tmp/ring]$ ##### 1264 #####
[rbarakX@ROSH005 /tmp/ring]$ ##########################################################
[rbarakX@ROSH005 /tmp/ring]$ ./two_way_pipes_ring 3
(190)
(200)
(214)
(112) start: c2p
(124) c2p
(137) c2p
(140) c2p: i=0 ; k=1 ; ID_list[0]=1264
(142) c2p: k=0 ; buf=|1264|
(150) c2p

This is process 1 with ID 1264 and parent id 1896
ID array:
1264(168) c2p

(165) c2p
(38) start: p2c
(63) c2p
(66) c2p: i=0 ; k=1 ; ID_list[0]=1264
(70) p2c: k=0 ; buf=|1264| ; rc=-1
(73 error) p2c: write: Bad file descriptor
(38) start: p2c
(63) c2p
(66) c2p: i=0 ; k=1 ; ID_list[0]=1896
Broken pipe
[rbarakX@ROSH005 /tmp/ring]$
[rbarakX@ROSH005 /tmp/ring]$
1 REPLY 1
Ron Barak
Advisor

Re: Pipes' program problem

Hi,

I moved the wait(NULL) to the p2c function, and now I don't get the errors, but the pipes still don't move the data as they should. Below is the changed program and its output.

Bye,
Ron.
---------------------------------
[rbarakX@ROSH005 /tmp/ring]$ cat two_way_pipes_ring_2.c
#include
#include
#include
#include
#include
#include
#include
#include /* defines isascii(), toupper(), and other */
/* character manipulation routines. */

/* function executed by the user-interacting process. */
int p2c(int input_pipe[], int output_pipe[], int i)
{
int rc; /* return values of functions. */
int error; /* return value from dup2 call */
int k; /* counter of ID array */
int nprocs; /* total number of processes in ring */
int icount; /* iteration count */
char buf[BUFSIZ]; /* input buffer */
int next_ID; /* next process id */
int *ID_list; /* pointer to list of process id's */
ssize_t nbytes ;
size_t mybufsize ;

fprintf(stderr, "(%d) start: p2c \n", 38) ;
/* first, close unnecessary file descriptors */
close(input_pipe[1]); /* we don't need to write to this pipe. */
close(output_pipe[0]); /* we don't need to read from this pipe. */


icount = i; /* save which iteration this is - in a global */
if (NULL == (ID_list = malloc(i * sizeof(int) ))) {
perror("Out of memory!");
exit(2);
}
ID_list[0] = next_ID = getpid();

/* read data from this process's parent... */
for (k = 1; k < icount; ++k) {
// rc = (int)fgets(buf, sizeof (buf), (FILE *)input_pipe[0]);
rc = read(input_pipe[0], buf, BUFSIZ);
if (rc <= 0) { /* fgets failed */
perror("p2c: read");
close(input_pipe[0]);
close(output_pipe[1]);
exit (1);
}
next_ID = ID_list[k] = atoi(buf);
}

fprintf(stderr, "(%d) c2p \n", 63) ;
/* a parent sends data to its child process */
for (k = 0; (icount != nprocs) && (k < icount); ++k) {
fprintf(stderr, "(%d) c2p: i=%d ; k=%d ; ID_list[%d]=%d\n", 66,k,i,k,ID_list[k]) ;
sprintf(buf, "%d\0", ID_list[k]) ;
mybufsize = (size_t)strlen(buf) ;
nbytes = write(output_pipe[1], (void *)buf, mybufsize);
fprintf(stderr, "(%d) p2c: k=%d ; buf=|%s| ; rc=%d\n", 70,k,buf,rc) ;
fflush(NULL); /* flushing output so child could get input */
if ((int)nbytes == -1) { /* fprintf failed */
perror("(73 error) p2c: write");
close(input_pipe[0]);
close(output_pipe[1]);
exit (1);
}
fflush(NULL); /* flushing output so child could get input */
}

/* and then wait for the child to expire */
wait(NULL) ;
/* say hello to the world */
fprintf(stderr, "\nThis is process %d with ID %ld and parent id %ld\nID array: ",
i, (long)getpid(), (long)getppid());

for (k = 0; k < icount; ++k) {
fprintf(stderr,"%c%d", k % 10 ? ' ' : '\n', ID_list[k]);
}

/* close pipes and return. */
close(input_pipe[0]);
close(output_pipe[1]);
fprintf(stderr,"\n");
return (0);

}

/* now comes the function executed by the translator process. */
int c2p(int input_pipe[], int output_pipe[], int i)
{
int rc; /* return values of functions. */
int error; /* return value from dup2 call */
int k; /* counter of ID array */
int nprocs; /* total number of processes in ring */
int icount; /* iteration count */
char buf[BUFSIZ]; /* input buffer */
int next_ID; /* next process id */
int *ID_list; /* pointer to list of process id's */
ssize_t nbytes ;
size_t mybufsize ;


fprintf(stderr, "(%d) start: c2p \n", 112) ;
/* first, close unnecessary file descriptors */
close(input_pipe[0]); /* we don't need to read from this pipe. */
close(output_pipe[1]); /* we don't need to write to this pipe. */

icount = i; /* save which iteration this is - in a global */
if (NULL == (ID_list = malloc(i * sizeof(int) ))) {
perror("Out of memory!");
exit(2);
}
ID_list[0] = next_ID = getpid();

fprintf(stderr, "(%d) c2p \n", 124) ;
/* read data from this process's parent... */
for (k = 1; k < icount; ++k) {
rc = read(output_pipe[0], buf, BUFSIZ);
// rc = (int)fgets(buf, sizeof (buf), (FILE *)output_pipe[0]);
fprintf(stderr, "(%d) c2p: k=%d ; buf=|%s| ; rc=%d\n", 130,k,buf, rc) ;
if (rc <= 0) { /* fgets failed */
perror("c2p: read");
close(input_pipe[1]);
close(output_pipe[0]);
exit (1);
}
next_ID = ID_list[k] = atoi(buf);
}

fprintf(stderr, "(%d) c2p \n", 137) ;
/* a parent sends data to its child process */
for (k = 0; (icount != nprocs) && (k < icount); ++k) {
fprintf(stderr, "(%d) c2p: i=%d ; k=%d ; ID_list[%d]=%d\n", 140,k,i,k,ID_list[k]) ;
sprintf(buf, "%d\0", ID_list[k]) ;
mybufsize = (size_t)strlen(buf) ;
nbytes = write(input_pipe[1], (void *)buf, mybufsize);
fprintf(stderr, "(%d) c2p: k=%d ; buf=|%s|\n", 142,k,buf) ;
fflush(NULL); /* flushing output so child could get input */
if ((int)nbytes == -1) { /* fprintf failed */
perror("(144 error) c2p: write");
close(input_pipe[1]);
close(output_pipe[0]);
exit (1);
}
fflush(NULL); /* flushing output so child could get input */
}

fprintf(stderr, "(%d) c2p \n", 150) ;
/* and then wait for the child to expire */
// wait(NULL) ;
/* say hello to the world */
fprintf(stderr, "\nThis is process %d with ID %ld and parent id %ld\nID array: ",
i, (long)getpid(), (long)getppid());

for (k = 0; k < icount; ++k) {
fprintf(stderr,"%c%d", k % 10 ? ' ' : '\n', ID_list[k]);
}
fprintf(stderr, "(%d) c2p \n", 168) ;

/* close pipes and return. */
close(input_pipe[1]);
close(output_pipe[0]);
fprintf(stderr,"\n");
fprintf(stderr, "(%d) c2p \n", 165) ;
return (0) ;
}



int main(int argc, char *argv[ ]) {
pid_t childpid; /* indicates process should spawn another */
int error; /* return value from dup2 call */
int writepipe[2]; /* parent -> child */
int readpipe [2]; /* child -> parent */
int fd[2]; /* file descriptors returned by pipe */
int i; /* number of this process (starting with 1) */
int k; /* counter of ID array */
int nprocs; /* total number of processes in ring */
int icount; /* iteration count */
char buf[BUFSIZ]; /* input buffer */
int next_ID; /* next process id */
int *ID_list; /* pointer to list of process id's */
/* 2 arrays to contain file descriptors, for two pipes. */
int p2cpipe[2];
int c2ppipe[2];
// int pid; /* pid of child process, or 0, as returned via fork. */
int rc; /* stores return values of various routines. */


/* check command line for a valid number of processes to generate */
if ( (argc != 2) || ((nprocs = atoi (argv[1])) <= 0) ) {
fprintf (stderr, "Usage: %s nprocs\n", argv[0]);
return 1;
}
fprintf(stderr, "(%d)\n", 190) ;
if (pipe (p2cpipe) == -1) { /* connect std input to std output via a pipe */
perror("Failed to create p2cpipe pipe");
return 1;
}
if (pipe (c2ppipe) == -1) { /* connect std input to std output via a pipe */
perror("Failed to create c2ppipe pipe");
return 1;
}

fprintf(stderr, "(%d)\n", 200) ;
for (i = 1; i < nprocs; i++) { /* create the remaining processes */
if (pipe (p2cpipe) == -1) {
fprintf(stderr, "[%ld]:failed to create p2cpipe pipe %d: %s\n",
(long)getpid(), i, strerror(errno));
return 1;
}
if (pipe (c2ppipe) == -1) {
fprintf(stderr, "[%ld]:failed to create c2ppipe pipe %d: %s\n",
(long)getpid(), i, strerror(errno));
return 1;
}

fprintf(stderr, "(%d)\n", 214) ;
switch (childpid = fork()) {
case -1: /* fork failed. */
{
fprintf(stderr, "[%ld]:failed to create child %d: %s\n",
(long)getpid(), i, strerror(errno));
return 1;
}
case 0: /* inside child process. */
c2p(p2cpipe, c2ppipe, i); /* line 'A' */
/* NOT REACHED */
default: /* inside parent process. */
{
// wait(NULL) ;
p2c(c2ppipe, p2cpipe, i); /* line 'B' */
}
/* NOT REACHED */
}
}

fprintf(stderr, "(%d)\n", 231) ;
fprintf(stderr,"\n");
return 0;
}
[rbarakX@ROSH005 /tmp/ring]$ two_way_pipes_ring_2 3
(190)
(200)
(214)
(38) start: p2c
(63) c2p
(66) c2p: i=0 ; k=1 ; ID_list[0]=2324
(70) p2c: k=0 ; buf=|2324| ; rc=4
(112) start: c2p
(124) c2p
(137) c2p
(140) c2p: i=0 ; k=1 ; ID_list[0]=2808

This is process 1 with ID 2324 and parent id 172
ID array:
2324
(214)
(38) start: p2c
(112) start: c2p
(124) c2p
(130) c2p: k=1 ; buf=|| ; rc=0
c2p: read: No error
p2c: read: No error
[rbarakX@ROSH005 /tmp/ring]$