pipe() dup2() fork() execl() select()

P

PC

Is it possible to create pipe()s (stdin/stdout) for a child process
and forking a shell with execl() and controlling the shell's
stdin/stdout from the parent with select()?
Heres a little snippet of code. it doesnt actually work.. but it is
how I envisioned it::

if((n=accept(s,(struct sockaddr *)&remote,&sz))==-1)
{printf("accept\n"); exit(0);}
close(0); close(1); close(2);
pipe(&i[0]);
dup2(0,i[0]);
dup2(1,i[1]);
dup2(n,i[0]);
dup2(n,i[1]);
if(!fork()) {
execl("/bin/sh","sh",0); close(n); exit(0); }
FD_ZERO(&rd); FD_ZERO(&wr);
FD_SET(0,&rd); FD_SET(1,&wr);
select(i[1]+1,&rd,&wr,0,0);
while(1) {
if(FD_ISSET(0,&rd)) { read(0,wb,1); }
if(FD_ISSET(1,&wr)) { read(1,wb,1); }
}}


I want the client's interaction (connecting via telnet) to work via
select. This is because, later I will add blowfish encryption routines
within FD_ISSET() Which will be encrypting/decrypting stdin/stdout of
the child process.

Am I headed in the right direction by using the functions I have?
Thanks in advance
PC
 
A

Artie Gold

Artie said:
PC said:
Is it possible to create pipe()s (stdin/stdout) for a child process
and forking a shell with execl() and controlling the shell's
stdin/stdout from the parent with select()?


Hold it right there!

None of the functions to which you are referring are part of standard C,
making your question off topic here (would be
an appropriate place).

A piece of advice -- when posting code to usenet it is a good idea to:

include the smallest possible compilable
snippet that exhibits the problem[1]

indent appropriately

specify what you think should be happening
and what is happening instead (annotations
within the code isn't a bad idea either)

All this is to enhance the probability of someone who knows the answer
actually spending the time to help.

One more piece of advice -- please read the FAQ, at:

http://www.eskimo.com/~scs/C-faq/top.html

before posting here again. It's really for your benefit.
Heres a little snippet of code. it doesnt actually work.. but it is
how I envisioned it::

if((n=accept(s,(struct sockaddr *)&remote,&sz))==-1)
{printf("accept\n"); exit(0);}
close(0); close(1); close(2);
pipe(&i[0]);
dup2(0,i[0]);
dup2(1,i[1]);
dup2(n,i[0]);
dup2(n,i[1]);


These last four lines can't be correct. Notice that you're immediately
overwriting the values in `i'.
if(!fork()) {
execl("/bin/sh","sh",0); close(n); exit(0); } FD_ZERO(&rd); FD_ZERO(&wr);
FD_SET(0,&rd); FD_SET(1,&wr);
select(i[1]+1,&rd,&wr,0,0); while(1) {
if(FD_ISSET(0,&rd)) { read(0,wb,1); }
if(FD_ISSET(1,&wr)) { read(1,wb,1); }
}}


I want the client's interaction (connecting via telnet) to work via
select. This is because, later I will add blowfish encryption routines
within FD_ISSET() Which will be encrypting/decrypting stdin/stdout of
the child process.

Am I headed in the right direction by using the functions I have?


<OT>
Erm...
You're headed in the right direction, but you have fundamental
misunderstandings about how some things work. Reread whatever reference
you're using, think about it, and wander over to c.u.p if you run into
trouble.
</OT>

HTH,
--ag

I forgot my footnote:
[1] Of course that's not always possible, particularly if you're trying
to track down a syntax error. But even then...
 
J

Jens Schicke

PC said:
if((n=accept(s,(struct sockaddr *)&remote,&sz))==-1)
{printf("accept\n"); exit(0);}
close(0); close(1); close(2);
pipe(&i[0]);
dup2(0,i[0]);
dup2(1,i[1]);
dup2(n,i[0]);
dup2(n,i[1]);
if(!fork()) {
execl("/bin/sh","sh",0); close(n); exit(0); }
FD_ZERO(&rd); FD_ZERO(&wr);
FD_SET(0,&rd); FD_SET(1,&wr);
select(i[1]+1,&rd,&wr,0,0);
while(1) {
if(FD_ISSET(0,&rd)) { read(0,wb,1); }
if(FD_ISSET(1,&wr)) { read(1,wb,1); }
}}

As already stated that is OT in comp.lang.c...

<OT>
You made a lot of error as I see it...

1. pipe() will create a pair of filedescriptors which _together_ form
_one_ pipe - you have to use pipe() two times for pipes are by
definition only useable in one direction.

2. dup2(n, i[0]) closes n and reopens it as i[0], but you still need the
socket filedescriptor, so remove the dup2(n... lines

3. select should be called inside a loop in order to react each time new
data becomes available.

4. in the select loop, if data becomes available copy it from the pipe
to the socket or the other way around.
</OT>
 
P

PC

You made a lot of error as I see it...

1. pipe() will create a pair of filedescriptors which _together_ form
_one_ pipe - you have to use pipe() two times for pipes are by
definition only useable in one direction.

2. dup2(n, i[0]) closes n and reopens it as i[0], but you still need the
socket filedescriptor, so remove the dup2(n... lines

3. select should be called inside a loop in order to react each time new
data becomes available.

4. in the select loop, if data becomes available copy it from the pipe
to the socket or the other way around.
</OT>
Thanks for clearing things up
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Communicating between processes 0
C pipe 1
conveyor non-stop 3
'execl' query 7
make a pipe perl2C 2
fork() & pipe() 3
Server/Client infinite loop problem 3
UDP + select problem 2

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top