mirror of
https://github.com/FDOS/kernel.git
synced 2025-07-17 19:04:29 +02:00
From Lucho: enable interactive re-execution of the SHELL.
git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@795 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
d61defe941
commit
3e3c05ff22
@ -152,6 +152,9 @@ VOID ASMCFUNC FAR int2a_handler(void);
|
|||||||
VOID ASMCFUNC FAR int2f_handler(void);
|
VOID ASMCFUNC FAR int2f_handler(void);
|
||||||
VOID ASMCFUNC FAR cpm_entry(void);
|
VOID ASMCFUNC FAR cpm_entry(void);
|
||||||
|
|
||||||
|
/* kernel.asm */
|
||||||
|
VOID ASMCFUNC FAR init_call_p_0(struct config FAR *Config); /* P_0, actually */
|
||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
VOID ASMCFUNC FreeDOSmain(void);
|
VOID ASMCFUNC FreeDOSmain(void);
|
||||||
BOOL init_device(struct dhdr FAR * dhp, char * cmdLine,
|
BOOL init_device(struct dhdr FAR * dhp, char * cmdLine,
|
||||||
|
@ -89,6 +89,36 @@ segment HMA_TEXT
|
|||||||
_intr:
|
_intr:
|
||||||
INTR
|
INTR
|
||||||
|
|
||||||
|
;; COUNT ASMCFUNC res_DosExec(COUNT mode, exec_blk * ep, BYTE * lp)
|
||||||
|
global _res_DosExec
|
||||||
|
_res_DosExec:
|
||||||
|
mov ah, 4bh
|
||||||
|
mov bx, sp
|
||||||
|
mov al, [bx+2]
|
||||||
|
push ds
|
||||||
|
pop es
|
||||||
|
mov dx, [bx+6] ; filename
|
||||||
|
mov bx, [bx+4] ; exec block
|
||||||
|
int 21h
|
||||||
|
jc short no_exec_error
|
||||||
|
xor ax, ax
|
||||||
|
no_exec_error:
|
||||||
|
ret
|
||||||
|
|
||||||
|
;; UCOUNT ASMCFUNC res_read(int fd, void *buf, UCOUNT count);
|
||||||
|
global _res_read
|
||||||
|
_res_read:
|
||||||
|
mov bx, sp
|
||||||
|
mov cx, [bx+6]
|
||||||
|
mov dx, [bx+4]
|
||||||
|
mov bx, [bx+2]
|
||||||
|
mov ah, 3fh
|
||||||
|
int 21h
|
||||||
|
jnc no_read_error
|
||||||
|
mov ax, -1
|
||||||
|
no_read_error:
|
||||||
|
ret
|
||||||
|
|
||||||
segment INIT_TEXT
|
segment INIT_TEXT
|
||||||
;
|
;
|
||||||
; void init_call_intr(nr, rp)
|
; void init_call_intr(nr, rp)
|
||||||
|
@ -673,6 +673,10 @@ _swap_indos:
|
|||||||
; _swap_indos but only if int2a ah=80/81 (critical section start/end)
|
; _swap_indos but only if int2a ah=80/81 (critical section start/end)
|
||||||
; are called upon entry and exit of the device drivers
|
; are called upon entry and exit of the device drivers
|
||||||
|
|
||||||
|
times 96 dw 0x9090 ; Process 0 Stack
|
||||||
|
global _p_0_tos
|
||||||
|
_p_0_tos:
|
||||||
|
|
||||||
segment DYN_DATA
|
segment DYN_DATA
|
||||||
|
|
||||||
global _Dyn
|
global _Dyn
|
||||||
@ -830,6 +834,11 @@ _reloc_call_clk_driver:
|
|||||||
_CharMapSrvc: jmp 0:_reloc_call_CharMapSrvc
|
_CharMapSrvc: jmp 0:_reloc_call_CharMapSrvc
|
||||||
call near forceEnableA20
|
call near forceEnableA20
|
||||||
|
|
||||||
|
global _init_call_p_0
|
||||||
|
extern reloc_call_p_0
|
||||||
|
_init_call_p_0: jmp 0:reloc_call_p_0
|
||||||
|
call near forceEnableA20
|
||||||
|
|
||||||
|
|
||||||
global __HMARelocationTableEnd
|
global __HMARelocationTableEnd
|
||||||
__HMARelocationTableEnd:
|
__HMARelocationTableEnd:
|
||||||
|
@ -336,17 +336,14 @@ STATIC VOID signon()
|
|||||||
|
|
||||||
STATIC void kernel()
|
STATIC void kernel()
|
||||||
{
|
{
|
||||||
exec_blk exb;
|
|
||||||
CommandTail Cmd;
|
CommandTail Cmd;
|
||||||
int rc;
|
|
||||||
|
|
||||||
exb.exec.env_seg = DOS_PSP + 8;
|
|
||||||
if (master_env[0] == '\0') /* some shells panic on empty master env. */
|
if (master_env[0] == '\0') /* some shells panic on empty master env. */
|
||||||
strcpy(master_env, "PATH=.");
|
strcpy(master_env, "PATH=.");
|
||||||
fmemcpy(MK_FP(exb.exec.env_seg, 0), master_env, sizeof(master_env));
|
fmemcpy(MK_FP(DOS_PSP + 8, 0), master_env, sizeof(master_env));
|
||||||
|
|
||||||
/* process 0 */
|
/* process 0 */
|
||||||
/* Execute command.com /P from the drive we just booted from */
|
/* Execute command.com from the drive we just booted from */
|
||||||
memset(Cmd.ctBuffer, 0, sizeof(Cmd.ctBuffer));
|
memset(Cmd.ctBuffer, 0, sizeof(Cmd.ctBuffer));
|
||||||
memcpy(Cmd.ctBuffer, Config.cfgInitTail, sizeof(Config.cfgInitTail));
|
memcpy(Cmd.ctBuffer, Config.cfgInitTail, sizeof(Config.cfgInitTail));
|
||||||
|
|
||||||
@ -356,7 +353,8 @@ STATIC void kernel()
|
|||||||
|
|
||||||
/* if stepping CONFIG.SYS (F5/F8), tell COMMAND.COM about it */
|
/* if stepping CONFIG.SYS (F5/F8), tell COMMAND.COM about it */
|
||||||
|
|
||||||
if (Cmd.ctCount < sizeof(Cmd.ctBuffer) - 3)
|
/* 3 for string + 2 for "\r\n" */
|
||||||
|
if (Cmd.ctCount < sizeof(Cmd.ctBuffer) - 5)
|
||||||
{
|
{
|
||||||
char *insertString = NULL;
|
char *insertString = NULL;
|
||||||
|
|
||||||
@ -376,55 +374,16 @@ STATIC void kernel()
|
|||||||
{
|
{
|
||||||
if (*p == ' ' || *p == '\t' || *p == '\r')
|
if (*p == ' ' || *p == '\t' || *p == '\r')
|
||||||
{
|
{
|
||||||
for (q = &Cmd.ctBuffer[Cmd.ctCount - 1]; q >= p; q--)
|
for (q = &Cmd.ctBuffer[Cmd.ctCount + 1]; q >= p; q--)
|
||||||
q[3] = q[0];
|
q[3] = q[0];
|
||||||
|
|
||||||
memcpy(p, insertString, 3);
|
memcpy(p, insertString, 3);
|
||||||
|
|
||||||
Cmd.ctCount += 3;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
strcpy(Config.cfgInitTail, Cmd.ctBuffer); /* save buffer */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
init_call_p_0(&Config); /* go execute process 0 (the shell) */
|
||||||
exb.exec.cmd_line = (CommandTail FAR *) & Cmd;
|
|
||||||
exb.exec.fcb_1 = exb.exec.fcb_2 = (fcb FAR *) 0xfffffffful;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("Process 0 starting: %s\n\n", Config.cfgInit);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while ((rc =
|
|
||||||
init_DosExec(Config.cfgP_0_startmode, &exb,
|
|
||||||
Config.cfgInit)) != SUCCESS)
|
|
||||||
{
|
|
||||||
BYTE *pLine;
|
|
||||||
printf("\nBad or missing Command Interpreter: %d - %s\n", rc,
|
|
||||||
Cmd.ctBuffer);
|
|
||||||
printf
|
|
||||||
("\nPlease enter the correct location (for example C:\\COMMAND.COM):\n");
|
|
||||||
rc = read(STDIN, Cmd.ctBuffer, sizeof(Cmd.ctBuffer) - 1);
|
|
||||||
Cmd.ctBuffer[rc] = '\0';
|
|
||||||
|
|
||||||
/* Get the string argument that represents the new init pgm */
|
|
||||||
pLine = GetStringArg(Cmd.ctBuffer, Config.cfgInit);
|
|
||||||
|
|
||||||
/* Now take whatever tail is left and add it on as a single */
|
|
||||||
/* string. */
|
|
||||||
strcpy(Cmd.ctBuffer, pLine);
|
|
||||||
|
|
||||||
/* and add a DOS new line just to be safe */
|
|
||||||
strcat(Cmd.ctBuffer, "\r\n");
|
|
||||||
|
|
||||||
Cmd.ctCount = rc - (pLine - Cmd.ctBuffer);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("Process 0 starting: %s\n\n", Config.cfgInit);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
printf("\nSystem shutdown complete\nReboot now.\n");
|
|
||||||
for (;;) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for a block device and update device control block */
|
/* check for a block device and update device control block */
|
||||||
|
@ -275,3 +275,22 @@ _spawn_int23:
|
|||||||
; cli
|
; cli
|
||||||
; ret
|
; ret
|
||||||
;_disable endp
|
;_disable endp
|
||||||
|
|
||||||
|
extern _p_0_tos,_P_0
|
||||||
|
|
||||||
|
; prepare to call process 0 (the shell) from P_0() in C
|
||||||
|
|
||||||
|
global reloc_call_p_0
|
||||||
|
reloc_call_p_0:
|
||||||
|
pop ax ; return address (32-bit, unused)
|
||||||
|
pop ax
|
||||||
|
pop ax ; fetch parameter 0 (32-bit) from the old stack
|
||||||
|
pop dx
|
||||||
|
mov ds,[cs:_DGROUP_]
|
||||||
|
cli
|
||||||
|
mov ss,[cs:_DGROUP_]
|
||||||
|
mov sp,_p_0_tos ; load the dedicated process 0 stack
|
||||||
|
sti
|
||||||
|
push dx ; pass parameter 0 onto the new stack
|
||||||
|
push ax
|
||||||
|
call _P_0 ; no return, allow parameter fetch from C
|
||||||
|
@ -220,6 +220,10 @@ UBYTE FcbClose(xfcb FAR * lpXfcb);
|
|||||||
void FcbCloseAll(void);
|
void FcbCloseAll(void);
|
||||||
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First);
|
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First);
|
||||||
|
|
||||||
|
/* intr.asm */
|
||||||
|
COUNT ASMCFUNC res_DosExec(COUNT mode, exec_blk * ep, BYTE * lp);
|
||||||
|
UCOUNT ASMCFUNC res_read(int fd, void *buf, UCOUNT count);
|
||||||
|
|
||||||
/* ioctl.c */
|
/* ioctl.c */
|
||||||
COUNT DosDevIOctl(lregs * r);
|
COUNT DosDevIOctl(lregs * r);
|
||||||
|
|
||||||
|
@ -48,6 +48,13 @@ static BYTE *RcsId =
|
|||||||
|
|
||||||
#define ExeHeader (*(exe_header *)(SecPathName + 0))
|
#define ExeHeader (*(exe_header *)(SecPathName + 0))
|
||||||
#define TempExeBlock (*(exec_blk *)(SecPathName + sizeof(exe_header)))
|
#define TempExeBlock (*(exec_blk *)(SecPathName + sizeof(exe_header)))
|
||||||
|
#define Shell (SecPathName + sizeof(exe_header) + sizeof(exec_blk))
|
||||||
|
|
||||||
|
#ifdef __TURBOC__ /* this is a Borlandism and doesn't work elsewhere */
|
||||||
|
#if sizeof(SecPathName) < sizeof(exe_header) + sizeof(exec_blk) + NAMEMAX
|
||||||
|
#error No room in SecPathName to be recycled!
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CHUNK 32256
|
#define CHUNK 32256
|
||||||
#define MAXENV 32768u
|
#define MAXENV 32768u
|
||||||
@ -792,3 +799,46 @@ COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "config.h" /* config structure definition */
|
||||||
|
|
||||||
|
/* start process 0 (the shell) */
|
||||||
|
VOID ASMCFUNC P_0(struct config FAR *Config)
|
||||||
|
{
|
||||||
|
BYTE *tailp, *endp;
|
||||||
|
exec_blk exb;
|
||||||
|
UBYTE mode = Config->cfgP_0_startmode;
|
||||||
|
|
||||||
|
/* build exec block and save all parameters here as init part will vanish! */
|
||||||
|
exb.exec.fcb_1 = exb.exec.fcb_2 = (fcb FAR *)-1L;
|
||||||
|
exb.exec.env_seg = DOS_PSP + 8;
|
||||||
|
fstrcpy(Shell, Config->cfgInit);
|
||||||
|
fstrcpy(Shell + strlen(Shell), Config->cfgInitTail); /* join name and tail */
|
||||||
|
endp = Shell + strlen(Shell);
|
||||||
|
|
||||||
|
for ( ; ; ) /* endless shell load loop - reboot or shut down to exit it! */
|
||||||
|
{
|
||||||
|
BYTE *p;
|
||||||
|
/* if there are no parameters, point to end without "\r\n" */
|
||||||
|
if((tailp = strchr(Shell,'\t')) == NULL &&
|
||||||
|
(tailp = strchr(Shell, ' ')) == NULL)
|
||||||
|
tailp = endp - 2;
|
||||||
|
/* shift tail to right by 2 to make room for '\0', ctCount */
|
||||||
|
for (p = endp - 1; p >= tailp; p--)
|
||||||
|
*(p + 2) = *p;
|
||||||
|
/* terminate name and tail */
|
||||||
|
*tailp = *(endp + 2) = '\0';
|
||||||
|
/* ctCount: just past '\0' do not count the "\r\n" */
|
||||||
|
exb.exec.cmd_line = (CommandTail *)(tailp + 1);
|
||||||
|
exb.exec.cmd_line->ctCount = endp - tailp - 2;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Process 0 starting: %s%s\n\n", Shell, tailp + 2);
|
||||||
|
#endif
|
||||||
|
res_DosExec(mode, &exb, Shell);
|
||||||
|
put_string("Bad or missing Command Interpreter: "); /* failure _or_ exit */
|
||||||
|
put_string(Shell);
|
||||||
|
put_string(tailp + 2);
|
||||||
|
put_string(" Enter the full shell command line: ");
|
||||||
|
endp = Shell + res_read(STDIN, Shell, NAMEMAX);
|
||||||
|
*endp = '\0'; /* terminate string for strchr */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user