Newsgroups: comp.sys.amiga.programmer
Date: Tue, 28 Jul 1992 14:14:11 -0400 
From: "Edward D. Berger" <eb15+@andrew.cmu.edu>
Subject: Still confused about System() and paths...

I guess I don't really understand AmigaDOS data structures, especially
BPTRs, TagItems, etc.

I want to add a simple "execute AmigaDOS Command" function to my program,
and for it to have a valid search path without regards to it being started
from a CLI or from Workbench.  The following program loses its path from
the CLI, and starts to give a search path for Workbench then green screen.
Anyone want to fix it?

;/* MySys.c - Execute me to compile me with SAS/C 5.10a
;   Demonstration of System(), AUTO CON, and broken paths from Workbench
LC -b1 -cfistq -v -y -j73 mysys.c
Blink FROM LIB:c.o,mysys.o TO MySys LIBRARY LIB:LC.lib,LIB:Amiga.lib
quit
*/

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef LATTICE
#include <clib/intuition_protos.h>
int CXBRK(void) { return(0); }  /* Disable Lattice CTRL/C handling */
int chkabort(void) { return(0); }  /* really */
#endif

/* our function error codes */
#define SYSTEMFAIL      (-1L)
#define WINDOWFAIL      (-2L)


/* function prototypes */
LONG beginCommand( UBYTE *command );
BPTR CopyPath( char *tass );
/* Formatted version string for the 2.0 VERSION command */
UBYTE *vers = "\0$VER: mysys_is_broken 0.01";
/* global BPTR, so that beginCommand can use it? */
BPTR wb_path = NULL;


int main(int argc, char **argv)
    {
    extern struct Library *DOSBase;

    LONG result;
    UBYTE *command;

    if(DOSBase->lib_Version < 36)
        {
        printf("This example requires dos.library V36 or higher\n");
        exit(RETURN_FAIL);
        }

    if( argc == 0 )  /* We are a child of Workbench? */
      {
       printf("Started from Workbench, Searching for Path! \n");
       Forbid();
       wb_path = CopyPath("Workbench");
       Permit();
      }

    /* ASYNCHRONOUS SYSTEM() WITH ON-DEMAND AUTO/WAIT CON:
     */
    printf("\n*** SystemTest: Asynchronous startup of 'path':\n");
    command = "path";
    result = beginCommand(command);

    printf("\nSystemTest exiting. Close Shell and Autocon window when you wish.\n");

    /* So we can see what the SAS/C stdio window for Workbench prints out */
    Delay(500);

    exit(RETURN_OK);
    }

UBYTE *autocon="CON:0/40/640/150/Auto CON Window Opens if Needed/auto/close/wait";
LONG beginCommand( UBYTE *command )
    {
    struct TagItem stags[6];
    BPTR file;

    if(file = Open(autocon, MODE_OLDFILE))
        {
        stags[0].ti_Tag = SYS_Input;
        stags[0].ti_Data = file;
        stags[1].ti_Tag = SYS_Output;
        stags[1].ti_Data = NULL;
        stags[2].ti_Tag = SYS_Asynch;
        stags[2].ti_Data = TRUE;
        stags[3].ti_Tag = SYS_UserShell;
        stags[3].ti_Data = TRUE;
        stags[4].ti_Tag = NP_Path;
        stags[4].ti_Data = wb_path;
        stags[5].ti_Tag = TAG_DONE;
        return(System(command, stags));
        }
    else return(WINDOWFAIL);
    }


BPTR CopyPath( tass ) char *tass;
  {
      struct Process *wb = (void *) FindTask( tass );
      struct CommandLineInterface *wbclap;
      BPTR *wext, *mext, *lastmext, newpath = 0;

      lastmext = &newpath;
      if( !wb ) return 0;
      if( !( wbclap = BADDR( wb->pr_CLI ) ) )
          return 0;

      for( wext = BADDR( wbclap->cli_CommandDir ); wext; wext = BADDR( *wext ) ) {
          if( !( mext = (BPTR *)AllocMem(  2 * sizeof(BPTR) , MEMF_PUBLIC ) ) )
              break;
          *lastmext = (long) mext >> 2;
          lastmext = mext;
          mext[1] = DupLock( wext[1] );
          mext[0] = 0;
      }
      return( newpath );
  }
Newsgroups: comp.sys.amiga.programmer