From 7f906c4c7c6828b5ed6f210453c8aff28cfa5942 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 27 Mar 2012 10:33:16 +0800 Subject: [PATCH] TESTING - Patches to implement Ctrl-C in VTerm --- KernelLand/Kernel/drv/vterm.c | 17 ++++++++++ KernelLand/Kernel/drv/vterm.h | 2 ++ KernelLand/Kernel/drv/vterm_input.c | 44 ++++++++++++++++++++++--- KernelLand/Kernel/drv/vterm_output.c | 2 ++ KernelLand/Kernel/include/acess.h | 3 ++ KernelLand/Kernel/include/threads_int.h | 6 +++- KernelLand/Kernel/threads.c | 8 +++++ 7 files changed, 76 insertions(+), 6 deletions(-) diff --git a/KernelLand/Kernel/drv/vterm.c b/KernelLand/Kernel/drv/vterm.c index 0489d41b..5f4a25ca 100644 --- a/KernelLand/Kernel/drv/vterm.c +++ b/KernelLand/Kernel/drv/vterm.c @@ -40,6 +40,9 @@ tVFS_Node *VT_FindDir(tVFS_Node *Node, const char *Name); size_t VT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer); size_t VT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer); int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data); +void VT_Terminal_Reference(tVFS_Node *Node); +void VT_Terminal_Close(tVFS_Node *Node); +//void VT_SetTerminal(int Term); // === CONSTANTS === @@ -164,7 +167,9 @@ int VT_Install(char **Arguments) VT_InitOutput(); VT_InitInput(); + // Create Nodes + Log_Debug("VTerm", "Initialising nodes (and creating buffers)"); for( i = 0; i < NUM_VTS; i++ ) { gVT_Terminals[i].Mode = TERM_MODE_TEXT; @@ -191,10 +196,12 @@ int VT_Install(char **Arguments) // Semaphore_Init(&gVT_Terminals[i].InputSemaphore, 0, MAX_INPUT_CHARS8, "VTerm", gVT_Terminals[i].Name); } + Log_Debug("VTerm", "Registering with DevFS"); // Add to DevFS DevFS_AddDevice( &gVT_DrvInfo ); // Set kernel output to VT0 + Log_Debug("VTerm", "Setting kernel output to VT#0"); Debug_SetKTerminal("/Devices/VTerm/0"); return MODULE_ERR_OK; @@ -703,6 +710,16 @@ int VT_Terminal_IOCtl(tVFS_Node *Node, int Id, void *Data) return -1; } +void VT_Terminal_Reference(tVFS_Node *Node) +{ + // Append PID to list +} + +void VT_Terminal_Close(tVFS_Node *Node) +{ + // Remove PID from list +} + /** * \fn void VT_SetTerminal(int ID) * \brief Set the current terminal diff --git a/KernelLand/Kernel/drv/vterm.h b/KernelLand/Kernel/drv/vterm.h index 00fbb7a6..55eea0e5 100644 --- a/KernelLand/Kernel/drv/vterm.h +++ b/KernelLand/Kernel/drv/vterm.h @@ -75,6 +75,8 @@ struct sVTerm Uint32 RawScancode; //!< last raw scancode recieved // tSemaphore InputSemaphore; + tPGID OwningProcessGroup; //!< The process group that owns the terminal + Uint32 *Buffer; // TODO: Do I need to keep this about? diff --git a/KernelLand/Kernel/drv/vterm_input.c b/KernelLand/Kernel/drv/vterm_input.c index 20e47db0..31b050f2 100644 --- a/KernelLand/Kernel/drv/vterm_input.c +++ b/KernelLand/Kernel/drv/vterm_input.c @@ -7,6 +7,7 @@ */ #include "vterm.h" #include +#define DEBUG 1 // === GLOBALS === // --- Key States --- (Used for VT Switching/Magic Combos) @@ -27,6 +28,7 @@ void VT_InitInput() return ; } VFS_IOCtl(giVT_InputDevHandle, KB_IOCTL_SETCALLBACK, VT_KBCallBack); + LOG("VTerm input initialised"); } /** @@ -173,30 +175,53 @@ void VT_KBCallBack(Uint32 Codepoint) break; case KEYSYM_HOME: - case KEYSYM_KP7: + case KEYSYM_KP7: // Codepoint==0, then it's home (not translated) buf[0] = '\x1B'; buf[1] = 'O'; buf[2] = 'H'; len = 3; break; case KEYSYM_END: - case KEYSYM_KP1: + case KEYSYM_KP1: // You get the drill buf[0] = '\x1B'; buf[1] = 'O'; buf[2] = 'F'; len = 3; break; case KEYSYM_INSERT: - case KEYSYM_KP0: + case KEYSYM_KP0: // See above buf[0] = '\x1B'; buf[1] = '['; buf[2] = '2'; buf[3] = '~'; len = 4; break; case KEYSYM_DELETE: - case KEYSYM_KPPERIOD: + case KEYSYM_KPPERIOD: // Are you that dumb? Look up buf[0] = '\x1B'; buf[1] = '['; buf[2] = '3'; buf[3] = '~'; len = 4; break; } } + else if( gbVT_CtrlDown ) + { + len = 1; + switch( term->RawScancode ) + { + case KEYSYM_2: + buf[0] = '\0'; + break; + case KEYSYM_3 ... KEYSYM_7: + buf[0] = 0x1b + (term->RawScancode - KEYSYM_3); + break; + case KEYSYM_8: + buf[0] = 0x7f; + break; + // - Ctrl-A = \1, Ctrl-Z = \x1a + case KEYSYM_a ... KEYSYM_z: + buf[0] = 0x01 + (term->RawScancode - KEYSYM_a); + break; + default: + goto utf_encode; + } + } else { + utf_encode: // Attempt to encode in UTF-8 len = WriteUTF8( buf, Codepoint ); if(len == 0) { @@ -214,6 +239,14 @@ void VT_KBCallBack(Uint32 Codepoint) // Handle meta characters if( !(term->Flags & VT_FLAG_RAWIN) ) { + // Implementation options for Ctrl-C -> SIGINT + // - Kernel-land: here in the VT + // > Pros: No userland change needed + // > Cons: Requires process groups + // - User-land, in the shell + // > Pros: Less threading changes + // > Cons: Needs the shell to get all user input before the app, worse latency + // > Won't work with bash etc switch(buf[0]) { case '\3': // ^C @@ -224,8 +257,9 @@ void VT_KBCallBack(Uint32 Codepoint) #endif // Write - if( MAX_INPUT_CHARS8 - term->InputWrite >= len ) + if( MAX_INPUT_CHARS8 - term->InputWrite >= len ) { memcpy( &term->InputBuffer[term->InputWrite], buf, len ); + } else { memcpy( &term->InputBuffer[term->InputWrite], buf, MAX_INPUT_CHARS8 - term->InputWrite ); memcpy( &term->InputBuffer[0], buf, len - (MAX_INPUT_CHARS8 - term->InputWrite) ); diff --git a/KernelLand/Kernel/drv/vterm_output.c b/KernelLand/Kernel/drv/vterm_output.c index 95a2bce8..4d1c352b 100644 --- a/KernelLand/Kernel/drv/vterm_output.c +++ b/KernelLand/Kernel/drv/vterm_output.c @@ -7,6 +7,7 @@ */ #include "vterm.h" #include +#define DEBUG 1 // === CODE === /** @@ -23,6 +24,7 @@ void VT_InitOutput() VT_SetResolution( giVT_RealWidth, giVT_RealHeight ); VT_SetTerminal( 0 ); VT_SetMode( VIDEO_BUFFMT_TEXT ); + LOG("VTerm output initialised"); } /** diff --git a/KernelLand/Kernel/include/acess.h b/KernelLand/Kernel/include/acess.h index 25077ca4..5b9effbf 100644 --- a/KernelLand/Kernel/include/acess.h +++ b/KernelLand/Kernel/include/acess.h @@ -38,6 +38,7 @@ // --- Types --- typedef Uint32 tPID; //!< Process ID type +typedef Uint32 tPGID; //!< Process Group ID type typedef Uint32 tTID; //!< Thread ID Type typedef Uint32 tUID; //!< User ID Type typedef Uint32 tGID; //!< Group ID Type @@ -93,6 +94,8 @@ extern const char gsGitHash[]; #define CLONE_VM 0x10 //! Don't copy user pages #define CLONE_NOUSER 0x20 +//! Inherit the parent's PGID +#define CLONE_PGID 0x40 /** * \} */ diff --git a/KernelLand/Kernel/include/threads_int.h b/KernelLand/Kernel/include/threads_int.h index 515ab0a3..6e345d02 100644 --- a/KernelLand/Kernel/include/threads_int.h +++ b/KernelLand/Kernel/include/threads_int.h @@ -8,7 +8,6 @@ #include #include - typedef struct sProcess tProcess; /** @@ -27,8 +26,12 @@ typedef struct sMessage */ struct sProcess { + struct sProcess *Next; + tPGID PGID; tPID PID; + int nThreads; + struct sThread *FirstThread; tUID UID; //!< User ID tGID GID; //!< User and Group @@ -53,6 +56,7 @@ struct sThread struct sThread *Next; struct sThread *GlobalNext; //!< Next thread in global list struct sThread *GlobalPrev; //!< Previous thread in global list + struct sThread *ProcessNext; tShortSpinlock IsLocked; //!< Thread's spinlock volatile int Status; //!< Thread Status void *WaitPointer; //!< What (Mutex/Thread/other) is the thread waiting on diff --git a/KernelLand/Kernel/threads.c b/KernelLand/Kernel/threads.c index 5e60c461..63671724 100644 --- a/KernelLand/Kernel/threads.c +++ b/KernelLand/Kernel/threads.c @@ -313,6 +313,10 @@ tThread *Threads_CloneTCB(Uint Flags) new->Process = malloc( sizeof(struct sProcess) ); newproc = new->Process; newproc->PID = new->TID; + if( Flags & CLONE_PGID ) + newproc->PGID = oldproc->PGID; + else + newproc->PGID = newproc->PID; newproc->UID = oldproc->UID; newproc->GID = oldproc->GID; newproc->MaxFD = oldproc->MaxFD; @@ -1001,6 +1005,10 @@ void Threads_SegFault(tVAddr Addr) } // --- Process Structure Access Functions --- +tPGID Threads_GetPGID(void) +{ + return Proc_GetCurThread()->Process->PGID; +} tPID Threads_GetPID(void) { return Proc_GetCurThread()->Process->PID; -- 2.20.1