X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=KernelLand%2FKernel%2Fdrv%2Fpty.c;h=d1f74c58d8fe47eab82114efa7c951b6f58119fe;hb=5f4d39ad0059ceec48c59d5ed87457a6bcb1c5f1;hp=69b1ce6e1ee4c590ad5bf5b5f39b9bbb3aad21a4;hpb=f7ec06bee2b80613d80c314bf864c69209d09829;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/drv/pty.c b/KernelLand/Kernel/drv/pty.c index 69b1ce6e..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, @@ -235,6 +237,7 @@ tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_Req 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(); @@ -308,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; @@ -377,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 @@ -401,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': @@ -444,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 @@ -601,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; @@ -787,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;