Is there an easy way to check that an AmigaDOS command exists? In my particular case, I wish to check that "Curl" exists in the command path, so that I can check before hand if executing "Run >NIL: Curl ..." should work or not (and if not then warn the user it is missing).
I canNOT just try to Lock() the command's name, because AmigaDOS will search the command path, but Lock() will not!
I just tried using LoadSeg(), but that doesn't seem to search the command path either.
Please don't tell me I need to get the AmigaDOS command path (somehow!) & search it myself!?!
How about:
edit: Ok, you'll still have to do some work on the hook.
Other than that, you may run "which <command>" and check the return code.
@gazelle
Thanks for the suggestions! It's a shame SearchCmdPathList() is OS4-only, but I guess trying to do the same on OS3 will be much more difficult. Using the "Which" command is an kludge, but possibly the best I can hope for.
Author of the PortablE programming language.
I love using Amiga OS4.1 on my X1000 & Sam440 :-D
Check this: http://thomas-rapp.homepage.t-online.de/examples/which.c
@thomas
Thanks! That looks almost exactly what I was looking for. (Maybe I'll use a #ifdef so OS4 executables can use the new OS function instead.)
Author of the PortablE programming language.
I love using Amiga OS4.1 on my X1000 & Sam440 :-D
@thomas
Part of your code worries me:
Specifically I am worried about the check_dir() calls, which uses CurrentDir(), Lock() & Examine(). Unfortunately AmigaOS4's autodocs say the following about using what is returned by FindDosEntry():
This is more stringent than the AmigaOS3 autodocs, which advised against it "for compatibility reasons", but then go on to suggest trying it anyway to see if it works(!).
However, I'm not sure how to follow AmigaOS4's advice, because it's not clear that I can keep a copy of dol_Lock or al_Lock & expect it to work after unlocking the list...
Author of the PortablE programming language.
I love using Amiga OS4.1 on my X1000 & Sam440 :-D
A possible alternative to LockDosList()+FindDosEntry() is GetDeviceProc()+SetFileSysTask(), but I suspect that may be even less desirable (although I do have code which uses it...).
However, OS4's autodocs do say "Application programmers should rarely need this function except ... possibly for an application that needs to walk multi-assignments."
Author of the PortablE programming language.
I love using Amiga OS4.1 on my X1000 & Sam440 :-D
I checked another source of mine and it uses this:
@thomas
Your code using GetDeviceProc() APPEARS to me to be slightly faulty: I would call SetFileSysTask(dvp->dvp_Port) before check_dir(), and then after check_dir() call SetFileSysTask() again to restore the original filesystem task. Otherwise if dvp_Lock is NULL, your code will assume dvp_Lock points to SYS: (which may not be correct). I don't know under what circumstances it can be NULL, so maybe you can prove that is never the case here?
There may also be other reasons for calling SetFileSysTask() that I am not aware of!
@thomas
To make your code using LockDosList() technically correct, I think one needs to use DupLock() on all entries in the returned list (storing the results in a private list), call UnLockDosList(), and only then call check_dir() on the private list.
Overall the GetDeviceProc() solution appears less complicated, but surely there must be some reason why LockDosList() exists, otherwise one would always use GetDeviceProc() anyway!
Author of the PortablE programming language.
I love using Amiga OS4.1 on my X1000 & Sam440 :-D
@gazelle
I've attempted to use SearchCmdPathList() to implement my own version of "Which", but it crashes. EDIT: I suck. Forgot to convert BCPL address to proper address.
Author of the PortablE programming language.
I love using Amiga OS4.1 on my X1000 & Sam440 :-D
SetFileSysTask: I don't see a reason for any application whatsoever to call this function. Which reason do you see?
Certainly the 0 lock points to SYS:, it is supposed to do so. As 0 is a valid lock, CurrentDir(0) is valid, too.
Anyhow, how shall a 0 lock appear in a C: multi assign? Even by assign c: sys: add you don't get the 0 lock but a lock to the current resolution of the sys: assign.
I'm hardly an AmigaOS expert, so I can't give you any good reasons:
Other code I've seen using GetDeviceProc() also uses SetFileSysTask(). Example code I've recently seen from the main developer of AmigaOS4's AmigaDOS also used SetFileSysTask(). And when I previously wrote code without SetFileSysTask() it didn't always work as expect (I don't recall details).
My vague understanding is that a lock of 0 should NOT point to SYS: when it is in the context of a device handler. Don't ask me why! My own source code comments don't say where/who I got this info from.
I would also point to the AmigaOS wiki, which currently seems down so here's Google's cache of it:
http://webcache.googleusercontent.com/search?q=cache:http://wiki.amigaos.net/wiki/Multiple_Assigns&strip=1
It contains the following code fragment:
This may provide a partial explanation.
I have no idea, but the above code (and more that I have seen) contains SetFileSysTask() to handle that case.
Author of the PortablE programming language.
I love using Amiga OS4.1 on my X1000 & Sam440 :-D
It's a good idea to check the documentation. But you should not only look at the example but also read the text above it because it describes in which situations dvp_Lock may be NULL.
And we should keep in mind that we talk about OS3 because in OS4 you can use SearchCmdPathList. OS3 has a fixed set of features and this includes some limitations, for example that the combination of PATH or DEFER with ADD is not allowed for the Assign command. This probably means that a multi-assign can only contain true locks and no late- or non-binding assignments.
Furthermore we should consider that we examine not just any path given to GetDeviceProc but we use hardcoded "C:" only to resolve a multi-assign which is known to always be an assign. (Certainly it would be possible to remove the C: assign from the DOS list and add a handler instead, but this would most likely break the installation of many people.)
Finally I made some experiments and I was not able to get a 0 lock from GetDeviceProc for anything else but ser:, par: and so on which never appear in a C: assign. Even if I add a floppy disk to C: and then remove the floppy from the drive, it still gives me a lock.
Here is the program I used for experimenting: http://thomas-rapp.homepage.t-online.de/examples/devproc.c