home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / unix / uw_term.sha / uwtool.c < prev   
C/C++ Source or Header  |  1985-11-12  |  3KB  |  143 lines

  1. #
  2.  
  3. /*
  4.  *    uwtool
  5.  *
  6.  * Copyright 1985 by John D. Bruner.  All rights reserved.  Permission to
  7.  * copy this program is given provided that the copy is not sold and that
  8.  * this copyright notice is included.
  9.  */
  10.  
  11. #include <sys/types.h>
  12. #include <sys/socket.h>
  13. #include <sys/ioctl.h>
  14. #include <sys/wait.h>
  15. #include <sys/time.h>
  16. #include <sys/resource.h>
  17. #include <sys/uio.h>
  18. #include <strings.h>
  19. #include <signal.h>
  20. #include <stdio.h>
  21. #include "openpty.h"
  22.  
  23. #define    NFDS    20            /* max number of file descriptors */
  24.  
  25. typedef int fildes_t;
  26.  
  27. extern char *getenv();
  28.  
  29. main(argc, argv)
  30. char **argv;
  31. {
  32.     register int pid;
  33.     register fildes_t sd;
  34.     auto fildes_t fd;
  35.     char *portal, *shell;
  36.     int lmode;
  37.     struct sgttyb sg;
  38.     struct tchars tc;
  39.     struct ltchars ltc;
  40.     struct iovec iov;
  41.     struct msghdr msg;
  42.     struct sockaddr sa;
  43.     auto struct ptydesc pt;
  44.  
  45.     /*
  46.      * Close all file descriptors except 0, 1, and 2.
  47.      */
  48.  
  49.     for (fd=3; fd < NFDS; fd++)
  50.         (void)close(fd);
  51.  
  52.     /*
  53.      * Get the terminal configuration for this tty.
  54.      */
  55.     (void)ioctl(0, (int)TIOCGETP, (char *)&sg);
  56.     (void)ioctl(0, (int)TIOCGETC, (char *)&tc);
  57.     (void)ioctl(0, (int)TIOCGLTC, (char *)<c);
  58.     (void)ioctl(0, (int)TIOCLGET, (char *)&lmode);
  59.  
  60.     /*
  61.      * Create a UNIX-domain socket.
  62.      */
  63.  
  64.     if (!(portal=getenv("UWIN"))) {
  65.         fprintf(stderr,
  66.             "You must run %s under the window manager\n", *argv);
  67.         exit(1);
  68.     }
  69.  
  70.     if ((sd=socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
  71.         perror("socket");
  72.         exit(1);
  73.     }
  74.     sa.sa_family = AF_UNIX;
  75.     (void)strncpy(sa.sa_data, portal, sizeof sa.sa_data-1);
  76.     sa.sa_data[sizeof sa.sa_data-1] = '\0';
  77.  
  78.  
  79.     /*
  80.      * Obtain a pseudo-tty.
  81.      */
  82.  
  83.     if (openpty(&pt) < 0) {
  84.         fprintf(stderr, "Can't obtain a pseudo-tty for a new window\n");
  85.         exit(1);
  86.     }
  87.  
  88.  
  89.     /* 
  90.      * Fork a child process using this pseudo-tty.  Initialize the
  91.      * terminal modes on the pseudo-tty to match those of the parent
  92.      * tty.
  93.      */
  94.  
  95.     while ((pid=vfork()) < 0)
  96.         sleep(5);
  97.     if (!pid) {
  98.         (void)setuid(getuid());/* in case it's setuid-root by mistake */
  99.         (void)signal(SIGTSTP, SIG_IGN);
  100.         (void)ioctl(open("/dev/tty", 2), (int)TIOCNOTTY, (char *)0);
  101.         (void)close(open(pt.pt_tname, 0)); /*set new ctrl tty */
  102.         (void)dup2(pt.pt_tfd, 0);
  103.         (void)dup2(0, 1);
  104.         (void)dup2(0, 2);
  105.         for (fd=3; fd < NFDS; fd++)
  106.             (void)close(fd);
  107.         (void)ioctl(0, (int)TIOCSETN, (char *)&sg);
  108.         (void)ioctl(0, (int)TIOCSETC, (char *)&tc);
  109.         (void)ioctl(0, (int)TIOCSLTC, (char *)<c);
  110.         (void)ioctl(0, (int)TIOCLSET, (char *)&lmode);
  111.         if (argc == 1) {
  112.             if (!(shell=getenv("SHELL")))
  113.                 shell = "/bin/sh";
  114.             execl(shell, shell, (char *)0);
  115.             perror(shell);
  116.         } else {
  117.             execvp(argv[1], argv+1);
  118.             perror(argv[1]);
  119.         }
  120.         _exit(1);
  121.     }
  122.  
  123.  
  124.     /*
  125.      * Pass the file descriptor to the window server and exit.
  126.      */
  127.  
  128.     iov.iov_base = pt.pt_pname;
  129.     iov.iov_len = strlen(pt.pt_pname);
  130.     msg.msg_name = (caddr_t)&sa;
  131.     msg.msg_namelen = sizeof sa.sa_family + strlen(sa.sa_data);
  132.     msg.msg_iov = &iov;
  133.     msg.msg_iovlen = 1;
  134.     msg.msg_accrights = (caddr_t)&pt.pt_pfd;
  135.     msg.msg_accrightslen = sizeof pt.pt_pfd;
  136.     if (sendmsg(sd, &msg, 0) < 0) {
  137.         perror("sendmsg");
  138.         exit(1);
  139.     }
  140.  
  141.     exit(0);
  142. }
  143.