home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / pty4 / part06 / ptytty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-18  |  9.6 KB  |  394 lines

  1. #include <sys/types.h>
  2. #include <sys/file.h>
  3. #include <sys/ioctl.h>
  4. #include <signal.h>
  5. #include <errno.h>
  6. extern int errno;
  7. #include "config/genericptr.h"
  8. #include "config/ttyopts.h"
  9. #include "ptytty.h"
  10.  
  11. static int ioc(fd,req,arg) /* non-interruptable ioctl */
  12. int fd;
  13. unsigned long req;
  14. GENERICPTR arg;
  15. {
  16.  int result;
  17.  do
  18.    result = ioctl(fd,req,(char *) arg);
  19.  while ((result == -1) && (errno == EINTR));
  20.  return result;
  21. }
  22.  
  23. #define IOC(f,req,arg) ioc((fd),(unsigned long) (req),(GENERICPTR) (arg))
  24. #define IOCR(f,req,arg) { if (IOC(f,req,arg) == -1) return -1; }
  25.  
  26. int tty_getctrl()
  27. {
  28.  int fd;
  29.  int dummy;
  30.  
  31. #define ISTTY(f) (IOC(f,TIOCGPGRP,&dummy) == 0)
  32.  
  33.  if ((fd = dup(3)) != -1)
  34.    if (ISTTY(fd)) return fd; else close(fd);
  35.  if ((fd = open("/dev/tty",O_RDWR)) != -1)
  36.    if (ISTTY(fd)) return fd; else close(fd);
  37.  if ((fd = dup(0)) != -1)
  38.    if (ISTTY(fd)) return fd; else close(fd);
  39.  if ((fd = dup(1)) != -1)
  40.    if (ISTTY(fd)) return fd; else close(fd);
  41.  if ((fd = dup(2)) != -1)
  42.    if (ISTTY(fd)) return fd; else close(fd);
  43.  return -1;
  44. }
  45.  
  46. int tty_spaceleft(fd)
  47. int fd;
  48. {
  49. #ifdef FIONREAD
  50.  long result;
  51.  if (IOC(fd,FIONREAD,&result) == -1)
  52.    return -1;
  53.  if (result > 200)
  54.    return 0;
  55.  return 200 - result;
  56. #else
  57.  errno = EIO;
  58.  return -1; /*XXX*/
  59. #endif
  60. }
  61.  
  62. int tty_setexcl(fd)
  63. int fd;
  64. {
  65. #ifdef TIOCEXCL
  66.  return IOC(fd,TIOCEXCL,0);
  67.  /* setting exclusive use is a bit unusual but it works */
  68.  /* opening /dev/tty should still be allowed, though */
  69. #else
  70.  errno = EIO;
  71.  return -1;
  72. #endif
  73. }
  74.  
  75. int tctpgrp(fd,pid)
  76. int fd;
  77. int pid;
  78. {
  79.  int pgrp;
  80.  if ((pgrp = getpgrp(pid)) == -1)
  81.    return -1;
  82.  return IOC(fdtty,TIOCSPGRP,&pgrp);
  83. }
  84.  
  85. int tty_forcefg(fd)
  86. int fd;
  87. {
  88.  int err;
  89.  signal(SIGTTOU,SIG_DFL);
  90.  /* XXX: what if TTOU is blocked? what if TTIN applies (e.g., under GNU)? */
  91.  err = tctpgrp(fd,getpid()); /* could also use ,0 */
  92.  signal(SIGTTOU,SIG_IGN);
  93.  return err;
  94. }
  95.  
  96. int tty_dissoc(fd)
  97. int fd;
  98. {
  99.  int fdtty;
  100.  if (fd != -1)
  101.    if (IOC(fd,TIOCNOTTY,0) == 0)
  102.      return 0;
  103.  fdtty = open("/dev/tty",O_RDWR); /* XXX */
  104.  if (fdtty == -1)
  105.    if (errno == EBUSY)
  106.      if (fd != -1)
  107.        return IOC(fd,TIOCNOTTY,0);
  108.      else
  109.        return -1;
  110.    else
  111.      return 0; /* XXX: in other words, if we're already dissociated, ok */
  112.  if (IOC(fdtty,TIOCNOTTY,0) == 0)
  113.   {
  114.    close(fdtty);
  115.    return 0;
  116.   }
  117.  close(fdtty);
  118.  return -1;
  119. }
  120.  
  121. int tty_getmodes(fd,tmo)
  122. int fd;
  123. struct ttymodes *tmo;
  124. {
  125. #ifdef TTY_TERMIO
  126.  IOCR(fd,TCGETA,&(tmo->ti))
  127. #else
  128.  IOCR(fd,TIOCGETD,&(tmo->di))
  129.  IOCR(fd,TIOCGETP,&(tmo->sg))
  130.  IOCR(fd,TIOCGETC,&(tmo->tc))
  131.  IOCR(fd,TIOCLGET,&(tmo->lb))
  132.  IOCR(fd,TIOCGLTC,&(tmo->lt))
  133. #endif
  134. #ifdef TTY_WINDOWS
  135.  IOCR(fd,TIOCGWINSZ,&(tmo->wi.ws))
  136. #endif
  137. #ifdef TTY_AUXCHARS
  138.  IOCR(fd,TIOCGAUXC,&(tmo->au))
  139. #endif
  140.  return 0;
  141. }
  142.  
  143. int tty_setmodes(fd,tmo)
  144. int fd;
  145. struct ttymodes *tmo;
  146. {
  147. #ifdef TTY_TERMIO
  148.  IOCR(fd,TCSETA,&(tmo->ti))
  149. #else
  150.  IOCR(fd,TIOCSETD,&(tmo->di))
  151.  IOCR(fd,TIOCSETP,&(tmo->sg))
  152.  IOCR(fd,TIOCSETC,&(tmo->tc))
  153.  IOCR(fd,TIOCLSET,&(tmo->lb))
  154.  IOCR(fd,TIOCSLTC,&(tmo->lt))
  155. #endif
  156. #ifdef TTY_WINDOWS
  157.  IOCR(fd,TIOCSWINSZ,&(tmo->wi.ws))
  158. #endif
  159. #ifdef TTY_AUXCHARS
  160.  IOCR(fd,TIOCSAUXC,&(tmo->au))
  161. #endif
  162.  return 0;
  163. }
  164.  
  165. int tty_modifymodes(fd,tmonew,tmoold)
  166. int fd;
  167. struct ttymodes *tmonew;
  168. struct ttymodes *tmoold;
  169. {
  170. #ifdef TTY_TERMIO
  171.  IOCR(fd,TCSETA,&(tmonew->ti))
  172.    /* XXX: someone want to flesh this out a bit? */
  173. #else
  174.  if (tmonew->di != tmoold->di)
  175.    IOCR(fd,TIOCSETD,&(tmonew->di))
  176. /* XXX: should make other tests dependent on new discipline? hmmm */
  177.  if ((tmonew->sg.sg_flags != tmoold->sg.sg_flags)
  178.    ||(tmonew->sg.sg_ispeed != tmoold->sg.sg_ispeed)
  179.    ||(tmonew->sg.sg_ospeed != tmoold->sg.sg_ospeed)
  180.    ||(tmonew->sg.sg_erase != tmoold->sg.sg_erase)
  181.    ||(tmonew->sg.sg_kill != tmoold->sg.sg_kill))
  182.    IOCR(fd,TIOCSETP,&(tmonew->sg))
  183.  if ((tmonew->tc.t_intrc != tmoold->tc.t_intrc)
  184.    ||(tmonew->tc.t_quitc != tmoold->tc.t_quitc)
  185.    ||(tmonew->tc.t_startc != tmoold->tc.t_startc)
  186.    ||(tmonew->tc.t_stopc != tmoold->tc.t_stopc)
  187.    ||(tmonew->tc.t_eofc != tmoold->tc.t_eofc)
  188.    ||(tmonew->tc.t_brkc != tmoold->tc.t_brkc))
  189.    IOCR(fd,TIOCSETC,&(tmonew->tc))
  190.  if (tmonew->lb != tmoold->lb)
  191.    IOCR(fd,TIOCLSET,&(tmonew->lb))
  192.  if ((tmonew->lt.t_suspc != tmoold->lt.t_suspc)
  193.    ||(tmonew->lt.t_dsuspc != tmoold->lt.t_dsuspc)
  194.    ||(tmonew->lt.t_rprntc != tmoold->lt.t_rprntc)
  195.    ||(tmonew->lt.t_flushc != tmoold->lt.t_flushc)
  196.    ||(tmonew->lt.t_werasc != tmoold->lt.t_werasc)
  197.    ||(tmonew->lt.t_lnextc != tmoold->lt.t_lnextc))
  198.    IOCR(fd,TIOCSLTC,&(tmonew->lt))
  199. #endif
  200. #ifdef TTY_WINDOWS
  201.  if ((tmonew->wi.ws.ws_xpixel != tmoold->wi.ws.ws_xpixel)
  202.    ||(tmonew->wi.ws.ws_ypixel != tmoold->wi.ws.ws_ypixel)
  203.    ||(tmonew->wi.ws.ws_row != tmoold->wi.ws.ws_row)
  204.    ||(tmonew->wi.ws.ws_col != tmoold->wi.ws.ws_col))
  205.    IOCR(fd,TIOCSWINSZ,&(tmonew->wi.ws))
  206. #endif
  207. #ifdef TTY_AUXCHARS
  208.  if ((tmonew->au.t_usemap != tmoold->au.t_usemap)
  209.    ||(tmonew->au.t_usest != tmoold->au.t_usest))
  210.    IOCR(fd,TIOCSAUXC,&(tmonew->au))
  211. #endif
  212.  return 0;
  213. }
  214.  
  215. void tty_copymodes(tmonew,tmoold)
  216. struct ttymodes *tmonew;
  217. struct ttymodes *tmoold;
  218. {
  219.  *tmonew = *tmoold; /* XXX: structure copying */
  220. }
  221.  
  222. void tty_modes2win(tmo,twi)
  223. struct ttymodes *tmo;
  224. struct ttywin *twi;
  225. {
  226.  ;
  227. #ifdef TTY_WINDOWS
  228.  twi->ws.ws_xpixel = tmo->wi.ws.ws_xpixel;
  229.  twi->ws.ws_ypixel = tmo->wi.ws.ws_ypixel;
  230.  twi->ws.ws_row = tmo->wi.ws.ws_row;
  231.  twi->ws.ws_col = tmo->wi.ws.ws_col;
  232. #endif
  233. }
  234.  
  235. void tty_win2modes(twi,tmo)
  236. struct ttywin *twi;
  237. struct ttymodes *tmo;
  238. {
  239.  ;
  240. #ifdef TTY_WINDOWS
  241.  tmo->wi.ws.ws_xpixel = twi->ws.ws_xpixel;
  242.  tmo->wi.ws.ws_ypixel = twi->ws.ws_ypixel;
  243.  tmo->wi.ws.ws_row = twi->ws.ws_row;
  244.  tmo->wi.ws.ws_col = twi->ws.ws_col;
  245. #endif
  246. }
  247.  
  248. void tty_zeromode(tmo)
  249. struct ttymodes *tmo;
  250. {
  251.  /* XXXXX: This is supposed to provide a mode in which the tty does */
  252.  /* absolutely no processing. I don't think such a mode truly exists. */
  253.  tty_mungemodes(tmo,3,0,2,0,3,0,3);
  254. }
  255.  
  256. void tty_mungemodes(tmo,cbreak,new,echo,crmod,raw,crt,p8bit)
  257. struct ttymodes *tmo;
  258. int cbreak;
  259. int new;
  260. int echo;
  261. int crmod;
  262. int raw;
  263. int crt;
  264. int p8bit;
  265. {
  266. #ifdef TTY_TERMIO
  267.  if (crmod >= 2)
  268.    tmo->ti.c_iflag = (tmo->ti.c_iflag & ~ICRNL) | (ICRNL * (crmod == 3));
  269.  if (echo >= 2)
  270.    tmo->ti.c_lflag = (tmo->ti.c_lflag & ~ECHO) | (ECHO * (echo == 3));
  271.  if (cbreak >= 2)
  272.   {
  273.    tmo->ti.c_lflag = (tmo->ti.c_lflag & ~ICANON) | (ICANON * (cbreak == 2));
  274.    if (cbreak == 2) { tmo->ti.c_cc[VEOF] = 4; tmo->ti.c_cc[VEOL] = 0; }
  275.      /* XXX */
  276.    else { tmo->ti.c_cc[VMIN] = 1; tmo->ti.c_cc[VTIME] = 1; }
  277.   }
  278.  if (raw >= 2)
  279.   {
  280. #define NOTIRAW (BRKINT | IGNBRK | IGNPAR | ISTRIP | IXON | IXANY | IXOFF)
  281.    tmo->ti.c_iflag = (tmo->ti.c_oflag & ~NOTIRAW) | (NOTIRAW * (raw == 2));
  282.    tmo->ti.c_oflag = (tmo->ti.c_oflag & ~OPOST) | (OPOST * (raw == 2));
  283.    tmo->ti.c_lflag = (tmo->ti.c_lflag & ~ISIG) | (ISIG * (raw == 2));
  284.   }
  285.  if (crt >= 2)
  286.   {
  287. #define CRTECHO (ECHOE | ECHOCTL | ECHOKE)
  288.    tmo->ti.c_lflag = (tmo->ti.c_lflag & ~CRTECHO) | (CRTECHO * (crt == 3));
  289.   }
  290.  /* XXX: p8bit: c_cflag? */
  291.  /* XXX: new: c_line? */
  292. #else
  293.  if (crmod >= 2)
  294.    tmo->sg.sg_flags = (tmo->sg.sg_flags & ~CRMOD) | (CRMOD * (crmod == 3));
  295.  if (echo >= 2)
  296.    tmo->sg.sg_flags = (tmo->sg.sg_flags & ~ECHO) | (ECHO * (echo == 3));
  297.  if (cbreak >= 2)
  298.    tmo->sg.sg_flags = (tmo->sg.sg_flags & ~CBREAK) | (CBREAK * (cbreak == 3));
  299.  if (raw >= 2)
  300.    tmo->sg.sg_flags = (tmo->sg.sg_flags & ~RAW) | (RAW * (raw == 3));
  301.  if (new >= 2)
  302.    tmo->di = ((new == 3) ? NTTYDISC : OTTYDISC);
  303.  if (p8bit >= 2)
  304.   {
  305.    tmo->lb = (tmo->lb & ~PASS8) | (PASS8 * (p8bit == 3));
  306.    tmo->sg.sg_flags = (tmo->sg.sg_flags & ~(EVENP | ODDP))
  307.      | ((EVENP | ODDP) * (p8bit == 2)); /* have to do this for Suns */
  308.   }
  309.  if (crt >= 2)
  310.    tmo->lb = (tmo->lb & ~(CRTBS | CRTERA | CRTKIL | CTLECH))
  311.                       | ((CRTBS | CRTERA | CRTKIL | CTLECH) * (crt == 3));
  312. #endif
  313. }
  314.  
  315. void tty_initmodes(tmo)
  316. struct ttymodes *tmo;
  317. {
  318. #ifdef TTY_TERMIO
  319.  /* Here we specify Ye Standard BSD Terminal Settings in termio format. */
  320.  tmo->ti.c_iflag =
  321.    IGNBRK | BRKINT | IGNPAR | ISTRIP | IXON | IXANY | IXOFF;
  322.    /* XXX: IMAXBEL? */
  323.  tmo->ti.c_oflag = OPOST | ONLCR;
  324.  tmo->ti.c_lflag = ISIG | ICANON; /* XXX: | ECHO? */
  325.  tmo->ti.c_cflag = CS7 | PARENB | PARODD;
  326.  /* XXX: XTABS? */
  327.  tmo->ti.c_cc[VINTR] = 3;
  328.  tmo->ti.c_cc[VQUIT] = 28;
  329.  tmo->ti.c_cc[VERASE] = 127;
  330.  tmo->ti.c_cc[VKILL] = 21;
  331.  tmo->ti.c_cc[VEOF] = 4;
  332.  tmo->ti.c_cc[VEOL] = 0;
  333.  tmo->ti.c_cc[VSTART] = 17;
  334.  tmo->ti.c_cc[VSTOP] = 19;
  335. #ifdef VSUSP
  336.  tmo->ti.c_cc[VSUSP] = 26;
  337. #endif
  338. #ifdef VDSUSP
  339.  tmo->ti.c_cc[VDSUSP] = 25;
  340. #endif
  341. #ifdef VREPRINT
  342.  tmo->ti.c_cc[VREPRINT] = 18;
  343. #endif
  344. #ifdef VDISCARD
  345.  tmo->ti.c_cc[VDISCARD] = 15;
  346. #endif
  347. #ifdef VWEASE
  348.  tmo->ti.c_cc[VWERASE] = 23;
  349. #endif
  350. #ifdef VLNEXT
  351.  tmo->ti.c_cc[VLNEXT] = 22;
  352. #endif
  353. #ifdef VSTATUS
  354.  tmo->ti.c_cc[VSTATUS] = 0;
  355. #endif
  356. #ifdef VEOL2
  357.  tmo->ti.c_cc[VEOL2] = 0;
  358. #endif
  359. #else
  360.  /* Here we specify Ye Standard BSD Terminal Settings. */
  361.  
  362.  tmo->di = OTTYDISC;
  363.  tmo->sg.sg_ispeed = EXTB;
  364.  tmo->sg.sg_ospeed = EXTB;
  365.  tmo->sg.sg_erase = 127; /* del */
  366.  tmo->sg.sg_kill = 21; /* ^U */
  367.  tmo->sg.sg_flags = EVENP | ODDP; /* XXX: | XTABS? | ECHO???? */
  368.  tmo->tc.t_intrc = 3; /* ^C */
  369.  tmo->tc.t_quitc = 28; /* ^\ */
  370.  tmo->tc.t_startc = 17; /* ^Q */
  371.  tmo->tc.t_stopc = 19; /* ^S */
  372.  tmo->tc.t_eofc = 4; /* ^D */
  373.  tmo->tc.t_brkc = -1; /* undef */
  374.  tmo->lb = DECCTQ; /* XXX: | PASS8? contradicts EVENP | ODDP */
  375.  tmo->lt.t_suspc = 26; /* ^Z */
  376.  tmo->lt.t_dsuspc = 25; /* ^Y */
  377.  tmo->lt.t_rprntc = 18; /* ^R */
  378.  tmo->lt.t_flushc = 15; /* ^O */
  379.  tmo->lt.t_werasc = 23; /* ^W */
  380.  tmo->lt.t_lnextc = 22; /* ^V */
  381. #endif
  382. #ifdef TTY_WINDOWS
  383.  tmo->wi.ws.ws_xpixel = 0; /* Or read from TERMCAP? Hmmm */
  384.  tmo->wi.ws.ws_ypixel = 0;
  385.  tmo->wi.ws.ws_row = 0;
  386.  tmo->wi.ws.ws_col = 0;
  387. #endif
  388. #ifdef TTY_AUXCHARS
  389.  tmo->au.t_usest = 20; /* ^T */
  390.  tmo->au.t_usemap = UST_LOAD1 | UST_LOAD5 | UST_LOAD15 | UST_RAWCPU
  391.    | UST_UPTIME | UST_PGRP | UST_CHILDS | UST_PCPU | UST_STATE;
  392. #endif
  393. }
  394.