[comp.unix.wizards] Pipes & Forks

jp27+@andrew.cmu.edu (Jacques Parker) (12/13/89)

I made the following program.  When compiled & run, it will accept
input, but not act on it.  It should accept commands, and the child
process should receive and execute them.  This
does not happen until the program is terminated (Enter ^D).  Any ideas? 
How do I insure that the child receives the parents output immediately?

Thank you for any help.

					Jacques Parker


#include <stdio.h>

#define MAXLEN  100
#define ST_INP	0
#define ST_OUT	1

extern char **environ;

char **arg = { "/bin/csh","-x"};

main(argc,argv,envp)
int argc;
char **argv, **envp;
{
    
    int     pd[2];
    int     pid;
    int     bak_inp = dup (ST_INP);/* Backup the input FD */
    int     bak_out = dup (ST_OUT);/* Backup the output FD */

    if (pipe(pd) < 0)
	printf("%s: Can't create pipe", cmd);

    dup2(pd[1], ST_OUT);	/* ST_OUT --> pipe WRITE */
    dup2(pd[0], ST_INP);	/* ST_INP --> pipe READ  */
    
    if ((pid = fork()) < 0)
	printf("%s: Can't spawn a process.", cmd);
    if (pid == 0) {
	dup2(bak_out, ST_OUT); 	/* child out --> ST_OUT */
				/* child in --> Pipe READ */
	execvp(arg[0],arg,environ);
	printf("Shell not started. '%s' failed.",cmd);
    }

    dup2(bak_inp,ST_INP);	/* parent out --> Pipe WRITE */
				/* parent in --> ST_INP */

    while (gets(cmd) != NULL) { /* Enter ^D to end. */
	printf("%s\n,cmd);
	fflush(NULL);
    }

}
Address: internet	jp27+@andrew.cmu.edu, 
	 uucp		...!{harvard,uunet}!andrew.cmu.edu!jp27,
         bitnet		jp27%andrew@cmccvb.bitnet.

caag@inf.rl.ac.uk (Crispin Goswell) (12/14/89)

In article <21729@adm.BRL.MIL> jp27+@andrew.cmu.edu (Jacques Parker) writes:
>
>I made the following program.  When compiled & run, it will accept
>input, but not act on it.

As listed here it did not compile at all on the systems that I have to hand.

>It should accept commands, and the child
>process should receive and execute them.  This
>does not happen until the program is terminated (Enter ^D).  Any ideas? 
>How do I insure that the child receives the parents output immediately?
>
>Thank you for any help.
>
>					Jacques Parker
>
>
>#include <stdio.h>
>
>#define MAXLEN  100
>#define ST_INP	0
>#define ST_OUT	1
>
>extern char **environ;
>
>char **arg = { "/bin/csh","-x"};

I had to replace this with:

char *arg[] = { "/bin/csh","-x",NULL };

the [] to get it to compile, and NULL to get execvp to work when it ran.

>
>main(argc,argv,envp)
>int argc;
>char **argv, **envp;
>{
>    
>    int     pd[2];
>    int     pid;
>    int     bak_inp = dup (ST_INP);/* Backup the input FD */
>    int     bak_out = dup (ST_OUT);/* Backup the output FD */

I added:

     char    cmd[BUFSIZ];

here to get it to compile. This is optimistic: the gets() does not check for
buffer overflow.

>    if (pipe(pd) < 0)
>	printf("%s: Can't create pipe", cmd);
>
>    dup2(pd[1], ST_OUT);	/* ST_OUT --> pipe WRITE */
>    dup2(pd[0], ST_INP);	/* ST_INP --> pipe READ  */
>    
>    if ((pid = fork()) < 0)
>	printf("%s: Can't spawn a process.", cmd);
>    if (pid == 0) {
>	dup2(bak_out, ST_OUT); 	/* child out --> ST_OUT */
>				/* child in --> Pipe READ */
>	execvp(arg[0],arg,environ);
>	printf("Shell not started. '%s' failed.",cmd);
>    }
>
>    dup2(bak_inp,ST_INP);	/* parent out --> Pipe WRITE */
>				/* parent in --> ST_INP */
>
>    while (gets(cmd) != NULL) { /* Enter ^D to end. */
>	printf("%s\n,cmd);

I had to add the " here:

	printf("%s\n",cmd);

>	fflush(NULL);

I had to replace this with:

	fflush (stdout);

to get the program to work.
>    }

This article probably belongs in comp.lang.c.

Name:   Crispin Goswell                   |-------|__   Informatics Department
UUCP: {... | mcvax}!ukc!rlinf!caag        |  Tea  |  | Rutherford Appleton Lab
JANET: caag@uk.ac.rl.inf                  \  Mug  /_/          Chilton, Didcot
ARPA: caag%inf.rl.ac.uk@nsfnet-relay.ac.uk \_____/           Oxon OX11 0QX, UK

"Where are you when the Sun goes down? You're so far away from me."
        - Dire Straits