User: Password:
|
|
Subscribe / Log in / New account

What's the problem?

What's the problem?

Posted Oct 27, 2010 22:23 UTC (Wed) by foom (subscriber, #14868)
In reply to: What's the problem? by michaeljt
Parent article: Ghosts of Unix Past: a historical search for design patterns

Yeah, if you want to talk about crazy APIs, sendmsg/recvmsg pretty are pretty far out there.


(Log in to post comments)

What's the problem?

Posted Oct 28, 2010 7:54 UTC (Thu) by michaeljt (subscriber, #39183) [Link]

> Yeah, if you want to talk about crazy APIs, sendmsg/recvmsg pretty are pretty far out there.

I think I have problems with the concept of passing a file descriptor through a socket regardless of the API. It just doesn't seem to fit "into the metaphor".

What's the problem?

Posted Oct 28, 2010 11:20 UTC (Thu) by neilbrown (subscriber, #359) [Link]

I think passing file descriptors around is potentially very sensible. However I don't think much of the API that buries it deep inside sendmsg for Unix domain sockets.

I imagine that if you already had a pipe between two processes (possible using a named pipe in the filesystem) then one process could:

openat(pipefd, NULL, flags);
and the other process could notice (via a poll() message) and
accept(pipefd, ....)
and they would each get an end of a (optionally bi-directional) pipe. This pipe would be private to the two, in contrast to the named pipe which is shared by every process that opens it.

If you really wanted to pass a file descriptor, you then 'splice' the file descriptor that you to pass onto the pipe. That gives the other end direct access to your file descriptor.

What's the problem?

Posted Oct 28, 2010 11:49 UTC (Thu) by michaeljt (subscriber, #39183) [Link]

> I imagine that if you already had a pipe between two processes (possible using a named pipe in the filesystem) then one process could:
>
> openat(pipefd, NULL, flags);
>
>and the other process could notice (via a poll() message) and
>
> accept(pipefd, ....)
>
>and they would each get an end of a (optionally bi-directional) pipe. This pipe would be private to the two, in contrast to the named pipe which is shared by every process that opens it.

Pardon me if I am being dense here, but isn't that roughly what Unix domain sockets do?

> If you really wanted to pass a file descriptor, you then 'splice' the file descriptor that you to pass onto the pipe. That gives the other end direct access to your file descriptor.

If we are talking about something accessible through the filesystem then surely either a process is allowed to open it (in which case they can be given permissions to do so) or they are not (in which case, well, they shouldn't be). I know there are edge cases like processes which grab a resource and drop privileges, but in that case permission to access the resource is tied to the fact that only a given process binary will manipulate it, and I don't know if you really gain much through passing it through a pipe or a socket instead, as you would need to add lots of extra security checks anyway to be sure you were really talking to that binary (so to speak).

What's the problem?

Posted Oct 28, 2010 14:35 UTC (Thu) by nix (subscriber, #2304) [Link]

Yes, this is just like Unix-domain sockets. Neil's point is that the Unix-domain socket API is needlessly clumsy for this application: his proposed API would be much better (only nobody would use it for years if implemented, because it's Linux-specific).

What's the problem?

Posted Nov 7, 2010 0:17 UTC (Sun) by kevinm (guest, #69913) [Link]

Splicing the file descriptor doesn't have the same semantics. With a passed file descriptor, the original process can exit, and the recipient process will still have the file open.

The most valuable part of the file descriptor interface is the sane, well-defined object lifetimes.

What's the problem?

Posted Nov 15, 2010 11:48 UTC (Mon) by rlhamil (guest, #6472) [Link]

On some systems, pipe(fds) is equivalent to socketpair(AF_UNIX,SOCK_STREAM,0,fds),
in which case one could pass an fd (using the ugly and obscure semantics for doing so over
an AF_UNIX socket) over a pipe.

On some other systems, a pipe is STREAMS based, and STREAMS has its own mechanism
for passing fds over STREAMS pipes. Moreover, an anonymous STREAMS pipe can be given
a name in the filesystem namespace (something distinct from a regular named pipe), and
can have the connld module pushed onto it by the "server" end, in which case each client
opening the named object gets a private pipe to the server, and the server is notified
that it can receive a file descriptor for that. In turn, client and server could then pass other
file descriptors over the resulting private pipe.

(On Solaris, pipe() is STREAMS based; but one can write an LD_PRELOADable object
that redefines pipe() in terms of socketpair(), and most programs that don't specifically
depend on STREAMS pipe semantics won't know the difference.)

Unfortunately, STREAMS is far from universal. As a networking API, it's less popular than
sockets, and as a method of implementing a protocol stack, unless there are shortcuts between
for example IP and TCP, it's not efficient enough for fast (say 1Gb and faster) connections.
But for local use, it's still pretty flexible where available.

For performance, some systems do not implement pipes as either socketpair() or STREAMS.
(I just looked at Darwin 10.6.4; the pipe() implementation was changed away from
socketpair() allegedly for performance, and may not even be bidirectional anymore,
although a minimal few ioctls are still supported, but not fd passing.)

As for other abstractions not often thought of with a file descriptor, let me recall
Apollo Domain OS. Its display manager "transcript pads" IIRC had a presence in the
filesystem namespace. And although on one level they were like a terminal, on another,
although they were append-only, one could for all practical purposes seek backward into
them, equivalent to scrolling back. Moreover, certain graphics modes were permitted
within such a pad, and would actually be replayed when scrolled back to! In addition to that,
files in Domain OS were "typed": they had type handlers that could impose particular record
semantics, or even encapsulate version history functions (their optional DSEE did that,
and was the direct ancestor of ClearCase). More conventional interpretations were possible;
they'd always had type "uasc" (unstructured byte stream), although it had a hidden header
which threw off some block counts; a later "unstruct" type gave more accurate sematics of
a regular Unix file. They could also do some neat namespace tricks: some objects that
weren't strictly directories could nevertheless choose to deal with whatever came after them
in a pathname. So if one opened /path/to/magic/thingie/of/mine, it's possible that
/path/to/magic was in some sense a typed file rather than a system-supported directory,
but could choose to allow as valid that a residual path was passed to it, in which case
it would be implicitly handed thingie/of/mine as something it could use to determine the
initial state it was to provide to whatever opened it. _Very_ flexible! Only some of the
abstractions that Plan 9 (or the seldom-used HURD) promise came close to what
Domain OS could do. If I felt like adding something to my collection, a


Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds