home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / DRIVERS / SRC / ptys.lzh / ptyman.c < prev    next >
Text File  |  1990-04-25  |  13KB  |  464 lines

  1. /*       This software is copyright (C) 1989 by Reimer Mellin        *
  2. *                                                                    *
  3. *        Permission is granted to reproduce and distribute           *
  4. *        this package by any means so long as no fee is charged      *
  5. *        above a nominal handling fee and so long as this            *
  6. *        notice is always included in the copies.                    *
  7. *        Commerical use or incorporation into commercial software    *
  8. *        is prohibited without the written permission of the         *
  9. *        author.                                                     *
  10. *                                                                    *
  11. *        Other rights are reserved except as explicitly granted      *
  12. *        by written permission of the author.                        *
  13. *                Reimer Mellin                                       *
  14. *                                                                    *
  15. *                Sulenstr.8                                          *
  16. *                D-8000 Muenchen 71 (Federal Republic of Germany)    *
  17. *                                                                    *
  18. *           EMAIL:                                                   *
  19. *                mellin@lan.informatik.tu-muenchen.dbp.de            *
  20. *                ram@altger.UUCP                                     *
  21. *                ....!pyramid!tmpmbx!doitcr!ramsys!ram (home)        *
  22. *                                                                    */
  23.  
  24. /*   */
  25.  
  26. /*
  27.  * HauptModul des PtyManagers -- Einsprung-Routinen vom Assembler-Interface
  28.  *
  29.  * $Header: /h0/USR/REIMER/PTYMAN/RCS/ptyman.c_v 1.2.1.2 89/09/04 13:14:23 ram Exp $
  30.  *
  31.  * $Log:    ptyman.c_v $
  32.  * Revision 1.2.1.2  89/09/04  13:14:23  ram
  33.  * added some comments
  34.  * 
  35.  * Revision 1.2.1.1  89/08/31  12:26:06  ram
  36.  * Copyright-message added
  37.  * 
  38.  * Revision 1.2  89/07/16  01:06:12  ram
  39.  * minor changes to Sub-net Release
  40.  * 
  41.  * Revision 1.1.1.1  89/07/14  19:49:56  ram
  42.  * Fixed: SS_SSig Bug. Sub-Net Beta-Release
  43.  * 
  44.  * Revision 1.1  89/07/13  23:22:15  ram
  45.  * Initial revision
  46.  * 
  47.  */
  48.  
  49. #include <types.h>
  50. #include <reg.h>
  51. #include "Ptyman.h"
  52. #include <path.h>
  53. #include <sg_codes.h>
  54. #include <procid.h>
  55. #include <modes.h>
  56. #include <sgstat.h>
  57. #include <setsys.h>
  58. #include <signal.h>
  59. #include <errno.h>
  60.  
  61. #ifdef ST
  62. #include <stconfuncs.h>
  63. #endif
  64.  
  65. #include "misc.h"
  66.  
  67. union pathdesc pd;      /* a6 points to the Path-Descriptor !!! */
  68.  
  69. extern  int     _prsnam();
  70.  
  71. extern  int     strcmp();
  72. extern  void    memcpy();
  73. extern  void    initbuf();
  74. extern  void    kill();
  75.  
  76. extern  int     dosleep();
  77. extern  int     hangup();
  78. extern  int     cpinraw();
  79. extern  int     cpin();
  80. extern  int     cpoutraw();
  81. extern  int     cpout();
  82.  
  83. /*
  84.  * O P E N
  85.  */
  86. Open(procdesc, ustack)
  87.   procid    *procdesc;
  88.   REGISTERS *ustack;
  89. {
  90.     register    u_char  *name = (u_char *) ustack->a[0];
  91.     register    int      namcnt,i;
  92.     register    Pathdesc ptr;
  93.  
  94.     pd.ptypvt.pd_typ = (name[1] == 'P' || name[1] == 'p') ? PTY : TTY;
  95.  
  96.     if( ( namcnt = _prsnam(name)) < 0)
  97.         return -1;
  98.     if( name[namcnt] != '/') {
  99.         errno = E_BPNAM;
  100.         return -1;
  101.     }
  102.     name += namcnt+1;
  103.  
  104.     if( ( namcnt = _prsnam(name)) < 0 || namcnt > 28 || name[namcnt] != '\0' ) {
  105.         errno = E_BPNAM;
  106.         return -1;
  107.     }
  108.  
  109.     pd.path.pd_mod = (u_char) ustack->d[0];
  110.  
  111.     for(i=0; i < namcnt;i++)
  112.         pd.ptyopt.pd_name[i] = upchar(name[i]);
  113.     pd.ptyopt.pd_namlen = namcnt;
  114.  
  115.     if( pd.ptypvt.pd_typ != PTY) {
  116.         /* tty */
  117.         /* look for correspondent pty in path-list and register, else sleep(0) */
  118.         do {
  119.         ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
  120.         for(; ptr ; ptr = ptr->path.pd_paths)
  121.             if( ptr->ptypvt.pd_typ == PTY && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
  122.                 pd.ptypvt.pd_pty = ptr;
  123.                 goto outloop;
  124.             }
  125.         } while ( dosleep(procdesc) == 0);
  126.         return -1;
  127.     } else {
  128.         /* pty */
  129.         /* iff same name exists, exists with error */
  130.         ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
  131.  
  132.         for(; ptr ; ptr = ptr->path.pd_paths)
  133.             if( ptr->ptypvt.pd_typ == PTY && ptr != &pd && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
  134.                 errno = E_SHARE;
  135.                 return -1;
  136.             }
  137.         /* set buffersize and allocate them */
  138.         pd.ptypvt.pd_rbuf.size = pd.ptypvt.pd_wbuf.size = DEFBUFSIZE;
  139.         if( (pd.ptypvt.pd_rbuf.buf = (u_char *)_srqmem( (pd.ptypvt.pd_rbuf.size))) == (u_char *)0 ||
  140.                 (pd.ptypvt.pd_wbuf.buf = (u_char *)_srqmem( (pd.ptypvt.pd_wbuf.size))) == (u_char *)0 ) {
  141.             if( pd.ptypvt.pd_wbuf.buf )
  142.                 (void) _srtmem(pd.ptypvt.pd_wbuf.buf,pd.ptypvt.pd_wbuf.size);
  143.             if( pd.ptypvt.pd_rbuf.buf )
  144.                 (void) _srtmem(pd.ptypvt.pd_rbuf.buf,pd.ptypvt.pd_rbuf.size);
  145.             return -1;
  146.         }
  147.  
  148.         pd.ptypvt.pd_rbuf.rptr = pd.ptypvt.pd_rbuf.wptr = pd.ptypvt.pd_rbuf.buf;
  149.         pd.ptypvt.pd_wbuf.rptr = pd.ptypvt.pd_wbuf.wptr = pd.ptypvt.pd_wbuf.buf;
  150.  
  151.         ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
  152.         /* look for a sleeping tty -- and wake it up */
  153.         for(; ptr ; ptr = ptr->path.pd_paths)
  154.             if( ptr->ptypvt.pd_typ == TTY && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
  155.                 if( ptr->path.pd_cpr != 0 )
  156.                     kill(ptr->path.pd_cpr, 
  157.                          (ptr->ptypvt.pd_esig ? ptr->ptypvt.pd_esig : SIGWAKE));
  158.             }
  159.     }
  160. outloop:
  161.     return 0;
  162. }
  163.  
  164. /*
  165.  * C l o s e
  166.  */
  167. Close(procdesc, ustack)
  168.   procid    *procdesc;
  169.   REGISTERS *ustack;
  170. {
  171.     register    struct ptybuf *bptr;
  172.  
  173.     /* clear _ss_sign() */
  174.     bptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
  175.     if( bptr->rpid == procdesc->_id )
  176.         bptr->rpid = 0;
  177.  
  178.     /* deallocate buffer if we are the last incarnation */
  179.     if( pd.path.pd_count == 0 )
  180.         if( pd.ptypvt.pd_typ == PTY ) {
  181.             register Pathdesc ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
  182.  
  183.     /*
  184.      * and send all listening ttys a HUP and mark that the connection is severed
  185.      */
  186.             for(; ptr ; ptr = ptr->path.pd_paths)
  187.                 if( ptr->ptypvt.pd_typ == TTY && ptr->ptypvt.pd_pty == &pd ) {
  188.                     ptr->ptypvt.pd_pty = (union pathdesc *) 0;
  189.                     kill( (ptr->path.pd_cpr ? ptr->path.pd_cpr : ptr->path.pd_lproc)
  190.                          ,(ptr->ptypvt.pd_esig ? ptr->ptypvt.pd_esig : SIGHUP));
  191.                 }
  192.             (void) _srtmem( pd.ptypvt.pd_rbuf.buf, pd.ptypvt.pd_rbuf.size);
  193.             (void) _srtmem( pd.ptypvt.pd_wbuf.buf, pd.ptypvt.pd_wbuf.size);
  194.         } else {
  195.             if((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf.lpd = &pd)
  196.                 (pd.ptypvt.pd_pty)->ptypvt.pd_rbuf.lpd = NULL;
  197.             if( pd.path.pd_buf )
  198.                 (void) _srtmem( pd.path.pd_buf, LINEBUFSIZ);
  199.         }
  200.     return(0);
  201. }
  202.  
  203. Read(procdesc, ustack)
  204.   procid    *procdesc;
  205.   REGISTERS *ustack;
  206. {
  207.     register int  numbytes;
  208.  
  209.     if( hangup(procdesc) )
  210.         return -1;
  211.  
  212.     /*
  213.      * select buffer ...
  214.      */
  215.     if( pd.ptypvt.pd_typ == PTY ) {
  216.         numbytes = cpinraw( &pd.ptypvt.pd_rbuf, &pd.ptypvt.pd_wbuf,
  217.             ustack, procdesc);
  218.     } else {
  219.         numbytes = cpinraw( &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf),
  220.             &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf), ustack, procdesc);
  221.     }
  222.     /*
  223.      * a neg. count means an error ....
  224.      */
  225.     if( numbytes < 0) {
  226.         ustack->d[1] += numbytes;
  227.         return -1;
  228.     }
  229.     ustack->d[1] -= numbytes;
  230.     return(0);
  231. }
  232.  
  233. ReadLn(procdesc, ustack)
  234.   procid    *procdesc;
  235.   REGISTERS *ustack;
  236. {
  237.     register int  numbytes;
  238.  
  239.     if( hangup(procdesc) )
  240.         return -1;
  241.     /*
  242.      * the line-editing buffer
  243.      */
  244.     if( pd.path.pd_buf == NULL) {
  245.         if((pd.path.pd_buf = (u_char *) _srqmem(LINEBUFSIZ)) == NULL)
  246.             return(-1);
  247.         else
  248.             initbuf(pd.path.pd_buf, LINEBUFSIZ-1);  /* dont change !! */
  249.     }
  250.  
  251.     if( ustack->d[1] > LINEBUFSIZ )
  252.         ustack->d[1] = LINEBUFSIZ;
  253.  
  254.     /*
  255.      * select buffer ...
  256.      */
  257.     if( pd.ptypvt.pd_typ == PTY ) {
  258.         numbytes = cpin( &pd.ptypvt.pd_rbuf, &pd.ptypvt.pd_wbuf,
  259.                          ustack, procdesc);
  260.     } else {
  261.         numbytes = cpin( &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf), &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf),
  262.                          ustack, procdesc);
  263.     }
  264.     /*
  265.      * a neg. count means an error ....
  266.      */
  267.     if( numbytes < 0) {
  268.         ustack->d[1] += numbytes;
  269.         return(-1);
  270.     }
  271.     ustack->d[1] -= numbytes;
  272.     return(0);
  273. }
  274.  
  275. Write(procdesc, ustack)
  276.   procid    *procdesc;
  277.   REGISTERS *ustack;
  278. {
  279.     register int  numbytes;
  280.  
  281.     if( hangup(procdesc) )
  282.         return -1;
  283.  
  284.     if( pd.ptypvt.pd_typ == PTY ) {
  285.         numbytes = cpoutraw( &pd.ptypvt.pd_wbuf, &pd.ptypvt.pd_rbuf, ustack, procdesc);
  286.     } else {
  287.         numbytes = cpoutraw( &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf), &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf), ustack, procdesc);
  288.     }
  289.     if( numbytes < 0) {
  290.         ustack->d[1] += numbytes;
  291.         return -1;
  292.     }
  293.     ustack->d[1] -= numbytes;
  294.     return(0);
  295. }
  296.  
  297. WriteLn(procdesc, ustack)
  298.   procid    *procdesc;
  299.   REGISTERS *ustack;
  300. {
  301.     register int  numbytes;
  302.  
  303.     if( hangup(procdesc) )
  304.         return -1;
  305.  
  306.     if( pd.ptypvt.pd_typ == PTY ) {
  307.         numbytes = cpout( &pd.ptypvt.pd_wbuf, &pd.ptypvt.pd_rbuf, 
  308.             ustack, procdesc);
  309.     } else {
  310.         numbytes = cpout( &((pd.ptypvt.pd_pty)->ptypvt.pd_rbuf), 
  311.             &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf), ustack, procdesc);
  312.     }
  313.     if( numbytes < 0) {
  314.         ustack->d[1] += numbytes;
  315.         return -1;
  316.     }
  317.     ustack->d[1] -= numbytes;
  318.     return(0);
  319. }
  320.  
  321.  
  322. /*
  323.  * G e t S t a t
  324.  */
  325. GetStat(procdesc, ustack)
  326.   procid    *procdesc;
  327.   REGISTERS *ustack;
  328. {
  329.     register struct ptybuf  *ptr;
  330.  
  331.     if( hangup(procdesc) )
  332.         return -1;
  333.     switch (ustack->d[1] & 0x0ffff) {
  334.  
  335.         case SS_DevNm:
  336.             /*
  337.              * returns name of the [pt]ty ...
  338.              */
  339.             memcpy( ustack->a[0], pd.ptyopt.pd_name, pd.ptyopt.pd_namlen);
  340.             *((u_char *) ustack->a[0] + pd.ptyopt.pd_namlen) = '\0';
  341.             break;
  342.  
  343.         case SS_Opt:
  344.             /*
  345.              * copy the option-field
  346.              */
  347.             memcpy( ustack->a[0], &(pd.ptyopt.pd_dtp), OPTMAX);
  348.             break;
  349.  
  350.         case SS_Ready:
  351.             /*
  352.              * return TRUE if number of chars in buffer > 0 ...
  353.              */
  354.             ptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
  355.             if((ustack->d[1] = (ptr->wptr - ptr->rptr)) <= 0 ) {
  356.                 errno = E_NOTRDY;
  357.                 return -1;
  358.             }
  359.             break;
  360.  
  361.         case SS_EOF:
  362.             /*
  363.              * always return 0
  364.              */
  365.             ustack->d[1] = 0;
  366.             break;
  367.  
  368.         case SS_BlkRd:
  369.             /*
  370.              * like a Read
  371.              */
  372.             ustack->d[1] = ustack->d[2];
  373.             return( Read( procdesc, ustack));
  374.  
  375.         default:
  376.             pd.path.pd_errno = E_UNKSVC;
  377.             return(-1);
  378.     }
  379.     return (0);
  380. }
  381.  
  382.  
  383. /*
  384.  * S e t S t a t
  385.  */
  386. SetStat(procdesc, ustack)
  387.   procid    *procdesc;
  388.   REGISTERS *ustack;
  389. {
  390.     register struct ptybuf  *ptr;
  391.  
  392.     if( hangup(procdesc) )
  393.         return -1;
  394.     switch (ustack->d[1] & 0x0ffff) {
  395.  
  396.         case SS_Opt:
  397.             /*
  398.              * copy the option-field
  399.              */
  400.             memcpy( &(pd.ptyopt.pd_dtp), ustack->a[0], OPTMAX);
  401.             break;
  402.  
  403.         case SS_SSig:
  404.             /*
  405.              * set ssig, if someother is already waiting --> error
  406.              * if data is already available --> send sig immediatly
  407.              */
  408.             ptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
  409.             if( ptr->rpid ) {
  410.                 errno = E_NOTRDY;
  411.                 return -1;
  412.             }
  413.             if( ((ptr->wptr - ptr->rptr)) <= 0 ) {
  414.                 ptr->rpid = procdesc->_id;
  415.                 ptr->rsig = ustack->d[2];
  416.             } else kill(procdesc->_id,ustack->d[2]);
  417.             break;
  418.  
  419.         case SS_Relea:
  420.             /*
  421.              * clear _ss_sign()
  422.              */
  423.             ptr = ( pd.ptypvt.pd_typ == PTY) ? &pd.ptypvt.pd_rbuf : &((pd.ptypvt.pd_pty)->ptypvt.pd_wbuf);
  424.             if( ptr->rpid == procdesc->_id)
  425.                 ptr->rpid = 0;
  426.             break;
  427.  
  428.         case SS_EnRTS:
  429.         case SS_DsRTS:
  430.         case SS_DCOn:
  431.             break;
  432.             
  433.         case SS_DCOff:
  434.             /*
  435.              * set the pd_esig -- thats all
  436.              */
  437.             if( pd.ptypvt.pd_typ == TTY)
  438.                 pd.ptypvt.pd_esig = (u_short) ustack->d[2];
  439.             break;
  440.  
  441. #ifdef ST
  442.         /*
  443.          * like Blkwr
  444.          */
  445.         case SS_Screen:
  446.             if( ustack->d[2] != ScrOut )
  447.                 break;
  448.             ustack->d[2] = ustack->d[3];
  449. #endif
  450.  
  451.         case SS_BlkWr:
  452.         /*
  453.          * like a Write
  454.          */
  455.             ustack->d[1] = ustack->d[2];
  456.             return( Write( procdesc, ustack));
  457.  
  458.         default:
  459.             pd.path.pd_errno = E_UNKSVC;
  460.             return(-1);
  461.     }
  462.     return (0);
  463. }
  464.