home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume32 / pol / part01 < prev    next >
Encoding:
Text File  |  1992-10-17  |  37.4 KB  |  1,582 lines

  1. Newsgroups: comp.sources.misc
  2. From: root@candle.uucp (Bruce Momjian)
  3. Subject:  v32i105:  pol - a poll() and select() for System Vr3, Part01/01
  4. Message-ID: <1992Oct16.143106.9325@sparky.imd.sterling.com>
  5. X-Md4-Signature: cea0fb6f51e6a32ef8192f5c8dda20f8
  6. Date: Fri, 16 Oct 1992 14:31:06 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: root@candle.uucp (Bruce Momjian)
  10. Posting-number: Volume 32, Issue 105
  11. Archive-name: pol/part01
  12. Environment: SYSVR3
  13.  
  14. Poll() and select() are Unix C library functions that allow programs to
  15. determine if a number of file descriptors are ready for reading or
  16. writing.
  17.  
  18. Many early Unix versions, and even some later ones do not have these
  19. functions.  I have written a device driver called pol that performs
  20. these functions for Unix System Vr3 versions that lack them.  It may
  21. work on other Unix versions, I haven't tested them.
  22.  
  23. A pty device driver is also included in this shar file, assuming that
  24. now that you have poll()/select(), you are going to want pty's too.
  25.  
  26. ----------------------------------------------------------------------
  27. #! /bin/sh
  28. # This is a shell archive.  Remove anything before this line, then feed it
  29. # into a shell via "sh file" or similar.  To overwrite existing files,
  30. # type "sh file -c".
  31. # Contents:  README MANIFEST CHANGELOG INSTALL Makefile patchlevel.h
  32. #   pol.c pol.h pol.lib.c poltest.c pty.c selec.h
  33. # Wrapped by kent@sparky on Fri Oct 16 09:24:18 1992
  34. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  35. echo If this archive is complete, you will see the following message:
  36. echo '          "shar: End of archive 1 (of 1)."'
  37. if test -f 'README' -a "${1}" != "-c" ; then 
  38.   echo shar: Will not clobber existing file \"'README'\"
  39. else
  40.   echo shar: Extracting \"'README'\" \(1881 characters\)
  41.   sed "s/^X//" >'README' <<'END_OF_FILE'
  42. XINSTALL        - this file
  43. XMakefile    - Makefile to compile pol and poltest
  44. XREADME         - readme file
  45. Xpol.c        - device driver
  46. Xpol.lib.c    - C library module
  47. Xpol.h        - /usr/include/sys/pol.h file
  48. Xselec.h        - /usr/include/sys/selec.h file
  49. Xpoltest.c    - used to test the device driver
  50. Xpty.c        - the PD sys5 pty device driver, with modifications
  51. X
  52. X----------------------------------------------------------------------
  53. XBasically, this package implements poll() and select() as a device
  54. Xdriver.  It is called pol() and selec() so as not to be confused with
  55. Xthe real thing.
  56. X
  57. XIt operates on standard tty devices, pty devices, pipes, and sxt devices.
  58. X
  59. XThe driver accepts bit masks of read and write file descriptors.  It
  60. Xfollows the descriptors to the file, then inode tables and gets the
  61. Xmajor and minor device numbers.  It then finds the tty structures
  62. Xassociated with those devices and stores their addresses.
  63. X
  64. XIt scans through the addresses once, looking for read or written
  65. Xcharacters, then either returns or goes to sleep.  Upon invocation, it
  66. Xreplaces the standard tty input/output functions with its own functions,
  67. Xwhich wake up the driver and call the usual tty functions.  In this way,
  68. Xthe driver is woken up when tty activity occurs.  When pol is closed,
  69. Xthe standard tty functions are reinstalled.
  70. X
  71. XA C library library is provided to translate the normal poll() and
  72. Xselect() parameters into pol device driver parameters, and then call the
  73. Xdevice driver.
  74. X
  75. XI have also provided a file called pty.c that is a modified version of
  76. Xthe  PD System V pty device driver written by Jens-Uwe Mager, with
  77. XSystem V changes by Michael Bloom.  To build this, you should follow the
  78. Xdirections in the second part of the INSTALL file.  Several PD pty
  79. Xdrivers are available in pub/micro/sysv-386 on gatekeeper.dec.com, or in
  80. Xpub/sysvX86 on ftp.win.tue.nl.
  81. X
  82. XBruce Momjian, root@candle.uucp (root%candle.uucp@bts.com)
  83. END_OF_FILE
  84.   if test 1881 -ne `wc -c <'README'`; then
  85.     echo shar: \"'README'\" unpacked with wrong size!
  86.   fi
  87.   # end of 'README'
  88. fi
  89. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  90.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  91. else
  92.   echo shar: Extracting \"'MANIFEST'\" \(359 characters\)
  93.   sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  94. XCHANGELOG    - version changes
  95. XINSTALL        - installation instructions
  96. XMANIFEST    - this file
  97. XMakefile    - Makefile to compile pol and poltest
  98. XREADME         - readme file
  99. Xpol.c        - device driver
  100. Xpol.lib.c    - C library module
  101. Xpol.h        - /usr/include/sys/pol.h file
  102. Xselec.h        - /usr/include/sys/selec.h file
  103. Xpoltest.c    - used to test the device driver
  104. Xpty.c         - a pty device driver
  105. END_OF_FILE
  106.   if test 359 -ne `wc -c <'MANIFEST'`; then
  107.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  108.   fi
  109.   # end of 'MANIFEST'
  110. fi
  111. if test -f 'CHANGELOG' -a "${1}" != "-c" ; then 
  112.   echo shar: Will not clobber existing file \"'CHANGELOG'\"
  113. else
  114.   echo shar: Extracting \"'CHANGELOG'\" \(382 characters\)
  115.   sed "s/^X//" >'CHANGELOG' <<'END_OF_FILE'
  116. XVersion        Description
  117. X-------        -----------
  118. X1.00         first general release, posted to comp.unix.internals
  119. X1.02        many bug fixes to pol.c, one to pol.lib.c
  120. X1.03        added comments to pol.c
  121. X1.04        changes to pol.c to fix possible pol character loss with
  122. X        rapid keyboard input, streamlined code, added code to
  123. X        detect hangup; added code and installation instructions
  124. X        for the PD pty package
  125. END_OF_FILE
  126.   if test 382 -ne `wc -c <'CHANGELOG'`; then
  127.     echo shar: \"'CHANGELOG'\" unpacked with wrong size!
  128.   fi
  129.   # end of 'CHANGELOG'
  130. fi
  131. if test -f 'INSTALL' -a "${1}" != "-c" ; then 
  132.   echo shar: Will not clobber existing file \"'INSTALL'\"
  133. else
  134.   echo shar: Extracting \"'INSTALL'\" \(3076 characters\)
  135.   sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
  136. X                   Installing the pol device driver
  137. X
  138. XBasically, pol.c is installed as a device driver with this line in 
  139. Xthe /etc/conf/cf.d/mdevice file:
  140. X
  141. Xpol    oci    iHc    pol    0    12    1    1    -1
  142. X                    ^
  143. X                    | major number of your choice
  144. X
  145. XCreate an appropriate file called /etc/conf/sdevice.d/pol like this:
  146. X
  147. Xpol    Y    1    0    0    0    0    0    0    0
  148. X
  149. XCreate a file called /etc/conf/node.d/pol so a character device called
  150. X/dev/pol gets created:
  151. X
  152. Xpol    pol    c    0
  153. X
  154. XOnly one entry is needed, even though many programs can pol at the same
  155. Xtime. 
  156. X
  157. XAdd a subdirectory under /etc/conf/pack.d called pol and compile pol.c
  158. Xand copy it to /etc/conf/pack.d/pol/Driver.o.
  159. X
  160. XCompile pol.lib.c and install it in your personal C library.  It will be
  161. Xthe link points for pol() and selec().
  162. X
  163. XInstall pol.h and selec.h in /usr/include/sys.
  164. X
  165. X
  166. X--------------------------------------------------------------------------
  167. X                 Installing the PD System V pty driver
  168. X
  169. XAdd this to /etc/conf/cf.d/mdevice:
  170. X
  171. Xpts    ocrwi    ict    pts    0    10    1    1    -1
  172. Xptm    ocrwi    icG    ptm    0    11    1    1    -1
  173. X                    ^
  174. X                    | two major numbers of your choice
  175. X
  176. XCreate an appropriate file called /etc/conf/sdevice.d/pts like this:
  177. X
  178. Xpts    Y    1    0    0    0    0    0    0    0
  179. X
  180. XCreate an appropriate file called /etc/conf/sdevice.d/ptm like this:
  181. X
  182. Xptm    Y    1    0    0    0    0    0    0    0
  183. X
  184. XCreate a file called /etc/conf/node.d/pts so slave pty's get created:
  185. X
  186. Xpts    ttyp0    c    0
  187. Xpts    ttyp1    c    1
  188. Xpts    ttyp2    c    2
  189. Xpts    ttyp3    c    3
  190. Xpts    ttyp4    c    4
  191. Xpts    ttyp5    c    5
  192. Xpts    ttyp6    c    6
  193. Xpts    ttyp7    c    7
  194. Xpts    ttyp8    c    8
  195. Xpts    ttyp9    c    9
  196. Xpts    ttypa    c    10
  197. Xpts    ttypb    c    11
  198. Xpts    ttypc    c    12
  199. Xpts    ttypd    c    13
  200. Xpts    ttype    c    14
  201. Xpts    ttypf    c    15
  202. Xpts    ttyq0    c    16
  203. Xpts    ttyq1    c    17
  204. Xpts    ttyq2    c    18
  205. Xpts    ttyq3    c    19
  206. Xpts    ttyq4    c    20
  207. Xpts    ttyq5    c    21
  208. Xpts    ttyq6    c    22
  209. Xpts    ttyq7    c    23
  210. Xpts    ttyq8    c    24
  211. Xpts    ttyq9    c    25
  212. Xpts    ttyqa    c    26
  213. Xpts    ttyqb    c    27
  214. Xpts    ttyqc    c    28
  215. Xpts    ttyqd    c    29
  216. Xpts    ttyqe    c    30
  217. Xpts    ttyqf    c    31
  218. X
  219. XCreate a file called /etc/conf/node.d/ptm so master pty's gets created:
  220. X
  221. Xptm    ptyp0    c    0
  222. Xptm    ptyp1    c    1
  223. Xptm    ptyp2    c    2
  224. Xptm    ptyp3    c    3
  225. Xptm    ptyp4    c    4
  226. Xptm    ptyp5    c    5
  227. Xptm    ptyp6    c    6
  228. Xptm    ptyp7    c    7
  229. Xptm    ptyp8    c    8
  230. Xptm    ptyp9    c    9
  231. Xptm    ptypa    c    10
  232. Xptm    ptypb    c    11
  233. Xptm    ptypc    c    12
  234. Xptm    ptypd    c    13
  235. Xptm    ptype    c    14
  236. Xptm    ptypf    c    15
  237. Xptm    ptyq0    c    16
  238. Xptm    ptyq1    c    17
  239. Xptm    ptyq2    c    18
  240. Xptm    ptyq3    c    19
  241. Xptm    ptyq4    c    20
  242. Xptm    ptyq5    c    21
  243. Xptm    ptyq6    c    22
  244. Xptm    ptyq7    c    23
  245. Xptm    ptyq8    c    24
  246. Xptm    ptyq9    c    25
  247. Xptm    ptyqa    c    26
  248. Xptm    ptyqb    c    27
  249. Xptm    ptyqc    c    28
  250. Xptm    ptyqd    c    29
  251. Xptm    ptyqe    c    30
  252. Xptm    ptyqf    c    31
  253. X
  254. X
  255. XAdd a subdirectory under /etc/conf/pack.d called pts and compile pty.c
  256. Xand copy it to /etc/conf/pack.d/pts/Driver.o.
  257. X
  258. XCopy the file below to /etc/conf/pack.d/pts/space.c.  I have configured
  259. Xthe system for 32 pty's.  If you want more or less, change the two
  260. Xnode.d files above and the definitions in space.c below.
  261. X
  262. X/*
  263. X * space.c for pts
  264. X */
  265. X#include <sys/types.h>
  266. X#include <sys/tty.h>
  267. Xstruct tty pts_tty[32];
  268. X
  269. Xint pts_state[32];
  270. Xint pts_cnt = 32;
  271. X
  272. XAdd a subdirectory under /etc/conf/pack.d called ptm and compile an
  273. Xempty source file and copy it to /etc/conf/pack.d/ptm/Driver.o.
  274. X
  275. X
  276. XThis works for AT&T 386 Unix System Vr3.1.  With both pol and the PD pty
  277. Xdriver, I can run pcomm2.0, iscreen 3.2, and ptyshl.  I hope it works
  278. Xfor you too. 
  279. X
  280. END_OF_FILE
  281.   if test 3076 -ne `wc -c <'INSTALL'`; then
  282.     echo shar: \"'INSTALL'\" unpacked with wrong size!
  283.   fi
  284.   # end of 'INSTALL'
  285. fi
  286. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  287.   echo shar: Will not clobber existing file \"'Makefile'\"
  288. else
  289.   echo shar: Extracting \"'Makefile'\" \(258 characters\)
  290.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  291. X#
  292. X# Makefile
  293. X#
  294. X#
  295. XTARGET = pol
  296. XXFLAGS = 
  297. XCFLAGS = -O
  298. XLIBS = 
  299. X
  300. Xpol.o    : pol.c 
  301. X    $(CC) -c $(XFLAGS) $(CFLAGS) pol.c
  302. X
  303. Xclean:
  304. X    rm -f *.o pol log core
  305. X
  306. Xinstall:
  307. X    cp pol.o /etc/conf/pack.d/pol/Driver.o
  308. Xpoltest: poltest.c poltest.o
  309. X    cc -opoltest poltest.c -lcandle
  310. X    
  311. END_OF_FILE
  312.   if test 258 -ne `wc -c <'Makefile'`; then
  313.     echo shar: \"'Makefile'\" unpacked with wrong size!
  314.   fi
  315.   # end of 'Makefile'
  316. fi
  317. if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  318.   echo shar: Will not clobber existing file \"'patchlevel.h'\"
  319. else
  320.   echo shar: Extracting \"'patchlevel.h'\" \(13 characters\)
  321.   sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
  322. Xversion 1.04
  323. END_OF_FILE
  324.   if test 13 -ne `wc -c <'patchlevel.h'`; then
  325.     echo shar: \"'patchlevel.h'\" unpacked with wrong size!
  326.   fi
  327.   # end of 'patchlevel.h'
  328. fi
  329. if test -f 'pol.c' -a "${1}" != "-c" ; then 
  330.   echo shar: Will not clobber existing file \"'pol.c'\"
  331. else
  332.   echo shar: Extracting \"'pol.c'\" \(11229 characters\)
  333.   sed "s/^X//" >'pol.c' <<'END_OF_FILE'
  334. X /*
  335. X    pol.c    - poll/select() implemented as a device driver
  336. X    version 1.04    9/17/92
  337. X    
  338. X    Bruce Momjian (root%candle.uucp@bts.com)
  339. X
  340. X*/
  341. X
  342. X/* tabs = 4 */
  343. X/* Include files */
  344. X
  345. X#ifdef DEBUG
  346. X#define    DB(x)    x
  347. X#else
  348. X#define DB(x)
  349. X#endif
  350. X
  351. X#include <errno.h>
  352. X#include <limits.h>
  353. X#include <sys/pol.h>
  354. X#include <sys/types.h>
  355. X#include <sys/param.h>
  356. X#include <sys/ioctl.h>
  357. X#include <sys/dir.h>
  358. X#include <sys/signal.h>
  359. X#include <sys/user.h>
  360. X#include <sys/file.h>
  361. X#include <sys/inode.h>
  362. X#include <sys/conf.h>
  363. X#include <sys/tty.h>
  364. X#include <sys/termio.h>
  365. X#include <sys/sxt.h>
  366. X#include <sys/sysmacros.h>
  367. X
  368. X#define TTIN_FUNCT        ttin
  369. X#define TTWRITE_FUNCT    ttwrite
  370. X
  371. X#define POL_READ_FLAG        0
  372. X#define POL_WRITE_FLAG        1
  373. X
  374. X#define IS_PTM                1
  375. X#define IS_PIPE                4
  376. X
  377. X#define TBUF_CNT_OFF    (int)&(((struct tty *)0)->t_tbuf.c_count)
  378. X#define TOUTQ_CC_OFF       (int)&(((struct tty *)0)->t_outq.c_cc)
  379. X#define TCANQ_CC_OFF       (int)&(((struct tty *)0)->t_canq.c_cc)
  380. X#define TRAWQ_CC_OFF       (int)&(((struct tty *)0)->t_rawq.c_cc)
  381. X#define T_CFLAG_OFF       (int)&(((struct tty *)0)->t_cflag)
  382. X#define T_STATE_OFF       (int)&(((struct tty *)0)->t_state)
  383. X
  384. Xint    pol_in_use = 0;                    /* is pol opened, also sleep addr. */
  385. Xint pol_intr = 0;                    /* was pol interupted during scan */
  386. X
  387. X/* pty and sxt external symbols */
  388. Xextern struct tty sxt_tty[], pts_tty[];
  389. Xextern int sxtopen(), ptmopen();
  390. Xextern char sxt_buf[];
  391. X
  392. X/* kernel symbols */
  393. Xextern int ttin(), ttwrite();
  394. X
  395. X/* my function symbols */
  396. Xint ttinpol(), ttwrpol(), poltimeo();
  397. X
  398. Xextern time_t lbolt;                    /* ticks since boot */
  399. X
  400. Xstruct pol_table {
  401. X        caddr_t addr;                    /* usually struct tty pointer */
  402. X        short    fd;
  403. X        short    ttyflags;
  404. X};
  405. X
  406. X/*---------------------------------------------------------------------------
  407. X**
  408. X**    polopen - called for each open() call
  409. X**
  410. X**--------------------------------------------------------------------------*/
  411. Xpolopen(fdev, flags)
  412. Xint    fdev, flags;
  413. X{
  414. X    if (pol_in_use == 0)
  415. X    {
  416. X        if (linesw[0].l_input != TTIN_FUNCT)    /* is linesw[] ok? */
  417. X        {
  418. X            printf("pol error:  linesw structure corrupted.\n");
  419. X              u.u_error = ENOMSG;
  420. X              u.u_rval1 = -1;
  421. X            return -1;
  422. X        }
  423. X        if (linesw[0].l_write != TTWRITE_FUNCT)
  424. X        {
  425. X            printf("pol error:  linesw structure corrupted.\n");
  426. X            u.u_error = ENOMSG;
  427. X            u.u_rval1 = -1;
  428. X            return -1;
  429. X        }
  430. X        spltty();                    /* don't let anyone use them yet */ 
  431. X        linesw[0].l_input = ttinpol;/* substitute our own functions */
  432. X        linesw[0].l_write = ttwrpol;
  433. X        spl0();
  434. X        pol_in_use = 1;                /* mark pol in use */
  435. X    }        
  436. X    return 0;
  437. X}
  438. X
  439. X/*---------------------------------------------------------------------------
  440. X**
  441. X**    polclose - called only for last close() call
  442. X**
  443. X**--------------------------------------------------------------------------*/
  444. Xpolclose(fdev)
  445. Xint    fdev;
  446. X{
  447. X    pol_in_use = 0;
  448. X    if (linesw[0].l_input != ttinpol)    /* is linesw[] ok? */
  449. X    {
  450. X        printf("pol error:  linesw structure corrupted.\n");
  451. X        u.u_error = ENOMSG;
  452. X        u.u_rval1 = -1;
  453. X    }
  454. X    else if (linesw[0].l_write != ttwrpol)
  455. X    {
  456. X        printf("pol error:  linesw structure corrupted.\n");
  457. X        u.u_error = ENOMSG;
  458. X        u.u_rval1 = -1;
  459. X    }
  460. X    else    u.u_rval1 = 0;
  461. X    spltty();                    /* don't let anyone use them */
  462. X    linesw[0].l_input = ttin;    /* replace the originals */
  463. X    linesw[0].l_write = ttwrite;
  464. X    spl0();
  465. X    return u.u_rval1;
  466. X}
  467. X
  468. X/*---------------------------------------------------------------------------
  469. X**
  470. X**    polioctl - called for each ioctl() call
  471. X**
  472. X**--------------------------------------------------------------------------*/
  473. Xpolioctl(fdev, command, polfd_p, mode) 
  474. Xint    fdev, command, mode;
  475. Xstruct polfd *polfd_p;
  476. X{
  477. X    int     i,
  478. X            rfds_num = 0,
  479. X            wfds_num = 0,
  480. X            hits = 0,
  481. X            char_cnt,
  482. X            timeout_idx = 0;
  483. X    time_t    start_ticks = lbolt,
  484. X            timeout_ticks;
  485. X    struct polfd pol_s;
  486. X    struct pol_table rfds_pol[NPOLFILE],
  487. X                     wfds_pol[NPOLFILE];
  488. X    
  489. X    DB(printf("Start func\n"));
  490. X    if (copyin(polfd_p, &pol_s, sizeof(struct polfd)) != 0)
  491. X    {
  492. X        u.u_error = EFAULT;
  493. X        u.u_rval1 = -1;
  494. X        return -1;
  495. X    }
  496. X    if (command != POL_FDS)        /* illegal ioctl() request */
  497. X    {
  498. X        u.u_error = EINVAL;        
  499. X        u.u_rval1 = -1;
  500. X        return -1;
  501. X    }
  502. X    
  503. X    if (pol_s.timeout != -1 && pol_s.timeout != 0)    /* is there a timeout? */
  504. X    {
  505. X        timeout_ticks = start_ticks + pol_s.timeout * (HZ)/1000;
  506. X        timeout_idx = timeout(    poltimeo,        /* wake us up later */
  507. X                                (caddr_t)NULL,
  508. X                                pol_s.timeout * (HZ)/1000);
  509. X    }
  510. X
  511. X    DB(printf("Start for loop.\n"));    
  512. X    DB(printf("Start while loop.\n"));
  513. X
  514. X                /* COLLECT READ AND WRITE ADDRESSES TO SCAN */
  515. X                
  516. X    if (poladdr( pol_s.rfds, rfds_pol, &rfds_num, POL_READ_FLAG) == -1)
  517. X    {
  518. X        if (timeout_idx != 0 && lbolt < timeout_ticks)
  519. X            untimeout(timeout_idx);
  520. X        return -1;
  521. X    }
  522. X    if (poladdr( pol_s.wfds, wfds_pol, &wfds_num, POL_WRITE_FLAG) == -1)
  523. X    {
  524. X        if (timeout_idx != 0 && lbolt < timeout_ticks)
  525. X            untimeout(timeout_idx);
  526. X        return -1;
  527. X    }
  528. X
  529. X    pol_s.rfds = pol_s.wfds = 0;
  530. X
  531. X                        /* MAIN POLLING LOOP */
  532. X    while(1)
  533. X    {
  534. X        do
  535. X        {
  536. X            pol_intr = 0;
  537. X            spl0();
  538. X                    /* READS */
  539. X            for (i=0; i < rfds_num; i++)
  540. X            {
  541. X                if (rfds_pol[i].ttyflags != IS_PIPE &&
  542. X                    !(*(short *)(rfds_pol[i].addr + T_CFLAG_OFF) & CLOCAL) &&
  543. X                    !(*(short *)(rfds_pol[i].addr + T_STATE_OFF) & CARR_ON))
  544. X                        char_cnt = 1;
  545. X                else
  546. X                    switch (rfds_pol[i].ttyflags)
  547. X                    {
  548. X                    case IS_PTM      :    char_cnt =
  549. X                                  *(int *)(rfds_pol[i].addr + TOUTQ_CC_OFF) +
  550. X                                *(short *)(rfds_pol[i].addr + TBUF_CNT_OFF);
  551. X                                    break;
  552. X                    case IS_PIPE  :    char_cnt = *(int *)(rfds_pol[i].addr);
  553. X                                    break;
  554. X                    default          :
  555. X                                    char_cnt =
  556. X                                 *(int *)(rfds_pol[i].addr + TCANQ_CC_OFF);
  557. X                                   if ((((struct tty *)rfds_pol->addr)->t_lflag
  558. X                                                            & ICANON) == 0)
  559. X                                    char_cnt +=
  560. X                                 *(int *)(rfds_pol[i].addr + TRAWQ_CC_OFF);
  561. X                                break;
  562. X                    }                
  563. X                if (char_cnt != 0)
  564. X                {
  565. X                    pol_s.rfds |= (1 << rfds_pol[i].fd);
  566. X                    hits++;
  567. X                }
  568. X            }
  569. X
  570. X                    /* WRITES */
  571. X            for (i=0; i < wfds_num; i++)
  572. X            {
  573. X                char_cnt = 0;
  574. X                if (wfds_pol[i].ttyflags != IS_PIPE &&
  575. X                    !(*(short *)(wfds_pol[i].addr + T_CFLAG_OFF) & CLOCAL) &&
  576. X                    !(*(short *)(wfds_pol[i].addr + T_STATE_OFF) & CARR_ON))
  577. X                        char_cnt = 1;
  578. X                else
  579. X                    switch (wfds_pol[i].ttyflags)
  580. X                    {
  581. X                        case IS_PIPE  :
  582. X                            if (*(int *)(wfds_pol[i].addr) < PIPE_MAX)
  583. X                                char_cnt = 1;
  584. X                        default          :
  585. X                            if (!(*(short *)(wfds_pol[i].addr + T_STATE_OFF)
  586. X                                                            & TBLOCK))
  587. X                                char_cnt = 1;
  588. X                    }
  589. X
  590. X                if (char_cnt != 0)
  591. X                {
  592. X                    pol_s.wfds |= (1 << wfds_pol[i].fd);
  593. X                    hits++;
  594. X                }
  595. X            }
  596. X                        /* DO WE HAVE SOMETHING TO REPORT? */
  597. X                        
  598. X            if (hits != 0)
  599. X            {
  600. X                if (timeout_idx != 0 && lbolt < timeout_ticks)
  601. X                    untimeout(timeout_idx);
  602. X                DB(printf("got result\n"));
  603. X                if (copyout(&pol_s, polfd_p, sizeof(struct polfd)) != 0)
  604. X                {
  605. X                    u.u_error = EFAULT;
  606. X                    u.u_rval1 = -1;
  607. X                }
  608. X                else u.u_rval1 = hits;
  609. X                return u.u_rval1;
  610. X            }
  611. X            
  612. X            spltty();
  613. X        } while (pol_intr != 0);    /* was there activity during scan */
  614. X
  615. X                            /* GO TO SLEEP */
  616. X
  617. X        DB(printf("Going to sleep\n"));
  618. X        if (pol_s.timeout == 0 || (
  619. X            pol_s.timeout != -1 && lbolt >= timeout_ticks))
  620. X        {
  621. X                spl0();
  622. X                if (timeout_idx != 0 && lbolt < timeout_ticks)
  623. X                    untimeout(timeout_idx);
  624. X                u.u_rval1 = 0;
  625. X                return 0;
  626. X        }
  627. X        sleep((caddr_t *)&pol_in_use, PSLEP);
  628. X        spl0();
  629. X    }
  630. X}
  631. X
  632. X/*---------------------------------------------------------------------------
  633. X**
  634. X**    wakepl - this is our wakeup substitute
  635. X**
  636. X**--------------------------------------------------------------------------*/
  637. Xwakepl(caddr)
  638. Xcaddr_t caddr;
  639. X{
  640. X    if (pol_in_use > 0)
  641. X    {
  642. X        DB(printf("wakepl called\n"));
  643. X        wakeup((caddr_t)&pol_in_use);
  644. X    }
  645. X    return wakeup(caddr);        /* call original wakeup() */
  646. X}
  647. X
  648. X/*---------------------------------------------------------------------------
  649. X**
  650. X**    poltimeo - this is our timeout() wakeup so we can return on timeout
  651. X**
  652. X**--------------------------------------------------------------------------*/
  653. Xpoltimeo()
  654. X{
  655. X    if (pol_in_use > 0)
  656. X    {
  657. X        DB(printf("timedout wakeup\n"));
  658. X        wakeup((caddr_t)&pol_in_use);        /* wake up all pol's */
  659. X    }
  660. X}
  661. X    
  662. X/*---------------------------------------------------------------------------
  663. X**
  664. X**    ttinpol - out ttin() substitute
  665. X**
  666. X**--------------------------------------------------------------------------*/
  667. Xttinpol(tty_p, flag)
  668. Xstruct tty *tty_p;
  669. Xint flag;
  670. X{
  671. X    if (pol_in_use > 0)
  672. X    {
  673. X        DB(printf("ttinpol called\n"));
  674. X        wakeup((caddr_t)&pol_in_use);
  675. X    }
  676. X    pol_intr = 1;
  677. X    return ttin(tty_p, flag);        /* call original ttin() */
  678. X}
  679. X
  680. X/*---------------------------------------------------------------------------
  681. X**
  682. X**    ttwrpol - out ttwrite() substitute
  683. X**
  684. X**--------------------------------------------------------------------------*/
  685. Xttwrpol(tty_p)
  686. Xstruct tty *tty_p;
  687. X{
  688. X    if (pol_in_use > 0)
  689. X    {
  690. X        DB(printf("ttwrpol called\n"));
  691. X        wakeup((caddr_t)&pol_in_use);
  692. X    }
  693. X    pol_intr = 1;
  694. X    return ttwrite(tty_p);            /* call original ttwrite() */
  695. X}
  696. X
  697. X
  698. X/*---------------------------------------------------------------------------
  699. X**
  700. X**    poladdr - collects addresses to scan after each char in or out
  701. X**
  702. X**--------------------------------------------------------------------------*/
  703. Xpoladdr(fmask, fds_pol, num_fds, flag)
  704. Xint fmask, *num_fds, flag;
  705. Xstruct pol_table *fds_pol;
  706. X{
  707. X    int i, j;
  708. X    struct inode *fd_inode;
  709. X    struct tty *major_tty;
  710. X    struct Link *fd_link;
  711. X    
  712. X    for (i = 0; i != -1 && i <= NPOLFILE; i++)    /* for each fd */
  713. X    {        
  714. X        if ( (fmask & (1 << i)) == 0)            /* is it marked? */
  715. X            continue;
  716. X        DB(printf("Found fd\n"));
  717. X        fds_pol->fd = i;
  718. X        fds_pol->ttyflags = 0;
  719. X        if (u.u_ofile[i] == NULL)                /* is it active? */
  720. X        {
  721. X            u.u_error = EBADF;        
  722. X            u.u_rval1 = -1;
  723. X            return -1;
  724. X        }
  725. X         fd_inode = (u.u_ofile[i])->f_up.f_uinode; /*is it active? */
  726. X        if (fd_inode == NULL)
  727. X        {
  728. X            u.u_error = EBADF;        
  729. X            u.u_rval1 = -1;
  730. X            return -1;
  731. X        }
  732. X
  733. X
  734. X                    /* IS IT A CHARACTER SPECIAL DEVICE? */
  735. X                    
  736. X        if ( (fd_inode->i_ftype & IFMT) == IFCHR)
  737. X        {
  738. X            DB(printf("char device\n"));
  739. X            DB(printf("major %d\n",major(fd_inode->i_rdev)));
  740. X            DB(printf("minor %d\n",minor(fd_inode->i_rdev)));
  741. X            
  742. X                /* DOES THIS MAJOR NUMBER LACK A TTY STRUCTURE? */
  743. X
  744. X            if ( (major_tty=cdevsw[major(fd_inode->i_rdev)].d_ttys) == 0)
  745. X                            /* IS IT AN SXT DEVICE */
  746. X                if (cdevsw[major(fd_inode->i_rdev)].d_open == sxtopen)
  747. X                    fds_pol->addr = (char *)sxt_buf +
  748. X                            (long)LINK(minor(fd_inode->i_rdev)) *
  749. X                            (long)(sizeof(struct Link) +
  750. X                             sizeof(struct Channel) * (MAXPCHAN-1)) +
  751. X                            (long)&((struct Link *)0)->chans[0] +
  752. X                                CHAN(minor(fd_inode->i_rdev)) *
  753. X                                sizeof(struct Channel) +
  754. X                                (long)&((struct Channel *)0)->tty;
  755. X                        /* IS IT A MASTER PTY DEVICE? */
  756. X                else if (cdevsw[major(fd_inode->i_rdev)].d_open == ptmopen)
  757. X                {            /* master ptys */
  758. X                        fds_pol->addr = (char *)pts_tty +
  759. X                            minor(fd_inode->i_rdev) * sizeof(struct tty);
  760. X                        fds_pol->ttyflags = IS_PTM;
  761. X                }                    
  762. X                else
  763. X                {
  764. X                    u.u_error = ENXIO;        
  765. X                    u.u_rval1 = -1;
  766. X                    return -1;
  767. X                }
  768. X            else        /* it has a tty structure */
  769. X                fds_pol->addr = (char *)major_tty +
  770. X                    minor(fd_inode->i_rdev) * sizeof(struct tty);
  771. X        }
  772. X        else if ( (fd_inode->i_ftype & IFMT) == IFIFO)    /* is it a pipe? */
  773. X        {
  774. X                    fds_pol->addr = (char *)&fd_inode->i_size;
  775. X                     fds_pol->ttyflags = IS_PIPE;
  776. X        }                    
  777. X        else
  778. X        {
  779. X            u.u_error = EBADF;        
  780. X            u.u_rval1 = -1;
  781. X            return -1;
  782. X        }
  783. X        DB(printf("Got address\n"));
  784. X        (*num_fds)++;
  785. X        fds_pol++;
  786. X        if ( (fmask &= ~(1 <<i)) == 0)    /* remove bit from mask */
  787. X            break;
  788. X    }
  789. X    return 0;
  790. X}
  791. END_OF_FILE
  792.   if test 11229 -ne `wc -c <'pol.c'`; then
  793.     echo shar: \"'pol.c'\" unpacked with wrong size!
  794.   fi
  795.   # end of 'pol.c'
  796. fi
  797. if test -f 'pol.h' -a "${1}" != "-c" ; then 
  798.   echo shar: Will not clobber existing file \"'pol.h'\"
  799. else
  800.   echo shar: Extracting \"'pol.h'\" \(521 characters\)
  801.   sed "s/^X//" >'pol.h' <<'END_OF_FILE'
  802. X/* sys/pol.h */
  803. X
  804. X#define POL_FDS    0x1234dcba
  805. X
  806. Xstruct polfd {
  807. X    int rfds, wfds;                /* file desc to poll */
  808. X    int timeout;            /* events of interest on fd */
  809. X};
  810. X
  811. X#define NPOLFILE    20
  812. X
  813. X/*#define DONT_HAVE_POLL  /* uncomment this out if you don't have poll.h */
  814. X
  815. X#ifdef DONT_HAVE_POLL
  816. X/*
  817. X * Structure of file descriptor/event pairs supplied in
  818. X * the poll arrays.
  819. X */
  820. Xstruct pollfd {
  821. X    int fd;                    /* file desc to poll */
  822. X    short events;            /* events of interest on fd */
  823. X    short revents;            /* events that occurred on fd */
  824. X};
  825. X#endif
  826. X
  827. END_OF_FILE
  828.   if test 521 -ne `wc -c <'pol.h'`; then
  829.     echo shar: \"'pol.h'\" unpacked with wrong size!
  830.   fi
  831.   # end of 'pol.h'
  832. fi
  833. if test -f 'pol.lib.c' -a "${1}" != "-c" ; then 
  834.   echo shar: Will not clobber existing file \"'pol.lib.c'\"
  835. else
  836.   echo shar: Extracting \"'pol.lib.c'\" \(2700 characters\)
  837.   sed "s/^X//" >'pol.lib.c' <<'END_OF_FILE'
  838. X/*
  839. X    pol.c    - poll/select() C interface
  840. X
  841. X    Bruce Momjian (root%candle.uucp@bts.com
  842. X
  843. X*/
  844. X
  845. X/* tabs = 4 */
  846. X/* Include files */
  847. X#include <fcntl.h>
  848. X
  849. X#include <sys/pol.h>
  850. X#include <sys/selec.h>
  851. X#include <poll.h>
  852. X
  853. Xstatic int pol_fd = -1;
  854. X
  855. X
  856. X/*---------------------------------------------------------------------------
  857. X**
  858. X**    pol()
  859. X**
  860. X**--------------------------------------------------------------------------*/
  861. Xpol(fds, nfds, timeout)
  862. Xstruct pollfd *fds;
  863. Xunsigned long nfds;
  864. Xint timeout;
  865. X{
  866. X    struct polfd    pl;
  867. X    int i, ret;
  868. X    
  869. X    if ( pol_fd == -1 && (pol_fd=open("/dev/pol",O_RDONLY)) == -1)
  870. X        return -1;
  871. X
  872. X    pl.rfds = pl.wfds = 0;
  873. X    pl.timeout = timeout;
  874. X
  875. X    for (i = 0; i < nfds; i++)
  876. X    {
  877. X        if ((fds[i].events & POLLIN) != 0)
  878. X            pl.rfds |= (1 << fds[i].fd);
  879. X        if ((fds[i].events & POLLOUT) != 0)
  880. X            pl.wfds |= (1 << fds[i].fd);
  881. X    }
  882. X    
  883. X    if ((ret=ioctl(pol_fd, POL_FDS, &pl)) == -1)
  884. X         return -1;
  885. X
  886. X    if (ret == 0 || ret == -1)
  887. X        pl.rfds = pl.wfds = 0;
  888. X    
  889. X    for (i=0; i < nfds; i++)
  890. X    {
  891. X        fds[i].revents = 0;
  892. X        if ( (pl.rfds & (1 << fds[i].fd)) != 0)
  893. X            fds[i].revents |= POLLIN;
  894. X        if ( (pl.wfds & (1 << fds[i].fd)) != 0)
  895. X            fds[i].revents |= POLLOUT;
  896. X    }
  897. X    return ret;
  898. X}
  899. X    
  900. X/*---------------------------------------------------------------------------
  901. X**
  902. X**    selec()
  903. X**
  904. X**--------------------------------------------------------------------------*/
  905. Xselec(nfds, rfds, wfds, expfds, timeout)
  906. Xunsigned long nfds, *rfds, *wfds, *expfds; /* exceptions not implemented */
  907. Xstruct timeval *timeout;
  908. X{
  909. X    struct polfd    pl;
  910. X    int i, ored, ret;
  911. X    
  912. X    if ( pol_fd == -1 && (pol_fd=open("/dev/pol",O_RDONLY)) == -1)
  913. X        return -1;
  914. X
  915. X    pl.rfds = pl.wfds = 0;
  916. X    if (timeout == 0L)
  917. X        pl.timeout = -1;
  918. X    else
  919. X        pl.timeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
  920. X
  921. X    for (i = 0; i < nfds; i++)
  922. X    {
  923. X        if ( (*rfds & (1 << i)) != 0)
  924. X            pl.rfds |= 1 << i;
  925. X        if ( (*wfds & (1 << i)) != 0)
  926. X            pl.wfds |= 1 << i;
  927. X    }
  928. X    
  929. X    if ((ret=ioctl(pol_fd, POL_FDS, &pl)) == -1)
  930. X         return -1;
  931. X
  932. X    *rfds = *wfds = *expfds = 0;
  933. X
  934. X    if (ret != 0 && ret != -1)
  935. X    {
  936. X        ret = 0;
  937. X        ored = pl.rfds | pl.wfds;
  938. X        for (i=0; i < nfds; i++)
  939. X        {
  940. X            if ( (pl.rfds & (1 << i)) != 0)
  941. X                (*rfds) |= (1 << i);
  942. X            if ( (pl.wfds & (1 << i)) != 0)
  943. X                (*wfds) |= (1 << i);
  944. X            if ( (ored & (1 << i)) != 0)
  945. X                ret++;
  946. X        }
  947. X    }
  948. X    return ret;
  949. X}
  950. X    
  951. X/*---------------------------------------------------------------------------
  952. X**
  953. X**    polclose()
  954. X**
  955. X**--------------------------------------------------------------------------*/
  956. Xpolclose()
  957. X{
  958. X    if (pol_fd != -1)
  959. X        return close(pol_fd);
  960. X    return 0;
  961. X}
  962. X/*---------------------------------------------------------------------------
  963. X**
  964. X**    selecclose()
  965. X**
  966. X**--------------------------------------------------------------------------*/
  967. Xselecclose()
  968. X{
  969. X    return polclose();
  970. X}
  971. END_OF_FILE
  972.   if test 2700 -ne `wc -c <'pol.lib.c'`; then
  973.     echo shar: \"'pol.lib.c'\" unpacked with wrong size!
  974.   fi
  975.   # end of 'pol.lib.c'
  976. fi
  977. if test -f 'poltest.c' -a "${1}" != "-c" ; then 
  978.   echo shar: Will not clobber existing file \"'poltest.c'\"
  979. else
  980.   echo shar: Extracting \"'poltest.c'\" \(305 characters\)
  981.   sed "s/^X//" >'poltest.c' <<'END_OF_FILE'
  982. X#include <stdio.h>
  983. X#include <fcntl.h>
  984. X#include <poll.h>
  985. X
  986. Xmain()
  987. X{
  988. X    int fd;
  989. X    struct pollfd pl;
  990. X    int x;
  991. X    
  992. X
  993. X    printf("fd = %d\n",fd);
  994. X    pl.fd = 0;
  995. X    pl.events = POLLIN;
  996. X    printf("Begin ioctl, return\n");
  997. X    if ((x=pol(&pl, 1, 5000)) == -1)
  998. X         halt("PERROR : ioctl fail\n");
  999. X    printf("End ioctl\n");
  1000. X    close(fd);
  1001. X}     
  1002. END_OF_FILE
  1003.   if test 305 -ne `wc -c <'poltest.c'`; then
  1004.     echo shar: \"'poltest.c'\" unpacked with wrong size!
  1005.   fi
  1006.   # end of 'poltest.c'
  1007. fi
  1008. if test -f 'pty.c' -a "${1}" != "-c" ; then 
  1009.   echo shar: Will not clobber existing file \"'pty.c'\"
  1010. else
  1011.   echo shar: Extracting \"'pty.c'\" \(9846 characters\)
  1012.   sed "s/^X//" >'pty.c' <<'END_OF_FILE'
  1013. X/*
  1014. X * pty.c - Berkeley style pseudo tty driver for system V
  1015. X *
  1016. X * Copyright (c) 1987, Jens-Uwe Mager, FOCUS Computer GmbH
  1017. X * Not derived from licensed software.
  1018. X *
  1019. X * Permission is granted to freely use, copy, modify, and redistribute
  1020. X * this software, provided that no attempt is made to gain profit from it,
  1021. X * the author is not construed to be liable for any results of using the
  1022. X * software, alterations are clearly marked as such, and this notice is
  1023. X * not modified.
  1024. X */
  1025. X#define TTI            /* comment this define out for the original
  1026. X                 * posted code
  1027. X                 */
  1028. X#ifndef TTI
  1029. X/*
  1030. X * the following are arbitrary 3 unused bits from t_state
  1031. X * in sys/tty.h
  1032. X */
  1033. X#endif TTI
  1034. X
  1035. X#ifndef TTI
  1036. X#define MRWAIT    01000000    /* master waiting in read */
  1037. X#else TTI
  1038. X#define MRWAIT    01        /* master waiting in read */
  1039. X#endif TTI
  1040. X#define t_rloc    t_cc[0]        /* rchannel */
  1041. X
  1042. X#ifndef TTI
  1043. X#define MWWAIT    02000000    /* master waiting in write */
  1044. X#else TTI
  1045. X#define MWWAIT    02        /* master waiting in write */
  1046. X#endif TTI
  1047. X#define t_wloc    t_cc[1]        /* wchannel */
  1048. X
  1049. X#ifndef TTI
  1050. X#define MOPEN    04000000    /* master is open */
  1051. X#else TTI
  1052. X#define MOPEN    04        /* master is open */
  1053. X#endif TTI
  1054. X
  1055. X#include "sys/param.h"
  1056. X#include "sys/types.h"
  1057. X#include "sys/sysmacros.h"
  1058. X#include "sys/seg.h"
  1059. X#include "sys/page.h"
  1060. X#include "sys/systm.h"
  1061. X#include "sys/file.h"
  1062. X#include "sys/conf.h"
  1063. X
  1064. X#ifndef tower
  1065. X#ifdef TTI
  1066. X#include "sys/immu.h"
  1067. X#endif TTI
  1068. X#include "sys/region.h"
  1069. X#endif
  1070. X
  1071. X#include "sys/proc.h"
  1072. X#include "sys/dir.h"
  1073. X#include "sys/tty.h"
  1074. X#include "sys/signal.h"
  1075. X#include "sys/user.h"
  1076. X#include "sys/errno.h"
  1077. X#include "sys/termio.h"
  1078. X#include "sys/ttold.h"
  1079. X
  1080. X/*
  1081. X * from config
  1082. X */
  1083. Xextern struct tty pts_tty[];
  1084. X
  1085. X#ifdef TTI
  1086. Xextern int pts_state[];
  1087. X#endif TTI
  1088. Xextern int pts_cnt;
  1089. X
  1090. Xint    ptsflush = 0;
  1091. X/*
  1092. X * slave side is a fairly standard system V tty driver
  1093. X */
  1094. X#ifndef TTI
  1095. Xptsopen(dev, flag)
  1096. X#else TTI
  1097. Xptsopen(fdev, flag)
  1098. X#endif TTI
  1099. X{
  1100. X#ifdef TTI
  1101. X    register dev = minor(fdev);
  1102. X#endif TTI
  1103. X    register struct tty *tp = &pts_tty[dev];
  1104. X    extern int ptsproc();
  1105. X
  1106. X    if (dev >= pts_cnt) {
  1107. X        u.u_error = ENXIO;
  1108. X        return;
  1109. X    }
  1110. X    if ((tp->t_state & (ISOPEN|WOPEN)) == 0) {
  1111. X        ttinit(tp);
  1112. X        tp->t_proc = ptsproc;
  1113. X    }
  1114. X    /*
  1115. X     * if master is still open, don't wait for carrier
  1116. X     */
  1117. X#ifndef TTI
  1118. X    if (tp->t_state & MOPEN)
  1119. X#else TTI
  1120. X    if (pts_state[dev] & MOPEN)
  1121. X#endif TTI
  1122. X        tp->t_state |= CARR_ON;
  1123. X    if (!(flag & FNDELAY)) {
  1124. X        while ((tp->t_state & CARR_ON) == 0) {
  1125. X            tp->t_state |= WOPEN;
  1126. X            sleep((caddr_t)&tp->t_canq, TTIPRI);
  1127. X        }
  1128. X    }
  1129. X    (*linesw[tp->t_line].l_open)(tp);
  1130. X}
  1131. X
  1132. X#ifndef TTI
  1133. Xptswrite(dev)
  1134. X#else TTI
  1135. Xptswrite(fdev)
  1136. X#endif TTI
  1137. X{
  1138. X#ifdef TTI
  1139. X    register dev = minor(fdev);
  1140. X#endif TTI
  1141. X    register struct tty *tp = &pts_tty[dev];
  1142. X
  1143. X#ifdef TTI
  1144. X#ifdef DEBUG
  1145. X        printf("T_TIME\n");
  1146. X#endif
  1147. X
  1148. X#endif TTI
  1149. X    (*linesw[tp->t_line].l_write)(tp);
  1150. X}
  1151. X
  1152. X#ifndef TTI
  1153. Xptsread(dev)
  1154. X#else TTI
  1155. Xptsread(fdev)
  1156. X#endif TTI
  1157. X{
  1158. X#ifdef TTI
  1159. X    register dev = minor(fdev);
  1160. X#endif TTI
  1161. X    register struct tty *tp = &pts_tty[dev];
  1162. X
  1163. X    (*linesw[tp->t_line].l_read)(tp);
  1164. X}
  1165. X
  1166. X#ifndef TTI
  1167. Xptsclose(dev)
  1168. X#else TTI
  1169. Xptsclose(fdev)
  1170. X#endif TTI
  1171. X{
  1172. X#ifdef TTI
  1173. X    register dev = minor(fdev);
  1174. X#endif TTI
  1175. X    register struct tty *tp = &pts_tty[dev];
  1176. X    
  1177. X    (*linesw[tp->t_line].l_close)(tp);
  1178. X    tp->t_state &= ~CARR_ON;
  1179. X}
  1180. X
  1181. X#ifndef TTI
  1182. Xptsioctl(dev, cmd, arg, mode)
  1183. X#else TTI
  1184. Xptsioctl(fdev, cmd, arg, mode)
  1185. X#endif TTI
  1186. X{
  1187. X#ifdef TTI
  1188. X    register dev = minor(fdev);
  1189. X#endif TTI
  1190. X    register struct tty *tp = &pts_tty[dev];
  1191. X
  1192. X        /* the driver hung on TCSETAF/W, so I have to do it myself, bjm */
  1193. X    if (cmd == TCSETAW || cmd == TCSETAF) 
  1194. X    {
  1195. X        ptsflush++;
  1196. X        while ( tp->t_tbuf.c_ptr != NULL && tp->t_tbuf.c_count != 0 &&
  1197. X                tp->t_outq.c_cc != 0)
  1198. X            sleep((caddr_t *)&ptsflush, PSLEP);
  1199. X        if (cmd == TCSETAF)
  1200. X            ttyflush(tp, FREAD);
  1201. X        cmd = TCSETA;
  1202. X        ptsflush--;
  1203. X    }
  1204. X    ttiocom(tp, cmd, arg, mode);
  1205. X}
  1206. X
  1207. Xptsproc(tp, cmd)
  1208. Xregister struct tty *tp;
  1209. X{
  1210. X    register struct ccblock *tbuf;
  1211. X    extern ttrstrt();
  1212. X
  1213. X    switch (cmd) {
  1214. X    case T_TIME:
  1215. X#ifdef DEBUG
  1216. X        printf("T_TIME\n");
  1217. X#endif
  1218. X        tp->t_state &= ~TIMEOUT;
  1219. X        goto start;
  1220. X    case T_WFLUSH:
  1221. X#ifdef DEBUG
  1222. X        printf("T_WFLUSH\n");
  1223. X#endif
  1224. X        tp->t_tbuf.c_size  -= tp->t_tbuf.c_count;
  1225. X        tp->t_tbuf.c_count = 0;
  1226. X        if (ptsflush)
  1227. X            wakeup((caddr_t)&ptsflush);
  1228. X        /* fall through */
  1229. X    case T_RESUME:
  1230. X#ifdef DEBUG
  1231. X        printf("T_RESUME\n");
  1232. X#endif
  1233. X        tp->t_state &= ~TTSTOP;
  1234. X        /* fall through */
  1235. X    case T_OUTPUT:
  1236. X#ifdef DEBUG
  1237. X        printf("T_OUTPUT\n");
  1238. X#endif
  1239. Xstart:
  1240. X        if (tp->t_state & (TTSTOP|TIMEOUT))
  1241. X            break;
  1242. X        tbuf = &tp->t_tbuf;
  1243. X        if (tbuf->c_ptr == NULL || tbuf->c_count == 0) {
  1244. X            if (tbuf->c_ptr)
  1245. X                tbuf->c_ptr -= tbuf->c_size;
  1246. X            if (!(CPRES & (*linesw[tp->t_line].l_output)(tp)))
  1247. X                break;
  1248. X        }
  1249. X#ifndef TTI
  1250. X        if (tbuf->c_count && (tp->t_state & MRWAIT)) {
  1251. X            tp->t_state &= ~MRWAIT;
  1252. X#else TTI
  1253. X        if (tbuf->c_count && (pts_state[tp-pts_tty] & MRWAIT)) {
  1254. X            pts_state[tp-pts_tty] &= ~MRWAIT;
  1255. X#endif TTI
  1256. X            wakeup((caddr_t)&tp->t_rloc);
  1257. X        }
  1258. X        break;
  1259. X    case T_SUSPEND:
  1260. X#ifdef DEBUG
  1261. X        printf("T_SUSPEND\n");
  1262. X#endif
  1263. X        tp->t_state |= TTSTOP;
  1264. X        break;
  1265. X    case T_BLOCK:
  1266. X#ifdef DEBUG
  1267. X        printf("T_BLOCK\n");
  1268. X#endif
  1269. X        /*
  1270. X         * the check for ICANON appears to be neccessary
  1271. X         * to avoid a hang when overflowing input
  1272. X         */
  1273. X        if ((tp->t_iflag & ICANON) == 0)
  1274. X            tp->t_state |= TBLOCK;
  1275. X        break;
  1276. X    case T_BREAK:
  1277. X#ifdef DEBUG
  1278. X        printf("T_BREAK\n");
  1279. X#endif
  1280. X        tp->t_state |= TIMEOUT;
  1281. X        timeout(ttrstrt, tp, HZ/4);
  1282. X        break;
  1283. X#ifdef T_LOG_FLUSH
  1284. X    case T_LOG_FLUSH:
  1285. X#ifdef DEBUG
  1286. X        printf("T_LOG_FLUSH\n");
  1287. X#endif
  1288. X#endif
  1289. X    case T_RFLUSH:
  1290. X#ifdef DEBUG
  1291. X        printf("T_RFLUSH\n");
  1292. X#endif
  1293. X        if (!(tp->t_state & TBLOCK))
  1294. X            break;
  1295. X        /* fall through */
  1296. X    case T_UNBLOCK:
  1297. X#ifdef DEBUG
  1298. X        printf("T_UNBLOCK\n");
  1299. X#endif
  1300. X        tp->t_state &= ~(TTXOFF|TBLOCK);
  1301. X        /* fall through */
  1302. X    case T_INPUT:
  1303. X#ifdef DEBUG
  1304. X        printf("T_INPUT\n");
  1305. X#endif
  1306. X#ifndef TTI
  1307. X        if (tp->t_state & MWWAIT) {
  1308. X            tp->t_state &= ~MWWAIT;
  1309. X#else TTI
  1310. X        if (pts_state[tp-pts_tty] & MWWAIT) {
  1311. X            pts_state[tp-pts_tty] &= ~MWWAIT;
  1312. X#endif TTI
  1313. X            wakeup((caddr_t)&tp->t_wloc);
  1314. X        }
  1315. X        break;
  1316. X#ifdef DEBUG
  1317. X    default:
  1318. X        printf("ptsproc: cmd %d\n",cmd);
  1319. X#endif
  1320. X    }
  1321. X}
  1322. X
  1323. X/*
  1324. X * master part - not actually like a tty
  1325. X */
  1326. X
  1327. X#ifndef TTI
  1328. Xptmopen(dev, flag)
  1329. X#else TTI
  1330. Xptmopen(fdev, flag)
  1331. X#endif TTI
  1332. X{
  1333. X#ifdef TTI
  1334. X    register dev = minor(fdev);
  1335. X#endif TTI
  1336. X    register struct tty *tp = &pts_tty[dev];
  1337. X
  1338. X#ifdef DEBUG
  1339. X    printf("ptmopen(%d)\n",dev);
  1340. X#endif
  1341. X    if (dev >= pts_cnt) {
  1342. X        u.u_error = ENXIO;
  1343. X        return;
  1344. X    }
  1345. X    /*
  1346. X     * allow only one controlling process
  1347. X     */
  1348. X#ifndef TTI
  1349. X    if (tp->t_state & MOPEN) {
  1350. X#else TTI
  1351. X    if (pts_state[dev] & MOPEN) {
  1352. X#endif TTI
  1353. X        u.u_error = EBUSY;
  1354. X        return;
  1355. X    }
  1356. X    if (tp->t_state & WOPEN)
  1357. X        wakeup((caddr_t)&tp->t_canq);
  1358. X#ifndef TTI
  1359. X    tp->t_state |= CARR_ON|MOPEN;
  1360. X#else TTI
  1361. X    tp->t_state |= CARR_ON;
  1362. X    pts_state[dev] |= MOPEN;
  1363. X#endif TTI
  1364. X}
  1365. X
  1366. X#ifndef TTI
  1367. Xptmread(dev)
  1368. X#else TTI
  1369. Xptmread(fdev)
  1370. X#endif TTI
  1371. X{
  1372. X#ifdef TTI
  1373. X    register dev = minor(fdev);
  1374. X#endif TTI
  1375. X    register struct tty *tp = &pts_tty[dev];
  1376. X    register n;
  1377. X
  1378. X#ifndef TTI
  1379. X    if ((tp->t_state & ISOPEN) == 0) {
  1380. X#else TTI
  1381. X    if ((tp->t_state & (ISOPEN|TTIOW)) == 0) {
  1382. X#ifdef DEBUG
  1383. X    printf("ptmread(%d) EIO\n",dev);
  1384. X#endif
  1385. X#endif TTI
  1386. X        u.u_error = EIO;
  1387. X        return;
  1388. X    }
  1389. X#ifdef DEBUG
  1390. X    printf("ptmread(%d)\n",dev);
  1391. X#endif
  1392. X#ifndef TTI
  1393. X    while (u.u_count) {
  1394. X#else TTI
  1395. X    while (u.u_count>0) {
  1396. X#endif TTI
  1397. X        ptsproc(tp, T_OUTPUT);
  1398. X        if ((tp->t_state & (TTSTOP|TIMEOUT))
  1399. X            || tp->t_tbuf.c_ptr == NULL || tp->t_tbuf.c_count == 0) {
  1400. X            if (u.u_fmode & FNDELAY)
  1401. X                break;
  1402. X#ifndef TTI
  1403. X            tp->t_state |= MRWAIT;
  1404. X#else TTI
  1405. X            pts_state[dev] |= MRWAIT;
  1406. X#endif TTI
  1407. X            sleep((caddr_t)&tp->t_rloc, TTIPRI);
  1408. X            continue;
  1409. X        }
  1410. X        n = min(u.u_count, tp->t_tbuf.c_count);
  1411. X        if (n) {
  1412. X            if (copyout(tp->t_tbuf.c_ptr, u.u_base, n)) {
  1413. X                u.u_error = EFAULT;
  1414. X                break;
  1415. X            }
  1416. X            tp->t_tbuf.c_count -= n;
  1417. X            tp->t_tbuf.c_ptr += n;
  1418. X            u.u_base += n;
  1419. X            u.u_count -= n;
  1420. X            if (ptsflush)
  1421. X                wakeup((caddr_t)&ptsflush);
  1422. X            break;      /* bjm and jrm */
  1423. X        }
  1424. X    }
  1425. X}
  1426. X
  1427. X#ifndef TTI
  1428. Xptmwrite(dev)
  1429. X#else TTI
  1430. Xptmwrite(fdev)
  1431. X#endif TTI
  1432. X{
  1433. X#ifdef TTI
  1434. X    register dev = minor(fdev);
  1435. X#endif TTI
  1436. X    register struct tty *tp = &pts_tty[dev];
  1437. X    register n;
  1438. X
  1439. X    if ((tp->t_state & ISOPEN) == 0) {
  1440. X        u.u_error = EIO;
  1441. X        return;
  1442. X    }
  1443. X#ifdef DEBUG
  1444. X    printf("ptmwrite(%d)\n",dev);
  1445. X#endif
  1446. X#ifndef TTI
  1447. X    while (u.u_count) {
  1448. X#else TTI
  1449. X    while (u.u_count>0) {
  1450. X#endif TTI
  1451. X        if ((tp->t_state & TBLOCK) || tp->t_rbuf.c_ptr == NULL) {
  1452. X            if (u.u_fmode & FNDELAY)
  1453. X                break;
  1454. X#ifndef TTI
  1455. X            tp->t_state |= MWWAIT;
  1456. X#else TTI
  1457. X            pts_state[dev] |= MWWAIT;
  1458. X#endif TTI
  1459. X            sleep((caddr_t)&tp->t_wloc, TTOPRI);
  1460. X            continue;
  1461. X        }
  1462. X        n = min(u.u_count, tp->t_rbuf.c_count);
  1463. X        if (n) {
  1464. X            if (copyin(u.u_base,tp->t_rbuf.c_ptr, n)) {
  1465. X                u.u_error = EFAULT;
  1466. X                break;
  1467. X            }
  1468. X            tp->t_rbuf.c_count -= n;
  1469. X            u.u_base += n;
  1470. X            u.u_count -= n;
  1471. X        }
  1472. X#ifdef vax || m68k
  1473. X        /*
  1474. X         * somebody told me this is necessary on the vax
  1475. X         */
  1476. X        (*linesw[tp->t_line].l_input)(tp, L_BUF);
  1477. X#else
  1478. X        (*linesw[tp->t_line].l_input)(tp);
  1479. X#endif
  1480. X    }
  1481. X}
  1482. X
  1483. X#ifndef TTI
  1484. Xptmclose(dev)
  1485. X#else TTI
  1486. Xptmclose(fdev)
  1487. X#endif TTI
  1488. X{
  1489. X#ifdef TTI
  1490. X    register dev = minor(fdev);
  1491. X#endif TTI
  1492. X    register struct tty *tp = &pts_tty[dev];
  1493. X
  1494. X#ifdef DEBUG
  1495. X    printf("ptmclose(%d)\n",dev);
  1496. X#endif
  1497. X    if (tp->t_state & ISOPEN) {
  1498. X        signal(tp->t_pgrp, SIGHUP);
  1499. X        ttyflush(tp, FREAD|FWRITE);
  1500. X    }
  1501. X    /*
  1502. X     * virtual carrier gone
  1503. X     */
  1504. X#ifndef TTI
  1505. X    tp->t_state &= ~(CARR_ON|MOPEN);
  1506. X#else TTI
  1507. X    tp->t_state &= ~CARR_ON;
  1508. X    pts_state[dev] &= ~MOPEN;
  1509. X#endif TTI
  1510. X}
  1511. X
  1512. X#ifndef TTI
  1513. Xptmioctl(dev, cmd, arg, mode)
  1514. X#else TTI
  1515. Xptmioctl(fdev, cmd, arg, mode)
  1516. X#endif TTI
  1517. X{
  1518. X#ifdef TTI
  1519. X    register dev = minor(fdev);
  1520. X#endif TTI
  1521. X    register struct tty *tp = &pts_tty[dev];
  1522. X
  1523. X    /*
  1524. X     * sorry, but we can't fiddle with the tty struct without
  1525. X     * having done LDOPEN
  1526. X     */
  1527. X    if (tp->t_state & ISOPEN) {
  1528. X        if (cmd == TCSBRK && arg ==  NULL) {
  1529. X            signal(tp->t_pgrp, SIGINT);
  1530. X            if ((tp->t_iflag & NOFLSH) == 0)
  1531. X                ttyflush(tp, FREAD|FWRITE);
  1532. X        } else {
  1533. X            /*
  1534. X             * we must flush output to avoid hang in ttywait
  1535. X             */
  1536. X            if (cmd == TCSETAW || cmd == TCSETAF || cmd == TCSBRK
  1537. X                || cmd == TIOCSETP)
  1538. X                ttyflush(FWRITE);
  1539. X            ttiocom(tp, cmd, arg, mode);
  1540. X        }
  1541. X    }
  1542. X}
  1543. X
  1544. END_OF_FILE
  1545.   if test 9846 -ne `wc -c <'pty.c'`; then
  1546.     echo shar: \"'pty.c'\" unpacked with wrong size!
  1547.   fi
  1548.   # end of 'pty.c'
  1549. fi
  1550. if test -f 'selec.h' -a "${1}" != "-c" ; then 
  1551.   echo shar: Will not clobber existing file \"'selec.h'\"
  1552. else
  1553.   echo shar: Extracting \"'selec.h'\" \(62 characters\)
  1554.   sed "s/^X//" >'selec.h' <<'END_OF_FILE'
  1555. X/* sys/selec.h */
  1556. Xstruct timeval {
  1557. X        long tv_usec, tv_sec;
  1558. X};
  1559. END_OF_FILE
  1560.   if test 62 -ne `wc -c <'selec.h'`; then
  1561.     echo shar: \"'selec.h'\" unpacked with wrong size!
  1562.   fi
  1563.   # end of 'selec.h'
  1564. fi
  1565. echo shar: End of archive 1 \(of 1\).
  1566. cp /dev/null ark1isdone
  1567. MISSING=""
  1568. for I in 1 ; do
  1569.     if test ! -f ark${I}isdone ; then
  1570.     MISSING="${MISSING} ${I}"
  1571.     fi
  1572. done
  1573. if test "${MISSING}" = "" ; then
  1574.     echo You have the archive.
  1575.     rm -f ark[1-9]isdone
  1576. else
  1577.     echo You still must unpack the following archives:
  1578.     echo "        " ${MISSING}
  1579. fi
  1580. exit 0
  1581. exit 0 # Just in case...
  1582.