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." ______________________________________________________________________________