[comp.sys.amiga.tech] Unix V7 functionality under

deven@pawl.rpi.edu (Deven Corzine) (03/06/89)

In article <6140@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>In article <DEVEN.89Mar3002118@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu 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...)

>>>>Also, when you run a resident command from the CLI or run, does Exit()
>>>>have a check for a resident seglist to decide whether or not to
>>>>UnLoadSeg() the seglist, or does it pass control back to the CLI or
>>>
>>>C programs should not be using Exit() which never matches the
>>>exit things your compiler startup wants you to clean up.
>>
>>1. Some programs still use Exit(); it's Amiga specific, not compiler
>>specific.
>>
>>2. Some programs are simply naughty and use it.
>
>	Yup.

I want a shell which will work correctly whether or not exit(),
_exit() or Exit() is called, and without regard to what compiler is
being used.  I want the shell to compile under Lattice or Aztec (but
I'm using Lattice) or any other compiler there may be (PDC if it
works, etc.)

>>3. The compiler exit() calls the compiler _exit() which calls Exit().
>
>	Not Lattice.
>
>>Regardless, I'm interested in the point where Exit() is called, not
>>where exit() is called.  I could use Lattice's onexit() function, but
>>I don't want to tie it to any single compiler and I don't want to use
>>the one onexit() available.  Also, I still want to catch it even if
>>Exit() is called by the program...
>
>	Lattice pops the stack back to the starting point, then does an RTS.
>The trick to making Exit() work is in the setting of pr_ReturnAddr.  Note
>this is somewhat magic.

So to have Exit() handled correctly, have the startup module (or
perhaps the shell?) look up the return address at the start of the
stack and copy it to pr_ReturnAddr?  Or must something else be done?

>>>The shell has the responsibility of unloading (or not unloading
>>>in the case of resident segments) the programs.
>>
>>But does this hold true when the shell is NOT running under the CLI?
>>It will be running as a DOS Process, but NOT as a CLI process.  The
>>manuals imply that Exit() frees the seglist for a DOS process but not
>>for a CLI process.  I want Exit() to leave it alone and let the shell
>>handle the seglist.  Under exactly what circumstances will Exit()
>>release memory?  (Or ANY resources...)
>
>	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?

>>Also, where can I safely store extra an extra data structure for the
>>process, without conflicting with anything?  Several possibilities
>>come to mind.
>
>	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?)

Hmm.  Looking at "The AmigaDOS manual," (AmigaDOS V1.1, I believe;
published February 1986.) it lists the Process structure starting with
BPTR SegArray, describing it as an array of SegList pointers with its
size in the first longword.  [seems consistent with BSTR's.]
"CreateProc creates this array with the first two elements of the
array pointing to resident code and the third element being the
SegList passed as argument.  When a process terminates, FreeMem is
used to return the space for the SegArray."

On the other hand, in the <libraries/dosextens.h> include file, the
Process struct is defined with pr_task, pr_MsgPort, pr_Pad, and then
BPTR pr_SegList, not SegArray.  But the comment on the line says:
/* Array of seg lists used by this process */
Is there then no difference but the name used?

>>One, put CLI process number 0 in the dos Process structure (i.e. not a
>>CLI process) and then use the CLI structure pointer field to point to
>>my structure.	 Would this cause any incompatability problems?
>
>	I'd bet yes.

I thought as much.

>>Two, make an extended structure with a process structure as its first
>>element, and add fields after it for my own use.
>
>	See above.

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
with a Process structure (as the Process struct begins with a Task
structure) that I may use the pr_SegList field as I see fit to manage
the memory, without affecting operation of programs ran by the shell?
(i.e. does anything depend on the way CreateProc() sets up
pr_SegList?)

(running down the list...)

May pr_Pad safely be ignored?

pr_StackSize seems straightforward enough.

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?

I'll set pr_TaskNum to zero.

For pr_StackBase, do I just allocate a memory area the size of
pr_StackSize, (and should I/need I allocate an extra longword to hold
the size of the allocated block, as AmigaDOS does?) and set
pr_StackBase to the last longword of the stack?  Or is it the last
byte?

Regarding pr_Result2, do I initialize it to zero and forget it, or do
I need to actually do something to get the secondary result from the
last call?  (And exactly what defines the secondary result?  The
Exit()/exit() value?)

For pr_CIS and pr_COS, should I set them to be the standard input and
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.)

Similarly, should I zero pr_ConsoleTask and pr_FileSystemTask or not?
(I intend to have read(), write(), etc. calls...  functionally similar
to Lattice's, but not dependant on the Lattice compiler or lc.lib
library.)

pr_CLI will be set to zero.

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.

I'll probably leave pr_PktWait as zero, at least for now.

I'm undecided on what to do with pr_WindowPtr.

My added structure would then follow.  Do you forsee any compatibility
problems caused by a setup like this?

>>Three, add a segment to the end of the segment list as follows:
>>
>>BPTR addseg(seglist,segsize)
>>BPTR seglist;
>>ULONG segsize;
>>{
>>>BPTR *segment, newsegment;
>>>APTR AllocMem();
>>
>>   segment=(BPTR *) BADDR(seglist);
>>   while(*segment) segment=(BPTR *) BADDR(*segment);
>>   newsegment=(BPTR *) AllocMem(segsize+8L,MEMF_PUBLIC|MEMF_CLEAR);
>>   *newsegment++=(BPTR) segsize;
>>   *segment=(BPTR) newsegment>>2;
>>   return(*segment);
>>}
>>
>>This is somewhat kludgy, to be sure, but it seems it should work.
>
>	Programs that seglist-split may be confused by this, as well as
>BCPL programs.

There is that.  I guess that idea is out.

>>On a related point, is this an equivalent function for UnLoadSeg(), or
>>does UnLoadSeg() do something else/more?
>
>	Much more.  First there's overlaid programs.  Releasing them is
>somewhat tricky, since they have open filehandles, and tables to be freed.
>Plus UnloadSeg must work for a NULL seglist.  And then there are "resident
>libraries" (yech).

Hmm.  Ok, then.  Maybe I won't try to rewrite UnLoadSeg(), at least
not unless I also rewrite LoadSeg() (which I may.)

>Another ex-RPI student...

Yes, I know.  :-)

Hey, maybe I could join CATS sometime!  :-)  (But being on the
Internet is just so nice...)

>Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

By the way, Randell, thanks for all your help...  (And I hope you'll
reply to this huge message, too...)

Time for a little more explanation of what I'm trying to do here.

I have programmed quite a bit under Unix and rather prefer the Unix
file system and system calls to many of those available on the Amiga.
I don't much care for AmigaDOS or BCPL.  Some of the user interface
issues between Unix and AmigaDOS are trivial, like "../" vs. "/" for
parent directory.

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.

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.

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.

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.)

I DO rather like the low level Exec.  The ROM Kernal is quite well
designed.  I consider AmigaDOS to be rather poor, on the other hand.
It DOES contain some rather clever design features; assigned devices
are useful (though not good as a general replacement for environment
variables) and being able to mount devices is a definite plus.

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.

Nice as it would be to rewrite the file system, I'm not quite ready to
do that just yet.  I don't have the time to spare, either.  (Sure, go
ahead and call my a hypocrite.  It's not *my* responsibility to
support the Amiga.  I have an excuse.  :-)

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.

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.

I'm afraid I don't have the RKM's with me, so I can't refer to the
semantics of AddTask().  <proto/exec.h> defines it as:

void AddTask(struct Task *, char *, char *);

The first argument is clearly the (initialized?) Task structure.  I
can't think of what the other two are offhand.  (I'll look it up
later, I guess.)

Anyhow, I see several points of possible difficulty.

First, is whether this fork() routine would need to disable
multitasking (interrupts seem fine) at all, such as when copying the
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
would be a preferable approach, but only if consistently safe.)

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().)

Third, how to make fork() return different values to the two
processes?  (I suppose by jumping to a different portion of the fork()
function with the AddTask() call, so the function can return two
different values to the two tasks.)

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.

So much for the "easy" one.  Phew!  Now, the hard one.  Coding exec().

Here is the steps Minix uses for its exec() system call:

1. Check permissions - is the file executable?
2. Read the header to get the segment and total sizes.
3. Fetch the arguments and environment from the caller.
4. Release the old memory and allocate the new one.
5. Copy stack to new memory image.
6. Copy text and data segments to new memory image.
7. Check for and handle setuid, setgid bits.
8. Fix up process table entry.
9. Tell kernal that process is now runnable.

Now, some difficulties are immediately apparent.

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.

If exec() was a real system call - if it was another function in
exec.library, there would be no big problem, as the code to replace
the text image would be separate from that image.

I could put exec() in a run-time library, true.  But I prefer to avoid
doing so.  It's one more run-time library you must remember to have
available to use the program.  It is quite annoying to try to use ARP
commands and get an error because you don't have arp.library (V34+) in
LIBS:.  So, unless the functions prove to be prohibitively large, I
prefer to have them as compile-time libraries, to simplify things for
the end user.

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.

If the setup were later modified to work as a run-time library, the
compile-time library could be easily changed to accomodate the
modification, with no program changes necessary, and recompilation
optional.

Actually, the checks for the exec() would be performed first,
including allocating memory for the new text and data segments, and
only once it is ready to replace the current process would it create
the seglist of the function to finish the job and CreateProc() it.  As
an argument to that part of the function, would be the process
structure for the process to replace.  (I suppose this would actually
be put either in a second segment in the seglist, or near the start or
at the end of the segment with the code.  As a separate [data] segment
seems best, no?)

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.)

How to handle resource deallocation of the old process presents yet
another difficulty.  (oh, but of course!)

The file descriptors would be preserved, but memory and resources
allocated by the prior process need to be released.  One solution (the
cheap and easy way out) is to free malloc() allocated memory (if I
write a malloc(), etc. set of routines) and leave other resources
allocated, (such as memory gained from AllocMem) to allow resources to
be passed to the called program.

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?)

Hmm.  I see potential problems with startup and cleanup code as well.
*sigh*  I guess I really would be better off making it a resident
library.  In that case, it would need to be set up by an
initialization program ("Unix" bootstrap program) which would install
the library in ram, start an "init" process, and then hang around as
the "system task" to coordinate everything.

And maybe add the file system and memory management tasks Minix has as
well.  I suppose adding simplistic ones to start with would be ok.
(Simplistic meaning they just process the requests by calling existing
Exec and AmigaDOS library routines, for now.)

Well, my mind is getting befuddled now, and I'm tired of typing and
this message is already too damn long.  So, I'll cut it off here.

Someone... anyone...  please reply.  I wouldn't want this to be a
wasted effort.  (And more information/ideas is always helpful.)

Enough for now.

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.

jesup@cbmvax.UUCP (Randell Jesup) (03/07/89)

In article <DEVEN.89Mar6082649@daniel.pawl.rpi.edu> 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.

>I want a shell which will work correctly whether or not exit(),
>_exit() or Exit() is called, and without regard to what compiler is
>being used.  I want the shell to compile under Lattice or Aztec (but
>I'm using Lattice) or any other compiler there may be (PDC if it
>works, etc.)

	Well, as I said, Exit() can be made to work by playing with
pr_ReturnAddr.  Note that if you play with it, restore it before you exit.
As I said before:
>>	Lattice pops the stack back to the starting point, then does an RTS.
>>The trick to making Exit() work is in the setting of pr_ReturnAddr.  Note
>>this is somewhat magic.
>
>So to have Exit() handled correctly, have the startup module (or
>perhaps the shell?) look up the return address at the start of the
>stack and copy it to pr_ReturnAddr?  Or must something else be done?

	All I'll say is figure out how it works: The tech manual and some
experimentation shoul do it (it's really very simple).

>>	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.

>>	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.

>On the other hand, in the <libraries/dosextens.h> include file, the
>Process struct is defined with pr_task, pr_MsgPort, pr_Pad, and then
>BPTR pr_SegList, not SegArray.  But the comment on the line says:
>/* Array of seg lists used by this process */
>Is there then no difference but the name used?

	Names were changed, that's all.

>>>Two, make an extended structure with a process structure as its first
>>>element, and add fields after it for my own use.
>>
>>	See above.
>
>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
>with a Process structure (as the Process struct begins with a Task
>structure) that I may use the pr_SegList field as I see fit to manage
>the memory, without affecting operation of programs ran by the shell?
>(i.e. does anything depend on the way CreateProc() sets up
>pr_SegList?)

	I _think_ you'll be ok.  I prefer to avoid the problem myself, and
find ways to not run into this.

>(running down the list...)
>
>May pr_Pad safely be ignored?

	I'd zero it.

>pr_StackSize seems straightforward enough.
>
>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.

>I'll set pr_TaskNum to zero.
>
>For pr_StackBase, do I just allocate a memory area the size of
>pr_StackSize, (and should I/need I allocate an extra longword to hold
>the size of the allocated block, as AmigaDOS does?) and set
>pr_StackBase to the last longword of the stack?  Or is it the last
>byte?

	Last longword (actually, you can set it to the loagword after the
last one, since when you push it pre-decrements.)

>Regarding pr_Result2, do I initialize it to zero and forget it, or do
>I need to actually do something to get the secondary result from the
>last call?  (And exactly what defines the secondary result?  The
>Exit()/exit() value?)

	Dos calls set pr_Result2.

>For pr_CIS and pr_COS, should I set them to be the standard input and
>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.)

	Input() and Output() return the values in pr_CIS and pr_COS.  They
must be valid for CLI-type programs.

>Similarly, should I zero pr_ConsoleTask and pr_FileSystemTask or not?
>(I intend to have read(), write(), etc. calls...  functionally similar
>to Lattice's, but not dependant on the Lattice compiler or lc.lib
>library.)

	pr_FileSystemTask is where to look if you have a 0 lock.  pr_ConsoleTask
can be dangerous to clone unless you KNOW it won't go away (used for Open("*",
...).

>pr_CLI will be set to zero.

	CLI-only programs may expect it.

>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.

>I'm undecided on what to do with pr_WindowPtr.

	Normally it's set to 0, though programs may modify it (but they should
set it back before exit).

>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.

>>>On a related point, is this an equivalent function for UnLoadSeg(), or
>>>does UnLoadSeg() do something else/more?
>>
>>	Much more.  First there's overlaid programs.  Releasing them is
>>somewhat tricky, since they have open filehandles, and tables to be freed.
>>Plus UnloadSeg must work for a NULL seglist.  And then there are "resident
>>libraries" (yech).
>
>Hmm.  Ok, then.  Maybe I won't try to rewrite UnLoadSeg(), at least
>not unless I also rewrite LoadSeg() (which I may.)

	Note: UnloadSeg is MUCH simpler than LoadSeg.  I know, I rewrote both.
Overlays are TRICKY.

>Hey, maybe I could join CATS sometime!  :-)  (But being on the
>Internet is just so nice...)

	Send a resume to carolyn@cbmvax

>I have programmed quite a bit under Unix and rather prefer the Unix
>file system and system calls to many of those available on the Amiga.
>I don't much care for AmigaDOS or BCPL.  Some of the user interface
>issues between Unix and AmigaDOS are trivial, like "../" vs. "/" for
>parent directory.

	See my posting on why this is very hard to switch (because handlers
and applications understand the syntax, and shells not knowing what is
a path versus a regular arguement.)

>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).

>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 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.

>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).

>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.

	I'll say this: your dislike for BCPL is shared by many here.

>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.

>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.

>So much for the "easy" one.  Phew!  Now, the hard one.  Coding exec().
>
>Here is the steps Minix uses for its exec() system call:
>
>1. Check permissions - is the file executable?
>2. Read the header to get the segment and total sizes.
>3. Fetch the arguments and environment from the caller.
>4. Release the old memory and allocate the new one.
>5. Copy stack to new memory image.
>6. Copy text and data segments to new memory image.
>7. Check for and handle setuid, setgid bits.
>8. Fix up process table entry.
>9. Tell kernal that process is now runnable.
>
>Now, some difficulties are immediately apparent.
>
>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.

>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.

>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.

>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.

	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.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

deven@pawl.rpi.edu (Deven Corzine) (03/08/89)

In article <6157@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>In article <DEVEN.89Mar6082649@daniel.pawl.rpi.edu> 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 <proto/exec.h>
#include <proto/dos.h>

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.

peter@sugar.hackercorp.com (Peter da Silva) (03/09/89)

In article <DEVEN.89Mar7222022@daniel.pawl.rpi.edu>, deven@pawl.rpi.edu (Deven Corzine) writes:
> And
> also try to work in links in the file system.  (hard links at the very
> least, preferably symbolic links as well.)

Symbolic links would probably be easier, actually.
-- 
Peter "Have you hugged your wolf today" da Silva      `-_-'
...texbell!sugar!peter, or peter@sugar.hackercorp.com  'U`

jesup@cbmvax.UUCP (Randell Jesup) (03/09/89)

In article <something@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu writes:
>In article <6157@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>>In article <DEVEN.89Mar6082649@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu writes:
>>>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?)

	Whatever called the program (and should cause any needed cleanup to
be done).  For something started by CreateProc, code to cleanup and remove
the process.  For something started by a shell, code to cleanup and return
to the command loop.  For things Run from a shell, similar to CreateProc
(with the addition of cleanup code for CLI structure).

>>>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_GlobVec can normally be filled in from the dos library structure.
Treat it as a magic cookie.

>>>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.)

	No.

	I'd advise using an extended CLI structure if you want any sort
of compatibility.  This may break in 1.4, but it will at least work (please
note in your docs that this may well break in 1.4 in that case).

>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.

	Yup.

>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.)

	No.

	I advise against modifying binaries.  Use one of the user
protection bits.

>>>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?

	Break out wack or metascope or some such, and look at some running
processes (write a test program).  Also, reread your tech ref manual, then
reread it again a few more times. :-(

>>>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..." :-)

	Maintain current CLI/Process structures, at least as a subset.

>>	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.)

	That's why I suggested a long time ago that Amiga-Minix be implemented
on top of Exec/Graphics/Intuition/etc.  This also means you get your
expansion hardware to work without having to hack the kernal for your
specific configuration, and plead for driver source from the HD makers.

>>	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.

	Who ever said FFS was static?  :-)

>>	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.)

	Almost everything in Exec in performance critical.  FFS is in ASM
already.

>>	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?

	yes, but respect any values already there (grab the old value, stuff
yours, and after you're called call the old value).  An example of stuff
that might use this would be saving '881 registers.

>>	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.)

	Fine, but watch out: if two BCPL programs try to use the same
filehandle, fireworks will erupt.

>>	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.

	As you wish.

>test program:
>
>#include <proto/exec.h>
>#include <proto/dos.h>
>
>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"

	First: drop -b and -r, they're redundant.  -y isn't needed, but use
-b0 (so you don't need code to set up a merged data pointer, normally in c.o).
Add a return 0, no random return codes please.  Add -cs to put strings in 
the code section, allows pc-rel access, faster, no relocations.

>(Yes, I'm looking for the smallest executable possible in C.  This
>came to about 168 bytes or so.)

	Note a fair amount of that is load-file overhead.

>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?)

	The "resident libraries" in the loadfile format were supposed to allow
that, but a) they're somewhat broken, and b) there's no way to specify version.
Do NOT try to use this feature, it won't work the way it's documented, and will
probably disappear in the future.

>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.
>
>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?

	If you don't need BCPL, it's easy, but requires ASM (well, not really
with 5.0).  You must set up A0/D0 with command string and length.  pr_ReturnAddr
should be set to avoid Exit() bypassing you.  After the program exits, you must
UnLoadSeg it.  Note that BCPL programs will NOT work in such an environment,
they are much harder to support.  Some other fields need to be set, such
as cli_Module, and other CLI fields.  When doing UnLoadSeg, use cli_Module
for your pointer, don't stash it and free.  Some programs zero cli_Module
to keep from being UnLoadSeg()ed.

	Make sure you save and restore any fields in the process/cli that you
change.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

deven@pawl.rpi.edu (Deven Corzine) (03/09/89)

In article <3607@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes:
>In article <DEVEN.89Mar7222022@daniel.pawl.rpi.edu>, I write:
>> And
>> also try to work in links in the file system.  (hard links at the very
>> least, preferably symbolic links as well.)

>Symbolic links would probably be easier, actually.

Yeah, given the silly backpointers to directories (like in the old Mac
FS) it probably would be easier to implement symbolic links.  Either
way, links should be in there.  One variety or another.

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.

deven@pawl.rpi.edu (Deven Corzine) (03/10/89)

In article <6185@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>Distribution: comp
?

>In article <something@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu writes:
>>In article <6157@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>>>In article <DEVEN.89Mar6082649@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu writes:
>	I'd advise using an extended CLI structure if you want any sort
>of compatibility.  This may break in 1.4, but it will at least work (please
>note in your docs that this may well break in 1.4 in that case).

That's one possibility, but I'd like to avoid using the CLI
structures, as they use noxious things like BPTRs and BSTRs...  I look
at it as having two ways to run programs - in a CLI environment, and
in this Unix-like environment.  New programs could be written to run
under the Unix-type environment, and CLI-type programs could be run as
a CLI process.

A big problem with CLI processes is that they are (quite arbitrarily)
limited to 20.  That is too few; I want to implement concurrent pipes
and simple backgrounding, and I don't want to have them all as CLI
processes.

Of course, the only real way to break from the BCPL crap is to rewrite
the file system, or at least the interface to it.  I wouldn't mind
doing so, and have considered it a number of times, but don't have the
time to do so just yet.  Maybe in a couple months.

Say I were to replace the interface to the file system?  (and rewrite
it later sometime. :-) )  Have open(), close(), read(), write(),
lseek(), pipe(), etc. and have most of them call AmigaDOS routines and
store things in internal tables...  If I do that, I could have a
single DOS Process to coordinate things and call the AmigaDOS
routines, and have the read(), etc. routines send messages to that
process.  Then I could replace the process structure altogether...
but have provisions to create a new CLI environment to run programs
which need it...  (or take the cheap way out and use Execute()...)

Another possibility would be to patch the OpenLibrary call (seems
preferable to patching ALL the DOS library calls) to catch any
OpenLibrary("dos.library",v) calls and check if it was one of the
non-DOS processes I created, and if so, have it open a compatibility
library instead...

Speaking of Execute(), I have a gripe with it.  V1.3 Execute() does
NOT use run if it is in the DOS Resident list, but still insists to
run c:run...  which is a BIG pain if the system disk isn't in the
drive.  (assigning c: to ram:c or rad:c isn't much help; then you
can't be asked for the system disk back to run programs in sys:c which
aren't resident...)

Say, if I replaced that Command Dir lock that's in the CLI structure
for that one CLI process, would it look there without having to
assign c: elsewhere?

>>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.)
>
>	No.

Argh.

>	I advise against modifying binaries.  Use one of the user
>protection bits.

Not such a good system.  user protection bits are all too easily lost.
I'd much rather have the binary identifiable.  The idea I had to
identify it which seems most workable is to have a special startup
module which begins with a branch past a magic number (longword) which
the shell's loader could check against.  Sound reasonable?

>>>	Tannenbaum has two students doing a port.

Tanenbaum, actually.  (glanced at his OpSys design book's cover.)

>>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.)
>
>	That's why I suggested a long time ago that Amiga-Minix be implemented
>on top of Exec/Graphics/Intuition/etc.  This also means you get your
>expansion hardware to work without having to hack the kernal for your
>specific configuration, and plead for driver source from the HD makers.

Yes, when I looked into it, I decided that it would be better
implemented on top of Exec and such.  However, there are some
low-level changes that would be valuable, like sending a signal to a
process when it goofs up, instead of GURUing and bringing down the
entire system...

But Exec is better designed in some ways than Unix.  Most notably, it
is far more dynamic, with everything in linked lists instead of static
arrays.  Then there's AmigaDOS, with its 20 CLI limit...  *sigh*

>>>	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?
>
>	yes, but respect any values already there (grab the old value, stuff
>yours, and after you're called call the old value).  An example of stuff
>that might use this would be saving '881 registers.

That's fine by me.  (expected to do so anyhow.)  What state do those
functions run in?  Supervisor or User mode?  Can they be interrupted
by the timer clock, and end up with Exec trying to switch out when it
already was?  Or, will they not be interrupted?  (i.e. if those
functions took 10 seconds to execute, would it break anything other
than system performance?)

How about using the tc_UserData field to point to an extended
structure?  Is it used for anything?  Or maybe using the name filed in
the task's node structure as an extended structure pointer?  Or are
both these out, too?

>>>	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.)
>
>	Fine, but watch out: if two BCPL programs try to use the same
>filehandle, fireworks will erupt.

No way to dup a filehandle?  Why couldn't two programs use the same
filehandle?  Can two non-BCPL programs share a file handle?  It is
lack of mutual exclusion or something else?
--
------- 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.

mcr@julie.UUCP (Michael Richardson) (03/10/89)

Someone said: (beats me, my copy of Amiga Usenet isn't up that type of thing)
[Reading in the message and deleting everything but the Subject: and
the Message-ID: line and then changing Message-ID: to References: works
nicely. Anyway--- ] SOMEONE SAID:
>>>>The shell has the responsibility of unloading (or not unloading
>>>>in the case of resident segments) the programs.
>>>
>>>But does this hold true when the shell is NOT running under the CLI?
>>>It will be running as a DOS Process, but NOT as a CLI process.  The
  I don't have any real AmigaDOS docs (just Exec docs) and I've yet to
completely understand just what is in the Process structure that is
not found in the Task structure....

>>       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.

>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?)
  So am I!!!!

>Hmm.  Looking at "The AmigaDOS manual," (AmigaDOS V1.1, I believe;
>published February 1986.) it lists the Process structure starting with
>BPTR SegArray, describing it as an array of SegList pointers with its
>size in the first longword.  [seems consistent with BSTR's.]
  I really have to get this a copy.

>On the other hand, in the <libraries/dosextens.h> include file, the
>Process struct is defined with pr_task, pr_MsgPort, pr_Pad, and then
                               ^^^^^^   ^^^^^^^^^
  I would assume that the pr_MsgPort has something to do with receiving
packets back from the file system task. (For Reads and Writes)

>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?

>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"

  I think the problem is:
    "will user x be able to run program y under your shell"
  (tell them to start a CLI)
   the problem is
    "will program x be able to run under the CLI or your shell"

  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...

>Similarly, should I zero pr_ConsoleTask and pr_FileSystemTask or not?
>(I intend to have read(), write(), etc. calls...  functionally similar
>to Lattice's, but not dependant on the Lattice compiler or lc.lib
>library.)
  Wish read(), write(), were better documented. I don't really understand
what they do... (internally)


>I have programmed quite a bit under Unix and rather prefer the Unix
>file system and system calls to many of those available on the Amiga.
>I don't much care for AmigaDOS or BCPL.  Some of the user interface
>issues between Unix and AmigaDOS are trivial, like "../" vs. "/" for
>parent directory.

>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.
  Rah! Rah! Rah!

>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. )
and then pass the argv and envp. The program which
is executed could then check for the flag and (if not set) do the "standard"
startup or just use the argv and envp. (Or things can be linked
with a startup that doesn't have this. Programmer choice)
  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.
  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()"

  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.
  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...

>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.)
  Have you talked to Colin (Plumb?) (microsoft!w-colinp)
  His extent based file system looks quite nice...

  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.)

>I DO rather like the low level Exec.  The ROM Kernal is quite well
>designed.  I consider AmigaDOS to be rather poor, on the other hand.
>It DOES contain some rather clever design features; assigned devices
>are useful (though not good as a general replacement for environment
>variables) and being able to mount devices is a definite plus.
  Unmount is need though.

>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.
  Why? In a way I rather like the idea of calling CreateTask with
an entry point. I think that the underlying mechanism could be
changed to support a more fork() like system, but in how many
cases is fork() not followed immediately by an exec()?
  In this case, the vfork() call was invented, and also the
"copy-on-write" MMU stuff (although that is very usefull for
shared libraries too)

>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.

>void AddTask(struct Task *, char *, char *);
               task         initialPC, finalPC


>Anyhow, I see several points of possible difficulty.
  So do I.

>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.

>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.

>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.

  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
passed to the execute.device (along with argv, envp and the name of the
program and/or address at which to execute)
  Parent/child is preserved without being forced.
  (How do you do redirection? Well, I guess one has to write
a custom fexec() as one couldn't go around changing the your own
FileHandles, there being no seperation like fork().  --- We don't need
to duplicate a running process structure, just get a new
"OSInterface" structure. Modify that, and pass it to the execute.device.
Actually, that could be interesting:
OpenDevice("Execute.device","ls",&lsInterface,0) and then modify the
lsInterface (instance of OSInterface) to change the environment, etc...
and then do a "DoIO()" on it with a CMD_START (or Send/BeginIO() for
asynchronous processes...))

[lots of stuff on exec() deleted]
>How to handle resource deallocation of the old process presents yet
>another difficulty.  (oh, but of course!)

>allocated by the prior process need to be released.  One solution (the
>cheap and easy way out) is to free malloc() allocated memory (if I
>write a malloc(), etc. set of routines) and leave other resources
>allocated, (such as memory gained from AllocMem) to allow resources to
>be passed to the called program.
  This makes sense to me. If you need to pass the resource, you
are already Amiga specific, use the amiga specific call...

>initialization program ("Unix" bootstrap program) which would install
>the library in ram, start an "init" process, and then hang around as
>the "system task" to coordinate everything.

  I called it "Execute.device"

>Someone... anyone...  please reply.  I wouldn't want this to be a
>wasted effort.  (And more information/ideas is always helpful.)
>
>Enough for now.
  I was going to send this as a reply (and some people may wish that
I had) but I changed my mind...

>Deven
>--
>------- shadow@pawl.rpi.edu ------- Deven Thomas Corzine ---------------------



--

  :!mcr!:
  Michael Richardson                     Amiga
                                  v--------+
 UUCP: uunet!attcan!lsuc!nrcaer!julie!mcr  | INTERNET mcr@doe.carleton.ca
 Fido: Michael Richardson @ 1:163/109.10<--+ Alter @ 7:483/109.10

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (03/12/89)

In <DEVEN.89Mar9113018@daniel.pawl.rpi.edu>, deven@pawl.rpi.edu (Deven Corzine) writes:
>A big problem with CLI processes is that they are (quite arbitrarily)
>limited to 20.  That is too few; I want to implement concurrent pipes
>and simple backgrounding, and I don't want to have them all as CLI
>processes.

This doesn't really help with what you are trying to do, but it reminded me of
a little hack I meant to post a long time ago.

-------------------------------------------------------------------------------
Hi folks, here is a useful little utility that can be stuck at the top of your
startup-sequence.  Basically what it does is it patches a DOS variable to allow
you to have up to 255 cli's open at once.  Believe it or not, you are limited
to only 20 under standard AmigaDOS.  In running this, you will permanently lose
1k of ram, but so what.  Hope this is useful to you folks out there.
   Enjoy,
      A. Caleb Gattegno
-------------------------------------------------------------------------------

begin 777 maxcli
M```#\P`````````#``````````(````9`````P````$```/I````&2QX``0@E
M/```!``B/``!``!.KO\Z+@!G2$/Y`````'``3J[]V"I`)FT`(B83Y8-.KO]\E
M($,L&")'6(E3AB+84<[__")'(KP```#_Y(=.KO^()H=.KO^"3J[_=B)-3J[^6
M8DYU``````/L`````0````$````:`````````_(```/J`````V1O<RYL:6)RR
487)Y`````_(```/K`````0```_(:_
``
end

-------------------------------------------------------------------------------

I don't know if this breaks any rules (probably does), or if it's completely
safe (might not be), but when I tried it, it worked fine. I had 255 CLIs open,
each window resized to minimum as they opened. Things got very slow, and I
could almost hear the layers code screaming for mercy, but I managed to make it
to 255, close them all again, and keep running with no apparent side effects.

A. Caleb Gattegno is a member of our loosely knit DAS group. (Devil's Advocate
Software)

-larry


--
Frisbeetarianism: The belief that when you die, your soul goes up on
                  the roof and gets stuck.
+----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                |
| \X/    lphillips@lpami.wimsey.bc.ca or uunet!van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                        |
+----------------------------------------------------------------------+

darin@nova.laic.uucp (Darin Johnson) (03/13/89)

However, the purpose of MINIX is to provide a instructional base to OS
design, not just to be an alternate OS for micro users.  This means
that if MINIX is implemented on top of Exec, then it is impossible to
expirement with different scheduling algorithms, etc.  Students would
have to still come into the labs to use the PC's, even if they did
have an Amiga.
Darin Johnson (leadsv!laic!darin@pyramid.pyramid.com)
	Can you "Spot the Looney"?

jesup@cbmvax.UUCP (Randell Jesup) (03/14/89)

In article <DEVEN.89Mar9113018@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu writes:
>In article <6185@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>>Distribution: comp
>?

	That's what Pnews gave me as a default.

>A big problem with CLI processes is that they are (quite arbitrarily)
>limited to 20.  That is too few; I want to implement concurrent pipes
>and simple backgrounding, and I don't want to have them all as CLI
>processes.

	Agreed, it is too few.  This may change.

>Of course, the only real way to break from the BCPL crap is to rewrite
>the file system, or at least the interface to it.  I wouldn't mind
>doing so, and have considered it a number of times, but don't have the
>time to do so just yet.  Maybe in a couple months.

	(suppressed giggle) it ain't as easy as it looks.  Just ask Steve
Beats (Mr FFS).

>Speaking of Execute(), I have a gripe with it.  V1.3 Execute() does
>NOT use run if it is in the DOS Resident list, but still insists to
>run c:run...  which is a BIG pain if the system disk isn't in the
>drive.  (assigning c: to ram:c or rad:c isn't much help; then you
>can't be asked for the system disk back to run programs in sys:c which
>aren't resident...)

	Known.

>Say, if I replaced that Command Dir lock that's in the CLI structure
>for that one CLI process, would it look there without having to
>assign c: elsewhere?

	You believed the name of the field, didn't you?  Poor naive boy. :-)
It's really the BPTR to the path list.

>>	I advise against modifying binaries.  Use one of the user
>>protection bits.
>
>Not such a good system.  user protection bits are all too easily lost.
>I'd much rather have the binary identifiable.  The idea I had to
>identify it which seems most workable is to have a special startup
>module which begins with a branch past a magic number (longword) which
>the shell's loader could check against.  Sound reasonable?

	I've seen it done.  Check the arp programmers docs.

>Yes, when I looked into it, I decided that it would be better
>implemented on top of Exec and such.  However, there are some
>low-level changes that would be valuable, like sending a signal to a
>process when it goofs up, instead of GURUing and bringing down the
>entire system...

	You can trap Alert().  Of course, code that dead-ends may not
deal well with Alert() returning....

[tc_Launch & tc_Switch]
>That's fine by me.  (expected to do so anyhow.)  What state do those
>functions run in?  Supervisor or User mode?  Can they be interrupted
>by the timer clock, and end up with Exec trying to switch out when it
>already was?  Or, will they not be interrupted?  (i.e. if those
>functions took 10 seconds to execute, would it break anything other
>than system performance?)

	I suspect in supervisor, non-interruptable (by the switcher, interrupts
will still occur, I suspect).  Taking 10 seconds would be very, very bad in
a real-time OS.  Even VMS doesn't take 10 seconds to switch! :-)  For more
data, ask bryce@cbmvax (I haven't played with it).

>How about using the tc_UserData field to point to an extended
>structure?  Is it used for anything?  Or maybe using the name filed in
>the task's node structure as an extended structure pointer?  Or are
>both these out, too?

	Applications are allowed to use it.  The ln_Name points to a real
task name.

>No way to dup a filehandle?  Why couldn't two programs use the same
>filehandle?  Can two non-BCPL programs share a file handle?  It is
>lack of mutual exclusion or something else?

	Two non-BCPL programs can right now.  BCPL programs use the buffering
fields in the file-handle, and would clash over them.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

jesup@cbmvax.UUCP (Randell Jesup) (03/14/89)

In article <473@laic.UUCP> darin@nova.UUCP (Darin Johnson) writes:
>However, the purpose of MINIX is to provide a instructional base to OS
>design, not just to be an alternate OS for micro users.  This means
>that if MINIX is implemented on top of Exec, then it is impossible to
>expirement with different scheduling algorithms, etc.  Students would
>have to still come into the labs to use the PC's, even if they did
>have an Amiga.

	Actually, you could easily (maybe easier than any other way)
implement Minix as a single Amiga process, with it's own internal scheduling.
Poof, problem solved (similar ideas can be used for FSs, etc - though
perhaps optionally, since FFS is real fast. :-)

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

deven@pawl.rpi.edu (Deven Corzine) (03/15/89)

In article <473@laic.UUCP> darin@nova.laic.uucp (Darin Johnson) writes:
>However, the purpose of MINIX is to provide a instructional base to OS
>design, not just to be an alternate OS for micro users.  This means
>that if MINIX is implemented on top of Exec, then it is impossible to
>expirement with different scheduling algorithms, etc.  Students would
>have to still come into the labs to use the PC's, even if they did
>have an Amiga.

The point is, an operating environment functionally compatible with
Unix would be very valuable to the Amiga user (and programmer)
community in general.  As an instructional base, fine.  Port Minix
straight.  But as an alternative operating system, it would be more
useful if layered on top of Exec/etc.  (But NOT AmigaDOS!)  There are
two different domains here; *I* am looking for the functionality, not
the instructional base, and as such, I don't care if it is a port of
Minix or not.  Actually, I prefer NOT a port of Minix, as Exec is more
dynamic than Minix, which is GOOD.  (more dynamic than Unix, too.)
AmigaDOS, however, just plain sucks.  It's a shame that people get
such a poor opinion of the Amiga's OS in general when it is only the
DOS which is so lame.  Such is life.  AmigaDOS needs to be replaced.
IMHO.

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.

rsb@dukeac.UUCP (R. Scott Bartlett) (03/15/89)

In article <6237@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>In article <DEVEN.89Mar9113018@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu writes:
>>In article <6185@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 
>>A big problem with CLI processes is that they are (quite arbitrarily)
>>limited to 20.  That is too few; I want to implement concurrent pipes
>>and simple backgrounding, and I don't want to have them all as CLI
>>processes.
 
>	Agreed, it is too few.  This may change.
 
What about setting the CLI proc number to 0?  Will some cli things choke on
this?  Lattice's forkv() uses proc number 0. (What do workbench programs do?)

>>Of course, the only real way to break from the BCPL crap is to rewrite
>>the file system, or at least the interface to it.  I wouldn't mind
>>doing so, and have considered it a number of times, but don't have the
>>time to do so just yet.  Maybe in a couple months.
>
>	(suppressed giggle) it ain't as easy as it looks.  Just ask Steve
>Beats (Mr FFS).
Let me know how you want to eliminate the BCPL stuff.  I plan on writing a ROOT:
to allow other filesystems to be mounted onto it.  It would be a great place to
eliminate some BCPL garbage (or at least hide it from those that are in the
know).
 
[stuff about braindead Execute() deleted]
 
[stuff about tc_CommandDir deleted]

>>>	I advise against modifying binaries.  Use one of the user
>>>protection bits.
>>
>>Not such a good system.  user protection bits are all too easily lost.
>>I'd much rather have the binary identifiable.  The idea I had to
>>identify it which seems most workable is to have a special startup
>>module which begins with a branch past a magic number (longword) which
>>the shell's loader could check against.  Sound reasonable?
 
>	I've seen it done.  Check the arp programmers docs.

Please use the magic number.  I think using the file protection bits is a BIG
kludge.  If we go ahead and implement magic numbers, programs that depend on
the MMU for different memory setups, etc. can be identified and dealt with
accordingly.  For instance programs that are very time sensitive can be labled
with a noswap attribute (are you happy Peter? :-).  And things that depend on
having an 881 around can be identified at load time and the user can be informed
about the problem instead of having the machine go through an F-line trap or
whatever. (this can go on to include 020's and 030's...040's 050's :-)
 
>>Yes, when I looked into it, I decided that it would be better
>>implemented on top of Exec and such.  However, there are some
>>low-level changes that would be valuable, like sending a signal to a
>>process when it goofs up, instead of GURUing and bringing down the
>>entire system...
 
>	You can trap Alert().  Of course, code that dead-ends may not
>deal well with Alert() returning....
 
>[tc_Launch & tc_Switch]
back to the question about having fork() and exec() included as a linked library
or as a runtime library.  Well, to put my two cents in, i think that it should
be a runtime library so that your code can depend on it being there (sorta...)
and so that your task does not have to include all of his extra code.  I like
the idea of an init proc.  You could send a message to init's port (internal to
fork) and wait for a reply.  Init would copy the proc and send a message to the
parent and to the child with the respective returns for each.  If i'm not
mistaken there is a field in the Task structure that contains the pc.  Init
could use this to set the child up executing at the same place (offsets would
of course have to be calculated).

>>How about using the tc_UserData field to point to an extended
>>structure?  Is it used for anything?  Or maybe using the name filed in
>>the task's node structure as an extended structure pointer?  Or are
>>both these out, too?
>
>	Applications are allowed to use it.  The ln_Name points to a real
>task name.

According to John Toebes, he uses tc_UserData for something in lc.lib.  If I
rember correctly, he uses it for forkv() and forkl().  I asked him about it
because i was going to use it to store env variables.  Oh well...

[problems with BCPL programs using the same file handles deleted (please
 answer the question though)]

>-- 
>Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup


						rsb

ps  I am NOT responsible for my spelchecker's errers.
--
-- 
rsb@dukeac.ac.duke.edu		///	"Amigas do it with hardware."-- Me
rutgers!mcnc!ecsvax!dukeac!rsb ///     "Sycamore is open."-- Negativ Land
I'm a HORSE, of course.    \\\///     "I luv S&M!!!"   "No geeks here!!"
Disclaimer NOT included!    \XX/     "This space for rent"

jesup@cbmvax.UUCP (Randell Jesup) (03/15/89)

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

jesup@cbmvax.UUCP (Randell Jesup) (03/15/89)

In article <DEVEN.89Mar14110615@daniel.pawl.rpi.edu> deven@pawl.rpi.edu (Deven Corzine) writes:
>AmigaDOS, however, just plain sucks.  It's a shame that people get
>such a poor opinion of the Amiga's OS in general when it is only the
>DOS which is so lame.  Such is life.  AmigaDOS needs to be replaced.
>IMHO.

	AmigaDos isn't totally bad.  It has some nice paradigms, some that are
much nicer than standard Unixes: easily mountable devices and handling of
removable media, user process filesystems (ala Mach), a message based filesystem
interface (as opposed to a monolithic kernel), unlimited numbers of open
files, some support of file locking (not totally complete yet - mainly an fs
issue).

	It is _currently_ written in BCPL and some asm.  This can be fixed.
Some of the interfaces use BPTRs and BSTRs, these can be mildly annoying but
aren't a big problem for most people, since most developers see only the C-
compatible dos.library interface.  Shell writers are the one exception to that,
and in 1.4 we hope to make it easier on them.  Sparse documentation on some
things didn't help either, but again it mostly affects shell-writers.

	The other major thing involved are the commands in the C directory.
They're not the same as Unix or MsDos, just close enough that people can get
confused sometimes.  They were originally low on functionality in some places,
that has been and is being improved (look at 1.3 for some good examples).  Most
are still in BCPL, that will change.  If you prefer, there are the arp commands
written in ASM, and using the arp.library.  They are smaller, and the arp
people added a number of options.

	The 1.3 AmigaShell is an improvement over the CLI.  Even Matt Dillon
(of csh fame) seems to really like it, and has switched over to it from his
own shell.

	Essentially what I'm saying is that it's been "fashionable" to 
denigrate AmigaDos, with some justification, but not as much as people often
imply.  The justification is much smaller in 1.3, with AmigaShell, new command
options, FFS for faster HD access, etc.  The justification will get much smaller
in 1.4.  The worst remaining problem, that of people writing shells, should be
dealt with fairly well (or I'll eat my terminal :-).

	Lastly, it's easy to say "AmigaDos sucks, we should throw it away and
start over", but in reality that's not a good option.  We would throw away
all the work people have done to work under AmigaDos, all old disks would
no longer be useable, old programs wouldn't work, we'd trade our current
annoyances for a brand spanking new set of _bugs_ and annoyances, and destroy
what confidence we have generated in the Amiga.  Plus it would take a MAJOR
effort to do that, compared to fixing what problems exist with it.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

FelineGrace@cup.portal.com (Dana B Bourgeois) (03/15/89)

Randell says one could implement Minix as a single process which would
solve the probelm of whether to put it over Exec or under.  Does that
mean some public-minded individual could implement MS-DOG on the Amiga
as a separate process?  No, wait!!  I'm serious!  Could it be done so
that recompiling would result in Amiga code?  Same calls, single threaded
but with faster graphics...

                           ...Nah!  I'm dain bramaged to think it.  I
was thinking that would be an easy way to get dBase/Lotus to port over
to the Amiga.  I'd rather have 'em learn to do it right and tackle it
head on the way WordPerfect Corp. did.  But perhaps CPM, or OS-9, or...

...Dana 

(Hey! Line Eater!  Here Boy, I've got a nice juicy line for you.)

jesup@cbmvax.UUCP (Randell Jesup) (03/15/89)

In article <1292@dukeac.UUCP> rsb@dukeac.UUCP (R. Scott Bartlett) writes:
>In article <6237@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>>	Agreed, it is too few.  This may change.
> 
>What about setting the CLI proc number to 0?  Will some cli things choke on
>this?  Lattice's forkv() uses proc number 0. (What do workbench programs do?)

	Not normally a good idea.  It removes the ability to Break the
program, or to have Status return anything reasonable.  Isn't really too
dangerous, though.

>Let me know how you want to eliminate the BCPL stuff.  I plan on writing a ROOT:
>to allow other filesystems to be mounted onto it.  It would be a great place to
>eliminate some BCPL garbage (or at least hide it from those that are in the
>know).

	Talk to Bill Hawes.  He wrote a PATH: that does similar sorts of things.
Warning: packet-forwarding can get tricky.

>>	I've seen it done.  Check the arp programmers docs.
>
>Please use the magic number.  I think using the file protection bits is a BIG
>kludge.  If we go ahead and implement magic numbers, programs that depend on
>the MMU for different memory setups, etc. can be identified and dealt with
>accordingly.  For instance programs that are very time sensitive can be labled

	Well, I don't really approve too much of magic number headers.  This
really is exactly waht the "protection" bits were designed for.  There are even
16 user-defined bits you could use.

>with a noswap attribute (are you happy Peter? :-).  And things that depend on
>having an 881 around can be identified at load time and the user can be informed
>about the problem instead of having the machine go through an F-line trap or
>whatever. (this can go on to include 020's and 030's...040's 050's :-)

	Bad example, it's trivial for the program to check execbase for 68881/2.
We don't use traps for non-881 systems.  If you want to work regardless of
'881 or not, use the math libraries.  They will automatically take advantage
of the '881 if it's there.  Far faster than traps, not as fast as in-line '881,
but works on all amigas without modification.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

peter@sugar.hackercorp.com (Peter da Silva) (03/15/89)

In article <473@laic.UUCP>, darin@nova.laic.uucp (Darin Johnson) writes:
> However, the purpose of MINIX is to provide a instructional base to OS
> design, not just to be an alternate OS for micro users.

That's the original intended purpose, maybe, but that's not waht most of
the Minix hackers out there are using it for. A minix implementation that
ran on top of exec (maybe even as a minix.library, so you could bind Minix
binaries with some minimal startup code and launch them from the CLI) would
be very useful...

Why am I reminded of Pascal?
-- 
Peter "Have you hugged your wolf today" da Silva      `-_-'
...texbell!sugar!peter, or peter@sugar.hackercorp.com  'U`

peter@sugar.hackercorp.com (Peter da Silva) (03/15/89)

Randell Jesup:
> 	Two non-BCPL programs can right now.  BCPL programs use the buffering
> fields in the file-handle, and would clash over them.

How many BCPL programs are left?

How many will be left after 1.4?

If any, why?
-- 
Peter "Have you hugged your wolf today" da Silva      `-_-'
...texbell!sugar!peter, or peter@sugar.hackercorp.com  'U`

peter@sugar.hackercorp.com (Peter da Silva) (03/15/89)

In article <6275@cbmvax.UUCP>, jesup@cbmvax.UUCP (Randell Jesup) writes:
> 	You can't dup() a filehandle.

Ah, pretty please. If you do nothing else in 1.4 could you let us dup()
filehandles, and track them so I can pass a FH to a process and not have
to worry about getting it back to close it?

I can deal with untracked memory, but there's ever so much UNIXy code out
there that expects UNIX file descriptor semantics...
-- 
Peter "Have you hugged your wolf today" da Silva      `-_-'
...texbell!sugar!peter, or peter@sugar.hackercorp.com  'U`

deven@pawl.rpi.edu (Deven Corzine) (03/16/89)

In article <0776.AA0776@julie> mcr@julie.UUCP (Michael Richardson) writes:
 >Someone said: (beats me, my copy of Amiga Usenet isn't up that type of thing)
 >[Reading in the message and deleting everything but the Subject: and
 >the Message-ID: line and then changing Message-ID: to References: works
 >nicely. Anyway--- ] SOMEONE SAID:
 >>>>>The shell has the responsibility of unloading (or not unloading
 >>>>>in the case of resident segments) the programs.

     ^^^^^  Randell Jesup said.

 >>>>
 >>>>But does this hold true when the shell is NOT running under the CLI?
 >>>>It will be running as a DOS Process, but NOT as a CLI process.  The

    ^^^^^  I said.  (Alternating between him and I.)

 >  I don't have any real AmigaDOS docs (just Exec docs) and I've yet to
 >completely understand just what is in the Process structure that is
 >not found in the Task structure....

 ^^^^^  You said.  :-)

You can look at the Process structure in <libraries/dosextens.h> for
starters...

 >>>>> 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.

Well...  I wouldn't say that.  The CLI *is* a shell.  A clumsy and
quite poor one, but it is.  It should be a cleaner implementation.

 >>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?)
 >  So am I!!!!

I've been thinking about it, and I'm not really sure I *do* want to
run as a DOS Process.  Methinks maybe as a task instead.

 >>Hmm.  Looking at "The AmigaDOS manual," (AmigaDOS V1.1, I believe;
 >>published February 1986.) it lists the Process structure starting with
 >>BPTR SegArray, describing it as an array of SegList pointers with its
 >>size in the first longword.  [seems consistent with BSTR's.]
 >  I really have to get this a copy.

It could be better, but it's definitely better than nothing.

 >>On the other hand, in the <libraries/dosextens.h> include file, the
 >>Process struct is defined with pr_task, pr_MsgPort, pr_Pad, and then
 >				 ^^^^^^^  ^^^^^^^^^^
 >  I would assume that the pr_MsgPort has something to do with receiving
 >packets back from the file system task. (For Reads and Writes)

Indeed it does.  I wasn't questioning *what* pr_MsgPort was for...

 >>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?

Not entirely decided yet.  Probably will have some Unixy things like
maybe UID's/GID's, etc...  I'll have to think about 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"

I suppose there is some of that, but it IS a rather difficult position
to be in whatever they say.  Don't be so hard on them.

 >  I think the problem is:
 >    "will user x be able to run program y under your shell"
 >  (tell them to start a CLI)
 >   the problem is
 >    "will program x be able to run under the CLI or your shell"

 >  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... 

NO.  The idea here is to improve the shell and simplify life for the
programmer and the user.  Saying "What, you need the CLI?  Well, go
start one, then!" doesn't help at all.  I can see adding a program,
command or special syntax which would run the specified program in a
CLI-type environment, if that's what it needs, but telling the user to
f*ck off and die just because he wants to run a CLI-dependant program
is not what I'm after.  That sort of attitude is all too prevalent
already.

I believe in doing things right the first time.  (Or as best as
reasonable.)  If I'm going to do it, I want it done right.  If I
didn't care if it were done right, I wouldn't bother doing it myself.
There's plenty of programs done poorly out there.

 >>Similarly, should I zero pr_ConsoleTask and pr_FileSystemTask or not?
 >>(I intend to have read(), write(), etc. calls...  functionally similar
 >>to Lattice's, but not dependant on the Lattice compiler or lc.lib
 >>library.)
 >  Wish read(), write(), were better documented. I don't really understand
 >what they do... (internally)

I'm not worried about how AmigaDOS Read() and Write() calls work
internally.  They're written in BCPL anyhow.  (Ugh.)  I can
extrapolate well enough from the function's functionality (hmm - time
to join the redundancy department of redundancy department...) and the
data structures (i.e. the file system format on-disk) they access.  I
don't need to know exactly how it was done.  (Though I'm always
curious.)

 >>I have programmed quite a bit under Unix and rather prefer the Unix
 >>file system and system calls to many of those available on the Amiga.
 >>I don't much care for AmigaDOS or BCPL.  Some of the user interface
 >>issues between Unix and AmigaDOS are trivial, like "../" vs. "/" for
 >>parent directory.

 >>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.
 >  Rah! Rah! Rah!

Gee, wow.  A supporter.  :-)

 >>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! :-)

Foo.  My idea first.  It was part of my motivation behind the whole
thing.  (I just hadn't bothered to mention it yet when I first posted
to the net for information...)

 >  Actually that would be a good initial difference for this shell.
 >Set a flag (pr_CIN and pr_COS==NULL? hmm. )

Eeew.  Yuck.  No.  I decided against that sort of approach already.
Smacks of kludginess (what a word) and will probably be incompatible
later on.  (oh, but of course.)

 >and then pass the argv and envp. The program which
 >is executed could then check for the flag and (if not set) do the "standard"
 >startup or just use the argv and envp. (Or things can be linked
 >with a startup that doesn't have this. Programmer choice)

Questionable.  I'd rather not introduce such complications into the
program startup; it goes against everything I'm trying to accomplish
here.  I'm looking for a cleaner implementation of both the shell and
generally for running programs as well.  Also, keeping the startup
simple and whatnot will help keep program executable sizes small,
which IS important to me.  Besides, directly supporting the CLI
environment for new programs like that not only encourages the
kludginess already extant, but it also discourages people actually
making full use of the setup I'm building.  Not a help.

 >  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.

I may well use message passing internally to the functions, but I do
NOT want to force the programs to deal with message passing just to
run.  Workbench does.  I don't want to.  I'll keep it internal; that's
fine.  I'm trying to make things EASIER here.

 >  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()"

I'm not so sure about that.  I've considered such an idea.  But, I
don't want to tie this to any compiler, first off.  (abort() and
exit() ARE compiler-dependant, though ought to be fairly consistent
across compilers.)  And I don't want to use Exit(), certainly.  (And I
CAN'T if the task isn't a dos process.)  But there's no telling what
you might be interrupting with it.  And what cleanup code might be
missed...  Needs more thought.

 >  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)

aCk.  I don't want to use ^E and ^F regardless; if I implement any
sort of job control, I'll try to use ^Z if I can.  I'm not sure what
the way to go is...

 >  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.

Ugh.  Wasn't it clear from the start that the programs would be
separate tasks from the shell?  Perhaps not.  Well, they most
certainly would be separate tasks.  I hate the "subroutine" structure
of the CLI; it makes it seem like you've got a bunch of virtual MS-DOS
(or some such simgle-tasking system) machines in one instead of a true
multitasking system.  Everyone's answer to wanting to run multiple
programs at once is "That's easy!  Just start a new CLI!"  Can you say
screen and system clutter?  It's also clumsy as all hell, and totally
unnecessary to boot.

And WHY do I get this sinking feeling that about half the Amiga
programmers out there (i.e. the mediocre ones) pulled their
programming practices straight from the C-64??  Argh.  Yeah, I know.
They probably DID.  *sigh*

 >  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...

What you're describing is basically Workbench in text form.

 >>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.)
 >  Have you talked to Colin (Plumb?) (microsoft!w-colinp)
 >  His extent based file system looks quite nice...

No, but I have noted his postings about his file system with some
interest.  It's a bit limited, however, being tied to floppies.  But
it could work well.  Myself, I'd just assume stick with a
block-oriented format, as it is much more portable.  (like, to hard
drives and file servers and whatever.)

 >  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.)

What I will do is write a file system handler in C which will interface
with AmigaDOS behind the scenes, handling the conversions for BPTRs
and BSTRs so as to provide a clean and consistent interface for
programs to use.  I *could* write a handler which directly accesses
AmigaDOS disks, but then I'd still have to deal with BCPL crap and I
would merely be tying myself to a specific version of AmigaDOS.  I
couldn't use it for FFS, for example.  No, just as well to have
AmigaDOS play with its disks itself and coordinate that instead.

 >>I DO rather like the low level Exec.  The ROM Kernal is quite well
 >>designed.  I consider AmigaDOS to be rather poor, on the other hand.
 >>It DOES contain some rather clever design features; assigned devices
 >>are useful (though not good as a general replacement for environment
 >>variables) and being able to mount devices is a definite plus.
 >  Unmount is need though.

It would be good to have, for consistency, but I don't see it as a
particular problem; devices which are mounted and unused don't really
use much in the way of resources.  And it shouldn't be too hard to
write an unmount; Forbid() and dig around in the AmigaDOS structures
and remove the entries mount put in.  But it's not a nice thing to do.
:-)

 >>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.
 >  Why? In a way I rather like the idea of calling CreateTask with
 >an entry point. I think that the underlying mechanism could be
 >changed to support a more fork() like system, but in how many
 >cases is fork() not followed immediately by an exec()?

Many cases.  Simplest example, to implement redirection.

 >  In this case, the vfork() call was invented, and also the
 >"copy-on-write" MMU stuff (although that is very usefull for
 >shared libraries too)

vfork() is more efficient than fork() when *soon* followed by an
exec().  a fork() *immediately* followed by an exec() is functionally
identical to a task spawning function like CreateProc.  The point is,
*between* the fork() and exec(), you can set up the environment for
the new process in the context of that new process.  It is a valuable
ability.

 >>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.

Not difficult, just slow and sorta kludgy.  As Randell said, it
involves swapping the stack and data segments around, at every task
switch.  (of the forked task, that is.)  If it is *soon* followed by
an exec(), everything will be dandy.

 >>void AddTask(struct Task *, char *, char *);
 >		task         initialPC, finalPC

Yeah, I looked it up after I posted.

 >>Anyhow, I see several points of possible difficulty.
 >  So do I.

 >>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.

Nor do I.

 >>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.

Indeed.  I don't think it's a problem, really.

 >>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.

Must duplicate all, really.  I don't know whether or not it's really
worth implementing vfork() also.  Maybe.  As for getting the return
address, a JSR to a point within the function code coupled with a JMP
seems cleanest.

 >>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.

 >  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
 >passed to the execute.device (along with argv, envp and the name of the
 >program and/or address at which to execute)

WTF?  No.  The list of file descriptors is NOT to be duplicated.  It
is to be shared.  (As it is under Unix.)

 >  Parent/child is preserved without being forced.

How is it preserved, pray tell?

 >  (How do you do redirection? Well, I guess one has to write
 >a custom fexec() as one couldn't go around changing the your own
 >FileHandles, there being no seperation like fork().  --- We don't need
 >to duplicate a running process structure, just get a new
 >"OSInterface" structure. Modify that, and pass it to the execute.device.

???  Why?

 >Actually, that could be interesting:
 >OpenDevice("Execute.device","ls",&lsInterface,0) and then modify the
 >lsInterface (instance of OSInterface) to change the environment, etc...
 >and then do a "DoIO()" on it with a CMD_START (or Send/BeginIO() for
 >asynchronous processes...))

It is NOT going to be implemented as a "device".  End of subject.  It
is NOT a device, nor does it pretend to be a device in any way, shape
or form.  And it is NOT going to use OpenDevice and DoIO to start a
new process.  Do you have ANY clue how f*cking complicated Exec device
I/O IS to anyone new to the Amiga???  You have to do quite a bit to
get something simple done.  Fine if you already know it, but a supreme
bitch to deal with the first 2 dozen times around.  This does not NEED
to be implemented as a device, not SHOULD it.  It won't be.
Externally OR internally.  It WILL be a Library, though whether
link-time or run-time (as in OpenLibrary, that is) I don't yet know.

 >[lots of stuff on exec() deleted]
 >>How to handle resource deallocation of the old process presents yet
 >>another difficulty.  (oh, but of course!)

 >>allocated by the prior process need to be released.  One solution (the
 >>cheap and easy way out) is to free malloc() allocated memory (if I
 >>write a malloc(), etc. set of routines) and leave other resources
 >>allocated, (such as memory gained from AllocMem) to allow resources to
 >>be passed to the called program.
 >  This makes sense to me. If you need to pass the resource, you
 >are already Amiga specific, use the amiga specific call...

Basically.

 >>initialization program ("Unix" bootstrap program) which would install
 >>the library in ram, start an "init" process, and then hang around as
 >>the "system task" to coordinate everything.

 >  I called it "Execute.device"

Wrong.  Like I said, it will NOT be any "Execute.device".  I
understand the logic behind it, but it just isn't the way to do it.

 >>Someone... anyone...  please reply.  I wouldn't want this to be a
 >>wasted effort.  (And more information/ideas is always helpful.)
 >>
 >>Enough for now.
 >  I was going to send this as a reply (and some people may wish that
 >I had) but I changed my mind...

It's ok by me; been having trouble with mailers to reply, and there
may well be lurkers which are actually interested in this trash.  :-)

And those that don't care are welcome to hit 'n' or 'k'.

Oh, and I meant I wanted someone, anyone to reply...  either to me
directly, OR to the net...

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.

deven@pawl.rpi.edu (Deven Corzine) (03/16/89)

In article <6237@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >>>Distribution: comp
 >>?

 >        That's what Pnews gave me as a default.

Interesting.  I wonder what difference it makes?

 >>A big problem with CLI processes is that they are (quite arbitrarily)
 >>limited to 20.  That is too few; I want to implement concurrent pipes
 >>and simple backgrounding, and I don't want to have them all as CLI
 >>processes.

 >        Agreed, it is too few.  This may change.

It ought to.  Even though I think the whole structure of the CLI sucks
to begin with.  :-)

 >>Of course, the only real way to break from the BCPL crap is to rewrite
 >>the file system, or at least the interface to it.  I wouldn't mind
 >>doing so, and have considered it a number of times, but don't have the
 >>time to do so just yet.  Maybe in a couple months.

 >        (suppressed giggle) it ain't as easy as it looks.  Just ask Steve
 >Beats (Mr FFS).

Who said it was easy?  I meant I may decide to start working on a file
system in several months, not that I'll finish one in several months.
(Though I just might, you never know...)  :-)

 >>Speaking of Execute(), I have a gripe with it.  V1.3 Execute() does
 >>NOT use run if it is in the DOS Resident list, but still insists to
 >>run c:run...  which is a BIG pain if the system disk isn't in the
 >>drive.  (assigning c: to ram:c or rad:c isn't much help; then you
 >>can't be asked for the system disk back to run programs in sys:c which
 >>aren't resident...)

 >        Known.

Well, do you think maybe someone could write a patch for it and post
it to the net?  It's a real annoying bug, (well, I consider it a bug,
or at the very least, a defect.)  and something that really shouldn't
be so difficult to fix...

 >>Say, if I replaced that Command Dir lock that's in the CLI structure
 >>for that one CLI process, would it look there without having to
 >>assign c: elsewhere?

 >        You believed the name of the field, didn't you?  Poor naive boy. :-)
 >It's really the BPTR to the path list.

Figures.  What form is this path list in?  BCPL array of BSTRs?  BCPL
array of locks?  Something else?

 >>>	I advise against modifying binaries.  Use one of the user
 >>>protection bits.
 >>
 >>Not such a good system.  user protection bits are all too easily lost.
 >>I'd much rather have the binary identifiable.  The idea I had to
 >>identify it which seems most workable is to have a special startup
 >>module which begins with a branch past a magic number (longword) which
 >>the shell's loader could check against.  Sound reasonable?

 >        I've seen it done.  Check the arp programmers docs.

Hmm.  I'll take a look at 'em.

 >>Yes, when I looked into it, I decided that it would be better
 >>implemented on top of Exec and such.  However, there are some
 >>low-level changes that would be valuable, like sending a signal to a
 >>process when it goofs up, instead of GURUing and bringing down the
 >>entire system...

 >        You can trap Alert().  Of course, code that dead-ends may not
 >deal well with Alert() returning....

Now, who said Alert() would return?  Remove the task and maybe dump a
"core" file (gee) and release what it can, reasonably.

 >[tc_Launch & tc_Switch]
 >>That's fine by me.  (expected to do so anyhow.)  What state do those
 >>functions run in?  Supervisor or User mode?  Can they be interrupted
 >>by the timer clock, and end up with Exec trying to switch out when it
 >>already was?  Or, will they not be interrupted?  (i.e. if those
 >>functions took 10 seconds to execute, would it break anything other
 >>than system performance?)

 >        I suspect in supervisor, non-interruptable (by the switcher, interrupts
 >will still occur, I suspect).  Taking 10 seconds would be very, very bad in
 >a real-time OS.  Even VMS doesn't take 10 seconds to switch! :-)  For more
 >data, ask bryce@cbmvax (I haven't played with it).

Ok, good.  That's what I figured it would be; just wanted to check.
I'm not intending to take 10 seconds to switch in and out; just wanted
to give an extreme example...  ("Can you say, 'serious system
performance degradation,' boys and girls?")

 >>How about using the tc_UserData field to point to an extended
 >>structure?  Is it used for anything?  Or maybe using the name filed in
 >>the task's node structure as an extended structure pointer?  Or are
 >>both these out, too?

 >        Applications are allowed to use it.  The ln_Name points to a real
 >task name.

I've thought about it, and I think the best system is to use a setup
similar to how a DOS Process is set up, with a structure starting with
a task structure.  Such processes (damn, need a new term, maybe...)
would NOT run as DOS Processes, and as such could not use dos.library
calls, but replacements would be provided which would communicate
(using message passing, internal to the functions) with the "system"
task which WOULD be a DOS Process, and would coordinate calls to
AmigaDOS, and my file system, should I ever get around to writing it...

In other words, there would be a program which would be run (from the
CLI or Workbench) which would initialize the Unix-type system, install
the run-time library as permanently ram-resident,  You can do this
easily, can you not?  I mean, without dealing with LIBS: and
disk-based libraries and all that?  I want the library to be part of
the data (and/or code) of this executable program, and have it use
that to install it as a permanently ram-resident Exec Library, without
any such library in LIBS:...  I haven't looked closely at the Library
routines, but as I recall, it seemed doable enough.

This program would split apart using CreateProc to create a system
task which would handle coordination of the programs run in this
environment with the memory management routines (probably just calling
Exec routines) and the file system, both AmigaDOS and later, should I
write it, my own file system as well.

It would set up a public message port which would be used for the
internal communication for the functions, and also for control
information, such as for running that initializing program again with
instructions to shut down (Unix-type half of) the system.
(de-installing the library, aborting the running tasks, etc.)

The original program would return to caller after completing
initialization and starting the separate system process, so as to
avoid any hassles with having to RUN the program, etc.

This seems the cleanest, most efficient and all-around most workable
setup to me.  What do you think?  (i.e.  now tell me why I'm dead
wrong about this. :-)

One more thing.  I need a name.  "Unix" is clearly out.  "Amix" I
rather like and would use, but now it's taken, too.  "Minix" I don't
especially like and would give the wrong impression, as this would not
be a Minix port.  A housemate suggested "Minisculix", which is sorta
amusing, but this is looking to be more than a miniscule project.  So,
I'm pretty much at a loss for what to call it.  It would probably be
nice to have it end in "ix", just for consistency.  (everyone ELSE
does it!!) :-)  So...  have you (or anyone) ANY suggestions what this
could be called?

It will (hopefully) be functionally similar to Unix V7 (Don't want to
deal with _most_ of BSD/SysV extensions, though maybe some of them,
sooner or later.)  It may eventually be able to run stand-alone
without AmigaDOS, but it will be able to run alongside AmigaDOS from
the beginning.  (Unlike C-A's Amix...)

So?  What to name it?

 >>No way to dup a filehandle?  Why couldn't two programs use the same
 >>filehandle?  Can two non-BCPL programs share a file handle?  It is
 >>lack of mutual exclusion or something else?

 >        Two non-BCPL programs can right now.  BCPL programs use the buffering
 >fields in the file-handle, and would clash over them.

Ok, that's what I thought.  Not that I really intend to share the file
handles directly anyhow...

Deven

p.s. I saw your old address in shell.doc on that shell 1.03 beta
disk...  2340 15th Street???  I live at 2346!!  Hey, we're neighbors!
(of a sort...)  :-)

--
------- 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.

deven@pawl.rpi.edu (Deven Corzine) (03/16/89)

Grr.  Forgot to set the Reply-To field on that last posting.  *sigh*
Gotta automate that one of these days.

In article <1292@dukeac.UUCP> rsb@dukeac.UUCP (R. Scott Bartlett) writes:
 >In article <6237@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >>In article <DEVEN.89Mar9113018@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu writes:
 >>>In article <6185@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >>>A big problem with CLI processes is that they are (quite arbitrarily)
 >>>limited to 20.  That is too few; I want to implement concurrent pipes
 >>>and simple backgrounding, and I don't want to have them all as CLI
 >>>processes.

 >>	Agreed, it is too few.  This may change.

 >What about setting the CLI proc number to 0?  Will some cli things choke on
 >this?  Lattice's forkv() uses proc number 0. (What do workbench programs do?)

I considered seting the CLI proc number to 0 and still using the CLI
pointer for an extended data structure, but deided against it.  Also
decided against using the Process structure...

 >>>Of course, the only real way to break from the BCPL crap is to rewrite
 >>>the file system, or at least the interface to it.  I wouldn't mind
 >>>doing so, and have considered it a number of times, but don't have the
 >>>time to do so just yet.  Maybe in a couple months.
 >>
 >>	(suppressed giggle) it ain't as easy as it looks.  Just ask Steve
 >>Beats (Mr FFS).
 >Let me know how you want to eliminate the BCPL stuff.  I plan on
 >writing a ROOT: to allow other filesystems to be mounted onto it.  It
 >would be a great place to eliminate some BCPL garbage (or at least
 >hide it from those that are in the know).

I intend to eliminate it from the programmer's end by providing
read(), write(), etc. functions which will communicate with a DOS
Process which will convert for BCPL crap and make the AmigaDOS calls.
Later, if I write my own file system, I simply won't USE and BCPL for
it, and the same interface will be available, unchanged.

[stuff about stuff deleted deleted] :-)

 >>>>	I advise against modifying binaries.  Use one of the user
 >>>>protection bits.
 >>>
 >>>Not such a good system.  user protection bits are all too easily lost.
 >>>I'd much rather have the binary identifiable.  The idea I had to
 >>>identify it which seems most workable is to have a special startup
 >>>module which begins with a branch past a magic number (longword) which
 >>>the shell's loader could check against.  Sound reasonable?

 >>	I've seen it done.  Check the arp programmers docs.

 >Please use the magic number.  I think using the file protection bits
 >is a BIG kludge.  If we go ahead and implement magic numbers, programs
 >that depend on the MMU for different memory setups, etc. can be
 >identified and dealt with accordingly.  For instance programs that are
 >very time sensitive can be labled with a noswap attribute (are you
 >happy Peter? :-).  And things that depend on having an 881 around can
 >be identified at load time and the user can be informed about the
 >problem instead of having the machine go through an F-line trap or
 >whatever. (this can go on to include 020's and 030's...040's 050's :-)

I'm not worried about MMU's for now, but I intend to use the magic
number; it's less likely to be lost inadvertantly.

 >>>Yes, when I looked into it, I decided that it would be better
 >>>implemented on top of Exec and such.  However, there are some
 >>>low-level changes that would be valuable, like sending a signal to a
 >>>process when it goofs up, instead of GURUing and bringing down the
 >>>entire system...

 >>	You can trap Alert().  Of course, code that dead-ends may not
 >>deal well with Alert() returning....

 >>[tc_Launch & tc_Switch]
 >back to the question about having fork() and exec() included as a
 >linked library or as a runtime library.  Well, to put my two cents in,
 >i think that it should be a runtime library so that your code can
 >depend on it being there (sorta...) and so that your task does not
 >have to include all of his extra code.  I like the idea of an init
 >proc.  You could send a message to init's port (internal to fork) and
 >wait for a reply.  Init would copy the proc and send a message to the
 >parent and to the child with the respective returns for each.  If i'm
 >not mistaken there is a field in the Task structure that contains the
 >pc.  Init could use this to set the child up executing at the same
 >place (offsets would of course have to be calculated).

I think I'll go with the runtime library because it will save a LOT of
code in other executables and it will greatly simplify writing exec()
(and remove some otherwise necessary kludges.)

 >>>How about using the tc_UserData field to point to an extended
 >>>structure?  Is it used for anything?  Or maybe using the name filed in
 >>>the task's node structure as an extended structure pointer?  Or are
 >>>both these out, too?
 >>
 >>	Applications are allowed to use it.  The ln_Name points to a real
 >>task name.

 >According to John Toebes, he uses tc_UserData for something in lc.lib.
 >If I remember correctly, he uses it for forkv() and forkl().  I asked
 >him about it because i was going to use it to store env variables.  Oh
 >well...

Hmm.  Try something else. 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.

deven@pawl.rpi.edu (Deven Corzine) (03/16/89)

In article <6275@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >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.

Quite so.

 >        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.

Nor need they.  The CLI tends to force itself on the programmer, in
contrast.

 >>>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.

I'd be happy to.

 >>>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.

Seems a sensible enough system to me.

 >>  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.

Well said.  Exactly my point.

 >>  Wish read(), write(), were better documented. I don't really understand
 >>what they do... (internally)

 >        Internals are supposed to be hidden.

There is that.

 >>>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.

Descriptive response.  :-)

 >>  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.

Indeed it does.

 >>  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.

I haven't looked into exceptions too closely, but they seem to be of
some value, at least.  How much, I'm not quite sure.

 >>  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.

But that isn't really job control.  It's more like ^Z followed by a
bg.  It doesn't stop the job, only waiting for it.  How about having a
function to suspend a task?  It could freeze the exec task, optionally
causing an exception so the process can clean up some...

 >>  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.

Meaning?

 >>  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.

Ayup.

 >>  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.

Indeed.  I might not even bother to deal with packets directly (we'll
see) but just call dos.library routines directly (from the system
task) and have the system task handle BPTR/BSTR conversions...

 >>>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.

Indeed.

 >>>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.

That's what I had been wondering if I needed to do, but it seems
unnecessary...  I suppose a sorta neat kludge you could use would be
to carefully set up the stack such that you call Forbid(), clean up
the memory and resources you're using, including the memory the code
being executed is in (hence the Forbid()) and set up the stack such
that you call Forbid() and the return from it would actually call
Exit()...  Sorta messy and surely dangerous, but vaguely neat at the
same time.  :-)

 >>>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).

Yeah.  Probably use and Exec-type list and have the switched-in data
set at the head of the list... and only do copying (swapping?)
operations if it's not the right one...)

 >>  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.

I don't know what he had in mind, but I would be duping file
_descriptors_, not file handles.  The descriptors would point to
handles, in a list.  Such descriptors could be safely duplicated.

As for implementation, I think the way to go is to number file
descriptors sequentially starting at 0, as in Unix, with 0 for stdin,
1 for stdout and 2 for stderr.  However, the file descriptors would
NOT be kept in a static array, but instead in an Exec list, which
would be sorted from most-recently-used to least-recently-used -- when
it needs to use a file descriptor (for a read() or whatever) it would
search the descriptor list starting at the head of the list until it
finds the descriptor or hits the end of the list.  When it finds the
descriptor, it would Remove() the node from the list and AddHead() it
to keep the most-used descriptors nearest to the head of the list.

That should be the most efficient while keeping everything dynamic and
flexible.  Finding a free file descriptor for and open() or dup() call
would be quite inefficient, however.  Unless, perhaps, a list of file
descriptor "holes" were kept...  Only keeping track of unused
descriptors up until the highest-numbered file descriptor (which would
also be recorded) since all after that one are automatically free...

Hey, sounds good to me.  Any comments/suggestions?

You see, I want to keep everything as dynamic as possible; that is a
very good point of Exec which I want to remain consistent with.  Plus,
dynamic allocation is almost always better in the long run...

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.

deven@pawl.rpi.edu (Deven Corzine) (03/16/89)

In article <6276@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >In article <DEVEN.89Mar14110615@daniel.pawl.rpi.edu> deven@pawl.rpi.edu (Deven Corzine) writes:
 >>AmigaDOS, however, just plain sucks.  It's a shame that people get
 >>such a poor opinion of the Amiga's OS in general when it is only the
 >>DOS which is so lame.  Such is life.  AmigaDOS needs to be replaced.
 >>IMHO.

 >        AmigaDos isn't totally bad.  It has some nice paradigms, some
 >that are much nicer than standard Unixes: easily mountable devices and
 >handling of removable media, user process filesystems (ala Mach), a
 >message based filesystem interface (as opposed to a monolithic
 >kernel), unlimited numbers of open files, some support of file locking
 >(not totally complete yet - mainly an fs issue).

This is true.  As I said in another posting, there ARE things
worthwhile in AmigaDOS, such as you mention above.  The good things in
AmigaDOS often don't get enough credit (myself included) but it really
would be better to replace AmigaDOS with a FS supporting the good
points to AmigaDOS and ditching the rest.  (BCPL, most notably.)

 >        It is _currently_ written in BCPL and some asm.  This can be
 >fixed.  Some of the interfaces use BPTRs and BSTRs, these can be
 >mildly annoying but aren't a big problem for most people, since most
 >developers see only the C-compatible dos.library interface.  Shell
 >writers are the one exception to that, and in 1.4 we hope to make it
 >easier on them.  Sparse documentation on some things didn't help
 >either, but again it mostly affects shell-writers.

Perhaps.  Still, getting rid of the BPTRs and BSTRs in the interface
would be an improvement, even if they are still in use behind the
scenes.

 >        The other major thing involved are the commands in the C
 >directory.  They're not the same as Unix or MsDos, just close enough
 >that people can get confused sometimes.  They were originally low on
 >functionality in some places, that has been and is being improved
 >(look at 1.3 for some good examples).  Most are still in BCPL, that
 >will change.  If you prefer, there are the arp commands written in
 >ASM, and using the arp.library.  They are smaller, and the arp people
 >added a number of options.

I don't particularly like either option...  ARP is very nice, but
still caters to the CLI, and more importantly, is designed and written
for AmigaDOS V1.2 and so isn't entirely compatible where changes have
been made for V1.3, such as the new protection bits, etc.

 >        The 1.3 AmigaShell is an improvement over the CLI.  Even Matt
 >Dillon (of csh fame) seems to really like it, and has switched over to
 >it from his own shell.

No argument here.  AmigaShell is a vast improvement over the CLI.
It's still not good enough for me.  :-)  What I mean is that I still
want something better, which is why I intend to write it myself.  I am
currently using AmigaShell also, but I want more.  I have use Matt's
shell nad variations of it, but I consider it basically a hack.  (No
offense, Matt...)  But it IS vastly better than the CLI also, though
still not what I want.  But AmigaShell is significantly faster, which
is part of why I am using it also.

Minor (?) gripe here, though.  I wish Matt wouldn't write his code
such that it only compiles under Aztec C.  *sigh*

 >        Essentially what I'm saying is that it's been "fashionable" to
 >denigrate AmigaDos, with some justification, but not as much as people
 >often imply.  The justification is much smaller in 1.3, with
 >AmigaShell, new command options, FFS for faster HD access, etc.  The
 >justification will get much smaller in 1.4.  The worst remaining
 >problem, that of people writing shells, should be dealt with fairly
 >well (or I'll eat my terminal :-).

The justification is smaller indeed, but it will probably remain until
the whole damn thing is revamped for (presumably) V2.0...  But I
certainly have nothing against increased functionality.  I just wish
it were more cleanly implemented.  (and I don't really believe it can
be until the BCPL is ditched.  debate is clearly possible on this point.)

 >        Lastly, it's easy to say "AmigaDos sucks, we should throw it
 >away and start over", but in reality that's not a good option.  We
 >would throw away all the work people have done to work under AmigaDos,
 >all old disks would no longer be useable, old programs wouldn't work,
 >we'd trade our current annoyances for a brand spanking new set of
 >_bugs_ and annoyances, and destroy what confidence we have generated
 >in the Amiga.  Plus it would take a MAJOR effort to do that, compared
 >to fixing what problems exist with it.

There is that.  One reason why I'm taking the approach I am...
If/when I write a file system to go along with the Unix-type
functionality link&run-time libraries, it will run concurrently with
AmigaDOS and they should be able to get along reasonably well...  And
later it would be easy enough to move it so the entire thing is
standalone, running with or without AmigaDOS equally well...  Seems a
worthwhile goal to me, and it does NOT sacrifice compatibility with
AmigaDOS if you want to have it.  What could be better?  :-)

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.

deven@pawl.rpi.edu (Deven Corzine) (03/16/89)

In article <6278@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >In article <1292@dukeac.UUCP> rsb@dukeac.UUCP (R. Scott Bartlett) writes:
 >>In article <6237@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >>>	Agreed, it is too few.  This may change.
 >> 
 >>What about setting the CLI proc number to 0?  Will some cli things choke on
 >>this?  Lattice's forkv() uses proc number 0. (What do workbench programs do?)

 >        Not normally a good idea.  It removes the ability to Break the
 >program, or to have Status return anything reasonable.  Isn't really too
 >dangerous, though.

Wouldn't Status simply ignore any process that has a CLI process
number of 0?  (Strangely, sometimes Status will show a process number
as being in the billions or so (many digits anyhow) after something
crashes...  very incongrous.)

 >>Let me know how you want to eliminate the BCPL stuff.  I plan on
 >>writing a ROOT: to allow other filesystems to be mounted onto it.  It
 >>would be a great place to eliminate some BCPL garbage (or at least
 >>hide it from those that are in the know).

 >        Talk to Bill Hawes.  He wrote a PATH: that does similar sorts
 >of things.  Warning: packet-forwarding can get tricky.

I still gotta track down that PATH: device sometime.  Yeah, I could
see packet-forwarding getting tricky...  Any particular caveats you
have in mind?

 >>>	I've seen it done.  Check the arp programmers docs.
 >>
 >>Please use the magic number.  I think using the file protection bits
 >>is a BIG kludge.  If we go ahead and implement magic numbers, programs
 >>that depend on the MMU for different memory setups, etc. can be
 >>identified and dealt with accordingly.  For instance programs that are
 >>very time sensitive can be labled

 >        Well, I don't really approve too much of magic number headers.
 >This really is exactly what the "protection" bits were designed for.
 >There are even 16 user-defined bits you could use.

Be that as it may, it remains a fact that protection bits are easily
lost in distribution and simple copying.  What are these 16
user-defined bits?  I assume the upper 16 bits, but I've never seen
mention of them...

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.

deven@pawl.rpi.edu (Deven Corzine) (03/16/89)

In article <3623@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes:
 >In article <473@laic.UUCP>, darin@nova.laic.uucp (Darin Johnson) writes:
 >> However, the purpose of MINIX is to provide a instructional base to OS
 >> design, not just to be an alternate OS for micro users.

 >That's the original intended purpose, maybe, but that's not waht most of
 >the Minix hackers out there are using it for. A minix implementation that
 >ran on top of exec (maybe even as a minix.library, so you could bind Minix
 >binaries with some minimal startup code and launch them from the CLI) would
 >be very useful...

Indeed.  basically what I've been saying...  Split the instructional
from the practical...

 >Why am I reminded of Pascal?

I have no idea.

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.

deven@pawl.rpi.edu (Deven Corzine) (03/16/89)

In article <3625@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes:
 >Randell Jesup:
 >> 	Two non-BCPL programs can right now.  BCPL programs use the buffering
 >> fields in the file-handle, and would clash over them.

 >How many BCPL programs are left?

Only the AmigaDOS programs themselves, right?

 >How many will be left after 1.4?

I hope none...

 >If any, why?

Brain damage?  :-)

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.

deven@pawl.rpi.edu (Deven Corzine) (03/16/89)

In article <3626@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes:
 >In article <6275@cbmvax.UUCP>, jesup@cbmvax.UUCP (Randell Jesup) writes:
 >> 	You can't dup() a filehandle.

 >Ah, pretty please. If you do nothing else in 1.4 could you let us dup()
 >filehandles, and track them so I can pass a FH to a process and not have
 >to worry about getting it back to close it?

Why can't you, if the program you pass it to closes it?

 >I can deal with untracked memory, but there's ever so much UNIXy code out
 >there that expects UNIX file descriptor semantics...

Surely so.  Got a simple example in mind?

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.

jesup@cbmvax.UUCP (Randell Jesup) (03/16/89)

In article <DEVEN.89Mar15143212@daniel.pawl.rpi.edu> deven@pawl.rpi.edu (Deven Corzine) writes:
> >>Say, if I replaced that Command Dir lock that's in the CLI structure
> >>for that one CLI process, would it look there without having to
> >>assign c: elsewhere?
>
> >        You believed the name of the field, didn't you?  Poor naive boy. :-)
> >It's really the BPTR to the path list.
>
>Figures.  What form is this path list in?  BCPL array of BSTRs?  BCPL
>array of locks?  Something else?

	BPTR to a linked (BPTR) list of locks. (as in: {BPTR next; BPTR lock;}).
(Note all locks are BPTRs to filelock structure (or things bigger than filelock
structures)).

>In other words, there would be a program which would be run (from the
>CLI or Workbench) which would initialize the Unix-type system, install
>the run-time library as permanently ram-resident,  You can do this
>easily, can you not?  I mean, without dealing with LIBS: and
>disk-based libraries and all that?  I want the library to be part of
>the data (and/or code) of this executable program, and have it use
>that to install it as a permanently ram-resident Exec Library, without
>any such library in LIBS:...  I haven't looked closely at the Library
>routines, but as I recall, it seemed doable enough.

	Sure, just make sure it isn't unloaded (cli_module = NULL), and
do a MakeLibrary exec call.

>The original program would return to caller after completing
>initialization and starting the separate system process, so as to
>avoid any hassles with having to RUN the program, etc.

	Will work fine.

>One more thing.  I need a name.  "Unix" is clearly out.  "Amix" I
>rather like and would use, but now it's taken, too.  "Minix" I don't
>especially like and would give the wrong impression, as this would not
>be a Minix port.
...
>I'm pretty much at a loss for what to call it.  It would probably be
>nice to have it end in "ix", just for consistency.  (everyone ELSE
>does it!!) :-)  So...  have you (or anyone) ANY suggestions what this
>could be called?

	Well, if it takes forever to finish, you could call it Vaporix. :-)
How about Maxix?  Micrix?  Amigix? (AIX is out)  Fooix, Barix, FooBarix?
Fix?  Trix (maybe GNU or some such grabbed this) Vix (visual Unix)?

>p.s. I saw your old address in shell.doc on that shell 1.03 beta
>disk...  2340 15th Street???  I live at 2346!!  Hey, we're neighbors!

	Yup, used to live there around 2 years back.  Had friends that lived
at 2348 (the "O-den").  Isn't the circularity of the world suprising?

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

jesup@cbmvax.UUCP (Randell Jesup) (03/16/89)

In article <DEVEN.89Mar15151920@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven Thomas Corzine) writes:
>In article <6275@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
> >>  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.
>
>I haven't looked into exceptions too closely, but they seem to be of
>some value, at least.  How much, I'm not quite sure.

	They are of some value, but not as much as unix signal handlers.
The idea originally was the same as Unix signal handlers, but it turns out
to not be as useful, since they can cause important resources to be lost,
and locking mechanisms to be defeated.

> >        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.
>
>But that isn't really job control.  It's more like ^Z followed by a
>bg.  It doesn't stop the job, only waiting for it.  How about having a
>function to suspend a task?  It could freeze the exec task, optionally
>causing an exception so the process can clean up some...

	True, it's not exactly the same semantics as ^Z, but it gives you the
most commonly used feature of it.  There is no real support in exec for
non-executing tasks.

> >>  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.
>Meaning?

	Meaning in my shell (though maybe not in the ancient version you have)
I send messages to subprocesses that do all actual program execution for me.
The message includes seglist, priority, current directory, input and output
streams, etc, etc.  When the program exits it sends the message back with the
return code.  I can have any number of these running for pipes, or background
tasks (via ^f or &).

>As for implementation, I think the way to go is to number file
>descriptors sequentially starting at 0, as in Unix, with 0 for stdin,
>1 for stdout and 2 for stderr.  However, the file descriptors would
>NOT be kept in a static array, but instead in an Exec list, which
>would be sorted from most-recently-used to least-recently-used -- when
...
>That should be the most efficient while keeping everything dynamic and
>flexible.  Finding a free file descriptor for and open() or dup() call
>would be quite inefficient, however.  Unless, perhaps, a list of file
>descriptor "holes" were kept...  Only keeping track of unused
>descriptors up until the highest-numbered file descriptor (which would
>also be recorded) since all after that one are automatically free...

	It sounds pretty good to me.  Just make sure close merges in the holes
correctly (I assume the holes will stored as ranges).

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

peter@sugar.hackercorp.com (Peter da Silva) (03/16/89)

In article <DEVEN.89Mar15164239@daniel.pawl.rpi.edu>, deven@pawl.rpi.edu (Deven Corzine) writes:
> In article <3626@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes:
>  >Ah, pretty please. If you do nothing else in 1.4 could you let us dup()
>  >filehandles, and track them so I can pass a FH to a process and not have
>  >to worry about getting it back to close it?

> Why can't you, if the program you pass it to closes it?

I'm working on a shell (it's called "browser"). The program I pass
it to does not, in general, know that I want them to close it.

>  >I can deal with untracked memory, but there's ever so much UNIXy code out
>  >there that expects UNIX file descriptor semantics...

> Surely so.  Got a simple example in mind?

Surely. Any UNIX program that does I/O redirection.

	if(!fork()) {
		close(0);
		fd = open("/tmp/workfile", 1);
		if(fd!=0) exit(1);
		execl("/usr/peter/bin/output", "output", (char *)0);
		exit(2);
	}

No need to do ANYTHING to clean up /tmp/workfile.
-- 
Peter "Have you hugged your wolf today" da Silva      `-_-'
...texbell!sugar!peter, or peter@sugar.hackercorp.com  'U`

andy@cbmvax.UUCP (Andy Finkel) (03/16/89)

In article <DEVEN.89Mar15163112@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven Thomas Corzine) writes:
>In article <6278@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
> >>What about setting the CLI proc number to 0?  Will some cli things choke on
> >>this?  Lattice's forkv() uses proc number 0. (What do workbench programs do?)
>
> >        Not normally a good idea.  It removes the ability to Break the
> >program, or to have Status return anything reasonable.  Isn't really too
> >dangerous, though.
>
>Wouldn't Status simply ignore any process that has a CLI process
>number of 0?  (Strangely, sometimes Status will show a process number

The standard Status command will ignore any process with a process
number of 0.  Of course, you realize that the CLI process number is
an index to the task table.  Other programs that play with the
task table may not have the error check that status does.
So it is a risk of memory corruption, depending on what other
programs the end user has.

>as being in the billions or so (many digits anyhow) after something
>crashes...  very incongrous.)

That's what happens when memory is corrupted.  You took a hit in your
process structure.

> >        Talk to Bill Hawes.  He wrote a PATH: that does similar sorts
> >of things.  Warning: packet-forwarding can get tricky.

>I still gotta track down that PATH: device sometime.  Yeah, I could
>see packet-forwarding getting tricky...  Any particular caveats you
>have in mind?

Though it may seem like a clean solution at first, you'll find that
a packet forwarder won't ever be able to just put the sender
in touch with the real receiver, but must stay in the loop, forwarding
each packet.

You might want to take a look at the path handler (with source)
that came by comp.amiga.sources as well.

>Be that as it may, it remains a fact that protection bits are easily
>lost in distribution and simple copying.  What are these 16
>user-defined bits?  I assume the upper 16 bits, but I've never seen
>mention of them...

There are only 8 user-defined protection bits; as you surmised, the
upper 8 bits are the user bits.  The 1.3 Copy command preserves
protection bits by default.  The next version of ZOO will preserve
all protection bits as well.  

Granted, magic numbers are never in danger of being lost, and may be
a better solution thab protection bits.  Hmmm, I wonder if romtags
could be adapted...nah :-)

		andy
-- 
andy finkel		{uunet|rutgers|amiga}!cbmvax!andy
Commodore-Amiga, Inc.

"The salesperson said this computer is the next best thing to sliced
 bread, but didn't say what to do about the crumbs in the disk drive."

Any expressed opinions are mine; but feel free to share.
I disclaim all responsibilities, all shapes, all sizes, all colors.

jesup@cbmvax.UUCP (Randell Jesup) (03/17/89)

In article <DEVEN.89Mar15164016@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven Thomas Corzine) writes:
> >How many BCPL programs are left?
>
>Only the AmigaDOS programs themselves, right?

	Well, anything from Metacomco (as in Assem and their Shell) is in BCPL.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

w-colinp@microsoft.UUCP (Colin Plumb) (03/17/89)

jesup@cbmvax.UUCP (Randell Jesup) wrote:
>> A big problem with CLI processes is that they are (quite arbitrarily)
>> limited to 20.
> 
> 	Agreed, it is too few.  This may change.

This isn't that hard to enlarge, but you want to get rid of the restriction
completely.  Arrgh!  If someone would give me a complete spec for dos.library
(basically, a list of BCPL kludges that need supporting), I could give you a
rewrite in a month.  The silly thing doesn't *do* dick all.

>> Of course, the only real way to break from the BCPL crap is to rewrite
>> the file system, or at least the interface to it.
> 
> 	(suppressed giggle) it ain't as easy as it looks.  Just ask Steve
> Beats (Mr FFS).

Actually, the interface isn't that bad.  A few BPTRs raise their heads,
and there are such idiocies as ExNext(), but it's bearable.  Still,
I wouldn't mind a nicer one, especially when dealing with the DevInfo
list.

>> I'd much rather have the binary identifiable.  The idea I had to
>> identify it which seems most workable is to have a special startup
>> module which begins with a branch past a magic number (longword) which
>> the shell's loader could check against.  Sound reasonable?
> 
> 	I've seen it done.  Check the arp programmers docs.

My preference is to define a new & improved executable format, preferably
an IFF FORM.  Then you can stick in all sorts of magic information and
not break anyone's loader.  But this would require one grand change to
LoadSeg() (and at least one conversion utility for producing executables
in this form, eventually to give way to direct linkers).

>> No way to dup a filehandle?  Why couldn't two programs use the same
>> filehandle?  Can two non-BCPL programs share a file handle?  It is
>> lack of mutual exclusion or something else?
> 
> 	Two non-BCPL programs can right now.  BCPL programs use the buffering
> fields in the file-handle, and would clash over them.

You have to handle the reference-counting manually, but you can have multiple
processes all sharing the same filehandle without problems.  The BCPL stuff
is disgusting, and I hope it gets fixed in 1.4, 'cause owing to a lack
of documentation, my FS is going to ignore that completely.  If someone
tries to jump through one of those fields, boom!

But there's no way a handler can tell that two processes talking to
it over the same filehandle aren't really one, that just has a
strange prediliction for asynchronous I/O using multiple return
message ports.

(BTW, does anyone know what AN_AsyncPkt is caused by?  Who sends an
unexpected packet to whom?)
-- 
	-Colin (uunet!microsoft!w-colinp)

"Don't listen to me.  I never do." - The Doctor

jesup@cbmvax.UUCP (Randell Jesup) (03/18/89)

In article <12361@microsoft.UUCP> w-colinp@microsoft.uucp (Colin Plumb) writes:
>jesup@cbmvax.UUCP (Randell Jesup) wrote:
>This isn't that hard to enlarge, but you want to get rid of the restriction
>completely.  Arrgh!  If someone would give me a complete spec for dos.library
>(basically, a list of BCPL kludges that need supporting), I could give you a
>rewrite in a month.  The silly thing doesn't *do* dick all.

	It does lots you don't see.  dos.library is a small part of it.

>> 	Two non-BCPL programs can right now.  BCPL programs use the buffering
>> fields in the file-handle, and would clash over them.
>
>You have to handle the reference-counting manually, but you can have multiple
>processes all sharing the same filehandle without problems.  The BCPL stuff
>is disgusting, and I hope it gets fixed in 1.4, 'cause owing to a lack
>of documentation, my FS is going to ignore that completely.  If someone
>tries to jump through one of those fields, boom!

	An FS is not allowed to even look at the fields of a filehandle other
than the value it stores in fh_Arg1 (or some such name) that is passed back
on read/write calls.  The rest of the filehandle is private to dos/application.
BCPL applications use the fields in there to do IO buffering, which is why
they break if they try to share a filehandle.

>But there's no way a handler can tell that two processes talking to
>it over the same filehandle aren't really one, that just has a
>strange prediliction for asynchronous I/O using multiple return
>message ports.

	Actually the killer is where you are in the file.  Also, who closes it?

>(BTW, does anyone know what AN_AsyncPkt is caused by?  Who sends an
>unexpected packet to whom?)

	dos.library.  If it gets a message at pr_MsgPort, and it's not the
packet it sent out to do a file operation coming back, it gurus with 
AN_AsynchPacket.  Typical mistake is to try to use any dos.library functions
that send packets from a handler for debugs (or anything else).

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

shadow@pawl.rpi.edu (Deven T. Corzine) (03/18/89)

 In article <6298@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >In article <DEVEN.89Mar15143212@daniel.pawl.rpi.edu> deven@pawl.rpi.edu (Deven Corzine) writes:
 >>>>Say, if I replaced that Command Dir lock that's in the CLI structure
 >>>>for that one CLI process, would it look there without having to
 >>>>assign c: elsewhere?
 >>
 >>>        You believed the name of the field, didn't you?  Poor naive boy. :-)
 >>>It's really the BPTR to the path list.
 >>
 >>Figures.  What form is this path list in?  BCPL array of BSTRs?  BCPL
 >>array of locks?  Something else?

 >        BPTR to a linked (BPTR) list of locks. (as in: {BPTR next;
 >BPTR lock;}).  (Note all locks are BPTRs to filelock structure (or
 >things bigger than filelock structures)).

Ok.  I understand...

 >>In other words, there would be a program which would be run (from the
 >>CLI or Workbench) which would initialize the Unix-type system, install
 >>the run-time library as permanently ram-resident,  You can do this
 >>easily, can you not?  I mean, without dealing with LIBS: and
 >>disk-based libraries and all that?  I want the library to be part of
 >>the data (and/or code) of this executable program, and have it use
 >>that to install it as a permanently ram-resident Exec Library, without
 >>any such library in LIBS:...  I haven't looked closely at the Library
 >>routines, but as I recall, it seemed doable enough.

 >        Sure, just make sure it isn't unloaded (cli_module = NULL), and
 >do a MakeLibrary exec call.

cli_module?  That's the seglist for the loaded program in the CLI
structure, isn't it?  I intended to use AllocMem (or AllocEntry,
maybe) and copy the data, allowing the CLI/Workbench to unload it, or
whatever.  Either way, I guess.

 >>The original program would return to caller after completing
 >>initialization and starting the separate system process, so as to
 >>avoid any hassles with having to RUN the program, etc.

 >        Will work fine.

I have a significant question as to the operation of AddTask(),
RemTask() and the relationships between them, memory allocation and
task termination.  The Exec RKM (V1.1) is rather unclear, I'm
afraid...

First, AddTask(task,initialPC,finalPC).  I understand that task is a
pointer to an initialized task structure and initialPC is the entry
point of the task.  That's straightforward enough.  My question
concerns the finalPC argument.

If finalPC is 0, does it simply cause a RemTask(), or will it follow
the list in the tc_MemEntry field and FreeEntry() for each entry in
the list?  (Or does RemTask() do this?)  Does it free the memory
associated with the task structure itself, or the tc_MemEntry list?
Does it try to?  If you can, would you post the actual code it uses
when you specify 0 for finalPC?  It would make things much clearer.

As for RemTask(), does it ONLY remove the task from the Exec task
ready/waiting queue, (between a Disable()/Enable() pair, of course) or
does it try to do any memory or resource deallocation as per above??
It makes a big difference...

 >>One more thing.  I need a name.  "Unix" is clearly out.  "Amix" I
 >>rather like and would use, but now it's taken, too.  "Minix" I don't
 >>especially like and would give the wrong impression, as this would not
 >>be a Minix port.
 >...
 >>I'm pretty much at a loss for what to call it.  It would probably be
 >>nice to have it end in "ix", just for consistency.  (everyone ELSE
 >>does it!!) :-)  So...  have you (or anyone) ANY suggestions what this
 >>could be called?

 >        Well, if it takes forever to finish, you could call it Vaporix. :-)
 >How about Maxix?  Micrix?  Amigix? (AIX is out)  Fooix, Barix, FooBarix?
 >Fix?  Trix (maybe GNU or some such grabbed this) Vix (visual Unix)?

It make take awhile, but hopefully not forever.  Amigix seems the best
of those...  FooBarix is amusing, though...  :-)

 >>p.s. I saw your old address in shell.doc on that shell 1.03 beta
 >>disk...  2340 15th Street???  I live at 2346!!  Hey, we're neighbors!

 >        Yup, used to live there around 2 years back.  Had friends that lived
 >at 2348 (the "O-den").  Isn't the circularity of the world suprising?

2348?  (like, on the corner?)  All I know is there's a doctor's office
there...  (and they don't ike us parking in the lot...)

 >-- 
 >Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

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.

451061@UOTTAWA.BITNET (Valentin Pepelea) (03/18/89)

Randell Jesup <jesup@cbmvax.uucp> in Message-ID: <6276@cbmvax.UUCP> writes:

>     Lastly, it's easy to say "AmigaDos sucks, we should throw it away and
> start over", but in reality that's not a good option.  We would throw away
> all the work people have done to work under AmigaDos, all old disks would
> no longer be useable, old programs wouldn't work, we'd trade our current
> annoyances for a brand spanking new set of _bugs_ and annoyances, and destroy
> what confidence we have generated in the Amiga.  Plus it would take a MAJOR
> effort to do that, compared to fixing what problems exist with it.

There is though an option which should have been considered a long time ago.
There is a multi-user, multi-tasking real-time operating system supporting
multi-processors in a mulitude of coupling models (closely, thin-wire, loosely)
called Harmony. This operating system was develloped at the NRC (National
Research Council) and released about a year or two before the Amiga came out.
The source code is readely available, so I am rather suprised that the Amiga
people way back then did not port it. Particularly knowing Carl Sassenrath s
love of object oriented operating systems.

The benefits of adopting this operating system are hardly believable. Can you
imagine an Amiga having 5 68020 Zorro boards clustered together to render that
ultimate ray-traced picture? Can you imagine an industry-wide adopted
operating system taking automatic advantage of the MMU. Harmony is one of the
only two real-time operating systems that have achieved industry-wide
acceptance. Harmony is used to control combat equipment on the latest frigates
and submarine detection on US s beloved nuclear submarines. And considering
the Soviets flair for advanced Western technology, do not be surprised if
Harmony was in control of the Mig-29.   :-)

Since the free world counts on Harmony to protect democracy, should we not
trust Harmony to run Word Perfect without crashing when memory is too low?

I talked with my professor about the possibility of porting Harmony to the
Amiga as a fourth year University project, but since Harmony has its own
low-level kernel, and thus makes porting Harmony over the Amiga Exec rather
unorthodox, I would have ended spending all my time write device driver. I
opted for another equally challenging project involving the Amiga.

Now couldn t you fellows, who already have the device drivers  source code,
port this marvellous thing. It would take you only two months.

Valentin

_________________________________________________________________________
"An  operating  system  without         Name: Valentin Pepelea
 virtual memory is an operating         Phone: (613) 233-1821
 system without virtue."                Bitnet: 451061@uottawa
                                        Usenet: Look at the header
         - Ancient Inca Proverb         Planet: Ontario!Canada!Earth

shadow@pawl.rpi.edu (Deven T. Corzine) (03/19/89)

ARGH.  Damned scheduled reboots.  Lost my original reply to this
message.  *sigh*

Gonna tentatively refer to the proposed system as "Amigix" for lack of
a better unused name.  If anyone can think of a better one, let me
know.  The sooner the better. :-)

In article <6299@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >In article <DEVEN.89Mar15151920@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven Thomas Corzine) writes:
 >>In article <6275@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >>>>  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()"

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?

 >>>        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.

 >>I haven't looked into exceptions too closely, but they seem to be of
 >>some value, at least.  How much, I'm not quite sure.

 >        They are of some value, but not as much as unix signal handlers.
 >The idea originally was the same as Unix signal handlers, but it turns out
 >to not be as useful, since they can cause important resources to be lost,
 >and locking mechanisms to be defeated.

Well, if at ALL possible, I want to implement Unix signal handlers, or
as close as I can get.  First, exactly HOW are exceptions and
SigExcept() to be used?  

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()...)

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?

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.

As for resources allocated, the solution is resource tracking.

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.

Of course, the sigdisable() and sigenable() calls would have no effect
on AmigaDOS processes or simple Exec tasks; they would only affect
Amigix processes.  The tracker functions could be written to only
operate on Amigix processes, or on all tasks.  A medium option is for
the tracker functions to note any allocated but not freed resources,
but only act on them for Amigix processes, in the form of the Amigix
process cleanup routines.  (Such routines could then easily be made
available for use by tasks and AmigaDOS processes, probably via an
OpenLibrary("amigix.library",0) call...)

Ideally, the tracker routines would be 2 general-purpose routines with
arguments indicating what arguments from the call need to be preserved
for later deallocation, along with the address of the jump vector for
the deallocation routine, with information on how to format the
arguments for the deallocation.  However, as such routines would
enormously complicate the calling sequence and probably slow things
down unacceptably and use unnecessary memory, specific functions (one
for AllocMem(), another for FreeMem(), etc.)

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*

 >>>        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.

 >>But that isn't really job control.  It's more like ^Z followed by a
 >>bg.  It doesn't stop the job, only waiting for it.  How about having a
 >>function to suspend a task?  It could freeze the exec task, optionally
 >>causing an exception so the process can clean up some...

 >        True, it's not exactly the same semantics as ^Z, but it gives
 >you the most commonly used feature of it.  There is no real support in
 >exec for non-executing tasks.

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.
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.)

 >>>>  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.
 >>Meaning?

 >        Meaning in my shell (though maybe not in the ancient version
 >you have) I send messages to subprocesses that do all actual program
 >execution for me.  The message includes seglist, priority, current
 >directory, input and output streams, etc, etc.  When the program exits
 >it sends the message back with the return code.  I can have any number
 >of these running for pipes, or background tasks (via ^f or &).

Mmm.  Not ideal, but a very workable system...

 >>As for implementation, I think the way to go is to number file
 >>descriptors sequentially starting at 0, as in Unix, with 0 for stdin,
 >>1 for stdout and 2 for stderr.  However, the file descriptors would
 >>NOT be kept in a static array, but instead in an Exec list, which
 >>would be sorted from most-recently-used to least-recently-used -- when
 >...
 >>That should be the most efficient while keeping everything dynamic and
 >>flexible.  Finding a free file descriptor for and open() or dup() call
 >>would be quite inefficient, however.  Unless, perhaps, a list of file
 >>descriptor "holes" were kept...  Only keeping track of unused
 >>descriptors up until the highest-numbered file descriptor (which would
 >>also be recorded) since all after that one are automatically free...

 >        It sounds pretty good to me.  Just make sure close merges in
 >the holes correctly (I assume the holes will stored as ranges).

Sounds good to me, too.  :-)

Yes, the holes would be stored as ranges.  And the final range may as
well be left in for consistency.

I'm considering numbering Amigix processes similarly.  (for kill(),
ps(1), etc.)  Comments/suggestions?


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?)  How (for
example) does GOMF (usually) trap it?  (and why does it sometimes
miss?)


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?

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.  I may be stuck with that option, though it is somewhat of
a kludge...


Next...  WHY is there no ReallocMem() in exec.library???  It should be
fairly trivial to implement; a Forbid(), scan the memory list to see
if there would be be an appropriately sized block AFTER the old block
is released, and if so, release the old block, allocate the new one,
byte copy the old block to the new one (it must handle overlapping
blocks) and Permit() and return the new block.  Simple.  I could
implement it in 30-45 minutes at most.

So WHY isn't it in there???  Geez.  I find it real hard to believe no
one designing Exec had heard of Unix's realloc() call, for example.  I
find it even harder to believe that anyone might consider such a
function to be useless.  Don't you people realize how frustrating it
is not to be able to SHRINK a window because there isn't enough memory
to hold both the old and new window bitmaps at once???  *sigh*  [flame
off]


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?


Ah, well...  this is enough for now...  I'm sure I'll think of
something new when I make my next post...  (in a few minutes...) :-)


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.

shadow@pawl.rpi.edu (Deven T. Corzine) (03/19/89)

In article <3632@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes:
 >In article <DEVEN.89Mar15164239@daniel.pawl.rpi.edu>, deven@pawl.rpi.edu (Deven Corzine) writes:
 >>In article <3626@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes:
 >>>Ah, pretty please. If you do nothing else in 1.4 could you let us dup()
 >>>filehandles, and track them so I can pass a FH to a process and not have
 >>>to worry about getting it back to close it?

 >>Why can't you, if the program you pass it to closes it?

 >I'm working on a shell (it's called "browser"). The program I pass
 >it to does not, in general, know that I want them to close it.

 >>>I can deal with untracked memory, but there's ever so much UNIXy code out
 >>>there that expects UNIX file descriptor semantics...

 >>Surely so.  Got a simple example in mind?

 >Surely. Any UNIX program that does I/O redirection.

 >        if(!fork()) {
 >                close(0);
 >                fd = open("/tmp/workfile", 1);
 >                if(fd!=0) exit(1);
 >                execl("/usr/peter/bin/output", "output", (char *)0);
 >                exit(2);
 >        }

 >No need to do ANYTHING to clean up /tmp/workfile.

Duh.  Yeah, that's a simple example.  I see what you mean.  Well, hey.
Use my "Amigix" environment, when/if I finish 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.

shadow@pawl.rpi.edu (Deven T. Corzine) (03/19/89)

In article <6303@cbmvax.UUCP> andy@cbmvax.UUCP (Andy Finkel) writes:
 >In article <DEVEN.89Mar15163112@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven Thomas Corzine) writes:
 >>In article <6278@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
 >>>>What about setting the CLI proc number to 0?  Will some cli things choke on
 >>>>this?  Lattice's forkv() uses proc number 0. (What do workbench programs do?)
 >>
 >>>        Not normally a good idea.  It removes the ability to Break the
 >>>program, or to have Status return anything reasonable.  Isn't really too
 >>>dangerous, though.
 >>
 >>Wouldn't Status simply ignore any process that has a CLI process
 >>number of 0?  (Strangely, sometimes Status will show a process number

 >The standard Status command will ignore any process with a process
 >number of 0.  Of course, you realize that the CLI process number is
 >an index to the task table.  Other programs that play with the
 >task table may not have the error check that status does.
 >So it is a risk of memory corruption, depending on what other
 >programs the end user has.

 >>as being in the billions or so (many digits anyhow) after something
 >>crashes...  very incongrous.)

 >That's what happens when memory is corrupted.  You took a hit in your
 >process structure.

That's what I figured.

 >>>        Talk to Bill Hawes.  He wrote a PATH: that does similar sorts
 >>>of things.  Warning: packet-forwarding can get tricky.

 >>I still gotta track down that PATH: device sometime.  Yeah, I could
 >>see packet-forwarding getting tricky...  Any particular caveats you
 >>have in mind?

 >Though it may seem like a clean solution at first, you'll find that
 >a packet forwarder won't ever be able to just put the sender
 >in touch with the real receiver, but must stay in the loop, forwarding
 >each packet.

Now why is that?  Ah, well.  No matter, I'm already going to have a
system task for coordination which will be an AmigaDOS process, though
I think I'll just have it use function calls to dos.library instead of
using packets directly, though I may change my mind...  I may well
patch dos.library also so Amigix processes can call them directly and
have the patch send a message to the system task to do the actual call
if the caller is an Amigix process instead of a dos process.

 >You might want to take a look at the path handler (with source)
 >that came by comp.amiga.sources as well.

A path handler came across comp.sources.amiga?  I don't recall one, at
least not source...  There was PathAss (gee, what a name) but I
thought that was a binary-only post.  Besides, that one is poorly
written and crashes under stressful conditions regularly.  (e.g. using
it for c: sucked.  "DOS Library general error: Unexpected packet
received."...  *sigh*)

 >>Be that as it may, it remains a fact that protection bits are easily
 >>lost in distribution and simple copying.  What are these 16
 >>user-defined bits?  I assume the upper 16 bits, but I've never seen
 >>mention of them...

 >There are only 8 user-defined protection bits; as you surmised, the
 >upper 8 bits are the user bits.  The 1.3 Copy command preserves
 >protection bits by default.  The next version of ZOO will preserve
 >all protection bits as well.  

 >Granted, magic numbers are never in danger of being lost, and may be
 >a better solution thab protection bits.  Hmmm, I wonder if romtags
 >could be adapted...nah :-)

Exactly what are romtags, hmm?

Actually, it's sorta tempting to try to write a loader which could
load object modules directly and link them dynamically...  SunOS 4.0
does this, and it's a real neat trick.  Also a bitch to implement, I
imagine...  Maybe I won't.  :-)

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.

aleks@well.UUCP (Brian J. Witt) (03/20/89)

In article <473@laic.UUCP> darin@nova.UUCP (Darin Johnson) writes:
>However, the purpose of MINIX is to provide a instructional base to OS
>design, not just to be an alternate OS for micro users.  This means
>that if MINIX is implemented on top of Exec, then it is impossible to
>expirement with different scheduling algorithms, etc.
>Darin Johnson (leadsv!laic!darin@pyramid.pyramid.com)

    Yes, running one scheduler on top of Exec it not a casual concept
to implement!  I tried putting a VAX/VMS like scheduler on top of
Exec's scheduling and had nothing but trouble.  The system was the
Wendin Operating System Toolbox. <--REFERENCE  Although I did get it
to work, the evil I was performing would make Carl lose sleep and
pace the floor.  One thing missing from the Exec process state
is "SUSPENDED": don't even try to launch me.  I faked it by
just placing the task on the WaitList.  I believe if you blew off
DOS, that creating the task would be much easier, though.

--- busy waiting for the next level 7 interrupt
--- brian

hubey@pilot.njin.net (Hubey) (03/20/89)

Here are some more names for an 'Amiga Unix':

AMUX == AMiga UniX
AVIX ==  Amiga Visual Unix
XIVA ==   Xiva Isnot Visual AmigaDOS
XINA == Xina IS Not AmigaDOS
AVX ==  Amiga Visual Unix
AVUX ==AVX, AVIX
UX == ?????  nice letter combination
DOX == Disk Operating uniX
AUX == Already in Use but good.
CAUX ==  Commodore Amiga Unix 

Personally, I have a theory called the "Power of the Three"  8-).:-).

All good names should have only three letters in their acronym.
((sometimes only two will do, but three is better))
Look  :  IBM, DEC, VAX, VMS, MVS, MAC, DOS, OS/2  PS/2  etc
          C-64, VIC, PDP, 

Looks at the Losers:  (DEC) Rainbow, Radio Shack TRS-80
             Color Computer, TRS-DOS

Amiga 2000 is too long.......How about something short and sweet for
the  future like  A-030, AX-030, AZ-020,  AMI-030X, AMI-XZ.  I don't
think the letters have to mean anything but it must be catchy.

I.e. like  EXXON, SENTRA  etc.  Sorry to waste BW but maybe it's not
such a waste.
-- 
          /   / 
         /   /         H.M. Hubey 
        /   /
\   \  /   /     INTERNET:   hubey@pilot.njin.net
 \   \/   /      RSN  ===>   hubey@OSultrix.montclair.edu
  \  /\  /       VOICE:      201-279-1603       
   \/  \/                    201-893-5269   Montclair State College
                      
      

peter@sugar.hackercorp.com (Peter da Silva) (03/20/89)

Make the Amigix tasks talk to the libraries through a specified set of glue
routines, and have all the glue routines check for pending amigix signals
when they return. This is basically how the UNIX signal handling works. Of
course, the Amigix signals would match to Amiga sigbits... you just need to
define SIGINT as SIGB_CTRLC, SIGQUIT as SIGB_CTRLD, SIGHUP as SIGB_CTRLE,
and SIGKILL as SIGB_CTRLF.

In fact a set of wrappers like that would be useful in general... Hmmm...
-- 
Peter "Have you hugged your wolf today" da Silva      `-_-'
...texbell!sugar!peter, or peter@sugar.hackercorp.com  'U`

jesup@cbmvax.UUCP (Randell Jesup) (03/22/89)

	Maybe we should start comp.sys.amiga.shells.  :-)

In article <SHADOW.89Mar19082253@pawl24.pawl.rpi.edu> 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:.

>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 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.

>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.

>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.

>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.

>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.

>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:.

>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.

>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).

>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?)

>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)

>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()!

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

deven@rpi.edu (Deven Corzine) (03/23/89)

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.89Mar19082253@pawl24.pawl.rpi.edu> 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.

jesup@cbmvax.UUCP (Randell Jesup) (03/24/89)

In article <6367@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
> >        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?)

	Exec doesn't (currently).  Other system modules do.

> >        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.

	No, the _only_ thing he has to do is open amiga.foo.library instead
of foo.library.  Since all the offsets are the same, nothing else need be done,
and amigix.foo.library will get all calls that would otherwise go to
foo.library.

>What system stuff would/could break by calling the library entry
>points, and how exactly?  (WHY would they break?)

	If make any changes to the semantics of regular system libraries, 
other libraries that called them might well break (as well as a big
performance drop).

>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...

	They're documented.  There are some new pages to the lattice manuals,
which cover some of the things you mention in more detail than in the original
manuals, call lattice support and ask about it.

>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?

	Check the exec memory chapter.

>So Forbid/FreeMem/RemTask(0) would be the recommended way to do that
>particular deallocation?

	Sure, though you don't need to RemTask(), just return from your
startup code, and you'll get removed by the system.

>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?

	All automatic variables (including pointers to automatic variables)
are on the stack.  You lose, sorry.

	int Foo() { int x; scanf("%d",&x); return x; }

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

deven@pawl.rpi.edu (Deven Corzine) (03/25/89)

In article <6389@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>In article <6367@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>>>        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.

>        No, the _only_ thing he has to do is open amiga.foo.library
>instead of foo.library.  Since all the offsets are the same, nothing
>else need be done, and amigix.foo.library will get all calls that
>would otherwise go to foo.library.

(The link stuff was more related to if the stub routines set errno.)

Sure, changing the library opened will work for all libraries, EXCEPT
for the exec.library...  Exec.library is accessed through ABSEXECBASE
at memory location 4, not from a return from the OpenLibrary call.  It
doesn't make sense to change that pointer (at ABSEXECBASE) as it would
likely cause big troubles, so I'm left with patching all the
exec.library functions, unless there's some other way I can have the
exception code figure out that it was called out of ROM code?  (Well,
that probably can't work; it still needs to handle the signals when
the call finishes...)

>>What system stuff would/could break by calling the library entry
>>points, and how exactly?  (WHY would they break?)

>        If make any changes to the semantics of regular system libraries, 
>other libraries that called them might well break (as well as a big
>performance drop).

I don't intend any semantic changes; merely to set a flag in a process
structure during the call.  Some performance drop (hopefully not TOO
bad) but shouldn't affect much else...  Oops, I guess I gotta make it
a counter so nested SysCalls will work correctly...

>>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?

>        Check the exec memory chapter.

Didn't want to look it up yourself, huh?  :-)  Well, the Exec memory
chapter doesn't say anything clear about it, except that you can't
depend on the granularity being 8; only a multiple of 4.  Nowhere does
it say anything about whether or not you can legitimately free a
different sized memory block than you originally allocated.  So what
can I do?  I don't want to preallocate memory just so I can reallocate
it as I wish...  and I'm wary of trying to write a ReallocMem()
function, unless I could convince someone to include it in V1.4...

>>So Forbid/FreeMem/RemTask(0) would be the recommended way to do that
>>particular deallocation?

>        Sure, though you don't need to RemTask(), just return from your
>startup code, and you'll get removed by the system.

You still haven't told me much about this; I don't understand how it
works.  Sure, I get the general idea, but I need to know exactly how
it all works so I can implement it correctly.  I truly hate programs
that run fine but randomly crash the machine when they exit.  I want
everything to work smoothly, and for that, I need to know how the Exec
routines operate.  I'd prefer not to go digging around in the ROMs
with a disassembler if I can avoid it.

AddTask(task,initialPC,finalPC)...

Task I understand fine.  I take it that AddTask starts off the task by
pushing finalPC on the stack (as a return address for initialPC) along
with the initial registers (including initialPC) such that it is in
the state it would be as switched out, and so have everything
conveniently set up?  (This makes most sense to me, and the
documentation I've seen implied this is the case.)

Now, the big question is what happens with finalPC.

If you fall of the end of the world (RTS) from initialPC, you will
fall into finalPC.  Fine, no problem.  What happens if you also
perform an RTS from your finalPC routine?  Will you then fall into the
system default finalizer, where you would have ended up with had you
specified a finalPC of zero?

If so, (well, regardless) what exactly does this system default
finalizer do?  Does it ONLY do a RemTask(0) (and hence never continue
past it) or does it first attempt any sort of memory or resource
deallocation, such as freeing entries listed in tc_MemEntry?  Does it
do anything else/more?

More importantly, does RemTask() ever call the finalPC routine to
allow cleanup, or is it merely a convenience for the programmer to
specify the return address from the starting point, and as such,
affecting nothing but the initial stack frame of the task?

If RemTask DOES call finalPC, then what happens when finalPC calls
RemTask()?  Sounds like a loop, which it clearly can't be, implying
that RemTask actually does nothing with finalPC and that it only
affects the task's initial stack frame.

Does RemTask itself try to handle any sort of resource deallocation
itself, including the tc_MemEntry field, or does it call finalPC to
attempt cleanup, or does it ignore all cleanup and simply pull the
task from the system task queues?

Exactly what agency handles the deallocation of the Task structure
itself?  Is this something the system default finalizer does before
calling RemTask (and after calling Forbid, perhaps?) or does RemTask
itself, or is the program which did the original AddTask expected to
hang around to handle it?

If you supply a finalPC routine which does resource deallocation,
including that of the program code, the Task structure and the
tc_MemEntry field, (code and task structure memory freed last after a
Forbid) ending the finalPC routine with RemTask(0), does that mean
that the system default finalizer would NEVER run, the finalPC routine
will run exactly once, and nothing will be tried to be freed twice?

Basically, what it all boils down to is just what the hell is
happening when a task terminates?

>>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?

>        All automatic variables (including pointers to automatic variables)
>are on the stack.  You lose, sorry.

>        int Foo() { int x; scanf("%d",&x); return x; }

Yeah, I realized that it would never work real soon after I posted the
idea...  Automatic variables are often addressed stack-base-relative,
but not when their addresses are passed, etc...  Ah, well.  So much
for that idea.

About the autodocs...  Are they the "man" type pages in Appendix A of
the (1.1) RKM L&D manual?  Or am I missing it altogether?

One last thing, (for now...  :-) about Message Ports, I was scanning
that Amiga Programmer's Handbook, and it says something about every
task having a message port an associated but separate reply port.  I
don't understand.  I thought the same port was used to send AND
receive the replies to a message?  Also, why would all tasks have to
have message ports?  In short, is this true?

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.

mcr@julie.UUCP (Michael Richardson) (03/26/89)

Randall Jesup writes:
>        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.
  Then why the pr_CLI entry in the Process structure? If I should
"consider the CLI structure as part of the program environment" then
the CLI IS special, as it maintains that structure.  Since writing
shells appears to be somewhat of a black art, and CLI being the
main shell in existence, then the CLI must be special.

>        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.
  Then 99% of unix users must spend all their time using those menu
driven stuff, in which case, Vic Basic (without a wedge) is all they
really need.
  If you do not include hackers as unix users, then you've cut the population
of Unix users by a LARGE proportion.

[stuff about 1.4, things breaking]
  Understand that I am not complaining that much about the contradiction,
I just wish you put your effort in the right places.

>        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.
  I find that amusing with Dave Haynie telling us that switching between
Unix, AmigaDOS, Vax/VMS, etc. is easy once you get used to it.
If writing shells was easier, (the shell/program interface was
well documented, supported inheritance of environments, redirection
(open file descriptors are passed), and error codes.) then the
issue of who does wildcarding, and what they are would be less
important. (If the shell wants to do it, then it need only
quote every argument. If the program doesn't want to do
it, then you wind up with things like DPAT.)

>>  Wish read(), write(), were better documented. I don't really understand
>>what they do... (internally)
>
>        Internals are supposed to be hidden.
  I meant the packet interface to the filing systems. What if I want to do
asynchronous I/O?

[Execute.device]

>        Sounds like a WorkBench process to me.
  It was meant to. (And Peter, I was thinking about and looking
at your launch code when I wrote that. That is exactly what I had
intended to do.)

>        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.
  Some standard exception code would be nice. (excption.zoo by Herald
T. Hewes came across the net awhile ago, although I've yet to
incorporate it into my code. I do intend to though.) And if that means
that code that wishes to lock a resource must also add unlocking
routines to the exception chain, then okay. Or else, it must request
that exceptions not be delivered while it is in progress.
(Enable()/Forbid() would automatically do this. A ExceptionMask()
call would also be a good idea when locking structures.)
The upshot of this is that programmers would have a cleaner way to
deallocate resources in an intelligent way.

>>  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.
  Exactly how you do what? talk to the serial device or the execute
device?

>>  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.
  The point is that people are looking into alternate filing systems.
I'm of the opinion that one SHOULD use different filing systems for
different applications. If you intend to store lots of little files
scattered into several hundred directories, (That is how I program ---
the effects of a youth spent with Unix boxes accessed at 300 baud.)
then use a filing system designed for that. If you like having
plenty of 300k animations around, a file system with a bigger allocation
unit is for you.

>>  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.
  So I can take the result of "Output()", pop it into a message,
send it to another task and have the other task write to wherever
I was writing? I gather that I must wait until the other task
has finished with it and then _I_ must close it (or return it to
wherever I got it.) But it is okay for the two of us to output to
this FileHandle at the same time? (It must, my "Run"ed commands can
send their output to the master window...)

>--
>Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup



--

  :!mcr!:
  Michael Richardson                     Amiga
                                  v--------+
 UUCP: uunet!attcan!lsuc!nrcaer!julie!mcr  | INTERNET mcr@doe.carleton.ca
 Fido: Michael Richardson @ 1:163/109.10<--+ Alter @ 7:483/109.10

FelineGrace@cup.portal.com (Dana B Bourgeois) (03/27/89)

Devin asked for name suggestions.  He doesn't like Unix, Amix, or Minix
because they are already in use and Miniscunix, while cute, doesn't
exactly fit.  So I have a couple of suggestions  which I am "running
up the flag pole to see who will salute".

Punix		-Puny Unix
Tunix		-Tiny Unix
Stunix		-Stunted Unix
Rudix		-Rudimentary Unix
Runix		-Runty Unix
Exiguousix	-This just says it with an '-ix' on the end
Infinitesix	-infinitesimal Unix
Indiscernix	-getting a bit far fetched
Invisix		-Invisible Unix?  Really now!
Atomix		-Atomic means small but this name is misleading
Amigix		-Amiga Unix.  But sounds revolting when voiced.

No saluters?  Oh, well.  Perhaps someone will come up with a few really
clever ones.

Dana

[ I disclaim this disclaimer inclusively ]

deven@pawl.rpi.edu (Deven Corzine) (03/28/89)

In article <16306@cup.portal.com> FelineGrace@cup.portal.com (Dana B Bourgeois) writes:
>Devin asked for name suggestions.  He doesn't like Unix, Amix, or Minix
>because they are already in use and Miniscunix, while cute, doesn't
>exactly fit.  So I have a couple of suggestions  which I am "running
>up the flag pole to see who will salute".

[DevEn, actually...  but I'm used to it.  :-)]

[...]
>Amigix		-Amiga Unix.  But sounds revolting when voiced.

The least noxious of the bunch.  :-)  I'm using it as a tentative name
until/unless something else better turns up...

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.

dbk@teroach.UUCP (Dave Kinzer) (03/28/89)

In article <16306@cup.portal.com> FelineGrace@cup.portal.com (Dana B Bourgeois) writes:
>Devin asked for name suggestions.  He doesn't like Unix, Amix, or Minix
>
>Punix		-Puny Unix
etc.

How bout:

     Devix

(It would be Dix if Matt were doing it :^) )


|    // GOATS - Gladly Offering All Their Support  Dave Kinzer (602)897-3085|
|   //  >> In Hell you need 4Mb to Multitask!  <<  uunet!mcdphx!teroach!dbk |
| \X/   #define policy_maker(name) (name->salary > 3 * dave.salary)         |

fc@lexicon.com (Frank Cunningham) (03/28/89)

Manix
-- 
Frank C

ddave@pnet02.cts.com (David Donley) (03/29/89)

Why not just call it "ix"?  (Or how about "Kix"?) :-)

              Don't call my BBS, my harddisk left me for a 2500.
          Disclaimer: If it doesn't work, I guess it's broken ain't it?
     ddave@pnet02.CTS.COM ddave@pnet.gryphon.COM killer!gryphon!pnet02!ddave

ddave@pnet02.cts.com (David Donley) (03/29/89)

Sorry about the broken signature:
                    Call the Bug Eyes BBS at (213) 372-4494
     ddave@pnet02.CTS.COM ddave@pnet.gryphon.COM killer!gryphon!pnet02!ddave

eachus@mbunix.mitre.org (Robert Eachus) (03/29/89)

In article <397@lexicon.com> fc@lexicon.com (Frank Cunningham) writes:
>Manix
>-- 
>Frank C

     I'll salute that... You don't have to worry about conflicting
copyrights from unrelated products of the same name, when it is
obvious that there is no relation.  (Now if this was to be an expert
system for private investigators...:-)

					Robert I. Eachus

jesup@cbmvax.UUCP (Randell Jesup) (03/29/89)

In article <DEVEN.89Mar25023341@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven T. Corzine) writes:
>In article <6389@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>>        No, the _only_ thing he has to do is open amiga.foo.library
>>instead of foo.library.  Since all the offsets are the same, nothing
>>else need be done, and amigix.foo.library will get all calls that
>>would otherwise go to foo.library.

>Sure, changing the library opened will work for all libraries, EXCEPT
>for the exec.library...  Exec.library is accessed through ABSEXECBASE
>at memory location 4, not from a return from the OpenLibrary call.  It
>doesn't make sense to change that pointer (at ABSEXECBASE) as it would
>likely cause big troubles, so I'm left with patching all the
>exec.library functions,

	Just write your stubs/pragmas to use something other than SysBase,
then.  Note that most programs stash execbase in a variable SysBase.  This
lessens reliance on accessing chip memory in a fast-mem system.  Look at the
lattice startup code and pragmas.

>>>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?
>
>>        Check the exec memory chapter.
>
>Didn't want to look it up yourself, huh?  :-)  Well, the Exec memory
>chapter doesn't say anything clear about it, except that you can't
>depend on the granularity being 8; only a multiple of 4.  Nowhere does
>it say anything about whether or not you can legitimately free a
>different sized memory block than you originally allocated.

	Page 1-64, White 1.1 RKMs: Partial blocks may be deallocated, but
note again that FreeMem() rounds your address down to the nearest even multiple
of MEM_BLOCKSIZE and the size up to the nearest multiple before the FreeMem()
request is performed.

	I said it was in the chapter....

>About the autodocs...  Are they the "man" type pages in Appendix A of
>the (1.1) RKM L&D manual?  Or am I missing it altogether?

	Yes, autodocs are equivalent to man pages.

> I was scanning
>that Amiga Programmer's Handbook, and it says something about every
>task having a message port an associated but separate reply port.  I
>don't understand.  I thought the same port was used to send AND
>receive the replies to a message?  Also, why would all tasks have to
>have message ports?  In short, is this true?

	A port is never "used" to send a message, only to recieve one (or
recieve a reply).  All _Processes_ have a port (pr_MsgPort) for recieving
(a) the inital WB startup message, and (b) replies to filesystem packets.
_Tasks_ do not have associated ports unless the application creating it
does so.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

jesup@cbmvax.UUCP (Randell Jesup) (03/29/89)

In article <0856.AA0856@julie> mcr@julie.UUCP (Michael Richardson) writes:
>Randall Jesup writes:
>>        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.
>  Then why the pr_CLI entry in the Process structure? If I should
>"consider the CLI structure as part of the program environment" then
>the CLI IS special, as it maintains that structure.  Since writing
>shells appears to be somewhat of a black art, and CLI being the
>main shell in existence, then the CLI must be special.

	As I said it isn't clean - some things in the CLI structure are accessed
directly, instead of through function calls.  What it means is that to be
compatible one must either maintain reasonable values in the CLI structure
from your shell, or look like WB to the program (WBMessage, etc).

>>        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.
>  Then 99% of unix users must spend all their time using those menu
>driven stuff, in which case, Vic Basic (without a wedge) is all they
>really need.
>  If you do not include hackers as unix users, then you've cut the population
>of Unix users by a LARGE proportion.

	What I meant is that for almost all people who use unix the fact that
a shell is "just another program" isn't important, only the features are
important.  I meant that few people write shells, even hackers.

>>        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.
>  I find that amusing with Dave Haynie telling us that switching between
>Unix, AmigaDOS, Vax/VMS, etc. is easy once you get used to it.

	Note the "get used to it".  Also note that we are not the people I
was refering to: I was refering to the generic user who buys an amiga, and
in general is not horribly computer-literate to begin with, or is only slightly
literate in one of msdos/C64/mac/Apple-II/ST/etc.  You know, _users_.

>>>  Wish read(), write(), were better documented. I don't really understand
>>>what they do... (internally)
>>
>>        Internals are supposed to be hidden.
>  I meant the packet interface to the filing systems. What if I want to do
>asynchronous I/O?

	I assumed that he was talking about the packet interface to handlers.
Packets are documented and supported (even if the documentation is not
perfect, it's usable).

>>>  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.
>  Exactly how you do what? talk to the serial device or the execute
>device?

	You misunderstand.  We're talking exec messages, sent from the shell
to processes that execute programs for the shell.

>>        You can't dup() a filehandle.
>  So I can take the result of "Output()", pop it into a message,
>send it to another task and have the other task write to wherever
>I was writing? I gather that I must wait until the other task
>has finished with it and then _I_ must close it (or return it to
>wherever I got it.) But it is okay for the two of us to output to
>this FileHandle at the same time? (It must, my "Run"ed commands can
>send their output to the master window...)

	Within limits stated before: BCPL programs can't share filehandles.
NEVER Close() the result of Output().  Don't pass it off and exit, wait until
the other process is done with it.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

FelineGrace@cup.portal.com (Dana B Bourgeois) (03/30/89)

DevEn:

Got it right that time.  You think that Amigix (ugh!!) is the best??!?
How about Uniga for Unix Amiga.  Or shorten it further to Unga.

How about UnixExec for Unix/Exec (Unix-over-Exec. Get it?)

Unix/ADos?  Or in the same vein as Xenix: Exenix for Exec-Unix.  Or use
ADos in place of Exec and you get ADosnix or ADonix.

Or put 'em all together and you get ADosExenix (Adosexenix? Adosexnix?)

Dana

deven@pawl.rpi.edu (Deven Corzine) (03/30/89)

In article <10605@mcdphx.phx.mcd.mot.com> dbk@teroach.UUCP (Dave Kinzer) writes:
>In article <16306@cup.portal.com> FelineGrace@cup.portal.com (Dana B Bourgeois) writes:
>>Devin asked for name suggestions.  He doesn't like Unix, Amix, or Minix
>>
>>Punix		-Puny Unix
>etc.

>How bout:

>     Devix

Sounds a bit too egotistical, even for me.  :-)

Just doesn't have the right "ring" to it, ya know?

>(It would be Dix if Matt were doing it :^) )

Probably true.  :-)

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.

deven@pawl.rpi.edu (Deven Corzine) (03/30/89)

In article <0856.AA0856@julie> mcr@julie.UUCP (Michael Richardson) writes:
>Randall Jesup writes:
>>        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.
>  Then why the pr_CLI entry in the Process structure? [...]

Easy...  pr_CLI is an example of where the division isn't totally
clean...

>>        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.
>  Then 99% of unix users must spend all their time using those menu
>driven stuff, in which case, Vic Basic (without a wedge) is all they
>really need.

Ick.  :-)

>  If you do not include hackers as unix users, then you've cut the population
>of Unix users by a LARGE proportion.

This be somewhat true...

>  I find that amusing with Dave Haynie telling us that switching between
>Unix, AmigaDOS, Vax/VMS, etc. is easy once you get used to it.

I don't like being told compatibility is unnecessary and you should
just learn a new approach for every different system.  Sorta defeats
the whole purpose...

[...]
>The upshot of this is that programmers would have a cleaner way to
>deallocate resources in an intelligent way.

My intention exactly...

> [...] If you like having
>plenty of 300k animations around, a file system with a bigger allocation
>unit is for you.

Not necessarily.  Why not a FS which doesn't use a fixed blocksize?

>  So I can take the result of "Output()", pop it into a message,
>send it to another task and have the other task write to wherever
>I was writing? I gather that I must wait until the other task
>has finished with it and then _I_ must close it (or return it to
>wherever I got it.) But it is okay for the two of us to output to
>this FileHandle at the same time? (It must, my "Run"ed commands can
>send their output to the master window...)

That would work, though it doesn't matter who closes it, as long as
the file handle is only closed ONCE.  I think sharing the file handle
will share the R/W pointer, but perhaps not.

"Run"ed commands send their output to the console window by opening
"*" as an output stream (or being passed the same), not by sharing
filehandles.  There is a difference.

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.

deven@pawl.rpi.edu (Deven Corzine) (03/30/89)

In article <6406@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>In article <DEVEN.89Mar25023341@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven T. Corzine) writes:
>>In article <6389@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>>>        No, the _only_ thing he has to do is open amiga.foo.library
>>>instead of foo.library.  Since all the offsets are the same, nothing
>>>else need be done, and amigix.foo.library will get all calls that
>>>would otherwise go to foo.library.

>>Sure, changing the library opened will work for all libraries, EXCEPT
>>for the exec.library...  Exec.library is accessed through ABSEXECBASE
>>at memory location 4, not from a return from the OpenLibrary call.  It
>>doesn't make sense to change that pointer (at ABSEXECBASE) as it would
>>likely cause big troubles, so I'm left with patching all the
>>exec.library functions,

>        Just write your stubs/pragmas to use something other than SysBase,
>then.  Note that most programs stash execbase in a variable SysBase.  This
>lessens reliance on accessing chip memory in a fast-mem system.  Look at the
>lattice startup code and pragmas.

That is another option.  Will #pragma's override older duplicate (but
different) declarations?  [also, is there any other valid type than
"libcall" and "syscall"?]

>>>>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?
>>
>>>        Check the exec memory chapter.
>>
>>Didn't want to look it up yourself, huh?  :-)  Well, the Exec memory
>>chapter doesn't say anything clear about it, except that you can't
>>depend on the granularity being 8; only a multiple of 4.  Nowhere does
>>it say anything about whether or not you can legitimately free a
>>different sized memory block than you originally allocated.

>        Page 1-64, White 1.1 RKMs: Partial blocks may be deallocated,
>but note again that FreeMem() rounds your address down to the nearest
>even multiple of MEM_BLOCKSIZE and the size up to the nearest multiple
>before the FreeMem() request is performed.

Ah...  there's the discrepency.  You have a different manual than I.
Time to be specific [and verbose] I suppose:

Amiga ROM Kernal Reference Manual: Exec

Authors: Carl Sassenrath, Rob Peck, and Susan Deyl
Program examples by Carl Sassenrath

Published 1986, Addison-Wesley.
--------------------------------------------------------
Library of Congress Cataloging-in-Publication Data

Amiga ROM kernal reference manual.

    (Amiga technical reference series)
    Includes index.
    1. Amiga (Computer)-Programming.  2. Read-only
storage.  I..  Commodore Business Machines.
QA76.8.A177A655  1986       005.4'46          86-10887
ISBN 0-201-11099-7
--------------------------------------------------------

Now...  what is the most concise, yet unambiguous way to refer to this
version of the RKM: Exec Manual?

There is no page "1-64"...  and page "64" is the blank page between
Chapter 5, Interrupts, and Chapter 6, Memory Allocation.  Clearly it
is a different version.  I believe it is V1.1, but perhaps not.

Anyway, you can deallocate partial blocks...  fine.  Is there any
place you can look up the MEM_BLOCKSIZE at run-time, or must you
recompile when the granularity changes?  [recompiling would be a
nuisance.]

>        I said it was in the chapter....

In YOUR copy of the RKM's, perhaps...  :-)

>>About the autodocs...  Are they the "man" type pages in Appendix A of
>>the (1.1) RKM L&D manual?  Or am I missing it altogether?

>        Yes, autodocs are equivalent to man pages.

Any place I can get the 1.3 Autodocs?  I don't have the money right
now to buy the developer's disk yet, or the 1.3 Includes & Autodocs
RKM...  [not that I've actually seen [or looked for] it, but...]  I
can handle making a printout of them myself, [;-)] and I prefer to
print them myself so I can have them loose-leaf, one-up.  [as I have
the Includes printed...]

I don't suppose it might be possible [or legal?] for you [or someone]
to email me [aCk] the V1.3 Autodocs, might it?  I would be most
appreciative...

>> I was scanning
>>that Amiga Programmer's Handbook, and it says something about every
>>task having a message port an associated but separate reply port.  I
>>don't understand.  I thought the same port was used to send AND
>>receive the replies to a message?  Also, why would all tasks have to
>>have message ports?  In short, is this true?

>        A port is never "used" to send a message, only to recieve one (or
>recieve a reply).  All _Processes_ have a port (pr_MsgPort) for recieving
>(a) the inital WB startup message, and (b) replies to filesystem packets.
>_Tasks_ do not have associated ports unless the application creating it
>does so.

Presumably the question of message vs. reply port would be if you had
to use a different port to receive the reply to a message you sent to
some other port from a port you could receive (via PutMsg()) a message
on.  Hence, not the same message -- one with the port as destination,
another with it as reply port.  No need to separate them, is there?
[apart from logical design?]

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.

deven@pawl.rpi.edu (Deven Corzine) (03/30/89)

In article <6420@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>        What I meant is that for almost all people who use unix the fact that
>a shell is "just another program" isn't important, only the features are
>important.  I meant that few people write shells, even hackers.

Pretty much true.  But for many it's comforting to know that they
COULD easily replace the shell, were they so inclined.  [though one of
the complexity of sh, csh, ksh, tcsh, etc. is no small project...]

[...]
>        Note the "get used to it".  Also note that we are not the
>people I was refering to: I was refering to the generic user who buys
>an amiga, and in general is not horribly computer-literate to begin
>with, or is only slightly literate in one of
>msdos/C64/mac/Apple-II/ST/etc.  You know, _users_.

The generic user is NEVER going to see the sense in "#?" as a
wildcard.  Not all generic users WANT to use graphical interfaces,
though many do.  It is a very poor assumption to make that ALL do...

[...]
>        Within limits stated before: BCPL programs can't share filehandles.
>NEVER Close() the result of Output().  Don't pass it off and exit, wait until
>the other process is done with it.

Well, you COULD have the child Close(Output()), if the parent and
child agree the child is to do so, but it is definitely a poor
programming style, and hence very strongly discouraged...  but legal.

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.

rap@ardent.UUCP (Rob Peck) (03/31/89)

In article <DEVEN.89Mar30052014@daniel.pawl.rpi.edu>, deven@pawl.rpi.edu (Deven Corzine) writes:
> 
> >        Page 1-64, White 1.1 RKMs: Partial blocks may be deallocated,
> >but note again that FreeMem() rounds your address down to the nearest
> >even multiple of MEM_BLOCKSIZE and the size up to the nearest multiple
> >before the FreeMem() request is performed.
> 
> Ah...  there's the discrepency.  You have a different manual than I.
> Time to be specific [and verbose] I suppose:
> 
> Amiga ROM Kernal Reference Manual: Exec
> 
> Authors: Carl Sassenrath, Rob Peck, and Susan Deyl
> Program examples by Carl Sassenrath
> 
> Now...  what is the most concise, yet unambiguous way to refer to this
> version of the RKM: Exec Manual?
> 
> There is no page "1-64"...  and page "64" is the blank page between
> Chapter 5, Interrupts, and Chapter 6, Memory Allocation.  Clearly it
> is a different version.  I believe it is V1.1, but perhaps not.

There are actually 3 versions of the RKM's floating around (soon to be
4 when the full 1.3 version comes out.  The first one was "1.0" and I
wrote the entire EXEC portion.  The second one is for 1.1, and it was
bound entirely in white.  The third one is with a nice Addison Wesley
cover, handles 1.2, and has the Green or Plum or Yellow stripe on the
cover.

As updates were made, wording got changed, chapters got moved and/or
replaced.  Some useful information, such as the above, mighta gotten
picked up and moved or picked up and deleted by one of the editors
who sincerely believed that certain material was either covered elsewhere
or he/she INTENDED to move it elsewhere.  C'est la vie.  It happens.

From what I have seen of the Autodoc portion of the 1.3 RKM, and the
amount of work that Bryce has put into it, I'd have to say that the
1.3 RKM, as a bunch, will doubtless be the best of the bunch, most
useful and so on.  I'll gladly push the old versions to the back of
the bookshelf in favor of using the new set when it becomes available.

Rob Peck

jesup@cbmvax.UUCP (Randell Jesup) (03/31/89)

In article <DEVEN.89Mar30052014@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven T. Corzine) writes:
>That is another option.  Will #pragma's override older duplicate (but
>different) declarations?  [also, is there any other valid type than
>"libcall" and "syscall"?]

	I think not.  Doesn't matter, since they all use SysBase,
which is set up in the c.a startup code.  All you need to do is put
your exec.amigix.library pointer in SysBase instead of the contents
of AbsExecBase.

>>        Page 1-64, White 1.1 RKMs: Partial blocks may be deallocated,
>>but note again that FreeMem() rounds your address down to the nearest
>>even multiple of MEM_BLOCKSIZE and the size up to the nearest multiple
>>before the FreeMem() request is performed.
>
>Ah...  there's the discrepency.  You have a different manual than I.

	The comments should still be there.

>Anyway, you can deallocate partial blocks...  fine.  Is there any
>place you can look up the MEM_BLOCKSIZE at run-time, or must you
>recompile when the granularity changes?  [recompiling would be a
>nuisance.]

	Recompile.  Better yet, don't _depend_ on a given granularity.

>Any place I can get the 1.3 Autodocs?  I don't have the money right
>now to buy the developer's disk yet, or the 1.3 Includes & Autodocs
>RKM... 

	They cost $20 from CATS.

>I don't suppose it might be possible [or legal?] for you [or someone]
>to email me [aCk] the V1.3 Autodocs, might it? 

	Not legal (they're copyrighted).  Sorry.

>Presumably the question of message vs. reply port would be if you had
>to use a different port to receive the reply to a message you sent to
>some other port from a port you could receive (via PutMsg()) a message
>on.  Hence, not the same message -- one with the port as destination,
>another with it as reply port.  No need to separate them, is there?

	Mind restating that in english?

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

jesup@cbmvax.UUCP (Randell Jesup) (03/31/89)

In article <DEVEN.89Mar30052930@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven T. Corzine) writes:
>>        Within limits stated before: BCPL programs can't share filehandles.
>>NEVER Close() the result of Output().  Don't pass it off and exit, wait until
>>the other process is done with it.
>
>Well, you COULD have the child Close(Output()), if the parent and
>child agree the child is to do so, but it is definitely a poor
>programming style, and hence very strongly discouraged...  but legal.

	No.  The definition of a process is that CIS and COS (aka Input()
and Output()) will remain valid (the owning CLI or WB closes them).
You should never Close the result of Input() or Output().  NEVER.  It IS
illegal.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

deven@pawl.rpi.edu (Deven Corzine) (03/31/89)

In article <16427@cup.portal.com> FelineGrace@cup.portal.com (Dana B Bourgeois) writes:
>DevEn:

:-)

>Got it right that time.  You think that Amigix (ugh!!) is the best??!?

Best of what I've come up with so far is all.  I don't really like the
sound of Amigix either, but the others are worse.  I really would've
liked to have used Amix, but C-A took that.

>How about Uniga for Unix Amiga.  Or shorten it further to Unga.

Amusing, but I don't really think it works any better...

>How about UnixExec for Unix/Exec (Unix-over-Exec. Get it?)

Not a bad thought, here...  Except I might be asking for trouble by
using "Unix" as even part of the name...  Maybe "AmixExec"?  Hmm...

[after all, this WILL be Unix implemented on top of Exec...]

>Unix/ADos?  Or in the same vein as Xenix: Exenix for Exec-Unix.  Or use
>ADos in place of Exec and you get ADosnix or ADonix.

Sorry, no.  AmigaDOS has no place here.  Eventually, I hope to write a
filesystem for it as well.  AmigaDOS will be initially used to access
the disk, though that will be behind the scenes.  AmigaDOS is NOT an
essential piece here, and I hope to allow its use to be ompletely
optional.  Exec, on the other hand, IS an intergral piece of this
system, hence "AmixExec" *might* be ok...  But then, I don't know what
Commodore-Amiga would think of my using that...   Would that be asking
for trouble also?

>Or put 'em all together and you get ADosExenix (Adosexenix? Adosexnix?)

Nah...

Exenix is a little too like Xenix, and I never liked the sound of
"Xenix" anyhow...

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.

deven@pawl.rpi.edu (Deven Corzine) (03/31/89)

In article <6464@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>In article <DEVEN.89Mar30052014@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven T. Corzine) writes:
>>That is another option.  Will #pragma's override older duplicate (but
>>different) declarations?  [also, is there any other valid type than
>>"libcall" and "syscall"?]

>        I think not.  Doesn't matter, since they all use SysBase,
>which is set up in the c.a startup code.  All you need to do is put
>your exec.amigix.library pointer in SysBase instead of the contents
>of AbsExecBase.

Oh...  if that is the case, then that would be an acceptable option,
methinks...  I already have to replace the startup code...

Of course, the other option is not to allow Amigix processes to
*directly* call Amiga libraries, only indirectly through
Amiga-specific amigix.library function calls...

>>>        Page 1-64, White 1.1 RKMs: Partial blocks may be deallocated,
>>>but note again that FreeMem() rounds your address down to the nearest
>>>even multiple of MEM_BLOCKSIZE and the size up to the nearest multiple
>>>before the FreeMem() request is performed.

>>Ah...  there's the discrepency.  You have a different manual than I.

>        The comments should still be there.

They're not.  I checked quite carefully.  It notes that the current
granularity is 8, but you can not depend on that size in future
revisions of the operating system.  And it noted that you CAN count on
longword alignment.

>>Anyway, you can deallocate partial blocks...  fine.  Is there any
>>place you can look up the MEM_BLOCKSIZE at run-time, or must you
>>recompile when the granularity changes?  [recompiling would be a
>>nuisance.]

>        Recompile.  Better yet, don't _depend_ on a given granularity.

But, you see, the dependency would be in writing a ReallocMem
function...  I do NOT want to force enough memory for the old AND new
memory blocks, so I must depend on the internal memory structure and
the granularity that Exec uses, as Exec does not provide a ReallocMem
function, and it is a pretty basic function...  Now, if C-A will add a
ReallocMem to Exec V1.4+, it won't be a problem, for nowhere else do I
expect to have any dependency on the granularity.  (Things WILL depend
on a ReallocMem, however.)

>>Any place I can get the 1.3 Autodocs?  I don't have the money right
>>now to buy the developer's disk yet, or the 1.3 Includes & Autodocs
>>RKM... 

>        They cost $20 from CATS.

Well, I just started working again, so maybe I'll be able to spare the
money...  [little free time, now.  :-(]

>>I don't suppose it might be possible [or legal?] for you [or someone]
>>to email me [aCk] the V1.3 Autodocs, might it? 

>        Not legal (they're copyrighted).  Sorry.

I expected as much.  Worth a try.  :-)

>>Presumably the question of message vs. reply port would be if you had
>>to use a different port to receive the reply to a message you sent to
>>some other port from a port you could receive (via PutMsg()) a message
>>on.  Hence, not the same message -- one with the port as destination,
>>another with it as reply port.  No need to separate them, is there?

>        Mind restating that in english?

I'll give it a try.

Say you've got 2 processes, each sending messages to the other.  Is
there or is there not a need to separate reply ports from message
ports [as receiving points, not reply-receiving points] or can you
have a single message port for each process, using it as the
destination port for the messages the other process sends, and as the
reply port for any messages the process spends.  That book implied
you'd need one port for the other process to send messages to, and
another to receive the reply messages for messages you send to the
other process...   What's the actuality?

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.

deven@pawl.rpi.edu (Deven Corzine) (03/31/89)

In article <6465@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
In article <DEVEN.89Mar30052930@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven T. Corzine) writes:
>>>        Within limits stated before: BCPL programs can't share
>>>filehandles.  NEVER Close() the result of Output().  Don't pass it off
>>>and exit, wait until the other process is done with it.

>>Well, you COULD have the child Close(Output()), if the parent and
>>child agree the child is to do so, but it is definitely a poor
>>programming style, and hence very strongly discouraged...  but legal.

>        No.  The definition of a process is that CIS and COS (aka
>Input() and Output()) will remain valid (the owning CLI or WB closes
>them). You should never Close the result of Input() or Output().
>NEVER.  It IS illegal.

True, given that definition, it IS illegal.  I retract that statement.
More appropriately, I meant that a passed file handle could be closed
legally by the child process.  I hadn't considered that closing
Input() and Output() is illegal, but of course it would have to be.
Even so, you could legitimately pass a separate file handle (perhaps
in an Exec message as suggested) to a child process which would close
it.  THAT is legal, is it not?

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.

deven@pawl.rpi.edu (Deven Corzine) (03/31/89)

In article <5241@ardent.UUCP> rap@ardent.UUCP (Rob Peck) writes:
 >There are actually 3 versions of the RKM's floating around (soon to be
 >4 when the full 1.3 version comes out.  The first one was "1.0" and I
 >wrote the entire EXEC portion.  The second one is for 1.1, and it was
 >bound entirely in white.  The third one is with a nice Addison Wesley
 >cover, handles 1.2, and has the Green or Plum or Yellow stripe on the
 >cover.

That Addison-Wesley edition is the one I have.

 >As updates were made, wording got changed, chapters got moved and/or
 >replaced.  Some useful information, such as the above, mighta gotten
 >picked up and moved or picked up and deleted by one of the editors
 >who sincerely believed that certain material was either covered elsewhere
 >or he/she INTENDED to move it elsewhere.  C'est la vie.  It happens.

I figured as much...

 >From what I have seen of the Autodoc portion of the 1.3 RKM, and the
 >amount of work that Bryce has put into it, I'd have to say that the
 >1.3 RKM, as a bunch, will doubtless be the best of the bunch, most
 >useful and so on.  I'll gladly push the old versions to the back of
 >the bookshelf in favor of using the new set when it becomes available.

I hope they will be the best of the bunch...  (it would be nice...)

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.

jesup@cbmvax.UUCP (Randell Jesup) (04/01/89)

In article <DEVEN.89Mar31025148@daniel.pawl.rpi.edu> shadow@pawl.rpi.edu (Deven T. Corzine) writes:
>Say you've got 2 processes, each sending messages to the other.  Is
>there or is there not a need to separate reply ports from message
>ports [as receiving points, not reply-receiving points] or can you
>have a single message port for each process, using it as the
>destination port for the messages the other process sends, and as the
>reply port for any messages the process spends.  That book implied
>you'd need one port for the other process to send messages to, and
>another to receive the reply messages for messages you send to the
>other process...   What's the actuality?

	You can use the port for recieving either.  ReplyMsg is essentially
{msg->mn_Node.ln_Type = NT_REPLYMSG; PutMsg(msg->mn_ReplyPort,msg);}.  Not
exactly that, but you get the idea.

	On another note: deven, you've shown up in the top 25 posters on
all of usenet by messages.  Try to include less "ok, I'll do that" and
included text in your messages, please.

	Thanks

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

deven@pawl.rpi.edu (Deven Corzine) (04/02/89)

In article <6473@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>        On another note: deven, you've shown up in the top 25 posters on
>all of usenet by messages.

No way!  Really?  Gee...  Didn't realize I've been posting THAT
much...  [and most of it HAS been to comp.sys.amiga.tech...]

>Try to include less "ok, I'll do that" and included text in your
>messages, please.

OK, I'll do that.  [just *had* to, this once.  :-)]

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.

peter@sugar.hackercorp.com (Peter da Silva) (04/04/89)

Why do you want the Amigix programs to be able to call a patched exec.library?
I thought the idea was to provide an environment for programs to run in that
has UNIX semantics. So your program is not gonna be making AmigaDOS calls in
any case.

Just let them use the regular exec.library long enough to open unix.library.
Unix.library will have Unix system calls and semantics. They should never
reference exec.library again, unless they need to go below unix.library.

In fact, you shouldn't be patching *any* libraries, since they're not relevant
to the Amigix environment, but AmigaOS software will still need to access
them...
-- 
Peter "Have you hugged your wolf today" da Silva      `-_-'
...texbell!sugar!peter, or peter@sugar.hackercorp.com  'U`

deven@pawl.rpi.edu (Deven Corzine) (04/05/89)

In article <3689@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes:
>Why do you want the Amigix programs to be able to call a patched exec.library?
>I thought the idea was to provide an environment for programs to run in that
>has UNIX semantics. So your program is not gonna be making AmigaDOS calls in
>any case.

AmigaDOS calls (dos.library) are certainly out; Amigix processes will
NOT be AmigaDOS processes.  Only the Amigix system task will be.

The idea behind allowing Amigix processes to call patched Amiga
libraries would be to simplify porting existing Amiga programs to the
environment.  I haven't decided if this is the way I want to go,
however.

>Just let them use the regular exec.library long enough to open unix.library.
>Unix.library will have Unix system calls and semantics. They should never
>reference exec.library again, unless they need to go below unix.library.

I'll probably use "amigix.library" just so I'm not using "Unix"
anywhere.  :-)  As far as the process using exec.library to open
amigix.library, it won't have to; part of the process handling code
will take care of opening it and closing it when processes are created
and die.  The process should be able to forget about it...

>In fact, you shouldn't be patching *any* libraries, since they're not relevant
>to the Amigix environment, but AmigaOS software will still need to access
>them...

I don't intend to affect regular Amiga programs, except that it would
be handy to port them, for consistency, job control (which I *do*
intend to implement, probably for a beta release) signal handling,
etc.  I just don't know how much to facilitate the process...  [making
everything work directly is complicated and may make people less
likely to write code FOR the environment, so perhaps it's not a good
idea...]

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.

keithd@gryphon.COM (Keith Doyle) (04/09/89)

In article <3689@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes:
>Why do you want the Amigix programs to be able to call a patched exec.library?
>I thought the idea was to provide an environment for programs to run in that
>has UNIX semantics. So your program is not gonna be making AmigaDOS calls in
>any case.

Perhaps we might want to provide a migration path for AmigaDOS applications
to run under UNIX.  Whatever level of AmigaDOS compatibility can be provided
will certainly be helpful, even if it is no more than implementing translation
calls.

BTW, what does the UNIX call look like to allocate CHIP ram vs FAST ram? :->

Keith Doyle
keithd@gryphon.COM    gryphon!keithd     gryphon!keithd@elroy.jpl.nasa.gov

dan@ivucsb.UUCP (Dan Howell) (04/10/89)

In article <16306@cup.portal.com> FelineGrace@cup.portal.com (Dana B Bourgeois) writes:
|Devin asked for name suggestions.  He doesn't like Unix, Amix, or Minix
|because they are already in use and Miniscunix, while cute, doesn't
|exactly fit.  So I have a couple of suggestions  which I am "running
|up the flag pole to see who will salute".
[...]
|Amigix		-Amiga Unix.  But sounds revolting when voiced.

How about Commodore-Amiga Unix ...

Comix!  :-)

-- 
-- Dan Howell  <ivucsb!dan@anise.acc.com>  <...!(pyramid|ucbvax)!ucsbcsl!
-- koyaanisqatsi <fr. Hopi> -                                nessus!ivucsb!dan>
     n. 1. crazy life 2. life without order 3. life out of balance 4. a way of
     life that calls for another way of living - syn. see 'graduate school'

deven@pawl.rpi.edu (Deven Corzine) (04/10/89)

In article <14465@gryphon.COM> keithd@gryphon.COM (Keith Doyle) writes:
>Perhaps we might want to provide a migration path for AmigaDOS applications
>to run under UNIX.  Whatever level of AmigaDOS compatibility can be provided
>will certainly be helpful, even if it is no more than implementing translation
>calls.

Indeed.  I expect I'll support porting old programs via a link
library, as opposed to run-time support.

>BTW, what does the UNIX call look like to allocate CHIP ram vs FAST ram? :->

The malloc() call will not distinguish between chip and fast ram; a
separate function will be provided to allow such distinctions.

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.

usenet@cps3xx.UUCP (Usenet file owner) (04/11/89)

This is a flame. Hit 'n' if you don't wanna hear it!


Well, here goes with my very first flame.

What the f*** does it matter what you call Amiga Unix (theres a
idea in itself!)????

Even if it does matter, this is definitly *NOT* the group to
discuss it in. Move it to another group or, heres a clever idea, EMAIL!

It is agrevating to constantly see this stupid discussion going on, and
obviously not going anywhere. It will never get anywhere since
*somebody* will always not like someone elses suggestions.

In article <703@ivucsb.UUCP> ivucsb!dan@anise.acc.com (Dan Howell) writes:
>In article <16306@cup.portal.com> FelineGrace@cup.portal.com (Dana B Bourgeois) writes:
>|Devin asked for name suggestions.  He doesn't like Unix, Amix, or Minix
>|because they are already in use and Miniscunix, while cute, doesn't
>
>Comix!  :-)

Please go away with this already!

ugkamins@sunybcs.uucp (John Kaminski) (04/11/89)

In article <14465@gryphon.COM> keithd@gryphon.COM (Keith Doyle) writes:
>BTW, what does the UNIX call look like to allocate CHIP ram vs FAST ram? :->
>
>Keith Doyle
>keithd@gryphon.COM    gryphon!keithd     gryphon!keithd@elroy.jpl.nasa.gov

hee hee....That actually has a serious note.  The UNIX standard for malloc()
has no defined semantic for types of memory, at least that I'm aware of.
How about a real far out concept which has been talked about extensively on
comp.os.minix and I don't know much about: what are the semantics of POSIX,
in this case, malloc() ? Does *IT* deal with the possiblity of differing
memory types?

Well, I would hope for portability's sake, you wouldn't be that hardware-
specific, and let the OS handle such hardware dependancies.  That's what
having an OS is all about in the first place!!  hmmmmm.....graphics rendering
with a bunch of ioctl()'s and write()'s ......hmmmmmmmmm!!!!!!

sean@ms.uky.edu (Sean Casey) (04/11/89)

In article <5171@cs.Buffalo.EDU> ugkamins@sunybcs.UUCP (John Kaminski) writes:
>hee hee....That actually has a serious note.  The UNIX standard for malloc()
>has no defined semantic for types of memory, at least that I'm aware of.

Ha Ha Ha Ha! Ho Ho Ho Ho! Hee Hee Hee Hee!

Standard? What standard? SVID? Posix? BSD? Minix? Xenix? Dynix? RTU?

Ha hah ha ha ha ha!


-- 
***  Sean Casey                         sean@ms.uky.edu, sean@ukma.bitnet
***  What, me worry?                    {backbone|rutgers|uunet}!ukma!sean
***  ``A computer network should be considerably faster than a slug.'' -Me

deven@pawl.rpi.edu (Deven Corzine) (04/11/89)

In article <2447@cps3xx.UUCP> usenet@cps3xx.UUCP (Usenet file owner) writes:
>What the f*** does it matter what you call Amiga Unix (theres a
>idea in itself!)????

It doesn't, much.  I would like to choose a good name, but I did NOT
intend for this bantering back and forth here on the net about random
names.  If people want to seriously suggest names, they should mail
them to me.  [shadow@pawl.rpi.edu]  (A number of people have done so.)
Most of the names posted to the net are jokes, and the joke is getting
old.  Tentatively, I am using "Amigix", and that will likely be the
name unless someone MAILS me a better choice.

I precipitated this chain, but I agree with this flame; stop POSTING
random names.  Email me.

>Even if it does matter, this is definitly *NOT* the group to
>discuss it in. Move it to another group or, heres a clever idea, EMAIL!

Yes.

>It is agrevating to constantly see this stupid discussion going on, and
>obviously not going anywhere. It will never get anywhere since
>*somebody* will always not like someone elses suggestions.

True, but it doesn't matter to me whether there's *somebody* who
doesn't like the name I use; I am doing this project, so I have the
final say in the matter.  It's as simple as that.

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.

karl@sugar.hackercorp.com (Karl Lehenbauer) (04/12/89)

In article <11469@s.ms.uky.edu>, sean@ms.uky.edu (Sean Casey) writes:
> In article <5171@cs.Buffalo.EDU> ugkamins@sunybcs.UUCP (John Kaminski) writes:
> >hee hee....That actually has a serious note.  The UNIX standard for malloc()
> >has no defined semantic for types of memory, at least that I'm aware of.
 
> Ha Ha Ha Ha! Ho Ho Ho Ho! Hee Hee Hee Hee!
 
> Standard? What standard? SVID? Posix? BSD? Minix? Xenix? Dynix? RTU?
 
> Ha hah ha ha ha ha!

I do not understand why you think this is funny.  

All the operating systems you named have the same calling sequence and
semantics for malloc, even though Minix, Dynix and RTU have never been
seriously supported as standards.

Access to special memory (eg. graphics memory, shared memory, etc) required 
special routines and system calls, as does the Amiga.

In fact, malloc has the same semantics on the Amiga as implemented in both 
vendors' C libraries as Unix et al.
-- 
-- uunet!sugar!karl  | "Time is an illusion.  Lunchtime doubly so."
--		     |				-- Ford Prefect
-- Usenet BBS (713) 438-5018

sneakers@heimat.UUCP (Dan "Sneakers" Schein) (04/13/89)

 [ Dan this isnt a shot at you, your message just happend to be the one I used ]

In Message <703@ivucsb.UUCP>, dan@ivucsb.UUCP (Dan Howell) writes:

>How about Commodore-Amiga Unix ...
>
>Comix!  :-)

  This whole discussion has gone past the comix stage and is no longer funny
  or related to comp.sys.amiga.tech in the least!

  Lets fact it Commodore is releasing the product and they will be naming it
  officially what 'they' want it to be called. So enough of the cute names &
  bullshit. Now back to some serious business....

-=-

  As for Minix under/over AmigaDOS, who cares?  Lets face it Minix doesn't
  have a real driver that allows modem/uucp communications so what good is it?

  Ive got an AT BridgeBoard running SCO Xenix and im real happy for now. When
  I finally get to look at CBM's version of Unix (Lauren ;-) ill decide if
  running AmigaDOS & Unix at the same time is important to me or not. Till then
  im running Unix, MS-DOS, and AmigaDOS *now*, not just talking about it.

  Sneakers

--
                                      ___
    Dan "Sneakers" Schein            ////          BERKS AMIGA BBS
    Sneakers Computing              ////   80+ Megs of software & messages
    2455 McKinley Ave.      ___    ////         12/2400 Baud - 24 Hrs
    West Lawn, PA 19609     \\\\  ////              215/678-7691
                             \\\\////
    {pyramid|rutgers|uunet}!cbmvax!heimat!sneakers   

deven@pawl.rpi.edu (Deven Corzine) (04/21/89)

In article <7812.AA7812@heimat> sneakers@heimat.UUCP (Dan "Sneakers" Schein) writes:
>In Message <703@ivucsb.UUCP>, dan@ivucsb.UUCP (Dan Howell) writes:

>>How about Commodore-Amiga Unix ...
>>
>>Comix!  :-)

>This whole discussion has gone past the comix stage and is no longer funny
>or related to comp.sys.amiga.tech in the least!

Quite so.  I started the chain, requested names, but did not intend
for multitudes of silly names to be posted, especially to .tech.  I
have since posted a request that any further name suggestions be
Emailed to me at shadow@pawl.rpi.edu, not posted.  I will probably
stick with "Amigix" however...  it's getting entrenched.  :-)

>Lets fact it Commodore is releasing the product and they will be naming it
>officially what 'they' want it to be called. So enough of the cute names &
>bullshit. Now back to some serious business....

BZZZ.  Wrong answer!  *I* am working on the project to get Unix-like
syscalls and environment under Exec (not necessarily with AmigaDOS,
but will coexist with AmigaDOS nicely) and as such, I get the power to
be arbitrary and choose what I want.  As I said, it looks like it'll
be "Amigix".  But, enough of the cute names and bullshit...  With that
I agree.

>As for Minix under/over AmigaDOS, who cares?  Lets face it Minix doesn't
>have a real driver that allows modem/uucp communications so what good is it?

Not Minix.  Someone else is doing a Minix port, but like with Amix,
you no longer have an Amiga when using that OS...  you just have a
Unix box.  Not good.  My project is to be based on Exec, and as such
will use standard Exec device drivers.

>Ive got an AT BridgeBoard running SCO Xenix and im real happy for now. When
>I finally get to look at CBM's version of Unix (Lauren ;-) ill decide if
>running AmigaDOS & Unix at the same time is important to me or not. Till then
>im running Unix, MS-DOS, and AmigaDOS *now*, not just talking about it.

Fine.  Myself, I wouldn't dare try to write an Amiga based MS-DOS
emulator, but I DO want Unix (of a sort) on an Amiga.  Coexisting with
Exec and AmigaDOS.  (Though I hope to allow it to run standalone --
without AmigaDOS, but with Exec.)

Hope this clears things up a little.

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.