Are STREAMS-based pipes available on FreeBSD?

Hi,

I read about passing files descriptors using STREAM-based pipes in Chapter 17 of "Advanced Programming in the Unix Environment" by W. Richard Stevens.

Are STREAMS-based pipes available on FreeBSD? Is it possible to pass file descriptor using pipe or named-pipe instead of Unix Domain Socket?

Thanks.
 
ta0kira said:
Will socketpair with SOCK_STREAM do what you're looking for?

Kevin Barry

I need to have a named-pipe or socket in the file system. One process will listen for file descriptors using it. Another process will open it and will write a file descriptor. I would like to avoid this listen()/accept()/connect() bussines associate with Stream Unix Domian Socket as it's unecessary. That's why I thought about named-pipe.

Maybe datagram Unix Domain Socket is the way to go?

Thanks Kevin.
 
pietrasm said:
I need to have a named-pipe or socket in the file system. One process will listen for file descriptors using it. Another process will open it and will write a file descriptor. I would like to avoid this listen()/accept()/connect() bussines associate with Stream Unix Domian Socket as it's unecessary. That's why I thought about named-pipe.

Maybe datagram Unix Domain Socket is the way to go?

Thanks Kevin.

Datagram does not provide a stream interface, every datagram packet has to have it's own context while stream packets share same context. 'listen()/accept()/connect()' define a context for a stream so they are kinda necessary unless you are looking for just 'one on one' stream interface, then sockets are not what you need exactly but should use anyways as this is most portable solution since FreeBSD does not have the POSIX spipes implemented.

Most software that I know off that requires such behavior use stream sockets or some d-bus like interface to establish stream between different apps.
 
expl said:
Datagram does not provide a stream interface, every datagram packet has to have it's own context while stream packets share same context. 'listen()/accept()/connect()' define a context for a stream so they are kinda necessary unless you are looking for just 'one on one' stream interface, then sockets are not what you need exactly but should use anyways as this is most portable solution since FreeBSD does not have the POSIX spipes implemented.

Most software that I know off that requires such behavior use stream sockets or some d-bus like interface to establish stream between different apps.

So it's not possible to pass a file descriptor using Datagram Unix Domian Socket? It's going to be only one-to-one unidirectional communication.

Thanks.
 
pietrasm said:
So it's not possible to pass a file descriptor using Datagram Unix Domian Socket? It's going to be only one-to-one unidirectional communication.

Thanks.

You can, but its not going to be a 'stream', meaning that you should not depend on order of arrival and you need to track origin for every packet. But since this will run on a local system you should receive them in order and if you only expect a single client, packet origin is not important either. So I guess it should be alright for your case.
 
expl said:
You can, but its not going to be a 'stream', meaning that you should not depend on order of arrival and you need to track origin for every packet. But since this will run on a local system you should receive them in order and if you only expect a single client, packet origin is not important either. So I guess it should be alright for your case.

Great, order of packets isn't important in this case. The only issue I can see now is how to decide when to close file descriptor on sending side?

From send(2) man page:
Because sendmsg() does not necessarily block until the data has been
transferred, it is possible to transfer an open file descriptor across an
AF_UNIX domain socket (see recv(2)), then close() it before it has actu-
ally been sent, the result being that the receiver gets a closed file
descriptor. It is left to the application to implement an acknowledgment
mechanism to prevent this from happening.

Many thanks.
 
I guess you could have bi-directional communication or simply use file locks, lock the file before sending descriptor then wait for receiver to unlock it before closing.
 
expl said:
I guess you could have bi-directional communication or simply use file locks, lock the file before sending descriptor then wait for receiver to unlock it before closing.

It's a great idea with locking file. Can I use for this purpose socket file?

Thanks.
 
pietrasm said:
I need to have a named-pipe or socket in the file system. One process will listen for file descriptors using it. Another process will open it and will write a file descriptor.
I don't really understand reading and writing file descriptors. Are you talking about reading from and writing to file descriptors, or are you talking about a means to communicate an actual descriptor identifier between processes? If it's the latter, does the receiver of the descriptor inherit it and just needs to know which of it's many descriptors is the proper one?

I agree that it's a pain to work with Unix sockets, which is why I essentially copy and paste the same socket/bind/listen routine every time I need it in a new project. Once you have that working, though, it really doesn't take any work to maintain it. If you only need one-way communication then a named pipe seems like a simple-enough solution.

Kevin Barry
 
ta0kira said:
I don't really understand reading and writing file descriptors. Are you talking about reading from and writing to file descriptors, or are you talking about a means to communicate an actual descriptor identifier between processes? If it's the latter, does the receiver of the descriptor inherit it and just needs to know which of it's many descriptors is the proper one?

I agree that it's a pain to work with Unix sockets, which is why I essentially copy and paste the same socket/bind/listen routine every time I need it in a new project. Once you have that working, though, it really doesn't take any work to maintain it. If you only need one-way communication then a named pipe seems like a simple-enough solution.

Kevin Barry

I am talking about passing file descriptor from one process to another - not just an index to per-process file descriptor table.

I would prefer to use named-pipe but passing file descriptors is possible only using Unix Domain Socket or STREAM-based pipe.

Thanks.
 
pietrasm said:
I am talking about passing file descriptor from one process to another - not just an index to per-process file descriptor table.
It's not easy. Obviously, simply sending a file descriptor (which is really just a number) from one process to another doesn't help because each process has its own open files table (which in turn contains indexes into the system-wide open files table), so a file descriptor in one process is pretty much useless in any other process. However, I do seem to recall there's an example of how to "pass file descriptors" (so to speak) using AF_UNIX sockets (rather than the more usual AF_INET ones) in one of William Stallings' books on networking and the code for that should be available from the Web somewhere.
 
fonz said:
It's not easy. Obviously, simply sending a file descriptor (which is really just a number) from one process to another doesn't help because each process has its own open files table (which in turn contains indexes into the system-wide open files table), so a file descriptor in one process is pretty much useless in any other process. However, I do seem to recall there's an example of how to "pass file descriptors" (so to speak) using AF_UNIX sockets (rather than the more usual AF_INET ones) in one of William Stallings' books on networking and the code for that should be available from the Web somewhere.

Thanks, I know that. However, I would prefer to use named-pipe instead of PF_LOCAL socket to simplify the process. Unfortunately, it seems rather impossible because FreeBSD doesn't implements STREAM-based pipes.

Many thanks.
 
pietrasm said:
Thanks, I know that. However, I would prefer to use named-pipe instead of PF_LOCAL socket to simplify the process. Unfortunately, it seems rather impossible because FreeBSD doesn't implements STREAM-based pipes.
I use Unix sockets to let a CLI interact with a daemon, and a new connection is made every time the CLI is called. Are you doing something similar?

Like I said before it's ugly to implement, but once it's working you can pretty much ignore/reuse that code forever. One problem with both approches (named pipes and Unix sockets) is cleanup upon abnormal termination, however. It's even more ugly than socket code to set a cleanup handler for every signal that could cause the process to terminate.

Kevin Barry
 
fonz said:
It's not easy. Obviously, simply sending a file descriptor (which is really just a number) from one process to another doesn't help because each process has its own open files table (which in turn contains indexes into the system-wide open files table), so a file descriptor in one process is pretty much useless in any other process. However, I do seem to recall there's an example of how to "pass file descriptors" (so to speak) using AF_UNIX sockets (rather than the more usual AF_INET ones) in one of William Stallings' books on networking and the code for that should be available from the Web somewhere.

Examples for UNIX sockets: http://infohost.nmt.edu/~eweiss/222_book/222_book/0201433079/ch17lev1sec4.html
 
fonz said:
Bookmarked, thanks. I don't find this in network programming books very often.

Its online copy of "Advanced Programming in the UNIX® Environment: Second Edition", a popular book I must say. Not sure on how legal is to host it like this, so I would either buy it or make a copy to hard disk while it is accessible.
 
ta0kira said:
I use Unix sockets to let a CLI interact with a daemon, and a new connection is made every time the CLI is called. Are you doing something similar?

Like I said before it's ugly to implement, but once it's working you can pretty much ignore/reuse that code forever. One problem with both approches (named pipes and Unix sockets) is cleanup upon abnormal termination, however. It's even more ugly than socket code to set a cleanup handler for every signal that could cause the process to terminate.

Kevin Barry

I am trying to do something completely different. I have one server process responsible for accepting connections. Then I need to send the newly accepted connection's file descriptor to another process to handle it. However, I am not forking a new process for every connection, rather I pick a running one from the pool.

I think I am good now.

Thanks.
 
expl said:
Its online copy of "Advanced Programming in the UNIX® Environment: Second Edition", a popular book I must say. Not sure on how legal is to host it like this, so I would either buy it or make a copy to hard disk while it is accessible.

Yeah, it's a part of the book that I mentioned in my first post. However, it's seems like it is not an exact copy of the book, some text is missing but there is a whole source code.

Also, it's described in the "Unix Network Programming" by the same author.
 
expl said:
Not sure on how legal is to host it like this, so I would either buy it or make a copy to hard disk while it is accessible.
It's probably not legal. But with a bit of searching you can find lots of books on the Internet, usually as a PDF torrent. In many cases you can even find solutions manuals that way :O Perhaps something worth keeping in mind if you're an instructor/teacher/lecturer/professor.
 
Back
Top