Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!batcomputer!rpi!rpi.edu!deven From: deven@pawl.rpi.edu (Deven Corzine) Newsgroups: comp.sys.amiga.tech Subject: Re: Unix V7 functionality under (or along with) AmigaDOS? (*LONG*) Keywords: Unix V7 Minix AmigaDOS shells ... CATS? Randell?? :-) Message-ID: Date: 8 Mar 89 03:20:22 GMT References: <6124@cbmvax.UUCP> <6140@cbmvax.UUCP> <6157@cbmvax.UUCP> Sender: usenet@rpi.edu Reply-To: shadow@pawl.rpi.edu (Deven Thomas Corzine) Organization: RPI Public Access Workstation Lab, Troy NY Lines: 338 In-reply-to: jesup@cbmvax.UUCP's message of 7 Mar 89 01:26:31 GMT In article <6157@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes: >In article shadow@pawl.rpi.edu writes: >>In article <6140@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes: >>> I remember these problems well, I wrote a csh clone, SeaShell, before >>>I came to commodore. >> >>Hmm. I have a shell you wrote several years ago resembling Matt >>Dillon's shell. (I got the disk from Sandro) Is that the one? >>(Hardcoded to "expire" sometime in 1986? [setting back the clock >>works great, by the way... :-)] I'll surely erase it soon, but the >>extra utilities you had on the disk seemed to be of some possible >>value...) > > Ugh! Boy, that's an old copy! Burn it before it gets you. (Naughty >Sandro, Naughty!) That one has a LOT of bugs in it - it's so old I don't >even remember what they are. Did that one even have process control? The >utilities are more or less ok. Yeah, it looked pretty old. I don't remember what it did really; I only ran it once or twice. Sandro was going to trash the whole disk, but I thought the utilities looked to be worth saving, for now at least. >>> Shells are shells, period. The Workbench is a visual shell. >>>Exit() itself does almost nothing, except return control to the "shell" >>>as if the program had exited. >> >>So Exit() only ever releases resources if pr_ReturnAddr points to some >>such cleanup routine? What does CreateProc() normally initialize >>pr_ReturnAddr to, then? Exactly such a routine? > > It sets up pr_returnaddr so you'll end up in the same place as if >you RTS'ed from your program. Which is? (Cleanup code for CreateProc, or something else?) >>> Nowhere, unless (a) you're willing to use AddTask for everything, >>>and therefor are willing to reimplement the functionality of CreateProc >>>(fully, including endcode for cleaning up things like directory locks, >>>pr_SegList pointer (which is bizarre), etc). >> >>I'm willing to use AddTask if it will still operate as a DOS process >>and be able to call dos.library routines. How should I go about doing >>this? Also, what makes pr_SegList bizare? (aside from usage of >>BPTRs?) > > I REALLY don't advise it, plus it almost certainly will break in the >future. Which is why I'd prefer to avoid it. >>I don't understand what the pr_GlobVec field is used for. Will >>non-BCPL programs ever use it? What do I need to initialize it to? > > Non-BCPL shouldn't be using it. And if I wanted to (gasp!) support BCPL programs? (yeah, yeah... use Execute()...) >>pr_CLI will be set to zero. > > CLI-only programs may expect it. Hmm. I'd like to be able to have non-CLI programs; different startup code, no CLI structures tied to it, etc. The CLI is a shell. I'd rather not design a shell which depends on another one. Therefore I'd like to be able to break from the CLI, yet support programs which depend on it. Which brings up the question - Is there any feasible (and practical) way to determine if a program depends on the CLI? (Aside from trial and error; I want the shell to determine it, if possible.) One way it could be done would be have another load-file format, and convert the binaries to that format. (maybe a.out-like format) However, I'm not too keen on the idea of going so far as to write a linker and a loader. (Or a converter and loader.) It just seems to be going too far. So, is there any legitimate way to identify the binaries as "I don't need a CLI environment"? Essentially, is there a way to tag the binaries with a "magic number"? Such that it won't interfere with LoadSeg() or the code itself? Can you set a hunk name on the hunk_header hunk? (The answer looks like it should be "yes", but I don't have any blink docs onhand; only this AmigaDOS manual.) >>What's the best way to set pr_ReturnAddr? Set it to the PC plus a >>constant? JSR to a piece of code which stores the return address in >>pr_ReturnAddr and JMP's to the code? Hmm. Silly question. The >>latter, of course. > > Look how BCPL sets it up. Where am I to look? How does BCPL set it up? >>My added structure would then follow. Do you forsee any compatibility >>problems caused by a setup like this? > > In 1.4, quite possibly, but for 1.3 (modulo above) it might be ok. >Having it run BCPL programs is harder. Hmm. Any suggestion how to keep things compatible through V1.4? (besides "don't rock the boat..." :-) > Note: UnloadSeg is MUCH simpler than LoadSeg. I know, I rewrote both. >Overlays are TRICKY. I can believe it. Simple solution. Ditch overlays, add VM. *sigh* (Well, I could forget about overlays, but I don't want to rewrite LoadSeg()...) >>Other differences, such as the way directories are implemented, differ >>more significantly. Unix-style directories are far more efficient at >>directory listing (but no the hash-lookup searching AmigaDOS does) >>than AmigaDOS with its backpointers. Also, the lack of links in >>AmigaDOS is a big loss. > > But AmigaDos is much faster at opening files and testing for existance. >Unix slows down a lot with large directories, especially creation. (Mach uses >both hashing and regular unix-style directories). Part of why I wouldn't want a direct Minix port. Adding those hash chains would be useful. It's one of the few good things about AmigaDOS... >>I want to write a shell which will be more cleanly implemented than >>the CLI (i.e. no BCPL) and which will start programs with argv AND >>envp arrays, and have Unix-type calls available. > > The trick is to not break other programs by changing their environment >too much. I could see only changing the environment drastically for those programs which are tagged as ready for it. >>I have the source code to Minix available, but I don't think I want to >>do a direct port. For one thing, there are some aspects of Minix I >>would like to improve on, and Minix, while it would be very nice, >>might not be ideal for an Amiga without a hard drive. > > Tannenbaum has two students doing a port. Nice to hear. I wouldn't relish the task. At least, replacing the REAL low-level stuff, like Exec and the device handlers, I really don't feel like messing with. Rewriting the file system is as low-level as I want to get at this point, on such a scale. (And that's no small project either.) >>What I would like to do is write a file system based in part on Minix, >>and in part on AmigaDOS (but *no* BCPL!) which would work more >>effectively with floppy-based systems. (i.e. Mount file systems like >>in Minix/Unix, but volume-oriented, as in AmigaDOS.) > > 1.4 should have FFS in ROM (and available for floppies). I'm not sure FFS is all it could be, but it is clearly a step in the right direction. >>Using BCPL for AmigaDOS seems a colossal error. Exec was done in C, >>but not AmigaDOS. (I've often wondered just what TriPOS was/is like, >>though...) I understand pressures to get the OS out the door, but it >>would be best to get rid of BCPL stuff totally, and the sooner the >>better. Already AmigaDOS is getting entrenched enough that it may be >>too late. But I do hope that AmigaDOS V2.0 will be written in and for >>C code, with no BCPL thrown in. > > Exec? In C? That's a nasty thought. Exec is in ASM, of course, for >speed. Not all of it in C, but I imagine most of it could be written in C without too much of a performance penalty, and it would likely gain much maintainability. But, I can see keeping Exec in ASM. But please ditch the BCPL and use either C or Assembly for the file system. And also try to work in links in the file system. (hard links at the very least, preferably symbolic links as well.) Also, a little more flexibility concerning C: would be nice. (i.e. Execute() requiring C:RUN... Ick.) > I'll say this: your dislike for BCPL is shared by many here. Hmm. Can't say I'm surprised. Seems almost universal at times. >>But what I DO want now is the fork() and exec() system calls from >>Unix. (execve() for purists) And I'm willing to take a stab at >>writing them myself. >> >>Being the simpler of the two, let's look at fork() first. >> >>I want a *real* fork(), not a fake one like the Lattice library >>offers, which is similar in function to Execute(). (Well, closer to >>LoadSeg() followed by CreateProc, actually.) I want a fork() which >>duplicates the current process with the only difference being the >>returned value, as in Unix. > > VERY hard to do without an MMU, since you MUST duplicate the stack >and data, and those contain absolute pointers. There is no way to know >where these pointers are. The ST/Amiga-Minix gets around this by copying >the data/stack of the two processes to save areas, and "swapping" in the >data/stack to the original position whenever one needs to run. Luckily, >almost all fork() calls are followed almost immediately by exec(), so the >overhead isn't too horrible. Oh, icky. My, I had overlooked that aspect. *sigh* It's a kludge, but I guess it'll work. Can the tc_Switch and tc_Launch fields in the task structure be used to handle this? Or are they already used or not usable as such? >>Finally, (I hope) how to handle file descriptors. The solution for >>this would seem to be to have file i/o operations in this library - >>open(), close(), read(), write(), etc. and have a table of file >>descriptors, file pointers, and AmigaDOS file handles (for now, at >>least.) that the "parent" and "child" share. I don't know whether or >>not to try to preserve the parent/child relationship as Unix does, or >>try some other setup. I'll have to think about it. > > there is no way to dup a filehandle. It would be duping handles to a table entry holding the file handle. (along with the count.) >>One significant obstacle is attempting to have an exec() call as a >>scanned library linked with to make an executable program. As such, >>the text image to be completely replaced by the new program will >>contain the code to do the replacing. Clearly this poses a problem. > > So keep the code around until the new code is loaded. may increase >fragmentation a bit, but will work. Ayup. >>So, there is the problem of separating the exec() call from the text >>image. What would seem to be the most usable method would be to have >>exec() start by duplicating itself (sans copying code) into a newly >>allocated single-segment seglist, which is passed to CreateProc() with >>a high priority and a minimal stack. This is somewhat of a kludge, >>but should be workable, as CreateProc() has the cleanup code for the >>exec() function itself, once it has done its work and is no longer >>needed. > > This will work if done right. Priority shouldn't come into the >picture. Nah, priority shouldn't really be significant. Just a whimsical digression. (sorta) >>If any of the checks, allocations, or the CreateProc were to fail, >>then the exec() call would deallocate any allocated memory, and return >>with a -1 and an error number, probably in the (global) variable errno. >>Otherwise, it would simply wait forever, (pick some event to wait for >>which will never happen) and the newly created process would RemTask >>the task and handle the switchover and deallocation of the original >>task, and starting the new process up. (Then it would return, falling >>into CreateProc's cleanup code.) > > No, Wait(0) to wait forever. That would've been my guess. >>Alternatively, most allocation types could be duplicated in the >>library, with tracking versions, for automatic deallocation upon exit >>or exec(). (Oboy, now I AM digging myself a grave here, aren't I?) > > Sounds like ARP. Indeed. Don't really wanna reinvent the wheel. > I think you're working at too low a level. There are better ways to >implement the functionality you want without making the internal semantics the >same as in Unix. Define your functionality first, then figure out what you >need to get that. Well, I'm afraid part of the functionality I want is that which fork() and exec() provide. Along with pipe(). Besides, I prefer the interface. test program: #include #include struct DosLibrary *DOSBase; char msg[]="Hello, World!\n"; main() { if (DOSBase=(struct DosLibrary *) OpenLibrary("dos.library",0)) { Write(Output(),msg,sizeof(msg)); CloseLibrary((struct Library *) DOSBase); } } compile with "lc -b -r -v -y -O hello.c" link with "blink hello.o to hello" (Yes, I'm looking for the smallest executable possible in C. This came to about 168 bytes or so.) Question is, do I need the OpenLibrary and CloseLibrary calls, or can I make the loader perform them? (and is dropping the calls courting disaster?) One other thing. How can I make a simple program which runs another program and exits? (without using Execute(), that is.) I want it to use the current CLI and structure, along with command line and arguments, all being handled by the executed program. Execute() is out. (C:RUN, among other things) LoadSeg()/CreateProc() is out. (Lose the CLI interface.) I tried something with LoadSeg() followed by a jsr (via a small assembly module which took one argument - an address to jsr to.) to BADDR(++segment) followed by UnLoadSeg(--segment). It loaded the code and seemed to run ok, but when it exited, GOMF popped up several times complaining about freeing memory already freed. And the memory it loaded into never got freed. What gives? Is there some way to do this? I also tried an awful kludge with setjmp() and longjmp(), which seemed to work, but the ran program crashed because it couldn't handle not being able to access its original load file, for some reason. It was a BBS (TAG BBS, V1.15 or so) which did NOT use overlays in that version. (The current version uses overlays, and simply won't run.) If it were run from ram:, and the load file were deleted after it was ran and loaded, but before it had initialized and started up the BBS... fireworks. No GOMF, no GURU, just fireworks. *sigh* Sloppy programmers. Damn executable was 148K too, and the BBS itself sucked. Approaching time to write a BBS also, I guess. Deven -- ------- shadow@pawl.rpi.edu ------- Deven Thomas Corzine --------------------- Cogito shadow@acm.rpi.edu 2346 15th Street Pi-Rho America ergo userfxb6@rpitsmts.bitnet Troy, NY 12180-2306 (518) 272-5847 sum... In the immortal words of Socrates: "I drank what?" ...I think.