# Are STREAMS-based pipes available on FreeBSD?



## pietrasm (Feb 17, 2013)

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 (Feb 17, 2013)

Will socketpair with SOCK_STREAM do what you're looking for?

Kevin Barry


----------



## pietrasm (Feb 17, 2013)

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.


----------



## expl (Feb 18, 2013)

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.


----------



## pietrasm (Feb 18, 2013)

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.


----------



## expl (Feb 18, 2013)

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.


----------



## pietrasm (Feb 18, 2013)

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
> ...



Many thanks.


----------



## expl (Feb 18, 2013)

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.


----------



## pietrasm (Feb 18, 2013)

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.


----------



## ta0kira (Feb 18, 2013)

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


----------



## pietrasm (Feb 18, 2013)

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.


----------



## fonz (Feb 18, 2013)

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.


----------



## pietrasm (Feb 19, 2013)

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.


----------



## ta0kira (Feb 19, 2013)

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


----------



## expl (Feb 19, 2013)

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 (Feb 19, 2013)

expl said:
			
		

> Examples for UNIX sockets: http://infohost.nmt.edu/~eweiss/222_book/222_book/0201433079/ch17lev1sec4.html


Bookmarked, thanks. I don't find this in network programming books very often.


----------



## expl (Feb 19, 2013)

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.


----------



## pietrasm (Feb 19, 2013)

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.


----------



## pietrasm (Feb 19, 2013)

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.


----------



## fonz (Feb 19, 2013)

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.


----------

