[comp.sys.amiga.tech] problems with forkv

bader+@andrew.cmu.edu (Miles Bader) (11/28/88)

Despite many re-readings of the manual section, and talking to
lattice technical support, I STILL can't forkv to work as advertised.
At the end of this mesage is a short program illustrating my
problems.  I would be extremely grateful if anyone can point out any
reasons why it doesn't work...

Thanks, -Miles

/* fail.c
 *
 * This program illustrates the problems I'm having with forkv:
 *   1) It doesn't use the search path as the manual claims; you have
 *      to give an explicit path to the program you want to run, when
 *      cli can find the same program as long its in a directory in your
 *      path.
 *   2) The program guru's 100% of the time, both when USESTDIO is defined
 *      or not.  Examination of all the arguments to the forkv call at
 *      run time doesn't give any clues due to bad arguments.
 *
 * Compile with:
 *     lc -L fail.c
 * OR  lc -L -dUSESTDIO fail.c
 *
 * It seems to occur no matter which program you use.  The following 
 * gurus, for instance (avail is a 1.3 program that lists availabe memory):
 *      fail ram:output c:avail
 *
 * The behavior is the same under both versions 4.1 and 5.0 of Lattice-C.
 */

#include <stdio.h>
#include <dos.h>
#include <proto/dos.h>
#include <ios1.h>

main(argc,argv)
int argc;
char **argv;
{
#ifdef USESTDIO
    FILE *outfp;
    struct UFB *ufb;
#endif
    long outfh;
    static struct FORKENV env={0,0,0,0,0,NULL};
    struct ProcID child;
    int status;

    if(argc<3){
	fprintf(stderr,"Usage: %s outfp command arg ...\n",argv[0]);
	exit(-1);
    }
    argv++;

#ifdef USESTDIO
    outfp=fopen(*argv++,"w");
    if(outfp==NULL){
	poserr("fopen");
	exit(-1);
    }

    ufb=chkufb(fileno(outfp));
    if(ufb==NULL){
	fputs("ufb is NULL\n",stderr);
	fclose(outfp);
	exit(-1);
    }

    outfh=ufb->ufbfh;
#else /* USESTDIO */
    outfh=Open(*argv++,MODE_NEWFILE);

    if(outfh==0){
	fputs("Open failed\n",stderr);
	exit(-1);
    }
#endif

    env.std_out=outfh;

    status=forkv(argv[0],argv,&env,&child);
    if(status==-1)
	poserr("forkv");
    else
	status=wait(&child);

    printf("Exit status is %d\n",status);

#ifdef USESTDIO
    fclose(outfp);
#else
    Close(outfh);
#endif

    exit(status);
}

fnf@fishpond.UUCP (Fred Fish) (11/28/88)

In article <wXY38Sy00Uka8=Ac5B@andrew.cmu.edu> bader+@andrew.cmu.edu (Miles Bader) writes:
>Despite many re-readings of the manual section, and talking to
>lattice technical support, I STILL can't forkv to work as advertised.

Forkv only works when the forked program is a C program.  This restriction
did not make it into the manual, but is apparently in one of the README
files supplied with the compiler (or so I've been informed, read the README
files?  never...  :-).

-Fred
-- 
# Fred Fish, 1346 West 10th Place, Tempe, AZ 85281,  USA
# noao!nud!fishpond!fnf                   (602) 921-1113

rminnich@super.ORG (Ronald G Minnich) (11/29/88)

In article <wXY38Sy00Uka8=Ac5B@andrew.cmu.edu> bader+@andrew.cmu.edu (Miles Bader) writes:
>Despite many re-readings of the manual section, and talking to
>lattice technical support, I STILL can't forkv to work as advertised.
Well, join the club :-)
It appears not to work worth a damn. I solved my problems by using
the ARP library. I recommend you do too. The Lattice 4.x docs on forkv
really suck wind, and the function does not work near as i can tell, 
and i sure hope i haven't wasted $75 on 5.0 and that 5.0 is actually 
gonna work ...
ron

bader+@andrew.cmu.edu (Miles Bader) (11/29/88)

fnf@fishpond.UUCP (Fred Fish) writes:
> Forkv only works when the forked program is a C program.  This restriction
> did not make it into the manual, but is apparently in one of the README
> files supplied with the compiler (or so I've been informed, read the README
> files?  never...  :-).

Actually, I can't get it to work with c programs either.  I just
tested it with a really small program that just does "exit(atoi(argv[1]))".
The reason I started out TRYING to use forkv in the first place was
so I could exit codes from the compiler passes, using a hacked up
version of (your) cc, and it couldn't deal with any of them
either (and I certainly assume they're written in c...).

Just in case, I also searched the read.me & addendum.doc on the
distribution disks, and they never even mention any of the fork
calls.  I also search the man entry again; no dice.

So my question (why doesn't forkv work?) still stands...

-Miles

fnf@fishpond.UUCP (Fred Fish) (11/29/88)

In article <AXYMTny00Uka0DRGpH@andrew.cmu.edu> bader+@andrew.cmu.edu (Miles Bader) writes:
>fnf@fishpond.UUCP (Fred Fish) writes:
>> Forkv only works when the forked program is a C program.  This restriction
>> did not make it into the manual, but is apparently in one of the README
>Actually, I can't get it to work with c programs either.  I just
>tested it with a really small program that just does "exit(atoi(argv[1]))".
>...
>So my question (why doesn't forkv work?) still stands...

Hmmm...  I managed to dig up the test programs I was using when I was 
investigating this exact thing, while trying to use forkv to run a subshell
(subcli ???).  They are attached to this posting.

To test:

	lc -L forkv.c
	lc -L echo.c
	forkv echo a b c

	(this should run the echo program, which should echo it's arguments
	 and return 123, which gets printed by the forkv program)

	forkv newcli

	(boom!!!   guru  ...00004.XXXX...)

===================================  echo.c  ===================================
main (argc, argv)
int argc;
char **argv;
{
	while (argc-- > 0) {
		printf ("%s ", *argv++);
	}
	printf ("\n");
	exit (123);
}
===================================  forkv.c  ===================================
/*
 *	Sample forkv program from Lattice 4.0 manual.
 */

#include "dos.h"
#include "stdio.h"

struct ProcID child;

void main (argc, argv)
int argc;
char *argv[];
{
	int ret;

	if (argc < 2) {
		printf ("no program specified\n");
		printf ("usage: fork program [arg1] [arg2] ...\n");
		exit (0);
	}
	printf ("parent: beginning fork of %s\n", argv[1]);
	if (forkv (argv[1], &argv[1], NULL, &child) == -1) {
		printf ("error forking child\n");
		exit (0);
	} else {
		ret = wait (&child);
	}
	printf ("parent: %s finished, ret = %d\n", argv[1], ret);
}
======================================================================

Hope this helps to track down the problem.

-Fred
-- 
# Fred Fish, 1346 West 10th Place, Tempe, AZ 85281,  USA
# noao!nud!fishpond!fnf                   (602) 921-1113

rsb@dukeac.UUCP (R. Scott Bartlett) (11/29/88)

[aliens ate my line eater]

In article <wXY38Sy00Uka8=Ac5B@andrew.cmu.edu> bader+@andrew.cmu.edu (Miles Bader) writes:
>Despite many re-readings of the manual section, and talking to
>lattice technical support, I STILL can't forkv to work as advertised.
>Thanks, -Miles
[ demo program deleted ]

If someone has figured out how to get this to work, PLEEEZE tell me too!
forkv() does exactly what i need it to do.  I have tried Execute(), but gave
up because i really didn't want to have to write a file to ram: and feed
Execute() that filehandle just to be able to do what i want.

Thanks a bunch!!

						rsb

-- 
rsb@dukeac.ac.duke.edu		///	"Amigas do it with hardware."-- Me
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^	       ///     "Sycamore is open."-- Negativ Land
Note the shorter addr	   \\\///     "I luv S&M!!!"   "No geeks here!!"
Disclaimer NOT included!    \XX/     "This space for rent"

bader+@andrew.cmu.edu (Miles Bader) (11/29/88)

fnf@fishpond.UUCP (Fred Fish) writes:
> Hmmm...  I managed to dig up the test programs I was using when I was 
> investigating this exact thing, while trying to use forkv to run a subshell
> (subcli ???).  They are attached to this posting.

Looking at your test prog made realize something I should have said
earlier:  forkv works, AS LONG AS YOU DON'T TRY TO REDIRECT THE OUTPUT.
Redirecting the output is where it starts failing big time.

-Miles

cmcmanis%pepper@Sun.COM (Chuck McManis) (11/30/88)

In article <AXYMTny00Uka0DRGpH@andrew.cmu.edu> (Miles Bader) writes:
>So my question (why doesn't forkv work?) still stands...
>-Miles

The following source (which is from my Life program) works fine :

/*
 * Function NewColors()
 *
 * Using Carolyn's Pallette requester this lets the user change the colors
 * around, later you can save them with the Save Defaults menu option.
 *
 * The interesting thing about this routine is that it uses a separate
 * program (Palette) to set the colors on the screen. It uses the Lattice
 * routine forkv() to start it up, the program itself opens a window on
 * the frontmost screen (the life screen) and lets the user twiddle the
 * colors. Note that I do not go back to the main event loop so you can't
 * continue to add cells etc.
 */

static char *palette_argv[] = {"Palette", NULL};	/* Program's argv[] */

NewColors(opt, f)

int opt;
{
    struct ProcID child;
    ULONG l;

    l = Lock("Palette", ACCESS_READ);
    if (l)
    {
	/* default environment */	
	forkv(palette_argv[0], palette_argv, NULL, &child);
	if (wait(&child))
	    DisplayBeep(MyScreen);	/* if they click
					   'cancel' */
	UnLock(l);
    } else {
	ShowWarning("Couldn't find the Palette program.", "OK", NULL);
    }
    return (TRUE);
}


--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.

rsb@dukeac.UUCP (R. Scott Bartlett) (11/30/88)

[aliens ate my line eater]

In article <167@fishpond.UUCP> fnf@fishpond.UUCP (Fred Fish) writes:
>In article <wXY38Sy00Uka8=Ac5B@andrew.cmu.edu> bader+@andrew.cmu.edu (Miles Bader) writes:
>>Despite many re-readings of the manual section, and talking to
>>lattice technical support, I STILL can't forkv to work as advertised.
>
>Forkv only works when the forked program is a C program.  This restriction
>did not make it into the manual, but is apparently in one of the README
>files supplied with the compiler (or so I've been informed, read the README
>files?  never...  :-).
>-Fred


I have forkv() call csh2.07m (thanks Matt & Steve), the shell gets loaded, but
bombs before it does anything. (Guru #0000000B(or 03) #20382038 when run from a
CLtd harddrive (old fs/driver); Guru #00000003(or 0B) #00032075 when from ram:)

News Flash!!  I just tried the program from RAM: on my roomate's 500:
Guru #00000003 #00032075    AARGH!!!  The shell loaded fine, but when it sourced
the file root:us1/rsb/.profile it crashed (root: assigned to ram:).  If that
file was not there, csh would complain that it couldn't find the file and leave
me at that shell's prompt.  Why the different behavior?

What gives??

						rsb

BTW:  ROOT:us1/rsb/.profile contained:

A1000-> pwd
	cd root:us1/rsb
	set _path c:,UUCP:c,df1:c,df0:c
	alias pg type
	endcli

A500->	cd root:us1/rsb
	echo hi


System:

A1000	1.3KS and WB (WB not loaded)
	2Mb Microbotics w/ MFM
	old CLtd harddrive /* Do they have an uucp-able email address? */
	PopCLI & MemWatch  /* 'cus I want to upgrade so i can use FFS  */

A500	1.2KS and WB (WB not loaded)
	A501 mem expansion
	PopCLI

Code segment below:

/* ************************************************************************* */
/* v0.1		11/16/88	it's a start.				     */
/* by R. Scott Bartlett							     */
/* ************************************************************************* */

/* Note that this is only part of the program!!! for posting purposes only */
/* (C)1988 R. Scott Bartlett	It's not PD (yet ;-)			   */

#include <exec/types.h>
#include <exec/tasks.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <stdio.h>
#include <dos.h>
#define		ROOT_DIR	"ROOT:"
#define 	CLI		CommandLineInterface

struct ProcID	child;

main()
{

struct Process	*myProc;
struct CLI	*my_CLI;
struct FORKENV	child_env;

char		*child_argv[3],
		home_dir[80],
		shell_name[80],

  printf("HOME:	'%s'\n",home_dir);
  printf("Shell:  '%s'\n",shell_name);
  child_argv[0] = shell_name;
  child_argv[1] = home_dir;
  child_argv[2] = NULL;

  Forbid();
  myProc = (struct Process *)FindTask(0L);
  my_CLI = (struct CLI *)BADDR(myProc->pr_CLI);
  Permit();
  child_env.priority = 0;
  child_env.stack = 25000;	/* STACK SIZE */
  child_env.std_in = my_CLI->cli_StandardInput;
  child_env.std_out = my_CLI->cli_StandardOutput;
  child_env.console = (BPTR)myProc->pr_WindowPtr;
  child_env.msgport = NULL;

  if (forkv(child_argv[0],child_argv,&child_env,&child) == -1) {
	perror("Error in fork!!!\n");
	perror("Goodbye\n");
	}
  else {
	perror("Hello\n");
	wait(&child);
	return(0);
	}

-- 
rsb@dukeac.ac.duke.edu		///	"Amigas do it with hardware."-- Me
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^	       ///     "Sycamore is open."-- Negativ Land
Note the shorter addr	   \\\///     "I luv S&M!!!"   "No geeks here!!"
Disclaimer NOT included!    \XX/     "This space for rent"

brianm@sco.COM (Brian Moffet) (12/01/88)

In article <1132@dukeac.UUCP> rsb@dukeac.UUCP (R. Scott Bartlett) writes:
>
>If someone has figured out how to get this to work, PLEEEZE tell me too!
>forkv() does exactly what i need it to do.  I have tried Execute(), but gave


How about forkl()?  Here is a sample bug report that I sent to 
lattice sometime ago, the call to echo does not work (crashes)
but a call to a C program (as compared to BCPL) seems to work.
I stopped using it because I need to use normal dos commands
like echo, list, dir ....

-=-=-=-=-start listing-=-=-=-=-

/*
 *	Lattice 4.01
 */

#include <stdio.h>
#include <dos.h>
#include <signal.h>

main( argc, argv )
int argc;
char *argv[];
{
	struct ProcID pid;

	signal( SIGINT, SIG_IGN );

	if( argc > 1 )
	{
		printf( "This works fine\n" );
		exit( 0 );
	}
	forkl( "fexec", "fexec", "hello there", NULL, NULL, &pid );
	wait( &pid );
	
	forkl( "echo", "echo", "hello there", NULL, NULL, &pid );
	wait( &pid );
}

-- 
Brian Moffet			{uunet,decvax!microsoft,ucscc}!sco!brianm
 -or-				...sco!alar!brian
"Evil Geniuses for a better tomorrow!"  My fish and company have policies.
					I have opinions.

brians@hpcljms.HP.COM (Brian Sullivan) (12/01/88)

  I remember having problems with forkv for Lattice 4.0 also.  I did get it
to work however.  I belive that one of the parameter to forkv is a small
record of some kind (memory quotas or something like that)  The documentation
implies that you can set this parameter to NULL (0) and forkv will create it
own parameter.  This does not work!!!  You must supply a pointer to this
array or structure.  I found out this by trial an error.   I will try and 
look up the example that I got to work.  I remember that most of this small
record contained fields that I left as zero, but that one of them at least
needed to be initialized.  

        Brian Sullivan
        (408)447-7352