nordmark@nada.kth.se (Arne Nordmark) (12/17/88)
Since several people have asked how to write a cron-program that runs as a daemon, i.e. without a window, I think this will be useful information for the net. I have my own extremely undocumented, uncommented and messy version called "CronSafe" :-) (only Swedes will understand the smiley) that seems *impossible* to crash. Even if you patch in the new 1.3 Shell instead of the CLI, it runs without gurus. I haven't got the time to clean up the code and write the documentation, but if you insist I could mail you a binary. The changes to an old AmiCron program is *so* simple, so I think that interested persons could make them themselves without much trouble. I don't know if it will work with other shells that do evil things like patching Execute() or mess with the resident list though. I wouldn't count on it. All I know is that it works with the new 1.3 Run and the standard CLI or Shell. (and fortunately, most other shells don't do evil things) This is what you should do: 1. Get the null: device that I posted to comp.sources.amiga recently. Append the supplied MountList and say Mount null: The null: device is of *vital* importance and you know why if you have followed the discussion in .tech 2. Add this to the cron code (if it is not allready there) /* #include <stdio.h> */ fclose(stderr); or do something of that effect. close(2); will do as well. You must close stderr to get rid of the "lock" on the current console. Then you will be able to close the window. You can also change _main.c and remove the line that Open("*", 1006); 3. Do this early in the program, i.e. before launching any commands: /* #include <libraries/dosextens.h> */ struct MsgPort *old_console, *new_console, *DeviceProc(); struct Process *proc; struct Task *FindTask(); proc=(struct Process *)FindTask(NULL); old_console=(struct MsgPort *)proc->pr_ConsoleTask; new_console=DeviceProc("null:"); if (new_console==NULL) { /* error, null: must be mounted */ } proc->pr_ConsoleTask=(APTR)new_console; 3. Find the place where Execute() is called and do the following: If there is a line that looks like ret=Execute(command, NULL, NULL); change it to BPTR cli_input, Open(); cli_input=Open("null:", MODE_OLDFILE); if (cli_input==NULL) { /* didn't I told you that null: must be mounted :-) */ } ret=Execute(command, cli_input, NULL); Close(cli_input); this *works*. Don't try to do it in a different way, pplleeease :-) It took several weeks to find out that you indeed must supply a input file-handle. And you can't use NIL: (= guru) If you don't supply a null: input-handle you will get a hanging background cli if the command is "Run foo" and foo isn't found. This is a bug deep down in AmigaDOS that you have to find out the hard way. 4. When the cron program finally exits, you must restore the old console: proc->pr_ConsoleTask=(APTR)old_console; Done! You now have a SAFE cron-program. Using the 1.3 Run command you would probably start cron by Run > NIL: cron ; (Here you *must* use NIL:, not null:) then you can safely close the console-window. Have fun! -- Gunnar SNAIL: Gunnar Nordmark VOICE: (+46) 8 - 755 42 52 Nora strand 5 S-182 34 DANDERYD EMAIL: gno@stacken.kth.se SWEDEN gno@SESTAK.BITNET "Words, words, words." William Shakespeare