home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / lib / libutil / pty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-10  |  3.7 KB  |  128 lines

  1. /*-
  2.  * Copyright (c) 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #if defined(LIBC_SCCS) && !defined(lint)
  35. static char sccsid[] = "@(#)pty.c    5.6 (Berkeley) 5/10/91";
  36. #endif /* LIBC_SCCS and not lint */
  37.  
  38. #include <sys/cdefs.h>
  39. #include <sys/types.h>
  40. #include <sys/stat.h>
  41. #include <sys/ioctl.h>
  42. #include <fcntl.h>
  43. #include <termios.h>
  44. #include <errno.h>
  45. #include <unistd.h>
  46. #include <stdio.h>
  47. #include <string.h>
  48. #include <grp.h>
  49.  
  50. openpty(amaster, aslave, name, termp, winp)
  51.     int *amaster, *aslave;
  52.     char *name;
  53.     struct termios *termp;
  54.     struct winsize *winp;
  55. {
  56.     static char line[] = "/dev/ptyXX";
  57.     register const char *cp1, *cp2;
  58.     register int master, slave, ttygid;
  59.     struct group *gr;
  60.  
  61.     if ((gr = getgrnam("tty")) != NULL)
  62.         ttygid = gr->gr_gid;
  63.     else
  64.         ttygid = -1;
  65.  
  66.     for (cp1 = "pqrs"; *cp1; cp1++) {
  67.         line[8] = *cp1;
  68.         for (cp2 = "0123456789abcdef"; *cp2; cp2++) {
  69.             line[9] = *cp2;
  70.             if ((master = open(line, O_RDWR, 0)) == -1) {
  71.                 if (errno == ENOENT)
  72.                     return (-1);    /* out of ptys */
  73.             } else {
  74.                 line[5] = 't';
  75.                 (void) chown(line, getuid(), ttygid);
  76.                 (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
  77.                 (void) revoke(line);
  78.                 if ((slave = open(line, O_RDWR, 0)) != -1) {
  79.                     *amaster = master;
  80.                     *aslave = slave;
  81.                     if (name)
  82.                         strcpy(name, line);
  83.                     if (termp)
  84.                         (void) tcsetattr(slave, 
  85.                             TCSAFLUSH, termp);
  86.                     if (winp)
  87.                         (void) ioctl(slave, TIOCSWINSZ, 
  88.                             (char *)winp);
  89.                     return (0);
  90.                 }
  91.                 (void) close(master);
  92.                 line[5] = 'p';
  93.             }
  94.         }
  95.     }
  96.     errno = ENOENT;    /* out of ptys */
  97.     return (-1);
  98. }
  99.  
  100. forkpty(amaster, name, termp, winp)
  101.     int *amaster;
  102.     char *name;
  103.     struct termios *termp;
  104.     struct winsize *winp;
  105. {
  106.     int master, slave, pid;
  107.  
  108.     if (openpty(&master, &slave, name, termp, winp) == -1)
  109.         return (-1);
  110.     switch (pid = fork()) {
  111.     case -1:
  112.         return (-1);
  113.     case 0:
  114.         /* 
  115.          * child
  116.          */
  117.         (void) close(master);
  118.         login_tty(slave);
  119.         return (0);
  120.     }
  121.     /*
  122.      * parent
  123.      */
  124.     *amaster = master;
  125.     (void) close(slave);
  126.     return (pid);
  127. }
  128.