1

consider the following:

  1. a parent process with a child
  2. child runs another program using exec system call
  3. parent and child communicating through a bi-directional pipe(named MAINPIPE in rest)
  4. the child is a server binding on a port(e.g. 5000)

my program should work as follows:

if child receives a certain message from a client create another bi-directional pipe to his parent and send/receive some info.

the problem is:

when I create a pipe in the child (using pipe()) and pass the file descriptors to the parent (using MAINPIPE), parent gets "Bad file descriptor" error message when trying to read from pipe.

any idea?

EDIT:

guys,

my problem isn't passing file-desciptors of new pipe -that is created in child process- to parent, i've already done that using MAINPIPE,

but problem is : parent can't read from new pipe, got this error message "bad file descriptor" it seems that the file descriptors is closed in parent process!

user1711001
  • 73
  • 1
  • 8

3 Answers3

3

Create the pipes before forking. Then the pipes are available in both the parent and child. No need to pass file descriptors around.

Here is a link to a library using unix domain sockets to send a file descriptor from child to parent:

http://gitorious.org/libancillary/libancillary

and here is the source:

http://gitorious.org/libancillary/libancillary/trees/master

You must adapt this to fit your requirements, of course.

Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • as i said my child process is a server and IF receive certain message then it should create another pipe to his parent – user1711001 Nov 06 '12 at 00:20
  • Change your work flow. Create the pipe before you fork, and send data only if you receive the message. – William Pursell Nov 06 '12 at 00:22
  • i have no idea how many clients connect to the server, the server must have one pipe for each client – user1711001 Nov 06 '12 at 00:34
  • It is normal for the parent to be the server and for it to spawn a child to process each client connection, not the other way round. Why do you need the server in the child? – William Morris Nov 06 '12 at 00:56
  • it's my OS homework,my question is can it possible to create pipes in child process between child and parent? actually, i know that the named pipe is my last solution, – user1711001 Nov 06 '12 at 01:11
  • What I have found so far is, you can pass file descriptors between processes. But the examples involve unix domain sockets as the transport medium. I haven't seen an example with named pipes. That said, I want again emphasize, that it is easier to create the pipes in the parent up front. You can create pipes between the parent and every child, if needed. – Olaf Dietsche Nov 06 '12 at 07:27
0

There is a way to send a file descriptor from the child to the parent process: you haven't said how you're trying to do it though, so I can't say why it doesn't work for you.

Note that, since you need an existing pipe to send the file descriptor over, you can just multiplex multiple logical streams over a single pipe. It's probably easier and more portable.


Edit: you still refuse to show the code you're using to send the file descriptor from the child to the parent, but this question contains some relevant discussion. Can you confirm if you're doing something similar?

Community
  • 1
  • 1
Useless
  • 64,155
  • 6
  • 88
  • 132
  • the MAINPIPE is a pipe made in parent process and, parent-child communication is OK through this pipe,when child(server) receives particular message, i create pipes in child process and pass file descriptors to parent , however, when parent want to read from newpipe,it get "bad file descriptor" error message – user1711001 Nov 06 '12 at 01:22
  • @user1711001 But HOW are you passing the file descriptor to the parent ? Are you just writing the integer to the already existing pipe ? That will not work, a pipe just deals with data transfer. – nos Nov 06 '12 at 08:35
  • @nos yeah,i just write file descriptor integer to MAINPAIPE and parent reads from , can you please explain why it wont work in seperate answer? thanks, – user1711001 Nov 06 '12 at 19:31
  • @user1711001 How would a pipe know that you wrote an int that happend to represent a file descriptor and not some other int that you e.g. calculated a square from, but happened to have the same value as an int that's a file descriptor ? pipes are designed to transfer data, not file descriptors - a pipe doesn't know or care if you're transferring an image, a line of text, or a number that happens to be the same number as a file descriptor. – nos Nov 06 '12 at 19:42
  • @nos i use my own format, for example when child process creates a new pipe send message to parent through MAINPIPE using this format=>"NEWPIPE 10 11" which 10 is read-end and 11 is write-end. when receive message in parent in this format, parent knows that 10 && 11 is file-descriptor ... – user1711001 Nov 06 '12 at 19:59
  • @nos: could you post this in a separate answer? that's completely what i was looking for, thanks nos;) – user1711001 Nov 12 '12 at 07:53
-1

A file descriptor belongs to a process. In your case the child process.

Transferring the number of a file descriptor, in your case 10, does not transfer the file descriptor itself. It just transfers the number 10. The number 10 can mean file descriptor 10 in the child process, but as a file descriptor belongs to a process, it is meaningless in the parent process. A child process only inherits the file descriptor from the parent when it was created.

Any file descriptors opened after the child is created are not shared between the parent and child.

If you need to pass the actual file descriptor to another (e.g. the parent) process, unix domain sockets have a mechanism for doing that, other posts here contains some relevant links for this.

nos
  • 223,662
  • 58
  • 417
  • 506