[comp.sys.amiga.tech] Is there a preferred way to do popen

qix@mit-vax.LCS.MIT.EDU (Ed Puckett) (08/14/88)

In article <618@super.ORG>, rminnich@metropolis.super.org (Ronald G Minnich) writes:
> Those of you who looked at the ucompat.c file i shipped out last week
> probably noticed that among others popen was a no-op. I have not
> the faintest idea of how to make this work on Amigados without bringing
> in P:, PIPE:, or some other non-standard hack. 
>    Am i missing something? Is there a way to do popen(), within the
> bounds of a straight workbench 1.2?
> ron
How about going through the clipboard.device?  I have never done
anything with it, so the following is just speculation....

Leafing through the RKM some time after writing P:, I noticed how the
clipboard would allow "clips" (or whatever that term is) could be
posted in such a way that data were not actually written, but instead
a message would be sent to the poster when any of the data were later
read.  Then the poster would have to write the data.

This seems like a good substrate for a pipe, which is really nothing
more than a bounded-sized queue whose I/O blocks when it's full/empty.

Since I've never worked with the clipboard.device, I may have totally
misunderstood its capabilities.  But if this would work, it would
seem like the right approach to pipes.  Since the underlying format
is IFF, more than just text could be shipped around, too.

			-Ed Puckett.

darin@nova.laic.uucp (Darin Johnson) (08/17/88)

In article <618@super.ORG>, rminnich@metropolis.super.org (Ronald G Minnich) writes:
> I have not
> the faintest idea of how to make this work on Amigados without bringing
> in P:, PIPE:, or some other non-standard hack. 
>    Am i missing something? Is there a way to do popen(), within the
> bounds of a straight workbench 1.2?
> ron

Well, if you hold off until workbench 1.3, then there will be a standard
pipe-style device.  You could use the non-standard PIPE: now, and then
whenever 1.3 comes out, somewhere before the turn of the century, you
just make minor mods and recompile.  If you go and use clipboards, etc.
now, then when 1.3 comes out you'll want to convert to pipes anyway.

Of course, high on my wishlist is to have the csh modified to use the
standard 1.3 pipe, and possibly job control.  Would be great to pipe
assign, dir, etc. into more, wc, grep, etc.

Darin Johnson (...pyramid.arpa!leadsv!laic!darin)
              (...ucbvax!sun!sunncal!leadsv!laic!darin)
	"All aboard the DOOMED express!"

mlelstv@faui44.informatik.uni-erlangen.de (Michael van Elst ) (08/18/88)

In article <618@super.ORG> rminnich@metropolis.super.org (Ronald G Minnich) writes:
>Those of you who looked at the ucompat.c file i shipped out last week
>probably noticed that among others popen was a no-op. I have not
>the faintest idea of how to make this work on Amigados without bringing
>in P:, PIPE:, or some other non-standard hack. 
>   Am i missing something? Is there a way to do popen(), within the
>bounds of a straight workbench 1.2?

Hmm, you say PIPE: is a non-standard hack ? I know of several
good pipe handlers that work. Anyway, it is difficult to write
a popen() function that matches the UNIX implementation of pipes.

popen() returns two filehandles that can both be used for
input and for ouput. In usual one task then closes input and
the other closes ouput.

In AmigaDOS you have to determine which of the two file handles
is for input and which of them is for output as no pipe-handler
that I know of has the ability of writing to the input side
and vice versa.

Another possibility for pipes (or at least pipy behaviour)
is the clipboard.device.
You can POST data blocks (that are not copied) and Wait until
someone has read your block. You may exit your program, then
the device copies your buffer to disk so that the other task
can read it even then.

				Michael van Elst

E-mail: UUCP: ...seismo!unido!fauern!faui44!mlelstv
E-mail: UUCP: ...uunet!unido!fauern!faui44!mlelstv	<- when seismo ceases
							   operation

jesup@cbmvax.UUCP (Randell Jesup) (08/22/88)

In article <601@faui44.informatik.uni-erlangen.de> mlelstv@faui44.UUCP (Michael van Elst) writes:
>In AmigaDOS you have to determine which of the two file handles
>is for input and which of them is for output as no pipe-handler
>that I know of has the ability of writing to the input side
>and vice versa.

	AmigaDos per se doesn't care.  It's all the handlers business.

	It can be done, the internal implementation may well be two
pipe structures, one for each direction (this becomes more like a socket).
I did one such for my shell, though it has a few problems (like it
kills the CLI info command, due to not handling the packets correctly).

	When (or if) I ever release my shell, I'll fix it.  It also allows
specifying the buffer size on open, and allows multiple readers/writers
(if specified on the open).

	There are a nunber of PD pipes out there, grab one and modify to add
whatever you want.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

rminnich@super.ORG (Ronald G Minnich) (08/22/88)

In article <601@faui44.informatik.uni-erlangen.de> mlelstv@faui44.UUCP (Michael van Elst) writes:
>Hmm, you say PIPE: is a non-standard hack ? I know of several
Sorry, i did not realize how bad that might sound. 
I very much like the variours P[IPE]: devices that have been shipped, 
but they are not part of a standard 1.2 distribution. 
I was wondering if there was a simple mechanism that 
exists in 1.2 that would do for popen().
>popen() returns two filehandles that can both be used for
>input and for ouput. In usual one task then closes input and
>the other closes ouput.
No, you are thinking of pipe(). Read the manual for popen().
It only returns a read or a write FILE *.
> ... mentions clipboard ...
I will look at it again. Has anybody used clipboard.device yet?
I have not seen it used. maybe it is time to write clip:
as Peter keeps telling us.
   Only problem is my docs for clipboard.device are all 1.1 ...
ron

phil@titan.rice.edu (William LeFebvre) (08/23/88)

In article <601@faui44.informatik.uni-erlangen.de> mlelstv@faui44.UUCP (Michael van Elst) writes:
>In article <618@super.ORG> rminnich@metropolis.super.org (Ronald G Minnich) writes:
>>...
>>   Am i missing something? Is there a way to do popen(), within the
>>bounds of a straight workbench 1.2?
>
>Hmm, you say PIPE: is a non-standard hack ? I know of several
>good pipe handlers that work. Anyway, it is difficult to write
>a popen() function that matches the UNIX implementation of pipes.
>
>popen() returns two filehandles that can both be used for
>input and for ouput. In usual one task then closes input and
>the other closes ouput.

Eh?!?  Which weird Unix are you using?  On every Unix I've ever used,
popen returns ONE (that's 1) file stream pointer ("FILE *").  It is opened
for either read *OR* write, but never both.  Popen takes two arguments:
the command to execute and the "type" which is either "r" for reading *OR*
"w" for writing.

The official and documented semantics for a Unix pipe (as defined by the
pipe(2) manual page) are ONE-WAY.  Pipe creates two file descriptors:  one
for reading ONLY and one for writing ONLY.  Those are the *documented*
semantics.  Some versions of Unix (such as BSD) implemented pipes as just
another form of network sockets.  So it turned out that the descriptors
were two ends of a complete socket and both could be read and written.
But a Unix program cannot rely on that peculiarity.  If it does, it is
wrong!

However, there is something else about popen that is hard to implement:
file descriptor sharing.  The child created by popen shares all the
parent's files (except for the pipe, of course) including standard in,
out, and error.  So popen can be used to start an input or output filter.
In order for popen to be completely correct, one would have to preserve
the "file pointer sharing":  if the child writes 10 bytes (to its
inherited standard output) then the parent writes 10 bytes (also to
standard out), the file should have 20 bytes, not 10.  But this difficulty
has nothing to do with pipes:  this requires emulating the semantics of
"dup" and "dup2".

			William LeFebvre
			Department of Computer Science
			Rice University
			<phil@Rice.edu>

hawes@dino.ulowell.edu (Bill Hawes) (08/24/88)

With regard to pipe devices and a popen() function on the Amiga:

There's an extremely easy way to implement a popen() function, using the
PIP: handler built into ConMan.  What, you didn't know ConMan was a pipe
handler, as well as a CON:, CNC:, RAW:, and soon others?  Well, you never
asked ...

To implement a popen(), just do the following:
  (1) Allocate a FileHandle structure, using the usual DOS memory convention

  (2) Call Open("PIP:",2000L) to get one filehandle

  (3) Copy the filehandle from the Open() to the one you allocated, keeping
      all the usual things in mind (BPTRs, you know)

The two filehandles can now be returned to the user, and should eventually
be Close()d when you're done.  AmigaDOS filehandles work for both reading
and writing.

The PIP: handler must be mounted before using (with the mountlist entry
included with ConMan).  The default pipe size is 4000 bytes, and can be
sized by specifying a byte count when you open it (e.b. PIP:10000).

One more trick/trap:  the AmigaDOS Close() function automatically flushes
BCPL buffers if the filehandle wasn't opened as MODE_NEWFILE, as the pipe
filehandle wasn't.  Therefre, if you've used the pipe with BCPL programs
(unlikely unless you're a command shell), you have to make sure the
filehandle buffer looks empty before closing it, or you'll get a deadlock
if the pipe is blocked at the time.  The buffer will look empty if you
set fh_Pos = 0 before closing.

Have fun, and let me know how it works out.

   Bill Hawes (ConMan author)