Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!bloom-beacon!apple!oliveb!amiga!cbmvax!jesup From: jesup@cbmvax.UUCP (Randell Jesup) 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: <6275@cbmvax.UUCP> Date: 15 Mar 89 03:28:04 GMT References: <0776.AA0776@julie> Reply-To: jesup@cbmvax.UUCP (Randell Jesup) Organization: Commodore Technology, West Chester, PA Lines: 175 In article <0776.AA0776@julie> mcr@julie.UUCP (Michael Richardson) writes: >>> 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. > But this also implies (correctly) that CLIs are NOT shells. They are >special. That is the very first thing that strikes people about Unix, >and where most if not all of its power comes from. Programs are programs. No, sorry. The CLI is a shell, just like Workbench, or AmigaShell. It so happens that the division isn't totally clean, and one should consider the CLI structure as part of the program environment, since programs often access it directly. 99% of unix users (not hackers) don't care much whether a Shell is somehow special or just another program. The only people who care are hackers/wizards and shell writers. >>Hmm. This seems the only reasonable way to go; replace CreateProc(), >>and use AddTask(). I take it the extra segments in the SegArray >>(pr_SegList) are such as that cleanup code for CreateProc() which are >>not to be unloaded. May I safely assume that if I replace >>CreateProc() with my own function which sets up a structure starting > What stuff do you intend on adding? No. I don't think we even want to hint whats in that SegArray, since it's pretty useless, and I'd like to see it disappear. Ignore it. >>output of the executed program, or set them to zero and define the >>standard input, output and error channels in my own structure? (I >>want stderr as a passed file descriptor, along with stdin and >>stdout...) I want to break dependency from the CLI, yet still be able > ^^^^^^^^^^^^^^^^^^^^^^^ >>to run programs which depend on the CLI themselves. (possibly by >>using or replacing the AmigaDOS RUN command.) > I disagree. CA= won't document a lot of things because they say > "it will break in 1.4" > but they won't change things because > "too many things would break" "it will break in 1.4" means we want to break people who use things they shouldn't. If they don't heed our warning, we may be more ruthless than in the past about breaking people. At some point we must move forward, or we're stuck forever with a stagnant, incomplete, outdated system. Sometimes there is no choice but to break people doing illegal things, and occasionally even legal things. Breaking people doing legal things is a last resort, and will be trumpeted if possible so people can revise. Often we will try to say "it'll work for this new release, but is outdated and will not be supported after that." This gives people 1 major release to revise their code. > That way, you can encourage people to write programs that conform >to your standard (generic programs will just need a relinking with >a new startup) instead of letting them run all their old >code unmodified. If they need the old stuff, "C=+ESC" gets most >people a CLI... This is all amusing, but we are trying to reduce the number of distinct environments in the system, not increase them. The current WB/CLI(or shell) split makes the system tough to work with, especially for novice users. > Wish read(), write(), were better documented. I don't really understand >what they do... (internally) Internals are supposed to be hidden. >>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. > Get out my head! That was my idea! :-) > Actually that would be a good initial difference for this shell. >Set a flag (pr_CIN and pr_COS==NULL? hmm. ) No. > How to pass argv and envp? This is a message passing operating >system right? Well, send the task a message... How do you tell when >the task is finished? Well, exit() returns this message (with an error >code) and then does a Wait(). The exec.library (woops that name >is taken. The Execute.library then--- I guess I mean Execute.device see >below) then RemTasks it, and deallocates it (if it isn't on the resident >list) and makes the error code available to the task. Sounds like a WorkBench process to me. > What else? How about a standard tc_ExeceptionCode? > Make SIGBREAKF_CTRL_C, and ^E exceptions. ^C will >cause an "abort()" routine to be run. (signal() or sigvec()'able of course) >The standard abort() should be able to run some number of clean up >functions, and then it should call "exit()" Can't be done unless you can GUARANTEE the PC will not be in a ROM routine, or with a Forbid() or LockIBase or ... held. Exceptions aren't as useful as you think. > Also, when ^E is received, the task does a "Wait(SIGBREAKF_CTRL_F)" >and PRESTO, Job control!!! (Or course, ^E is signal()/sigvec() settable too.) >When the shell wishes the job to continue, just send a ^F signal. (Or >any other agreed upon signal) > > This assumes something about the shell though: that it isn't part of the >same task as the programs it runs. This is fine, as this CLI "subroutine" >stuff bugs me a lot. One can get job control (at least the unix ^z part of it) without exceptions. The shell simply notices ^f and stops waiting for the current sub-process to complete. Does require running all programs in other processes. This has been done by at least one person. > It ISN'T fork()/exec(), but it does make a much more orthogonal >system, shells send messages to "execute" servers, much the same >way that comm programs send messages to "serial" devices... In fact, exactly how I do it. > Have you talked to Colin (Plumb?) (microsoft!w-colinp) > His extent based file system looks quite nice... Not for HD's. Also might be kinda slow in some cases. > I suggest that you start by writting a file system handler that >understands the AmigaDOS file system in C. Then rewrite it >(with a different file system type) that is completely C. (Get >rid of BSTR, etc... Incompatible, but that's ok.) The BSTR stuff there's mildly annoying, but really isn't too big a pain. Just use C pointers internally, and convert on packet reception/ reply. Works well, and is ever so much more compatible. >>Fork() would start with a FindTask(0L) call, allocate space for a new >>Task structure, copy the data over, and similarly duplicate the text >>and data segments, modifying the appropriate fields to point to the > ^^^^^^^^^^^ >>copies, and link in the new task to Exec with either AddTask() >>(obviously preferable) or manually if necessary. > As has been pointed out, this is VERY difficult without an MMU. No, just expensive if you _don't_ do an exec soon thereafter. Conceptually, it's easy. >>First, is whether this fork() routine would need to disable >>multitasking (interrupts seem fine) at all, such as when copying the > I don't think so. >>Task structure of the current process. Or, is it perfectly safe and >>consistent (no race conditions) to let multitasking continue >>unhindered while it initializes the new Task structure? (Clearly, it > ^^^^^^^^^^^ > Nobody but you knows about the task structure until you AddTask. >And at that point, you had better be finished fiddling with it, because >the process is ready to run. Well, you _could_ do a Forbid before the AddTask, but I wouldn't advise it if you don't need to. >>Second, how should the fork() call make execution begin at the return >>point of said fork() call? (Perhaps this question will answer itself >>when I look up AddTask().) > Look up the return address of the fork(). Put the return value under >it, and give the address of a routine that will just do an "RTS". >This stack is, of course a freshly copied stack, having all >the frame pointers, changed. Even if you leave all the data and >code shared, you must at least duplicate the stack. The stack bit won't work without MMU, at the very least. You have to make copies of the stack and data area, and then copy to the original area on a task switch whichever one is about to run (don't copy if the right tasks data is there - remember, other tasks cause switches as well). > The fexec() library function would lookup the highest FileHandle assigned >to ask (kept in an Exec list of course to eliminate that 20 files open bit) >and duplicate each one. This list would be part of the standard stuff You can't dup() a filehandle. -- Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup