X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fdrv%2Fpty.c;h=d1f74c58d8fe47eab82114efa7c951b6f58119fe;hb=6274aaa8894e14462a36c69090e2f9235f130e31;hp=ebce208518c2598840c82870f9e5f83ddff1694a;hpb=d0f611cd4716fa5647ce029a2fe827eadac8dd4b;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/drv/pty.c b/KernelLand/Kernel/drv/pty.c index ebce2085..d1f74c58 100644 --- a/KernelLand/Kernel/drv/pty.c +++ b/KernelLand/Kernel/drv/pty.c @@ -85,6 +85,7 @@ tVFS_NodeType gPTY_NodeType_Root = { }; tVFS_NodeType gPTY_NodeType_Client = { .TypeName = "PTY-Client", + .Flags = VFS_NODETYPEFLAG_STREAM, .Read = PTY_ReadClient, .Write = PTY_WriteClient, .IOCtl = PTY_IOCtl, @@ -93,6 +94,7 @@ tVFS_NodeType gPTY_NodeType_Client = { }; tVFS_NodeType gPTY_NodeType_Server = { .TypeName = "PTY-Server", + .Flags = VFS_NODETYPEFLAG_STREAM, .Read = PTY_ReadServer, .Write = PTY_WriteServer, .IOCtl = PTY_IOCtl, @@ -121,7 +123,7 @@ int PTY_Install(char **Arguments) } // --- Management --- -tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_ReqResize ReqResize, tPTY_ModeSet ModeSet) +tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_ReqResize ReqResize, tPTY_ModeSet ModeSet, const struct ptydims *InitialDims, const struct ptymode *InitialMode) { tPTY **prev_np = NULL; size_t namelen; @@ -229,7 +231,13 @@ tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_Req ret->OutputFcn = Output; ret->ReqResize = ReqResize; ret->ModeSet = ModeSet; + // - Initialise modes + if( InitialDims ) + ret->Dims = *InitialDims; + if( InitialMode ) + ret->Mode = *InitialMode; // - Client node + ret->ClientNode.Size = -1; ret->ClientNode.ImplPtr = ret; ret->ClientNode.Type = &gPTY_NodeType_Client; ret->ClientNode.UID = Threads_GetUID(); @@ -303,7 +311,8 @@ int PTY_SetAttrib(tPTY *PTY, const struct ptydims *Dims, const struct ptymode *M else { // SIGWINSZ to client - Threads_SignalGroup(PTY->ControllingProcGroup, SIGWINCH); + if( PTY->ControllingProcGroup > 0 ) + Threads_SignalGroup(PTY->ControllingProcGroup, SIGWINCH); } LOG("PTY %p dims set to %ix%i", PTY, Dims->W, Dims->H); PTY->Dims = *Dims; @@ -372,21 +381,22 @@ size_t PTY_int_SendInput(tPTY *PTY, const char *Input, size_t Length) size_t ret = 1, print = 1; // Input mode stuff only counts for text output mode - // - Any other is Uint32 keypresses + // - Any other mode sends Uint32 keypresses if( (PTY->Mode.OutputMode & PTYOMODE_BUFFMT) != PTYBUFFMT_TEXT ) return PTY_int_WriteInput(PTY, Input, Length); - // If in raw mode, flush directlr + // If in raw mode, flush directly if( (PTY->Mode.InputMode & PTYIMODE_RAW) ) return PTY_int_WriteInput(PTY, Input, Length); if( PTY->Mode.InputMode & PTYIMODE_CANON ) { - const char char_bs = '\b'; + switch(Input[0]) { case 3: // INTR - ^C // Send SIGINT - Threads_SignalGroup(PTY->ControllingProcGroup, SIGINT); + if( PTY->ControllingProcGroup > 0 ) + Threads_SignalGroup(PTY->ControllingProcGroup, SIGINT); print = 0; break; case 4: // EOF - ^D @@ -396,17 +406,21 @@ size_t PTY_int_SendInput(tPTY *PTY, const char *Input, size_t Length) print = 0; break; case 8: // Backspace - if(PTY->LineLength != 0) + if(PTY->LineLength != 0) { PTY->LineLength --; + PTY_WriteClient(&PTY->ClientNode, 0, 3, "\b \b", 0); + } + print = 0; break; case 'w'-'a': // Word erase while(PTY->LineLength != 0 && isalnum(PTY->LineData[--PTY->LineLength])) - PTY_WriteClient(&PTY->ClientNode, 0, 1, &char_bs, 0); + PTY_WriteClient(&PTY->ClientNode, 0, 1, "\b", 0); + PTY_WriteClient(&PTY->ClientNode, 0, 3, "\x1b[K", 0); print = 0; break; case 'u'-'a': // Kill - while(PTY->LineLength > 0) - PTY_WriteClient(&PTY->ClientNode, 0, 1, &char_bs, 0); + PTY_WriteClient(&PTY->ClientNode, 0, 8, "\x1b[2K\x1b[0G", 0); + PTY->LineLength = 0; print = 0; break; case 'v'-'a': @@ -439,7 +453,24 @@ size_t PTY_int_SendInput(tPTY *PTY, const char *Input, size_t Length) } else { - ret = PTY_int_WriteInput(PTY, Input, Length); + #if 0 + if( PTY->Mode.InputMode & PTYIMODE_NLCR ) + { + if( Input[0] == '\n' ) { + char ch = '\r'; + ret = PTY_int_WriteInput(PTY, &ch, 1); + } + else { + int i; + for( i = 0; i < Length && Input[i] != '\n'; i ++ ) + ; + ret = PTY_int_WriteInput(PTY, Input, i); + } + } + // TODO: CRNL mode? + else + #endif + ret = PTY_int_WriteInput(PTY, Input, Length); } // Echo if requested @@ -596,12 +627,14 @@ size_t PTY_WriteClient(tVFS_Node *Node, off_t Offset, size_t Length, const void // If the server has terminated, send SIGPIPE if( pty->ServerNode && pty->ServerNode->ReferenceCount == 0 ) { + LOG("SIGPIPE, server has terminated"); Threads_PostSignal(SIGPIPE); errno = EIO; return -1; } // Write to either FIFO or directly to output function + LOG("pty->OutputFcn = %p", pty->OutputFcn); if( pty->OutputFcn ) { pty->OutputFcn(pty->OutputHandle, Length, Buffer); return Length; @@ -782,6 +815,8 @@ int PTY_IOCtl(tVFS_Node *Node, int ID, void *Data) int is_server = !pty || Node == pty->ServerNode; + LOG("(%i,%p) %s", ID, Data, (is_server?"Server":"Client")); + switch(ID) { case DRV_IOCTL_TYPE: return DRV_TYPE_TERMINAL; @@ -825,7 +860,7 @@ int PTY_IOCtl(tVFS_Node *Node, int ID, void *Data) case PTY_IOCTL_SETID: if( Data && !CheckString(Data) ) { errno = EINVAL; return -1; } if( pty ) return EALREADY; - pty = PTY_Create(Data, NULL, NULL,NULL, NULL); + pty = PTY_Create(Data, NULL, NULL,NULL, NULL, NULL,NULL); if(pty == NULL) return 1; Node->ImplPtr = pty;