Merge branch 'master' of git://cadel.mutabah.net/acess2
[tpg/acess2.git] / KernelLand / Kernel / drv / pty.c
index ebce208..d1f74c5 100644 (file)
@@ -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;

UCC git Repository :: git.ucc.asn.au