Skip to contentSkip to conversation

How do I make a circular pipe?

DISCUSSION Rob Landley 4 participants 5 messages Apr 14, 2001 – Apr 17, 2001

lore
Share & tools
lore
#0 lore raw

How do I do the following:

# --> pppd notty | pppoe -I eth1 | --
|_________________________________|

I.E. connect the stdout of a process (or chain thereof) to its own stdin?

So I wrote a program to do it, along the lines of:

sixty-nine /bin/sh -c "pppd notty | pppoe -I eth1"

With an executable approximately along the lines of (warning, pseudo-code, the other machine isn't hooked up to the internet at the moment for obvious reasons):

int main(int argc, char *argv[], char *envp[]) {
int fd[2];
pipe(fd);
dup2(fd[0],0);
dup2(fd[0],1);
execve(argv[1],argv+1,envp); fprintf(stderr,"Bad.\n");
exit(1);
}

And it didn't work. I made a little test program that writes to stdout and reads from stdin and reports to stderr, and it gets nothing. Apparently, the pipe fd's evaporate when the process does an execve.

What do I do? (If anybody else knows an easier way to get pppoe working, that would be helpful too.

Rob

(P.S. WHY does pppd want to talk to a tty by default instead of stdin and stdout? Were the people who wrote it at all familiar with the unix philosophy? Just curious...)

__________________________________________________
Do You Yahoo!?
Get email at your own domain with Yahoo! Mail.
http://personal.mail.yahoo.com/

#1 lore raw
Quoted 27 lines · Rob Landley

How do I do the following:

# --> pppd notty | pppoe -I eth1 | --
|_________________________________|

I.E. connect the stdout of a process (or chain thereof) to its own stdin?

So I wrote a program to do it, along the lines of:

sixty-nine /bin/sh -c "pppd notty | pppoe -I eth1"

With an executable approximately along the lines of (warning, pseudo-code, the other machine isn't hooked up to the internet at the moment for obvious reasons):

int main(int argc, char *argv[], char *envp[]) {
int fd[2];
pipe(fd);
dup2(fd[0],0);
dup2(fd[0],1);
execve(argv[1],argv+1,envp); fprintf(stderr,"Bad.\n");
exit(1);
}

Quoted 4 lines

And it didn't work. I made a little test program that writes to stdout and reads from stdin and reports to stderr, and it gets nothing. Apparently, the pipe fd's evaporate when the process does an execve.

Check out:

	#include <unistd.h>
	#include <fcntl.h>

		 /* ... */

	fcntl (fd, F_SETFD, (long) FD_CLOEXEC);

to set/reset the close on exec bit.

Quoted 2 lines

What do I do? (If anybody else knows an easier way to get pppoe working, that would be helpful too.

You might want to check out something like Stevens advanced UNIX programming, though it is probably somewhat dated :-)

Quoted 6 lines

Rob

(P.S. WHY does pppd want to talk to a tty by default instead of stdin and stdout? Were the people who wrote it at all familiar with the unix philosophy? Just curious...)

At a guess I would say that the reason is you don't have as much control with pipes as you do with devices. Under the standard termios, you can tell the system to not return from the read until either n characters have been read, or a given character such as a newline has been read. You can also switch to alternative line disciplines that are more targeted to a given application such as PPP, etc.

You probably want to check out pseudo tty's (pty's), which allow you to create your own terminal. Here is the glibc documentation, but you really should pick up a more advanced treatment of pty's, particularly for the interaction with signals, job control, etc.:

File: libc.info, Node: Allocation, Next: Pseudo-Terminal Pairs, Up:
Pseudo-Terminals

Allocating Pseudo-Terminals
---------------------------

This subsection describes functions for allocating a pseudo-terminal,
and for making this pseudo-terminal available for actual use. These functions are declared in the header file `stdlib.h'.

- Function: int getpt (void)
The getpt' function returns a new file descriptor for the next available master pseudo-terminal. The normal return value from getpt' is a non-negative integer file descriptor. In the case of an error, a value of -1 is returned instead. The following `errno' conditions are defined for this function:

`ENOENT'
There are no free master pseudo-terminals available.

This function is a GNU extension.

- Function: int grantpt (int FILEDES)
The `grantpt' function changes the ownership and access permission of the slave pseudo-terminal device corresponding to the master pseudo-terminal device associated with the file descriptor FILEDES. The owner is set from the real user ID of the calling process (*note Process Persona::), and the group is set to a special group (typically "tty") or from the real group ID of the calling process. The access permission is set such that the file is both readable and writable by the owner and only writable by the group.

On some systems this function is implemented by invoking a special setuid' root program (*note How Change Persona::). As a consequence, installing a signal handler for the SIGCHLD' signal (*note Job Control Signals::) may interfere with a call to `grantpt'.

The normal return value from grantpt' is 0; a value of -1 is returned in case of failure. The following errno' error conditions are defined for this function:

`EBADF'
The FILEDES argument is not a valid file descriptor.

`ENINVAL'
The FILEDES argument is not associated with a master pseudo-terminal device.

`EACCESS'
The slave pseudo-terminal device corresponding to the master associated with FILEDES could not be accessed.

- Function: int unlockpt (int FILEDES)
The `unlockpt' function unlocks the slave pseudo-terminal device corresponding to the master pseudo-terminal device associated with the file descriptor FILEDES. On many systems, the slave can only be opened after unlocking, so portable applications should always call `unlockpt' before trying to open the slave.

The normal return value from unlockpt' is 0; a value of -1 is returned in case of failure. The following errno' error conditions are defined for this function:

`EBADF'
The FILEDES argument is not a valid file descriptor.

`EINVAL'
The FILEDES argument is not associated with a master pseudo-terminal device.

- Function: char * ptsname (int FILEDES)
If the file descriptor FILEDES is associated with a master pseudo-terminal device, the `ptsname' function returns a pointer to a statically-allocated, null-terminated string containing the file name of the associated slave pseudo-terminal file. This string might be overwritten by subsequent calls to `ptsname'.

- Function: int ptsname_r (int FILEDES, char *BUF, size_t LEN) The ptsname_r' function is similar to the ptsname' function except that it places its result into the user-specified buffer starting at BUF with length LEN.

This function is a GNU extension.

*Portability Note:* On System V derived systems, the file returned
by the ptsname' and ptsname_r' functions may be STREAMS-based, and therefore require additional processing after opening before it actually behaves as a pseudo terminal.
therefore require additional processing after opening before it actually behaves as a pseudo terminal.

Typical usage of these functions is illustrated by the following
example:

     int
     open_pty_pair (int *amaster, int *aslave)
     {
       int master, slave;
       char *name;
     
       master = getpt ();
       if (master < 0)
         return 0;
     
       if (grantpt (master) < 0 || unlockpt (master) < 0)
         goto close_master;
       name = ptsname (master);
       if (name == NULL)
         goto close_master;
     
       slave = open (name, O_RDWR);
       if (slave == -1)
         goto close_master;
     
       if (isastream (slave))
         {
           if (ioctl (slave, I_PUSH, "ptem") < 0
               || ioctl (slave, I_PUSH, "ldterm") < 0)
             goto close_slave;
         }
     
       *amaster = master;
       *aslave = slave;
       return 1;
     
     close_slave:
       close (slave);
     
     close_master:
       close (master);
       return 0;
     }
Signature · 4 lines
Michael Meissner, Red Hat, Inc.  (GCC group)
PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886, USA
Work:	  [email protected]		phone: +1 978-486-9304
Non-work: [email protected]	fax:   +1 978-692-4482
#2 lore raw
Quoted 5 lines
Quoted 2 lines

Apparently, the pipe
fd's evaporate when the process does an execve.

Check out:

Quoted 8 lines
	#include <unistd.h>
	#include <fcntl.h>

		 /* ... */

	fcntl (fd, F_SETFD, (long) FD_CLOEXEC);

to set/reset the close on exec bit.

Cool. That's EXACTLY what I was looking for. Thanks.

Thanks also to the people who pointed out pppd's "pty" option (yes I read the docs on that, but they're a bit cryptic). And yes, my pseudo-code example used fd[0] twice. Thanks. You can stop emailing me now. :)

Quoted 3 lines

You might want to check out something like Stevens advanced UNIX programming, though it is probably somewhat dated :-)

I've got about fifteen books with names like that, but strangely in real world situations I keep trying to use the man pages instead. Sad, I know...

Quoted 4 lines

At a guess I would say that the reason is you don't have as much control with pipes as you do with devices. Under the standard termios, you can tell the system to not return from the read until either

n

Quoted 4 lines

characters have been read, or a given character such as a newline has been read. You can also switch to alternative line disciplines that are more targeted to a given application such as PPP, etc.

Hmmm. And the reason these cool toys aren't available as some kind of wrapper around a normal read-from-fd is...? (Performance?)

Quoted 2 lines

You probably want to check out pseudo tty's (pty's), which allow you to create your own terminal.

This occurred to me in the car on the way home after
five hours messing with this. (Of course. :)

Quoted 1 line

Here is the glibc documentation,

Thanks.

Info. Never thought to check info. Here I am checking linuxdoc's howtos, man pages, and google... Sigh... I don't suppose there's an info2html tool anywhere?

Well what do you know, there is. (I LIKE Google.)

http://www.cs.dartmouth.edu/~jonh/info2html/

Rob

__________________________________________________
Do You Yahoo!?
Get email at your own domain with Yahoo! Mail.
http://personal.mail.yahoo.com/

#3 lore raw
In reply to Michael Meissner
Quoted 4 lines · Rob Landley

Info. Never thought to check info. Here I am checking linuxdoc's howtos, man pages, and google... Sigh... I don't suppose there's an info2html tool anywhere?

'pinfo' can also be very useful - looks a lot like lynx, but processess info files directly.

Quoted 1 line

Well what do you know, there is. (I LIKE Google.)

They also like linux, I hear :-)

Regards,

bert

Signature · 3 lines
http://www.PowerDNS.com      Versatile DNS Services  
Trilab                       The Technology People   
'SYN! .. SYN|ACK! .. ACK!' - the mating call of the internet
#4 lore raw
In reply to Rob Landley

Can't you do it like this?

# mkfifo fifo
# pppd notty < fifo | pppoe -I eth1 >fifo
/Johan

----- Original Message -----
From: Rob Landley <[email protected]>
To: <[email protected]>
Sent: Saturday, April 14, 2001 3:05 AM
Subject: How do I make a circular pipe?

Quoted 52 lines

How do I do the following:

# --> pppd notty | pppoe -I eth1 | --
|_________________________________|

I.E. connect the stdout of a process (or chain
thereof) to its own stdin?

So I wrote a program to do it, along the lines of:

sixty-nine /bin/sh -c "pppd notty | pppoe -I eth1"

With an executable approximately along the lines of (warning, pseudo-code, the other machine isn't hooked up to the internet at the moment for obvious reasons):

int main(int argc, char *argv[], char *envp[])
{
int fd[2];
pipe(fd);
dup2(fd[0],0);
dup2(fd[0],1);
execve(argv[1],argv+1,envp);
fprintf(stderr,"Bad.\n");
exit(1);
}

And it didn't work. I made a little test program that writes to stdout and reads from stdin and reports to stderr, and it gets nothing. Apparently, the pipe fd's evaporate when the process does an execve.

What do I do? (If anybody else knows an easier way to get pppoe working, that would be helpful too.

Rob

(P.S. WHY does pppd want to talk to a tty by default instead of stdin and stdout? Were the people who wrote it at all familiar with the unix philosophy? Just curious...)

__________________________________________________
Do You Yahoo!?
Get email at your own domain with Yahoo! Mail.
http://personal.mail.yahoo.com/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/