X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fdrv%2Fpty.c;h=d1f74c58d8fe47eab82114efa7c951b6f58119fe;hb=5f4d39ad0059ceec48c59d5ed87457a6bcb1c5f1;hp=37fc47b43ceee1ef85cc5284e43cd1c8d3f2206b;hpb=44fd0422a8308bee8ee10021f1f5b61c58732b02;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/drv/pty.c b/KernelLand/Kernel/drv/pty.c index 37fc47b4..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,12 +123,16 @@ 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; int idx = 1; - if( !Name || Name[0] == '\0' ) + + if( !Name ) + Name = ""; + + if( Name[0] == '\0' ) { RWLock_AcquireWrite(&glPTY_NumPTYs); // Get a pty ID if Name==NULL @@ -146,6 +152,7 @@ tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_Req // whichever is free prev_np = &gpPTY_FirstNamedPTY; + RWLock_AcquireWrite(&glPTY_NamedPTYs); idx = 0; namelen = strlen(Name)-1; for( tPTY *pty = gpPTY_FirstNamedPTY; pty; prev_np = &pty->Next, pty = pty->Next ) @@ -214,17 +221,23 @@ tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_Req ret->Name = (char*)(ret + 1); if( idx == -1 ) strcpy(ret->Name, Name); - else { - if(!Name) Name = ""; + else if( Name[0] ) sprintf(ret->Name, "%.*s%u", strlen(Name)-1, Name, idx); - } + else + sprintf(ret->Name, "%u", idx); ret->NumericName = idx; // - Output function and handle (same again) ret->OutputHandle = Handle; 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(); @@ -235,7 +248,7 @@ tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_Req ret->OwnerRW.Ent.ID = Threads_GetUID(); ret->OwnerRW.Perm.Perms = -1; - if( Name && Name[0] ) { + if( Name[0] ) { giPTY_NamedCount ++; RWLock_Release(&glPTY_NamedPTYs); } @@ -298,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; @@ -367,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 @@ -391,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': @@ -434,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 @@ -591,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; @@ -777,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; @@ -820,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;