[comp.sys.amiga.tech] fork

koren@hpfelg.HP.COM (Steve Koren) (10/07/89)

My appologies if this has been discussed before; our site just began
subscribing to comp.sys.amiga* yesterday.  If it has been discussed,
could someone mail the thread to me?

I have two questions.  One concerns tasks, the other conserns the
console device.  I have lattice 5.02, if that matters.

I am trying to accomplish what fork() does in UNIX.  Lattice provides
forkv(), but that is not at all the same thing and won't really meet
my needs.  I need to be able to say something like this:

      if (fork()) {
         /* process 1 */
      } else {
         /* process 2 */
      }

I have found that FindTask(0) will return a pointer to a structure
that contains the address of the segment list.  I tried passing that
into CreateProc() like this:

     CreateProc("MY_PROC", 0, p->pr_SegList, 5000);
       (from memory - may not be exact!)

and then putting some code in the first segment that can tell if this is
the first or second execution of itself.  It didn't work though.  The
CreateProc() call seems to finish (when I trace it through with the
debugger), but it never gets as far as actually executing my code.  It
stops on a rts instruction , and guru's if run outside cpr.  Does anyone
know what I am doing wrong, how to fix it, or an easier/better way to
accomplish this?  I tried AddTask() too, but couldn't make that fly
either, and it involved lots of pushups to do a simple thing.

Question 2: (maybe easier!)

I'm trying to put the console device in a RAW mode, such that I can
read single characters from it without waiting for a newline.  I can
turn off buffering in Lattice, but it still waits for a newline.
I know that in Manx there is an stty() call; is there anything like that
in Lattice?  I know I can read characters via IntuiMessage events, but
it's important that I do it through the console device.  I can't find
anything about this in the Lattice manuals, other than the function
to turn off buffering.

That's all for now.  Thanks to anyone who has answers.  BTW, please no
RTFM's.  I have a bunch of Ami books, none of which say anything about
either problem.  Also, I can't find a place on the planet that has the
1.3 ROM kernel manual set.

           thanks

              - steve (koren@hpfela)

koren@hpfelg.HP.COM (Steve Koren) (10/10/89)

Here's another moderately related question on executing programs.
I need to call a program from within mine.  I've found several ways
to do this:

    1) LoadSeg, CreateProc, UnloadSeg
    2) Lattice forkv() or forkl()
    3) Lattice system()
    4) Execute()

Unfortunately they each seem to have problems.  The Lattice forkv()
call causes a GURU when it tries to execute almost anything in the c:
directory.  It also GURU's on a few other things as well - this
behaviour makes its use unacceptable.

Lattice system() call will not accept input and output file streams
to let me redirect the output or input of a command.

Execute() comes close, but I can find no way to obtain the return code
of the executed command.  The Execute() call itself always returns
-1, and IoErr() always contains zero.  I need to be able to examine the
return code.

LoadSeg, CreateProc, UnloadSeg has no apparent way to pass command line
parameters to a command.  Also, I've heard that it will also crash on
c: programs.

So, how do you do it?  There must be an easy way to execute a program
that won't crash on some programs, and will let you have the return
code back from the command, and lets you redirect I/O.

              - thanks

                  steve (koren@hpfela.HP.COM)

dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (10/11/89)

:Here's another moderately related question on executing programs.
:I need to call a program from within mine.  I've found several ways
:to do this:
:
:    1) LoadSeg, CreateProc, UnloadSeg
:    2) Lattice forkv() or forkl()
:    3) Lattice system()
:    4) Execute()

	One thing to note:  In OS1.4, all C: programs will be written
    in C.  Thus, Lattice's fork*() calls should work just fine then.

	I talked to John Toebes 'bout this.  They didn't make fork*()
    compatible w/ BCPL programs because you need to do a lot of
    unsupported structure munging to setup the global vectors right.
    So Lattice is using a more supportable method with its fork*()
    calls at the expense of BCPL compatibility.

:Unfortunately they each seem to have problems.  The Lattice forkv()
:call causes a GURU when it tries to execute almost anything in the c:
:directory.  It also GURU's on a few other things as well - this
:behaviour makes its use unacceptable.
:
:Lattice system() call will not accept input and output file streams
:to let me redirect the output or input of a command.
:
:Execute() comes close, but I can find no way to obtain the return code
:of the executed command.  The Execute() call itself always returns
:-1, and IoErr() always contains zero.  I need to be able to examine the
:return code.

	Was the Execute() return code problem going to be fixed in
    1.4?  That and properly disconnecting the console device.  Rightly,
    if RUN detects <NIL: >NIL: it ought to fill in pr_ConsoleDevice
    with a dummy console (like NULL:)

:LoadSeg, CreateProc, UnloadSeg has no apparent way to pass command line
:parameters to a command.  Also, I've heard that it will also crash on
:c: programs.

	CreateProc() has no apparent way to pass command line params
    to the command.  You need to CreateProc() to a tag that sets up 
    all the process fields properly and then there is the question of
    what to do about the CLI pointer...

:So, how do you do it?  There must be an easy way to execute a program
:that won't crash on some programs, and will let you have the return
:code back from the command, and lets you redirect I/O.
:
:              - thanks
:
:                  steve (koren@hpfela.HP.COM)

	1.4 is really comming together... it isn't vapor and developers
    have received 1.4 alpha 16 for testing... it's pretty solid.

	I think the issue will not be resolved until 1.4 comes out.

				-Matt

addison@pollux.usc.edu (Richard Addison) (10/11/89)

In article <13920001@hpfelg.HP.COM> koren@hpfelg.HP.COM (Steve Koren) writes:
>My appologies if this has been discussed before; our site just began
>subscribing to comp.sys.amiga* yesterday.  If it has been discussed,
>could someone mail the thread to me?
>
>I have two questions.  One concerns tasks, the other conserns the
>console device.  I have lattice 5.02, if that matters.
 ...
>Question 2: (maybe easier!)
>
>I'm trying to put the console device in a RAW mode, such that I can
>read single characters from it without waiting for a newline.  I can
>turn off buffering in Lattice, but it still waits for a newline.
>I know that in Manx there is an stty() call; is there anything like that
>in Lattice?  I know I can read characters via IntuiMessage events, but
>it's important that I do it through the console device.  I can't find
>anything about this in the Lattice manuals, other than the function
>to turn off buffering.
 ...
>              - steve (koren@hpfela)

I can handle that one.  In fact I had to a few years back.  Should
still work:

#/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
#Human archive.  Cut here and figure it out yourself.  :-)
#\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

/* For those of you who like prototypes: */

extern void SetConMode(long);



/* Includes needed for SetConMode: */

#include <exec/types.h>
#include <exec/exec.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>

#include <proto/exec.h>
#include <proto/dos.h>

#include <stdlib.h>
#include <stdio.h>


/* SetConMode
 *
 * This routine sets the console input mode to raw (for single character
 * input) or to cooked (passed through line editor, default).  Notice that
 * this requires AmigaDos version 1.2 or higher.
 */

void SetConMode(mode)
long mode;			/* -1: raw, 0: cooked */
{
  register struct Process *proc;
  register struct MsgPort *mp;
  register struct StandardPacket *spkt;

  proc = (struct Process *) FindTask(NULL);
  if (proc->pr_ConsoleTask)
  {
    if (mp = CreatePort(NULL,0))
    {
      if (spkt = (struct StandardPacket *)
       AllocMem(sizeof(struct StandardPacket),MEMF_CLEAR|MEMF_PUBLIC))
      {
	spkt->sp_Msg.mn_Node.ln_Name = (char *) &spkt->sp_Pkt;
	spkt->sp_Pkt.dp_Link = &spkt->sp_Msg;
	spkt->sp_Pkt.dp_Port = mp;
	spkt->sp_Pkt.dp_Type = ACTION_SCREEN_MODE;
	spkt->sp_Pkt.dp_Arg1 = mode;
	spkt->sp_Pkt.dp_Arg2 = (long) proc;
	PutMsg((struct MsgPort *) proc->pr_ConsoleTask,&spkt->sp_Msg);
	WaitPort(mp);
	(void) GetMsg(mp);
	FreeMem((char *) spkt,sizeof(struct StandardPacket));
      }
      DeletePort(mp);
    }
  }
}

/* Richard Addison, said the C program AUTHORatively. */

jesup@cbmvax.UUCP (Randell Jesup) (10/11/89)

In article <13920001@hpfelg.HP.COM> koren@hpfelg.HP.COM (Steve Koren) writes:
>I am trying to accomplish what fork() does in UNIX.  Lattice provides
>forkv(), but that is not at all the same thing and won't really meet
>my needs.  I need to be able to say something like this:
>
>      if (fork()) {
>         /* process 1 */
>      } else {
>         /* process 2 */
>      }

	Exact unix semantics are hard at best to achieve, due to the assumption
by unix of seperate address spaces.  Spawning a subroutine as a process can
be done, but be warned that it will share all you global variables, and you
DON'T want to exit before it does.

>I have found that FindTask(0) will return a pointer to a structure
>that contains the address of the segment list.  I tried passing that
>into CreateProc() like this:
>
>     CreateProc("MY_PROC", 0, p->pr_SegList, 5000);
>       (from memory - may not be exact!)

	Not good.  Your startup code (from the compiler) assumes that it is
either being started by CLI/shell or by WB.  CreateProc is neither.  You can
build a seglist that includes a jump to the routine you want to execute.

>I'm trying to put the console device in a RAW mode, such that I can
>read single characters from it without waiting for a newline.  I can
>turn off buffering in Lattice, but it still waits for a newline.
>I know that in Manx there is an stty() call; is there anything like that
>in Lattice?  I know I can read characters via IntuiMessage events, but
>it's important that I do it through the console device.  I can't find
>anything about this in the Lattice manuals, other than the function
>to turn off buffering.

	Console device or console handler?  They are different.  There is
a packet that you can send to the console handler that changes it into
raw mode.  Code for this can be found on the fish disks.

-- 
Randell Jesup, Keeper of AmigaDos, Commodore Engineering.
{uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.cbm.commodore.com  BIX: rjesup  
Common phrase heard at Amiga Devcon '89: "It's in there!"

presley@oahu.cs.ucla.edu (Matthew Presley) (09/25/90)

Is there a way to fork one program from another and
then exiting the parent program.  Basically, I want
to have one program to start another program, but
I want to be able to end the first program before
the second.

The fork command makes the parent program wait until
all the forked children return.

--
----------------------------------------------------------------
Matthew Presley (UCLA CS Grad. Student) & (JPL CS dude)
Internet (presley@cs.ucla.edu) or (matt@sapphire.jpl.nasa.gov)
"Twisted yellow puppies play loudly broken flutes..."

specter@disk.uucp (Byron Max Guernsey) (05/19/91)

Is there anyway to redirect a process i/o to the serial.device? In essence I
want to be able to do a CLI or SHELL andrun different console type programs
through the serial.device. I know there are programs to do this (like serserver)
but this is for my own program (so I need to create my own routine or find a
PD one). I don't suppose there would be any way to set the stdin, stdout, etc
in the FORKENV struct to a file associated with AUX: or SER: ??? I didn't
think so. I would rather not write another device if at all possible. 

Also, does anyone have a list of functions or docs for the req.library? (any
version would do..but the newest one is desirable) Just the dox. 

I would appreciate Mail replies but I will attempt to scan csa.tech as much
as possible. 

A budding enthusiast..

Byron Guernsey

-- 
Byron 'Maxwell' Guernsey                       |       ///  //\\
specter@disk.UUCP     or                       |      ///  //  \\
uunet!ukma!corpane!disk!specter                |  \\\///  //====\\
"Great programs aren't written, they're fathered." \\\/  //      \\ m i g a

carolyn@cbmvax.commodore.com (Carolyn Scheppner - CATS) (05/21/91)

In article <1991May19.065047.21385@disk.uucp> specter@disk.uucp (Byron Max Guernsey) writes:
>Is there anyway to redirect a process i/o to the serial.device? In essence I
>want to be able to do a CLI or SHELL andrun different console type programs
>through the serial.device.

newshell AUX: from s:aux-startup

Make a file in s: called aux-startup and
have it turn off requesters and then execute s:shell-startup.
To turn off requesters you will need a program that pokes
((struct Process *)FindTask(NULL))->pr_WindowPtr to -1.
You should be able to find canned programs to do this on
Fish Disks, etc. 

-- 
==========================================================================
 Carolyn Scheppner -- Tech. Mgr. CATS - Commodore Amiga Technical Support
 PHONE 215-431-9180 {uunet,rutgers}!cbmvax!carolyn  carolyn@commodore.com

   "Under the multitasking operating system, the trackdisk.device is
	the defied interface..."     - Bryce
==========================================================================