brian@bradley.UUCP (07/18/88)
I'm considering writing a shell for the IBM PC... I'm using Microsoft C 5.0. This version does not provide a fork() function. Instead, they provide a set of functions called spawn, which are similar to exec. That is, there is a spawnve(), spawnl(), etc. Their effect is similar to a fork(), with an exec() in the child process, and a wait() in the parent process. Unfortunatley, to do I/O redirection, I need to put some code between the fork() and the exec() in the child process. Since there is not really a fork(), this isn't possible. Of course, I could do a system() with my whole command line, but this is not a solution because 1) there is no way to pass the environment in this case, 2) I would have to somehow translate my shell's syntax back to MS-DOS COMMAND.COM syntax, which may not be possible, and 3) the system() function probaly will load in another copy of COMMAND.COM, and my shell will be cutting into avaible memory at it is. So what I need is a way to run a child process, with (possibly) redirected input and/or output, passing the environment, and having the parent process resume execution after the child process completes. Does anyone have any clues as to how this can be done? ............................................................................... When the going gets weird, the weird turn pro. Brian Michael Wendt UUCP: {cepu,ihnp4,uiucdcs,noao}!bradley!brian Bradley University ARPA: cepu!bradley!brian@seas.ucla.edu (309) 677-2230 ICBM: 40 40' N 89 34' W
platt@emory.uucp (Dan Platt) (07/21/88)
In article <9900005@bradley> brian@bradley.UUCP writes: > > I'm considering writing a shell for the IBM PC... I'm using Microsoft >C 5.0. This version does not provide a fork() function. Instead, they >provide a set of functions called spawn, which are similar to exec. >That is, there is a spawnve(), spawnl(), etc. ... There is no fork because DOS doesn't support multitasking. What DOS will support is an interupt driven suspension of one routine and activation of another routine (this is demonstrated in the DOS print command), or for a software suspension of one routine for a temporary execution of another one (until memory runs out) which is what spawnve() etc. do. > Unfortunatley, to do I/O redirection, I need to put some code between >the fork() and the exec() in the child process. Since there is not >really a fork(), this isn't possible. You want PIPEs. Well, there aren't any real pipes in DOS (unlike UNIX) since there is no multitasking. However, there is re-direction and DOS does support a pseudo-PIPE. The way DOS does it is to have one process direct stdout to a temporary file PIPE*.* which is then directed to stdin of the next process. Multiple pipes are possible, but each process has to be able to run sequentially; they can't be written to run concurrently with the process. If you really want to sweat, you could make a hybrid where an agreed upon temporary file was used as the input, and have the secondary process execute a little on each clock interupt... > > Of course, I could do a system() with my whole command line, but this >is not a solution because 1) there is no way to pass the environment >in this case, 2) I would have to somehow translate my shell's syntax >back to MS-DOS COMMAND.COM syntax, which may not be possible, and >3) the system() function probaly will load in another copy of COMMAND.COM, >and my shell will be cutting into avaible memory at it is. > > So what I need is a way to run a child process, with (possibly) >redirected input and/or output, passing the environment, and having the >parent process resume execution after the child process completes. >Does anyone have any clues as to how this can be done? > The only way I can see you doing it is using spawnv*() with a temporary file used to pass the information. You may need to tolerate loaded versions of COMMAND.COM. If you are only loading one process at a time on top of your shell, this shouldn't be too much of a problem unless your shell is large. You may also want to consider using exemod on your shell program to reduce the execution space size (your shell will take up a lot more space than command.com unless you do this). Most of the spawn*() and system() function calls use DOS BIOS function calls anyway. This is one reason to 1) Go to UNIX systems, or 2) Go to OS/2 (if it ever flies)... Dan Platt
brian@bradley.UUCP (07/21/88)
My thanks to everyone who responded to my question on doing I/O redirection for a child process without disturbing the parent processes I/O under Microsoft C 5.0. Apparently the only way to do it is by using dup() to copy stdin/stdout/stderr before starting the child process, and dup2() to restore them afterwards. The only drawback is that Microsoft C already reserves 5 fildes. If I dup() three, that only leaves 12 for the child process... ............................................................................... When the going gets weird, the weird turn pro. Brian Michael Wendt UUCP: {cepu,ihnp4,uiucdcs,noao}!bradley!brian Bradley University ARPA: cepu!bradley!brian@seas.ucla.edu (309) 677-2230 ICBM: 40 40' N 89 34' W
daveh@marob.MASA.COM (Dave Hammond) (07/22/88)
In article <3083@emory.uucp> platt@emory.UUCP (Dan Platt) writes: >In article <9900005@bradley> brian@bradley.UUCP writes: >> >> I'm considering writing a shell for the IBM PC... I'm using Microsoft >>C 5.0...................[stuff deleted]................................ > >> Unfortunatley, to do I/O redirection................................. > >You want PIPEs. Well, there aren't any real pipes in DOS (unlike UNIX) >since there is no multitasking. However, there is re-direction and >DOS does support a pseudo-PIPE.......................................... > May I recommend an excellent book (and accompanying source code diskette): ``On Command: Writing a Unix-like Shell for MS-DOS'', by Allen Holub Published by M&T Publishing, 800-533-4372 The book explains subprocess spawning, i/o redirection, piping, environ management and history substitution in detail. The optional source diskette contains a very useable MS-DOS shell, as well. >This is one reason to 1) Go to UNIX systems, or 2) Go to OS/2 (if it... OPINION: UNIX yes! OS/2... When UNIX (on a '386) can provide DOS file compatibility, DOS program execution, X-Windows, Ethernet, TCP/IP, and hundreds of utilities, what's the point of an OS/2 (barring discussions on bureaucratic comfort with Big Blue). Dave Hammond UUCP: {uunet|rutgers|spl1|...}!hombre!marob!daveh -----------------------------------------------------
rwhite@nusdhub.UUCP (Robert C. White Jr.) (07/23/88)
in article <3083@emory.uucp>, platt@emory.uucp (Dan Platt) says: > In article <9900005@bradley> brian@bradley.UUCP writes: >> Of course, I could do a system() with my whole command line, but this >>is not a solution because 1) there is no way to pass the environment >>in this case, 2) I would have to somehow translate my shell's syntax >>back to MS-DOS COMMAND.COM syntax, which may not be possible, and >>3) the system() function probaly will load in another copy of COMMAND.COM, >>and my shell will be cutting into avaible memory at it is. > The only way I can see you doing it is using spawnv*() with a > temporary file used to pass the information. You may need to > tolerate loaded versions of COMMAND.COM. If you are only loading > one process at a time on top of your shell, this shouldn't be to > much of a problem unless your shell is large. I think you are missing one small point here. "COMMAND.COM" is the MS-DOS shell. If you write something to replace it, you must *include* a loader of you own in the text of your shell. If you look up the dos function call which loads programs, you will find that it invokes the shell (e.g. command.com) to do the loading. If you write your own true shell, it must contain a assembly or such which will act as the loader from then on. Once you have doen this, you may simply decide that the loade will remain in low memory all the time, and never worry about loading the loader again. All this is you own choice. If you only wish to write a simple command editor/environment that is your own get out, but it is not a "MS-DOS shell" Put simply: If you write a _true_ shell, you will have the procedures to do whatever you want durring loading locally available to your shell. At that point spawn() and exec() from the Microsoft C compiler become irrevelant. Rob.
Ralf.Brown@B.GP.CS.CMU.EDU (07/24/88)
In article <1112@nusdhub.UUCP>, rwhite@nusdhub.UUCP (Robert C. White Jr.) writes: }I think you are missing one small point here. "COMMAND.COM" is the }MS-DOS shell. If you write something to replace it, you must }*include* a loader of you own in the text of your shell. If you }look up the dos function call which loads programs, you will find }that it invokes the shell (e.g. command.com) to do the loading. That is only true of DOS 1.x and PC-DOS 2.x. MS-DOS 2.x and MS/PC-DOS 3.x have the loader in the kernel. PC-DOS 2.x doesn't invoke COMMAND.COM, it just happens that COMMAND.COM intercepts INT 21h and branches to a second transient portion containing the 1K or so of code to do the loading. That's why PC-DOS 2.x requires COMMAND.COM to be present, as the loader code may have to be read in from the COMMAND.COM file on disk. -- UUCP: {ucbvax,harvard}!cs.cmu.edu!ralf -=-=-=- Voice: (412) 268-3053 (school) ARPA: ralf@cs.cmu.edu BIT: ralf%cs.cmu.edu@CMUCCVMA FIDO: Ralf Brown 1:129/31 Disclaimer? I |Ducharm's Axiom: If you view your problem closely enough claimed something?| you will recognize yourself as part of the problem.