[comp.sys.amiga.tech] Execute

rfrost@cs.ua.oz.au (Richard Frost) (03/27/90)

   Yes, I HAVE read the recent articles concerning locks handed
   to applications run from the WBench, but thats not my problem
   actually I THINK I am treating WB locks safely. (check my code
   below!)

   I have a problem with the Execute() call with programs
   that are run from the WorkBench. I have been trying everything
   to get it fixed for the LAST 4 DAYS and I am resorting to Usenet
   for a solution!!

   This problem is the last BUG to be fixed in a program I hope to
   submit to comp.binaries.amiga (Could someone tell me the current
   email address to send to as I have not done this before.).

   Let me say that the program will be of GREAT help to all people
   who receive USENET news on their Amigas, thats all I can say at
   this stage.

===================================================================
WARNING: This news item is LONG as it contains source code!
         PLEASE don't flame me over the length, I promise I will
         not do this again!!!!
=================================================================== 

THE PROBLEM:
   
   I wrote this program below to test the Execute() call in a workbench 
   environment, why you say?

   I am writing a program that allows an alternate text reader to be
   selected by the user rather than use the program's internal text
   reader (not everyone likes to be restricted, I LIKE programs that
   allow you to change things!!).

   The program can be started from the WB or the CLI.
  
   When run from the CLI, a directory name is given as an argument, if 
   not the current directory is used. 

   ( The directory argument is a directory that contains files to be
     read by the program.)

   When run in the workbench either the icon for the program
   is clicked on (hence the Current Directory is used) or, an extra icon
   is clicked on (ie. a Drawer, Disk or Project Icon) which is used as 
   the directory argument.
 
   Once the directory is established I make a call to CurrentDir()
   to change to the directory that contains all the files.

   My problem is that I make a call to the Execute() function with
   an argument string that contains both the text reader name and
   the argument filename like.. 

	ie:
	     Execute("ram:Less myfile",0L,my_fhand)

             ("my_hand" is a file handle to a console for output)

   which should attempt to load the 'Less' command located in the
   RAM: directory with a filename argument "myfile", however the call
   works for the CLI but not the WB.
   
   "Less" obtains the file "myfile" and displays it fine when TestEx is
   run from the CLI but if the program is run by clicking on its icon
   in the RAM: disk , "Less" will not see the file "myfile" as "Less" 
   has a current directory that does NOT agree with TestEx. I have
   checked this as in the Workbench case the current directory assumed 
   by "Less" is "SYS1:" (my boot disk) and TestEx is "" (the RAM: disk).
  

    
   The problem boils down to:

       HOW DO YOU INFORM PROGRAMS RUN VIA EXECUTE(), OF THE CURRENT
   DIRECTORY OF A PROGRAM RUN FROM THE WORKBENCH AS CurrentDir() SEEMS
   TO HAVE NO EFFECT?
    

   I have written this program to see if anyone can help me with my
   problem.

   Here is the source code folks:
 
/* =============================================================== */
/*								   */
/* TITLE:	 	         TestEx				   */
/*								   */
/*								   */
/* AUTHOR:       (C) 1990 Richard Frost			           */
/*								   */
/*								   */
/* DATE  :       26th March 1990  			           */
/*								   */
/*								   */
/* DESCRIPTION:	 Test the Execute() call with a command and input  */
/*               file for both the WBench & CLI environments.	   */
/*								   */
/* =============================================================== */

/*
 
			  --------------------------
                           I N S T R U C T I O N S:
			  --------------------------
   
   N O T E:
   ========
      *  The program requires you to make an ICON file for it with a 
         TOOLTYPES field set to :

         WINDOW = CON:0/0/380/100/TestEx INPUT

         This allows AZTEC C to set up its console so input can take place
         when run from WBENCH.

      *  Compile TestEx under Aztec C

      *  Make sure you run TestEx from a disk which has the RUN command
         in the C: directory or Execute() won't work.
	
      *  Copy a text file (call it 'myfile'), TestEx and
         "Less" (or any other text viewer of your choice .. ie: 'type')
         into RAM:

      *  Run the program and then at the prompt in the con: window:
 
            "Input Command {<RET> to quit}:
      
         type in the response: 
    
             ram:Less  

         { NOTE: If you dont have 'less', try 'type' }
 
         and at the second prompt,
 
             "Input Filename {<RET> to quit}:"
 
         type the response:

	     myfile

         at this point you should see the output of the Executed program
         in the con: window  named "ExecuteOUTPUT".


      *  To quit just hit RET at the prompts.


      *  Next, run the program again at the cli repeating the above
         steps and notice the difference in the Execute() call!!
*/


   

#include <exec/types.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <workbench/startup.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <stdio.h>



extern struct WBStartup   *WBenchMsg;
extern void 		  *AllocMem();
extern void 		  *OpenLibrary();
extern struct FileLock    *Lock(), *CurrentDir();
extern FILE		  *fopen();
extern struct FileHandle  *Open();

struct Library 		  *DosBase  = NULL;
struct FileLock 	  *dirlock, *old_cd;
struct FileHandle	  *my_fhand;
struct FileInfoBlock	  *my_fib;

BOOL   			  did_cd    = FALSE,
			  WBlock    = FALSE;
int			  WBench;


/* Close Safely ...  I hope! */
die(str)	
char *str;
{
BYTE c;

  if (str) puts(str);

  if (WBlock)
    {
      printf("HIT any key to QUIT\n");
      while((c=getchar()) != '\n'); 
    }

  if (dirlock && !WBlock)  UnLock(dirlock);
  if (did_cd) 	 CurrentDir(old_cd);
  if (my_fhand)  Close(my_fhand);
  if (DosBase)   CloseLibrary(DosBase);
  if (my_fib)    FreeMem(my_fib,sizeof(struct FileInfoBlock));
  exit(0);
}


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

#define MAX_CMD 20
#define MAX_ARG 20
#define MAX_LINE MAX_CMD+MAX_ARG+1

BOOL   ok;
int    len;
char   cmd[MAX_CMD], fname[MAX_ARG], commandline[MAX_LINE];

struct WBArg *arg;



  if ( (DosBase = OpenLibrary("dos.library",1) ) == NULL)
    die("No DOS LIBRARY!!\n");

  my_fib  = AllocMem( sizeof(struct FileInfoBlock),MEMF_PUBLIC);
    if (my_fib == NULL)
      die("Could not alloc File Info Block!\n");

  switch (argc)	     /* OBTAIN A LOCK TO THE DIRECTORY */
    {
		     
      case 0:	     
		   /* Started from WorkBench! */
        switch (WBenchMsg->sm_NumArgs)
         {
  	   case 1:	/* Clicked Icon only */
	     WBlock  =  TRUE;
             arg     =  &WBenchMsg->sm_ArgList[0];
             dirlock =  (struct FileLock *) arg->wa_Lock;
	     break;

	   case 2 :	/* Extra Icons clicked */
           default:
	     WBlock  =  TRUE;
	     arg     = &WBenchMsg->sm_ArgList[1];
	     dirlock = (struct FileLock *) arg->wa_Lock;
         }
        break;

  		       /* Started From CLI */

      case 1:   /* No directory arg ... assume the Current Dir */
        dirlock  = Lock("",ACCESS_READ);
        break;

      case 2:   /* Lock the directory argument */
      default: 
        if (argv[1][0] == '?')	/* User requests a USAGE? */
	  {
	    printf("Usage: %s <directory>\n",argv[0]);
            die(NULL);
	  }
        else
          dirlock = Lock(argv[1],ACCESS_READ);  /* Lock the argument */
    }


  if ((my_fhand = (struct FileHandle *) Open("CON:385/0/200/100/ExecuteOUTPUT", MODE_OLDFILE)) == NULL)
    printf("Could not open NIL: device!");


  if (dirlock == NULL)
    die("Couldn't lock ( find ) the directory.\n");

  ok = Examine(dirlock,my_fib);
     if (!ok) die("Examine dir failed! ");
     if ( my_fib->fib_EntryType < 0) die("Need a directory name ARGUMENT!\n");
  
  printf("NEW CURRENT DIRECTORY == [%s]\n",my_fib->fib_FileName);
  old_cd = CurrentDir(dirlock);
  did_cd = TRUE;

  if (Examine(old_cd,my_fib))
    printf("OLD CURRENT DIRECTORY == [%s]\n",my_fib->fib_FileName);

  while (TRUE)
    {
        /* Obtain the command from the user: */

       	printf("\nInput Command {<RET> to quit}:\n");
  	gets(cmd);
	if (len = strlen(cmd))
	  {
	    cmd[len] = '\0';
	    strcpy(commandline,cmd);	/* build up input string */
	  }
	else break;

	/* Insert a spacing char */
	strcat(commandline," ");


  	/* Obtain the Argument from the user: */

  	printf("Input FileName {<RET> to quit}:\n");
  	gets(fname);
	if (len = strlen(fname))
	  {
 	    fname[len] = '\0';
	    strcat(commandline,fname);
	  }
	else break;

        printf("Issuing Execute("); printf(commandline);printf(")\n");

  	if (Execute( commandline, 0L, my_fhand))
    	  printf("Execute() ok!\n");
  	else
    	  printf("Execute() failed.\n");
    }

  die("All done.");
}
--
______________________________________________________________________________
_          ___       | Email Address:  rfrost@spam.ua.oz.au
I)         I_        |
I\ ichard  I rost    | FidoNet (ADAM LINK BBS): 3:680/805 Richard Frost
---------------------+--------------------------------------------------------
                  THE AMIGA, the programmer's dream machine!!

Bewildered Earth Scientist: "How do you re-wire alien equipmnent like that??"
Dr. Who: "Its easy when you've had 900 years experience in alien technology."
______________________________________________________________________________