Path: utzoo!attcan!uunet!lll-winken!csd4.milw.wisc.edu!leah!rpi!rpi.edu!deven From: deven@rpi.edu (Deven Corzine) Newsgroups: comp.sys.amiga.tech Subject: Re: Unix V7 functionality under (or along with) AmigaDOS? (*LONG*) Message-ID: Date: 23 Mar 89 02:50:50 GMT References: <0776.AA0776@julie> <6275@cbmvax.UUCP> <6299@cbmvax.UUCP> <6367@cbmvax.UUCP> Sender: usenet@rpi.edu Organization: RPI Public Access Workstation Lab, Troy NY Lines: 208 In-reply-to: jesup@cbmvax.UUCP's message of 21 Mar 89 20:38:56 GMT In article <6367@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes: > Maybe we should start comp.sys.amiga.shells. :-) heh... go for it. :-) >In article shadow@pawl.rpi.edu (Deven Thomas Corzine) writes: >>Exactly what generates (and allocates?) the SIGBREAKF_CTRL_{C,D,E,F} >>signals? CON:? console.device? dos.library? What? And how can you >>change/disable/deallocate these signals? > CON: assumes them, dos process startup always marks them as >allocated. They are sent by CON:. Ok, so I can just write a tty: (/dev/tty) and have it allocate different signals and use them for ^Z, etc? (Sounds like that should work perfectly...) >>If a task is RemTask()'d while in a Forbidden state, does Exec perform >>an implicit Permit(), or does the system merely die? (Same question >>goes for Disable()/Enable()...) > Yes, RemTask() implies Permit(). Also, any call to Wait() implies >Permit() until your task wakes up again. I understood that Wait() implies Permit() for the duration... but there was nothing in the documentation clearly stating what happens when a Forbidden task is RemTask()'d... >>I take it the danger is using exceptions is that the task might be in >>the middle of a ROM routine modifying system structures, and the >>system may not be internally consistent when the exception takes >>effect? (e.g. in the middle of an AllocMem() and modifying system >>memory free lists...) If not, what? > Yup. Also, the rom code maybe holding a lock on a semaphore, >or using Forbid() locking on a system structure, etc. Ok... (I thought the RKM said that Exec doesn't use semaphores itself?) >>Proposal - use exceptions to implement Amigix signal handlers. When a >>system routine is called, call a sigdisable() function which sets a >>flag in the Amigix process structure. If an exception is called and >>the exception handler finds the flag set, it simply returns so as not >>to interrupt any system calls. After the system call, sigenable() >>would be called to enable the exception handler AND process any >>pending signals. > If you want to call ROM routines, I suspect that's the only safe >way. Great. Just wanted confirmation that it would be safe and legal... >>Both the signal disabling and resource tracking are best done at the >>libcall level by patching all (ugh) of the library vectors... either >>just in exec.library, or globally in all libraries. (Not too nice to >>modify all the library jump vectors in the world, but I don't see any >>other really viable alternative. > NOT good. Better to implement your own libraries (gets you tracking >as well) that call the system libraries. You don't want to break system >stuff that calls the library entry points. Yeah, I was/am leary of the idea... The only problem I see of using my own libraries is you need to rely on the programmer to use them, and the programmer has to be more careful, with #includes and order of library linking. As an alternative, still patch all the Exec functions (much as I hate the idea of patching so many) and have the OpenLibrary() patch create a stub library for the newly opened library (if the stub library doesn't exist already, that is) and return a libptr to that. It still means patching all the exec.library functions, as the ABSEXECBASE and Lattice #pragma syscall make it difficult to use a similar stub library for the exec.library. What system stuff would/could break by calling the library entry points, and how exactly? (WHY would they break?) >>A patch could even be added to OpenLibrary() to patch any new >>libraries installed into the system (such as disk-based libraries) if >>they haven't been. Gawd, but what a mess. *sigh* > Just have amigix.exec.library OpenLibrary create the libraries >for you. Yes, an improvement... >>A common use is indeed ^Z followed by bg, for when the user forgot the >>& sign, but real job control is need for you to actually switch >>between jobs and multiplex them on one (virtual) terminal. > Well, I do have ps and wait, which is sort of useful, but there are >problems if multiple things want console input. Hence the need to change the tty driver to implement the TOSTOP ioctl so that the background task will be suspended if it attempts tty input... >>Unfortunately, it will most likely necessitate rewriting (in whole or >>in part) the console.device... Possibly making a tty.device which >>opens the console.device and adds functions, such as those needed to >>do the full job control correctly. (e.g. Unix "stty TOSTOP", etc.) > Actually it's not so much console.device as CON:. True enough. Write it as tty: for now, maybe... or just keep the driver internal until I add the file system and put it in as /dev/tty... >>Next question... exactly how do I go about handling both task traps >>and Alert() calls (and "task held"'s?) such that I can recover from >>them (killing [and cleaning up] the offending process and dumping core >>if serious enough) without the usual GURU... (i.e. how can I cause >>only a Signal() call when the system would normally GURU?) > Task helds go through the task trap vectors, I think, and are set up >by the DOS createproc code. You can catch any traps you want. Alert()s >can be SetFunction()ed. Sounds good. Any particular caveats to be mindful of here? >>Next... How can I have the run-time library (opened by OpenLibrary() >>in the process startup long before the new process image begins to >>run) return a secondary value in the global variable errno? Is it >>possible with allowing #pragmas for the library, or MUST I use stub >>routines in a compile-time library? Is it possible to specify such an >>return sequence with #pragma in Lattice? > You'll have to tell the library in every call where errno is, >I suspect (or at least the stub code). I don't think pragmas can handle >multiple returns (nor can C generate them easily). It would be easy enough to do in stub code, but I want it possible to use the #pragma libcall form... Methinks there's quite a bit of undocumented features in LC5.0... I was looking at the examples/avail.c program and the neat things it does with declaring "void __asm avail(register __a0 char *cmd)" to get the CLI command line without using any assembly startup code... and later in the program, "void __regargs prbuf(char c)" (where c is passed in D0) and calling functions __builtin_getreg() and __builtin_putreg()... all sorts of neat tricks I don't recall ever seeing documented... And starting the source file with: ; /* lc -v -j73 -cus -M -O avail blink avail.o nd protect avail +p quit */ was a stroke of genius. (not an undocumented feature, just a cute, practical and very handy trick taking full advantage of the ways comments work in EXECUTE scripts and in C... makes it easy to remember how to compile... :-) >>I suppose I could have as part of the necessary startup routine code >>to store the address of errno in a field in the Amigix process >>structure. > That will work to. Or make errno a field in your process structure >(can you say Result2?) Thought about it, but I'm still trying to keep as close to Unix semantics as I can, so I think I'll stick it in the startup... >>Next... WHY is there no ReallocMem() in exec.library??? > Actually, you can't shrink because the number of small, seperate, >bitmaps and other things needed by layers. I'm not sure layers could use >ReAllocMem. Also, unix realloc has a really sick semantic: free(ptr); >realloc(ptr,...) doesn't lose info under unix, and some unix programs (and >programmers) use that. (YECH) It IS a sick semantic, but I guess I might as well support it... It's not difficult to do after all; merely weird. (handy in cases, though...) However, you still evaded the question. Even if layers can't use ReallocMem (ReAllocMem?) [it ought to be able to, I'd say.] it should still be in exec.library. Tell you what, if I write one, will you put it in? :-) Also, is it legal to FreeMem a different sized block than you AllocMem()'d? If so, how can you keep it from depending on the granularity of the memory allocators? >>Next... How can a terminating task safely and legally deallocate the >>memory section the terminiation code is executing it? Forbid(), >>FreeMem(), RemTask(0L)? (with implicit Permit() at RemTask()?) Some >>other way? What? > It is safe to use memory that was FreeMem()ed under a Forbid(), IF >you never call Wait() or any routine that might call Wait()! So Forbid/FreeMem/RemTask(0) would be the recommended way to do that particular deallocation? One other thing... will there ever be absolute references to the stack segment (other than tc_SP*) or would it be legal (and safe) for a program to extend its stack by reallocating it, copying it and changing the few fixed pointers to it? 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.