From: Tom Christiansen <tchrist@convex.COM>
Subject: named pipes (was: Finger and .plan, .project)
Followup-To: comp.unix.programmer
Originator: tchrist@pixel.convex.com
Keywords: named pipes, fopen, popen, .plan, .profile, .signature
Reply-To: tchrist@pixel.convex.COM (Tom Christiansen)
Organization: CONVEX Realtime Development, Colorado Springs, CO
Date: Sun, 26 Jul 1992 16:58:38 GMT
Expires: Wed, 12 Aug 1992 04:00:00 GMT
X-Disclaimer: This message was written by a user at CONVEX Computer
              Corp. The opinions expressed are those of the user and
              not necessarily those of CONVEX.

From the keyboard of Christophe.Wolfhugel@univ-lyon1.fr (Christophe Wolfhugel):
:scotth@felix.filenet.com (Scott Hopson) writes:
:> [use a named pipe]
:> You must be sure that this daemon gets started after your system
:> is rebooted or readers like "finger" will hang.
:
:You can't be sure that the daemon will still be around when someone
:will be fingering you.  It's not because you start it a boot time
:(first you need priviledge to do this) that it will still be in the
:air two days later.

You can deal with this using a moderately clever user-level cron 
entry.   Hmm... do we need a user-level rc hook, or maybe a way
to specify in cron that something should be run at boot time?

:Second, just imagine if I'd allow that to my 300+ users?  Do you really
:except a SA can tolerate 300 permanent processes for just nothing?
:
:A viable solution would be to change the fingerd to something that
:fits your need. It's as easy to do as the replacement code you have
:proposed and it has the advantage to generate one active process
:per finger!
:
:Please folks, don't use named pipes for you finger stuff, this is
:not the good approach.

     Note: I've given this a wider crossposting because I've been
     thinking about the matter for some time, and I'd like to incite
     some discussion on it.  Followups are funnelled back to one group.

It may not be the optimal approach, but is certainly one available
to the non-privileged user without modification of any system
utilities.  

I don't believe that you'd ever have all 300 of your users running
a program to service the named pipes which are their dot-plan or
dot-project files.  And if they did, what could you do to improve
this?  

What sorts of uses do people make of named pipes that they couldn't
do with files? I tend to find them an idea that's only partially
successful due to their drawbacks described several paragraphs below.

Two improvements come to mind: either run just one process all the time,
or else run per-user temporary processes that last only for the duration
of the read.

I'm not sure how to do a good named-pipe inetd.  I'd like to just
do a listen, er, select on all the pipes, and dispatch a user process
when one is opened.  But to select on them, you're going to have to
have opened then, which makes you block for someone on the other end.
Even if a workaround were found for this, you'd still have a lot
of files open, which means it might work for multiplexing 10 of
them, but almost certainly not 1000, since I don't know many
systems that support 1000 concurrently open files in one process.

For one thing, they're used as rendezvous points for communications
between unrelated processes.  If they were related, then regular,
anonymous pipes would have worked.  I've seen then used in some shells for
process redirection, although I've never quite seen why this couldn't have
been implemented using temporary files.  I'm thinking of things like

    $ diff (tail file1) (tail file2)

which sometimes is implemented using temporary named pipes, or sometimes
with the /dev/fd stuff if you're lucky enough to have it.  I'm not 
sure why on systems without either you couldn't use a regular temp file.

Named pipes also used when someone wants a program to intercept I/O calls,
allowing a file to produce more interesting output.  This is the case when
people replace their dot-plan with a pipe, for instance.  An advantage of
this method is that unlike a UNIX-domain socket, named pipes really look a
good deal like files, allowing programs that are doing normal reads or
writes (note "or" not "and") on them to function virtually transparently
when you replace them with a named pipe.

As the poster above brought up, there are some problems with this.
The main one is that you must have a PRE-EXISTING server process, or
else the client will hang until one exists.  Another problem is
that you have to know whether the pipe is intended to be read from
or written to, so that your server can open it the other way.  Yet
another problem is that having multiple readers and writers makes
for intermixed and mangled.  Still another problem is that they
don't work across NFS.  If you had a server for them on one machine,
the next machine wouldn't know.  And in fact, on some systems, you
can crash your kernel by attempting to access a remote named pipe.

At various times, I've wanted to have /etc/motd, my .signature, and my
.plan and .project be hooks to programs, not regular files.  In the case
of /etc/motd, I altered login to execute it if the execute bit is set.
For my .signature, it reads from a named pipe, which means I have to run a
program all the time. Ick, yes, but at least I didn't have to modify each
and every program that would read my .signature, of which there are a few.
That would have been even more bother.

Now, if we were running certain specialized versions of UNIX, or
reasonably UNIX-like systems, better solutions could be devised.  
With systems running with file watchdogs, it should be possible to come
up with a general solution.  I'd try it on a Convex, but the watchdog
stuff was designed by a kernel hacker, not a user-level guy, so it's
a bit cumbersome to use, and certainly not in the least bit portable.

Furthermore, I believe that under both Plan9 and SunOS that you can have a 
filesystem type that does the right thing, so if people did this:

    ln -s ~/.plan /plans/$USER

Then have /plans be a special filesystem type that triggers invocation
of the right code.

One workaround for the rest of us is to relink your code (hey, better
than modifying the kernel) such that an fopen() on a file with the
execute bit set actually does a popen() of the appropriate mode.
This still means tracking down all the programs that are going to
try to do this, unless you alter your C library.  This might be
the best solution.

What programs would break drastically if we changed the library fopen()
call to either accept "rx"/"wx" to indicate a popen(), or else for the
sake of transparency, to have it stat() the file and check for the execute
bit?  (Should we to do it for open() as well?  Probably.)  Certainly editors
would prefer the former solution, but most general purpose programs the
latter one.

--tom
-- 
    Tom Christiansen      tchrist@convex.com      convex!tchrist

"The number of UNIX installations has grown to 10, with more expected."
    - _The UNIX Programmer's Manual_, Second Edition, June, 1972.
Xref: sparky comp.unix.questions:9524 comp.unix.sysv386:12594