home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / DRIVERS / SRC / ptys.lzh / funcs.c < prev    next >
Text File  |  1990-03-08  |  17KB  |  544 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.  * Funcs.c : Unterfunktionen zum Pty-FileManager.
  27.  *
  28.  * $Header: /h0/USR/REIMER/PTYMAN/RCS/funcs.c_v 1.2.1.2 89/09/04 13:12:41 ram Exp $
  29.  *
  30.  * $Log:    funcs.c_v $
  31.  * Revision 1.2.1.2  89/09/04  13:12:41  ram
  32.  * added some comments
  33.  * 
  34.  * Revision 1.2.1.1  89/08/31  12:24:51  ram
  35.  * negative Read/Write Counts are made positive
  36.  * 
  37.  * Revision 1.2  89/07/16  01:04:51  ram
  38.  * minor changes to Sub-net release
  39.  * 
  40.  * Revision 1.1.1.1  89/07/14  19:48:36  ram
  41.  * Fixed: kbich, kbach. Sub-net Beta-Release
  42.  * 
  43.  * Revision 1.1  89/07/13  23:21:10  ram
  44.  * Initial revision
  45.  * 
  46.  */
  47.  
  48. #include <types.h>
  49. #include <reg.h>
  50. #include "ptyman.h"
  51. #include <path.h>
  52. #include <sg_codes.h>
  53. #include <procid.h>
  54. #include <signal.h>
  55. #include <modes.h>
  56. #include <errno.h>
  57.  
  58. #include "misc.h"
  59.  
  60. extern union pathdesc pd;
  61.  
  62. extern u_char  *_srqmem();
  63. extern void     _srtmem();
  64. extern void     iowait();
  65. extern void     kill();
  66. extern int      getctrlchar();
  67.  
  68. extern int      tsleep();
  69.  
  70. int
  71. hangup(procdesc)
  72. register   procid    *procdesc;
  73. {
  74.     /* TRUE:
  75.      *          - pty-typ is a tty
  76.      *          - and correspondent pty has gone
  77.      * Action:    send a SIGHUP, if conection was severed by server
  78.      */
  79.  
  80.     if(pd.ptypvt.pd_typ == TTY && pd.ptypvt.pd_pty == (union pathdesc *) 0) {
  81.         errno = E_HANGUP;
  82.         kill( procdesc->_id, (pd.ptypvt.pd_esig ?
  83.             pd.ptypvt.pd_esig : SIGHUP));
  84.         return TRUE;
  85.     }
  86.     return FALSE;
  87. }
  88.  
  89. int inline
  90. dosleep( procdesc )
  91. register    procid  *procdesc;
  92. {
  93.     /*
  94.      * 0:   - if wakedup by SIGWAKE
  95.      * -1:  - if signal is < 32 ( ENOENT ) orseq process has been aborted
  96.      * 0:   - other
  97.      */
  98.  
  99.     if( tsleep(0) == 0 && procdesc->_signal == 0)
  100.         return 0;
  101.     if( (errno = procdesc->_signal) < 32 || procdesc->_state & P_CONDEMNED)
  102.         return -1;
  103.     return 0;
  104. }
  105.  
  106. /*
  107.  * Falls Echo angeschaltet ist, schreibe einen Charakter in den Echobuffer
  108.  * 1:   - falls echo ausgeschaltet ist oder echo erfolgreich
  109.  * -1:  - Fehler bei Ausgabe (z.b. Prozess aborted)
  110.  */
  111. int
  112. echochar( ch, buf, procdesc)
  113. register    u_char          ch;
  114. register    struct  ptybuf *buf;
  115.             procid         *procdesc;
  116. {   register    int rv;
  117.  
  118.     /*
  119.      * if echo is off, return success
  120.      */
  121.     if( pd.ptyopt.pd_eko == '\0')
  122.         return(1);
  123.  
  124.     /*
  125.      * wait for other I/O, and register for SIGINT,SIGQUIT
  126.      */
  127.     iowait( buf->wpid);
  128.     buf->wsig = SIGWAKE;
  129.     buf->lpd = &pd;
  130.  
  131.     /*
  132.      * my standard output-loop
  133.      */
  134.     while( buf->wptr >= (buf->buf + buf->size)) {
  135.         WAKE(buf->rpid, buf->rsig);
  136.         buf->wpid = procdesc->_id;
  137.         do {
  138.             if( dosleep(procdesc) < 0) {
  139.                 rv = -1;
  140.                 goto outloop;
  141.             }
  142.         } while( buf->wpid);
  143.     }
  144.     *(buf->wptr)++ = ch;
  145.     rv = 1;
  146. outloop:
  147.     buf->wpid = 0;
  148.     if( buf->wptr > buf->rptr)
  149.         WAKE(buf->rpid, buf->rsig);
  150.     return( rv );
  151. }
  152.  
  153. /*
  154.  * Lese cnt-Bytes im Raw-modus ein. Kein Echo, Lineediting etc....
  155.  * 0:   - cnt-bytes gelesen
  156.  * x:   - (cnt-x) bytes gelesen
  157.  * -x:  - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
  158.  */
  159. int
  160. cpinraw(buf, echobuf, ustack, procdesc)
  161. register    struct  ptybuf *buf;
  162. register    struct  ptybuf *echobuf;
  163.             REGISTERS      *ustack;
  164.             procid         *procdesc;
  165. {   register    int     cnt = ustack->d[1] & 0x7fffffff; /* no neg. counts */
  166.     register    u_char *dest = (u_char *) ustack->a[0];
  167.  
  168.     /*
  169.      * this can only happen if _ss_sign() was set
  170.      */
  171.     if( buf->rpid == procdesc->_id) {
  172.         errno = E_NOTRDY;
  173.         return -cnt;
  174.     }
  175.  
  176.     iowait( buf->rpid);
  177.     buf->rsig = SIGWAKE;
  178.  
  179.     for(; cnt > 0; --cnt) {
  180.         while( buf->rptr >= buf->wptr ) {
  181.             buf->wptr = buf->rptr = buf->buf;
  182.             WAKE(buf->wpid, buf->wsig);
  183.             buf->rpid = procdesc->_id;
  184.             do {
  185.                 if( dosleep(procdesc) < 0) {
  186.                     cnt = -cnt;
  187.                     goto outloop;
  188.                 }
  189.             } while ( buf->rpid);
  190.         }
  191.         /*
  192.          * in read, one has still to check for SIGQUIT etc..
  193.          * the signal is sent by the writing-process
  194.          */
  195.         switch( getctrlchar( *dest++ = *(buf->rptr)++)) {
  196.             case INT:
  197.                 errno = SIGINT;
  198.                 cnt = - (--cnt);
  199.                 goto outloop;
  200.  
  201.             case QUT:
  202.                 errno = SIGQUIT;
  203.                 cnt = - (--cnt);
  204.                 goto outloop;
  205.  
  206.             case EOR:
  207.                 pd.ptypvt.pd_line = 0;
  208.                 break;
  209.     }
  210.     }
  211. outloop:
  212.     if(buf->rptr >= buf->wptr ) {
  213.         buf->wptr = buf->rptr = buf->buf;
  214.         WAKE(buf->wpid, buf->wsig);
  215.     }
  216.     buf->rpid = 0;
  217.     return( cnt);
  218. }
  219.  
  220. /*
  221.  * Lese cnt-Bytes. Echo, Lineediting, vorzeitiger Abbruch bei Lesen von CR
  222.  * 0:   - cnt-bytes gelesen
  223.  * x:   - (cnt-x) bytes gelesen
  224.  * -x:  - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
  225.  */
  226. int
  227. cpin(buf, echobuf, ustack, procdesc)
  228. register    struct  ptybuf *buf;
  229.             struct  ptybuf *echobuf;
  230.             REGISTERS      *ustack;
  231.             procid         *procdesc;
  232. {   register    int     cnt = ustack->d[1] & 0x7fffffff; /* no neg. counts */
  233.     register    u_char *dest = (u_char *) ustack->a[0];
  234.     register    u_char *old  = pd.path.pd_buf;
  235.     register    u_char  ch;
  236.  
  237.     /*
  238.      * this can only happen if _ss_sign() was set
  239.      */
  240.     if( buf->rpid == procdesc->_id) {
  241.         errno = E_NOTRDY;
  242.         return -cnt;
  243.     }
  244.  
  245.     iowait( buf->rpid);
  246.     buf->rsig = SIGWAKE;
  247.  
  248.     for(; cnt > 0; --cnt) {
  249.         while( buf->rptr >= buf->wptr ) {
  250.             buf->wptr = buf->rptr = buf->buf;
  251.             WAKE(buf->wpid, buf->wsig);
  252.             buf->rpid = procdesc->_id;
  253.             do {
  254.                 if( dosleep(procdesc) < 0) {
  255.                     cnt = -cnt;
  256.                     goto outloop;
  257.                 }
  258.             } while( buf->rpid);
  259.         }
  260.         ch = (pd.ptyopt.pd_upc ? upchar(*(buf->rptr)++) : *(buf->rptr)++);
  261.         switch( getctrlchar(ch) ) {
  262.             case BSP:
  263.                /*
  264.                 * look in the Tech. manual to see what is meant here
  265.                 */
  266.                if( ( pd.ptyopt.pd_bso ?
  267.                    (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) +
  268.                     echochar( ' ' ,echobuf, procdesc) +
  269.                     echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 3) :
  270.                    (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 1))) {
  271.                         cnt = -cnt;
  272.                         goto outloop;
  273.                 }
  274.                 dest--; old--;
  275.                 dest = MAX( (dest), ((u_char *) ustack->a[0]));
  276.                 old  = MAX( (old ), pd.path.pd_buf);
  277.                 if( cnt == ustack->d[1] )
  278.                     cnt = ustack->d[1]+1;
  279.                 else
  280.                     cnt += 2;
  281.                 break;
  282.  
  283.             case EOR:
  284.                 /*
  285.                  * EOR resets pd_line and finishes
  286.                  */
  287.                 pd.ptypvt.pd_line = 0;
  288.                 *old++ = *dest++ = ch;
  289.                 if( ( echochar( ch, echobuf, procdesc) < 0
  290.                     || ( pd.ptyopt.pd_alf && echochar( '\l', echobuf, procdesc) < 0))) {
  291.                     cnt = -cnt;
  292.                     goto outloop;
  293.                 }
  294.                 cnt--;
  295.                 goto outloop;
  296.  
  297.             case INT:
  298.                 *old = *dest = errno = SIGINT;
  299.                 cnt = - (--cnt);
  300.                 goto outloop;
  301.  
  302.             case QUT:
  303.                 *old = *dest = errno = SIGQUIT;
  304.                 cnt = - (--cnt);
  305.                 goto outloop;
  306.  
  307.             case EOF:
  308.                 /*
  309.                  * EOF only as first character !
  310.                  */
  311.                 if( old == pd.path.pd_buf) {
  312.                     errno = E_EOF;
  313.                     cnt = -cnt;
  314.                     goto outloop;
  315.                 }
  316.  
  317.             case DEL:
  318.                 if( pd.ptyopt.pd_dlo != '\0' ) {
  319.                     for(; old > pd.path.pd_buf; --old,cnt++)
  320.                         if( ( pd.ptyopt.pd_bso ?
  321.                             (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) +
  322.                              echochar( ' ' ,echobuf, procdesc) +
  323.                              echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 3) :
  324.                             (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 1))) {
  325.                             cnt = -cnt;
  326.                             goto outloop;
  327.                         }
  328.                 }
  329.                 else
  330.                    if( (echochar( pd.ptyopt.pd_eor, echobuf, procdesc)
  331.                         + echochar( '\l', echobuf, procdesc) < 2)) {
  332.                             cnt = -cnt;
  333.                             goto outloop;
  334.                    }
  335.                 dest = (u_char *) ustack->a[0];
  336.                 old  = pd.path.pd_buf;
  337.                 cnt  = ustack->d[1]+1;
  338.                 break;
  339.  
  340.             case DUP:
  341.                 for(; cnt > 0 ; --cnt) {
  342.                     if((ch = *dest++ = *old++) == pd.ptyopt.pd_eor &&
  343.                         pd.ptyopt.pd_eor) {
  344.                             dest--; old--;
  345.                             break;
  346.                         }
  347.                     if( echochar( (ch < ' ' ? '.': ch), echobuf, procdesc) < 0) {
  348.                         cnt = - (--cnt);
  349.                         goto outloop;
  350.                         }
  351.                 }
  352.                 break;
  353.  
  354.             case RPR:
  355.                 *old = *dest = pd.ptyopt.pd_eor;
  356.                 if(( echochar( *old, echobuf, procdesc) < 0
  357.                     || ( pd.ptyopt.pd_alf && echochar( '\l', echobuf, procdesc) < 0))) {
  358.                     cnt = -cnt;
  359.                     goto outloop;
  360.                 }
  361.                 {
  362.                     register u_char *tmp = pd.path.pd_buf;
  363.  
  364.                     for(; tmp < old; tmp++)
  365.                         if( echochar( *tmp, echobuf, procdesc) < 0) {
  366.                             cnt = - cnt;
  367.                             goto outloop;
  368.                         }
  369.         }
  370.                 break;
  371.  
  372.             case PSC:
  373.                 /*
  374.                  * not supported
  375.                  */
  376.             default:
  377.                 *old++ = *dest++ = ch;
  378.                 if( echochar( (ch < ' ' ? '.': ch)
  379.                         , echobuf, procdesc) < 0) {
  380.                     cnt = - (--cnt);
  381.                     goto outloop;
  382.                 }
  383.         }
  384.     }
  385. outloop:
  386.     buf->rpid = 0;
  387.     if( buf->rptr >= buf->wptr ) {
  388.         buf->wptr = buf->rptr = buf->buf;
  389.         WAKE(buf->wpid, buf->wsig);
  390.     }
  391.     return( cnt);
  392. }
  393.  
  394. /*
  395.  * Schreibe cnt-Bytes im Raw-modus. Kein Alf etc....
  396.  * 0:   - cnt-bytes geschrieben
  397.  * x:   - (cnt-x) bytes geschrieben
  398.  * -x:  - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
  399.  */
  400. int
  401. cpoutraw(buf, echobuf, ustack, procdesc)
  402. register    struct  ptybuf *buf;
  403. register    struct  ptybuf *echobuf;
  404.             REGISTERS      *ustack;
  405.             procid         *procdesc;
  406. {   register    int     cnt = ustack->d[1] & 0x7fffffff;
  407.     register    u_char *src = (u_char *) ustack->a[0];
  408.     register    u_char     ch;
  409.     register    u_int   bufend = (u_int) buf->buf + buf->size;
  410.  
  411.     iowait( buf->wpid);
  412.     buf->wsig = SIGWAKE;
  413.     buf->lpd = &pd;
  414.  
  415.     for(; cnt > 0; --cnt) {
  416.         while( buf->wptr >= (u_char *) bufend) {
  417.             WAKE(buf->rpid, buf->rsig);
  418.             buf->wpid = procdesc->_id;
  419.             do {
  420.                 if( dosleep(procdesc) < 0) {
  421.                     cnt = -cnt;
  422.                     goto outloop;
  423.                 }
  424.         } while( buf->wpid);
  425.         }
  426.         ch = *(buf->wptr)++ = *src++;
  427.         if( ch && echobuf->lpd ) {
  428.             /*
  429.              * here the INT and QUIT signals are sent
  430.              */
  431.             if( echobuf->lpd->ptyopt.pd_int == ch)
  432.                 kill(echobuf->lpd->path.pd_lproc,SIGINT);
  433.             if( echobuf->lpd->ptyopt.pd_qut == ch)
  434.                 kill(echobuf->lpd->path.pd_lproc,SIGQUIT);
  435.         }
  436.     }
  437. outloop:
  438.     buf->wpid = 0;
  439.     if( buf->wptr > buf->rptr)
  440.         WAKE(buf->rpid, buf->rsig);
  441.     return( cnt);
  442. }
  443.  
  444. /*
  445.  * Schreibe cnt-Bytes. Alf, Tab-expanding, Pause-behandlung, Abbruch bei
  446.  * vorzeitigem CR
  447.  * 0:   - cnt-bytes geschrieben
  448.  * x:   - (cnt-x) bytes geschrieben
  449.  * -x:  - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
  450.  */
  451. int
  452. cpout(buf, echobuf, ustack, procdesc)
  453. register    struct  ptybuf *buf;
  454. register    struct  ptybuf *echobuf;
  455.             REGISTERS      *ustack;
  456.             procid         *procdesc;
  457. {   register    int     cnt = ustack->d[1] & 0x7fffffff;
  458.     register    u_char *src = (u_char *) ustack->a[0];
  459.     register    u_char  ch;
  460.     register    u_int   bufend = (u_int) buf->buf + buf->size;
  461.  
  462.     iowait( buf->wpid );
  463.     buf->wsig = SIGWAKE;
  464.     buf->lpd = &pd;
  465.  
  466.     for(; cnt > 0; --cnt) {
  467.         while( buf->wptr >= (u_char *) bufend) {
  468.             WAKE(buf->rpid, buf->rsig);
  469.             buf->wpid = procdesc->_id;
  470.             do {
  471.                 if( dosleep(procdesc) < 0) {
  472.                     cnt = -cnt;
  473.                     goto outloop;
  474.                 }
  475.             } while( buf->wpid);
  476.         }
  477.         pd.ptyopt.pd_Col++;
  478.         ch = *(buf->wptr)++ = (pd.ptyopt.pd_upc ? upchar(*src++) : *src++);
  479.         /*
  480.          * QUIT and INT signals to last writing device
  481.          */
  482.         if( ch && echobuf->lpd ) {
  483.             if( echobuf->lpd->ptyopt.pd_int == ch)
  484.                 kill(echobuf->lpd->path.pd_lproc,SIGINT);
  485.             if( echobuf->lpd->ptyopt.pd_qut == ch)
  486.                 kill(echobuf->lpd->path.pd_lproc,SIGQUIT);
  487.         }
  488.         if( ch && ch == pd.ptyopt.pd_eor ) {
  489.             pd.ptyopt.pd_Col = 0;
  490.             if( pd.ptyopt.pd_pau && ++pd.ptypvt.pd_line == pd.ptyopt.pd_pag ) {
  491.                 pd.ptypvt.pd_line = 0;
  492.                 iowait( echobuf->rpid);
  493.                 WAKE(echobuf->wpid, echobuf->wsig);
  494.                 echobuf->rpid = procdesc->_id;
  495.                 do {
  496.                    if( dosleep(procdesc) < 0) {
  497.                       cnt = -cnt;
  498.                       goto outloop;
  499.                    }
  500.                 } while( echobuf->rpid);
  501.                 echobuf->rptr++;
  502.             }
  503.             if( pd.ptyopt.pd_alf ) {
  504.                 if( buf->wptr >= (buf->buf + buf->size)) {
  505.                     WAKE(buf->rpid, buf->rsig);
  506.                     buf->wpid = procdesc->_id;
  507.                     do {
  508.                         if( dosleep(procdesc) < 0) {
  509.                             cnt = -cnt;
  510.                             goto outloop;
  511.                         }
  512.                     } while( buf->wpid);
  513.         }
  514.                 *(buf->wptr)++ = '\l';
  515.             }
  516.             --cnt;
  517.             break;
  518.         } else
  519.             if( pd.ptyopt.pd_Tabs && pd.ptyopt.pd_Tab && ch == pd.ptyopt.pd_Tab) {
  520.                 register short i = (pd.ptyopt.pd_Col-1) % pd.ptyopt.pd_Tabs;
  521.                 *(buf->wptr - 1) = ' ';
  522.                 for(; i > 0; i--) {
  523.                     while( buf->wptr >= (buf->buf + buf->size)) {
  524.                         WAKE(buf->rpid, buf->rsig);
  525.                         buf->wpid = procdesc->_id;
  526.                         do {
  527.                             if( dosleep(procdesc) < 0) {
  528.                                 cnt = -cnt;
  529.                                 goto outloop;
  530.                             }
  531.                         } while( buf->wpid);
  532.                     }
  533.                     *(buf->wptr)++ = ' ';
  534.                 }
  535.  
  536.             }
  537.     }
  538. outloop:
  539.     buf->wpid = 0;
  540.     if( buf->wptr > buf->rptr)
  541.         WAKE(buf->rpid, buf->rsig);
  542.     return( cnt);
  543. }
  544.