Where it USED to crash, it now reports "No task in port" for the SFS filing system. I don't understand what "(port->mp_Flags & PF_ACTION) == PA_SIGNAL" is doing, so perhaps you can explain why this check is needed for your code to work?
Message ports can have one of three actions associated when a message is sent to them: PA_SIGNAL, PA_SOFTINT, PA_IGNORE.
Only for PA_SIGNAL is mp_SigTask a pointer to a task. For PA_SOFTINT mp_SigTask points to an interrupt and for PA_IGNORE the contents of mp_SigTask are undefined.
TBH I wouldn't have expected any file system to be using PA_SOFTINT though.
Only for PA_SIGNAL is mp_SigTask a pointer to a task. For PA_SOFTINT mp_SigTask points to an interrupt and for PA_IGNORE the contents of mp_SigTask are undefined.
TBH I wouldn't have expected any file system to be using PA_SOFTINT though.
Thanks!
@colinw The above would also seem to explain why your code is crashing! There is nothing wrong with it, but rather the "process" I give it from mp_SigTask isn't actually a process. Thus the "cli" I get isn't a CLI structure, and hence a crash. (I will test this idea soon.)
The only puzzle is why GetProcSegList() does NOT crash in the same situation! I suppose it might use IS_PROCESS() to check it isn't being given a task, which would probably also detect the rubbish I am giving it?
...but it does not explain why segarray[1] works better on OS3 than segarray[3] for finding $VER.
I suppose it might use IS_PROCESS() to check it isn't being given a task, which would probably also detect the rubbish I am giving it?
That is most likely the reason.
As Interrupt structure also contains a Node structure at the beginning (same as Task and Process) the check should be quite reliable but it might still be a good idea to check mp_Flags just to be safe.
I'm not going to argue online with you anymore about what is in seglist[3]. If it's not working for you, you ARE doing something wrong.
seglist[1] is the dos klib seglist, it has nothing to do with application code, so please stop trying to grasp at straws.
Check your seglist scanner parameters, some seglists can have a fake length, do a signed check for multiple of 4 and not negative, also check for nonsence segment lengths.
Also, do propper error checks, they are not optional, don't assume processes, it could be a task and you would end up reading random memory.
I also have the actual original 68K source code for V40 DOS, so i'm not making this stuff up. If even that is not enough to convince you that I do know what I am talking about, here is the source code that launches new processes, see it for yourself.
From CreateProc() :
/* CNP_ActiveCode sets up a0/d0 and calls seglist in segarray[3] */ if (!AddTask(&(np->pr_Task),(void *) CNP_ActiveCode, (void *) deactcode)) {
And here's CNP_ActiveCode in 68K ASM, read the comments at the end of the lines, if you can't read 68K assembly code;
_CNP_ActiveCode: MOVE.L SysBase,A6 MOVE.L ThisTask(A6),A6 MOVE.L pr_Arguments(A6),A0 ; argument parameter (NULL if no args) MOVE.L A0,d0 ; registers other than a0/d0 are free BEQ.S noargs ; if a0 is NULL d0 is 0
;-- warning! this uses 2x stack!!!! move.l a0,d3 ; save in d3 BSR @strlen ; (a0) - length returned in d0 move.l d0,d4 ; length ; d3 is already pr_Arguments move.l pr_StackSize(A6),D2 ; in bytes move.l pr_SegList(A6),D1 ; segarray (BPTR) asl.l #2,d1 ;BADDR move.l d1,a0 move.l 3*4(a0),d1 ; Segarray[3], the seglist we should use bra _RunCommand ; returns to DEACT [...]
@colinw Sorry for offending you. It was not my intention to "argue" with you, but rather just to report the unexpected behaviour I was seeing, in the hope you or someone else might have some idea as to why, or at least start a discussion that leads to the answer. I never meant to imply you didn't know what you were talking (I know you ought to know, probably better than anyone else here).
As I already reported, I'd already found one cause of your code not working (me supplying it with a "process" that wasn't, hence invalid "cli" pointer).
A buggy seglist scanner is certainly a possible cause that I hadn't previously considered, although I find it a bit difficult to see how it could work correctly with segarray[3] on OS4, and yet fail to work correctly on OS3 (and yet seemingly work with segarray[1]). I shall inspect my code closer...
If seglists can have fake lengths, in undefined ways, then I don't see how I can detect that with *certainty* (multiples of 4 & negative would just rule-out the most obvious ones). This seems like something that might not be reliably documented anywhere...
I'll leave it at that, as I fear the more I say, the greater the risk of sounding argumentative (even though that has never been my intention).
@colinw You were correct about fake seglist sizes (not divisible by 4). Having aborted searching of $VER with these, segarray[1] no-longer finds any $VER. Fake sizes is something I never expected...
@all (To avoid appearing argumentative, I'm making it clear the following is not directed at anyone specifically.)
So I guess the question now is why segarray[3] doesn't find $VER for some handlers (which clearly must exist since my previous buggy code did find them, seemingly by chance). (I will of course look at my code again, but I fear I may not know enough to solve the issue.)
BTW, it's not immediately clear to me why the seglist size *has* to be divisible by 4, when surely the code in seglists can be any arbitrary length... (Hmmm, could it be somehow related to BPTR limitations? But BSTRs can be any length, so maybe not? Or is it down to allowing multiple seglists to be packed together? In which case BPTR limitations would require seglists to be multiples of 4... But it's beyond my knowledge as to whether multiple seglists are packed together - it merely seems plausible to me from an early AmigaOS efficiency perspective.) All I found so far is the statement (no explanation) in dosextens.h that "The 'SegSize' value MUST also be a longword multiple.".
P.S. Seemingly contrary to OS4 guidelines in dosextens.h, none of the $VER strings end in '\r\n\0' (at least for SMBFS, FTP Mount & (surprisingly) ram-handler).
Edited by ChrisH on 2016/5/26 21:30:16 Edited by ChrisH on 2016/5/26 21:30:54 Edited by ChrisH on 2016/5/26 21:31:31 Edited by ChrisH on 2016/5/26 21:32:58 Edited by ChrisH on 2016/5/26 21:34:32 Edited by ChrisH on 2016/5/26 21:37:47 Edited by ChrisH on 2016/5/26 21:39:29 Edited by ChrisH on 2016/5/26 21:40:38 Edited by ChrisH on 2016/5/26 21:52:16 Edited by ChrisH on 2016/5/26 22:01:54 Edited by ChrisH on 2016/5/26 22:03:35 Edited by ChrisH on 2016/5/26 22:07:48
I didn't mention it before since I thought you were only interested in smbfs but to make the code handle more cases you should probably scan for a ROM tag (Resident structure) as well if the search for a version tag fails (look for rtc_MatchWord, rtc_MatchTag and maybe rt_EndSkip, since Resident structure should be WORD aligned you only need to check even addresses).
The rt_IdString contained there is basically the same as the version tag but without the leading "$VER: ".
For AmigaOS 4.x you should use the GSLI_ResidentVersionString tag with GetSegListInfo().
@ChrisH Seglist sizes dont HAVE to be multiples of four, but they were and are still maintained that way in OS4, I also made it so DOS won't actually recognise them as valid unless they are.
I had to deal with loading hunk files about 14 years ago. If I remember correctly, the hunk size is always stored in longwords, but it's also a bit screwy in that the longword size only occupied the low bits 0-29 and they used the upper 2 bits for the memory type flags.
So, when you read in the file to get the hunk size and memory type, you had to basically do this; ULONG bytesize = (longwordsize << 2); ULONG memflags = (longwordsize >> 29); And that ladies and gentlemen is why segments are also longword multiples.
As I said, I have maintained this quirk in OS4 seglist segments too, see AllocSegList() autodoc.
P.S. Seemingly contrary to OS4 guidelines in dosextens.h, none of the $VER strings end in '\r\n\0' (at least for SMBFS, FTP Mount & (surprisingly) ram-handler).
The Amiga version string seems to be a long standing point of confusion. For example:
Most of the OS3 AmigaDOS commands (in C:) have version strings that are terminated with " \n\r\0 ".
Some of the OS4 AmigaDOS commands (in C:) have version strings that are terminated with " \r\n\0 " and some with just " \0 ".
Most of the programming examples in the OS3 developer CD have version strings like this: "\0$VER: appname 37.1 (20.3.91)"
The OS4 AmigaDOS AllocSegList autodoc shows a version string like this: "$VER: name ver.rev (dd.mm.yyyy)\r\n\0"
In "The Amiga GURU Book" by Ralph Babel it states that the version string may be terminated by any of the three control characters: \n \r \0 and shows several examples.
It's not surprising that 3rd party developers might not be using the version string termination recommended in the OS4 AmigaDOS autodocs; especiallly in software originally written for OS3.
Amiga X1000 with 2GB memory & OS 4.1FE + Radeon HD 5450
All operating system components use the "BumpRev" command, it should actually be in your distributed SDK installation, ( in sdk:c ) it creates the correct format for all types of version strings in the (name)_rev.h file for C language. The file is simply included in the source code and contains pretty well everything you will need for version tags, resident version strings or anything else.
Here are the contents of the ram-handler_rev.h file for the ram-handler, you simply use the definition you require in the source code file;
======================================================= #define VERSION 54 #define REVISION 12 #define DATE "21.9.2015" #define VERS "ram-handler 54.12" #define VSTRING "ram-handler 54.12 (21.9.2015)\r\n" #define VERSTAG "\0$VER: ram-handler 54.12 (21.9.2015)" =======================================================
Identifying devices shouldn't be such a difficult task. The OS should know what each device specifically is and can tell you easily.
That's against its philosophy. From the very beginning AmigaDOS treated all devices the same. It does not know, does not need to know, does not want to know which type a device is. Each attempt to identify a device type in AmigaDOS is a hack, based on assumptions which might or might not always work.
Exactly! We are hacking at this every time. Each person could be doing it slightly different, getting slightly different results, or just giving up in frustration. Let's fix the problem!
Take an ISO burner program, for example. Get a list of devices (DH0:, CD0: USB0:, RAM:, etc.) Run through a loop and check the type with a new DOS function:
result=IDOS->IdentifyDevice("CD0:"); Is it a CD/DVD drive? Yes, check it's properties: IDOS->GetDeviceProperties("CD0:"); Is it a burner? Nope, skip. result=IDOS->IdentifyDevice("CD1:"); Is it a CD/DVD drive? Yes, check it's properties: IDOS->GetDeviceProperties("CD1:"); Is it a burner? Yes, success.
I have a device, WD0:, on my system. What kind of device is it? The world will never know.....
Workbench Explorer - A better way to browse drawers
@mritter0 Can you please take your discussion/argument (about changing how AmigaOS works) to a different thread? I'm only interested in dealing with AmigaOS as it currently stands.
I didn't mention it before since I thought you were only interested in smbfs but to make the code handle more cases you should probably scan for a ROM tag ... For AmigaOS 4.x you should use the GSLI_ResidentVersionString tag with GetSegListInfo().
I wasn't really expecting it to help for FTP Mount or SMBFS (since they aren't ROM resident), but anyway way it doesn't. (It might help for other cases, like FFS, but I'll leave that until another time.)
Which leaves me puzzled how to find $VER for FTP Mount & SMBFS (using OS3-compatible code), when using colinw's rule that seglist sizes must be multiples of 4.
All operating system components use the "BumpRev" command, it should actually be in your distributed SDK installation, ( in sdk:c ) it creates the correct format for all types of version strings in the (name)_rev.h file for C language. ... #define VSTRING "ram-handler 54.12 (21.9.2015)\r\n" #define VERSTAG "\0$VER: ram-handler 54.12 (21.9.2015)"
I'm sure that's true, but I would like to point out that the above is wrong according to what dosextens.h says: Quote:
/* structure or a nul-terminated version string which is to be */ /* formatted as; "$VER: name ver.rev (dd.mm.yyyy)\r\n\0" */ /* or any other data that needs to be included in the segment. */ /* See also; dos/AllocSegList() for more information. */
Which leaves me puzzled how to find $VER for FTP Mount & SMBFS (using OS3-compatible code), when using colinw's rule that seglist sizes must be multiples of 4.
If you check the FTP device in the DOS/DEVICES tab of "Ranger" you will see a complete path to the handler and a version for the filesystem. Maybe Ranger is checking the version in the handler file since it has the complete path to the file. I'm not sure if that helps you though.
Amiga X1000 with 2GB memory & OS 4.1FE + Radeon HD 5450
If you check the FTP device in the DOS/DEVICES tab of "Ranger" you will see a complete path to the handler and a version for the filesystem
My test code already extracts the handler's path for FTP Mount... but this doesn't work for SMBFS (perhaps not surprisingly), so it's not sufficiently general to be useful.
Now, I *can* get the command used to start SMBFS from "cli->cli_CommandName", but this is typically a relative/local path, and so might not work. So that's not much help either. (I suppose it might be possible to get the cli's current path, but would that be guaranteed to be the PROGDIR: of the command?)
I notice that cli (CommandLineInterface) does have "cli_Module" (seglist of the currently loaded command), so that MIGHT be a viable way to get $VER for SMBFS... but it would be nice for a general (not ad-hoc) way of finding $VER from the general DosList task's seglist. edit: It seems my code is already doing this for OS3, and yet still fails to find $VER of SMBFS for some reason.
edit: Testing OS3 code (parsing seglists) on OS4 may be misleading me, because I see all the seglist sizes are tiny (e.g. 56 bytes).
Edited by ChrisH on 2016/6/26 10:07:00 Edited by ChrisH on 2016/6/26 10:41:46