Annotation of 43BSDReno/contrib/isode-beta/others/X/xinit/xinit.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *rcsid_xinit_c = "$XConsortium: xinit.c,v 11.32 88/10/05 09:27:45 jim Exp $";
                      3: #endif /* lint */
                      4: #include <X11/copyright.h>
                      5: 
                      6: /* Copyright    Massachusetts Institute of Technology    1986  */
                      7: 
                      8: #include <X11/Xos.h>
                      9: #include <X11/Xlib.h>
                     10: #include <stdio.h>
                     11: #include <ctype.h>
                     12: #include <signal.h>
                     13: #include <sys/resource.h>
                     14: #ifndef SYSV
                     15: #include <sys/wait.h>
                     16: #endif
                     17: #include <errno.h>
                     18: extern int sys_nerr;
                     19: #ifdef hpux
                     20: #include <sys/utsname.h>
                     21: #endif
                     22: #include <setjmp.h>
                     23: 
                     24: extern char *getenv();
                     25: extern char **environ;
                     26: char **newenviron = NULL;
                     27: 
                     28: #ifndef SHELL
                     29: #define SHELL "sh"
                     30: #endif
                     31: 
                     32: #ifdef macII
                     33: #define vfork() fork()
                     34: #endif /* macII */
                     35: 
                     36: #if defined(SYSV) && !defined(hpux)
                     37: #define vfork() fork()
                     38: #endif /* SYSV and not hpux */
                     39: 
                     40: char *bindir = BINDIR;
                     41: char *server_names[] = {
                     42: #ifdef vax                             /* Digital */
                     43:     "Xqvss       Digital monochrome display on Microvax II or III series",
                     44:     "Xqdss       Digital color display on Microvax II or III series",
                     45: #endif
                     46: #ifdef sun                             /* Sun */
                     47:     "Xsun        Sun monochrome and color displays on Sun 2, 3, or 4 series",
                     48: #endif
                     49: #ifdef hpux                            /* HP */
                     50:     "Xhp         HP monochrome and colors displays on 9000/300 series",
                     51: #endif
                     52: #ifdef apollo                          /* Apollo */
                     53:     "Xapollo     Apollo monochrome and color displays",
                     54: #endif
                     55: #ifdef ibm                             /* IBM */
                     56:     "Xibm        IBM AED, APA, 8514a, megapel, VGA displays on PC/RT",
                     57: #endif
                     58: #ifdef macII                           /* MacII */
                     59:     "XmacII      Apple monochrome display on Macintosh II",
                     60: #endif
                     61: #ifdef M4310                           /* Tektronix Pegasus */
                     62:     "Xpeg        Tektronix Pegasus display on 4310",
                     63: #endif
                     64: #if defined(vax) || defined(sun)       /* Parallax */
                     65:     "Xplx        Parallax color and video graphics controller",
                     66: #endif
                     67:     NULL};
                     68: 
                     69: #ifndef XINITRC
                     70: #define XINITRC ".xinitrc"
                     71: #endif
                     72: char xinitrcbuf[256];
                     73: 
                     74: #ifndef XSERVERRC
                     75: #define XSERVERRC ".xserverrc"
                     76: #endif
                     77: char xserverrcbuf[256];
                     78: 
                     79: #define        TRUE            1
                     80: #define        FALSE           0
                     81: #define        OK_EXIT         0
                     82: #define        ERR_EXIT        1
                     83: #ifdef ISOCONN
                     84: char displayname[100] = ":X0";
                     85: #else /* ISOCONN */
                     86: char displayname[100] = "unix";
                     87: #endif /* ISOCONN */
                     88: char client_display[100];
                     89: 
                     90: #ifdef ISOCONN
                     91: char *default_server = "Xsun";
                     92: char *default_display = ":X0";         /* choose most efficient */
                     93: char *default_client[] = {"xt", NULL};
                     94: #else /* ISOCONN */
                     95: char *default_server = "X";
                     96: char *default_display = ":0";          /* choose most efficient */
                     97: char *default_client[] = {"xterm", "-geometry", "+1+1", "-n", "login", "-display perky:X0", NULL};
                     98: #endif /* ISOCONN */
                     99: char *serverargv[100];
                    100: char *clientargv[100];
                    101: char **server = serverargv + 2;                /* make sure room for sh .xserverrc args */
                    102: char **client = clientargv + 2;                /* make sure room for sh .xinitrc args */
                    103: char *displayNum;
                    104: char *program;
                    105: Display *xd;                   /* server connection */
                    106: #ifndef SYSV
                    107: union wait     status;
                    108: #endif /* SYSV */
                    109: int serverpid = -1;
                    110: int clientpid = -1;
                    111: extern int     errno;
                    112: 
                    113: sigCatch(sig)
                    114:        int     sig;
                    115: {
                    116:        signal(SIGQUIT, SIG_IGN);
                    117:        signal(SIGINT, SIG_IGN);
                    118:        Error("unexpected signal %d\r\n", sig);
                    119:        shutdown(serverpid, clientpid);
                    120:        exit(1);
                    121: }
                    122: 
                    123: #ifdef SYSV
                    124: sigAlarm(sig)
                    125:        int sig;
                    126: {
                    127:        signal (sig, sigAlarm);
                    128: }
                    129: #endif /* SYSV */
                    130: 
                    131: static Execute (vec)
                    132:     char **vec;                                /* has room from up above */
                    133: {
                    134:     execvp (vec[0], vec);
                    135:     if (access (vec[0], R_OK) == 0) {
                    136:        vec--;                          /* back it up to stuff shell in */
                    137:        vec[0] = SHELL;
                    138:        execvp (vec[0], vec);
                    139:     }
                    140:     return;
                    141: }
                    142: 
                    143: main(argc, argv)
                    144: int argc;
                    145: register char **argv;
                    146: {
                    147:        register char **sptr = server;
                    148:        register char **cptr = client;
                    149:        register char **ptr;
                    150:        int pid, i;
                    151:        int client_given = 0, server_given = 0;
                    152:        int client_args_given = 0, server_args_given = 0;
                    153:        int start_of_client_args, start_of_server_args;
                    154: #ifdef ISOCONN
                    155:        extern char *index();
                    156:        char *cd;
                    157: #endif /* ISOCONN */
                    158: 
                    159:        program = *argv++;
                    160:        argc--;
                    161: 
                    162: #ifndef UNIXCONN
                    163: #ifdef hpux
                    164:        /* Why not use gethostname()?  Well, at least on my system, I've had to
                    165:         * make an ugly kernel patch to get a name longer than 8 characters, and
                    166:         * uname() lets me access to the whole string (it smashes release, you
                    167:         * see), whereas gethostname() kindly truncates it for me.
                    168:         */
                    169:        {
                    170:        struct utsname name;
                    171: 
                    172:        uname(&name);
                    173:        strcpy(displayname, name.nodename);
                    174:        }
                    175: #else
                    176:        gethostname(displayname, sizeof(displayname));
                    177: #ifdef ISOCONN
                    178:        if ((cd = index(displayname, '.')) != NULL)
                    179:                *cd = '\0';
                    180: #endif /* ISOCONN */
                    181: #endif
                    182: #endif /* UNIXCONN */
                    183:        /*
                    184:         * copy the client args.
                    185:         */
                    186:        if (argc == 0 ||
                    187:            (**argv != '/' && **argv != '.' && !isalpha(**argv))) {
                    188:                for (ptr = default_client; *ptr; )
                    189:                        *cptr++ = *ptr++;
                    190:                strcpy(client_display, displayname);
                    191:                strcat(client_display, default_display);
                    192:                *cptr++ = client_display;
                    193: #ifdef sun
                    194:                /* 
                    195:                 * If running on a sun, and if WINDOW_PARENT isn't defined, 
                    196:                 * that means SunWindows isn't running, so we should pass 
                    197:                 * the -C flag to xterm so that it sets up a console.
                    198:                 */
                    199:                if ( getenv("WINDOW_PARENT") == NULL )
                    200:                    *cptr++ = "-C";
                    201: #endif /* sun */
                    202:        } else {
                    203:                client_given = 1;
                    204:        }
                    205:        start_of_client_args = (cptr - client);
                    206:        while (argc && strcmp(*argv, "--")) {
                    207:                client_args_given++;
                    208:                *cptr++ = *argv++;
                    209:                argc--;
                    210:        }
                    211:        *cptr = NULL;
                    212:        if (argc) {
                    213:                argv++;
                    214:                argc--;
                    215:        }
                    216: 
                    217:        /*
                    218:         * Copy the server args.
                    219:         */
                    220:        if (argc == 0 ||
                    221:            (**argv != '/' && **argv != '.' && !isalpha(**argv))) {
                    222:                *sptr++ = default_server;
                    223:        } else {
                    224:                server_given = 1;
                    225:                *sptr++ = *argv++;
                    226:                argc--;
                    227:        }
                    228:        if (argc > 0 && (argv[0][0] == ':' && isdigit(argv[0][1])))
                    229:                displayNum = *argv;
                    230:        else
                    231:                displayNum = *sptr++ = default_display;
                    232: 
                    233:        start_of_server_args = (sptr - server);
                    234:        while (--argc >= 0) {
                    235:                server_args_given++;
                    236:                *sptr++ = *argv++;
                    237:        }
                    238:        *sptr = NULL;
                    239: 
                    240: 
                    241:        strcat(displayname, displayNum);
                    242: 
                    243:        /*
                    244:         * if no client arguments given, check for a startup file and copy
                    245:         * that into the argument list
                    246:         */
                    247:        if (!client_given) {
                    248:            char *cp;
                    249:            Bool required = False;
                    250: 
                    251:            xinitrcbuf[0] = '\0';
                    252:            if ((cp = getenv ("XINITRC")) != NULL) {
                    253:                strcpy (xinitrcbuf, cp);
                    254:                required = True;
                    255:            } else if ((cp = getenv ("HOME")) != NULL) {
                    256:                (void) sprintf (xinitrcbuf, "%s/%s", cp, XINITRC);
                    257:            }
                    258:            if (xinitrcbuf[0]) {
                    259:                if (access (xinitrcbuf, F_OK) == 0) {
                    260:                    client += start_of_client_args - 1;
                    261:                    client[0] = xinitrcbuf;
                    262:                } else if (required) {
                    263:                    fprintf (stderr,
                    264:                             "%s:  warning, no client init file \"%s\"\n",
                    265:                             program, xinitrcbuf);
                    266:                }
                    267:            }
                    268:        }
                    269: 
                    270:        /*
                    271:         * if no server arguments given, check for a startup file and copy
                    272:         * that into the argument list
                    273:         */
                    274:        if (!server_given) {
                    275:            char *cp;
                    276:            Bool required = False;
                    277: 
                    278:            xserverrcbuf[0] = '\0';
                    279:            if ((cp = getenv ("XSERVERRC")) != NULL) {
                    280:                strcpy (xserverrcbuf, cp);
                    281:                required = True;
                    282:            } else if ((cp = getenv ("HOME")) != NULL) {
                    283:                (void) sprintf (xserverrcbuf, "%s/%s", cp, XSERVERRC);
                    284:            }
                    285:            if (xserverrcbuf[0]) {
                    286:                if (access (xserverrcbuf, F_OK) == 0) {
                    287:                    server += start_of_server_args - 1;
                    288:                    server[0] = xserverrcbuf;
                    289:                } else if (required) {
                    290:                    fprintf (stderr,
                    291:                             "%s:  warning, no server init file \"%s\"\n",
                    292:                             program, xserverrcbuf);
                    293:                }
                    294:            }
                    295:        }
                    296: 
                    297: 
                    298:        /*
                    299:         * put the display name into the environment
                    300:         */
                    301:        set_environment ();
                    302: 
                    303:        /*
                    304:         * Start the server and client.
                    305:         */
                    306:        signal(SIGQUIT, sigCatch);
                    307:        signal(SIGINT, sigCatch);
                    308: #ifdef SYSV
                    309:        signal(SIGALRM, sigAlarm);
                    310: #endif /* SYSV */
                    311:        if ((serverpid = startServer(server)) > 0
                    312:         && (clientpid = startClient(client)) > 0) {
                    313:                pid = -1;
                    314:                while (pid != clientpid && pid != serverpid)
                    315:                        pid = wait(NULL);
                    316:        }
                    317:        signal(SIGQUIT, SIG_IGN);
                    318:        signal(SIGINT, SIG_IGN);
                    319: 
                    320:        shutdown(serverpid, clientpid);
                    321: 
                    322:        if (serverpid < 0 || clientpid < 0)
                    323:                exit(ERR_EXIT);
                    324:        exit(OK_EXIT);
                    325: }
                    326: 
                    327: 
                    328: /*
                    329:  *     waitforserver - wait for X server to start up
                    330:  */
                    331: 
                    332: waitforserver(serverpid)
                    333:        int     serverpid;
                    334: {
                    335:        int     ncycles  = 120;         /* # of cycles to wait */
                    336:        int     cycles;                 /* Wait cycle count */
                    337: 
                    338: #ifdef ISOCONN
                    339: sleep(2);
                    340: #endif
                    341:        for (cycles = 0; cycles < ncycles; cycles++) {
                    342:                if (xd = XOpenDisplay(displayname)) {
                    343:                        return(TRUE);
                    344:                }
                    345:                else {
                    346: #define MSG "X server to begin accepting connections"
                    347:                    if (!processTimeout (serverpid, 1, MSG)) 
                    348:                      break;
                    349: #undef MSG
                    350:                }
                    351:        }
                    352: 
                    353:        fprintf (stderr, "giving up.\r\n");
                    354:        return(FALSE);
                    355: }
                    356: 
                    357: /*
                    358:  * return TRUE if we timeout waiting for pid to exit, FALSE otherwise.
                    359:  */
                    360: processTimeout(pid, timeout, string)
                    361:        int     pid, timeout;
                    362:        char    *string;
                    363: {
                    364:        int     i = 0, pidfound = -1;
                    365:        static char     *laststring;
                    366: 
                    367:        for (;;) {
                    368: #ifdef SYSV
                    369:                alarm(1);
                    370:                if ((pidfound = wait(NULL)) == pid)
                    371:                        break;
                    372:                alarm(0);
                    373: #else /* SYSV */
                    374:                if ((pidfound = wait3(&status, WNOHANG, NULL)) == pid)
                    375:                        break;
                    376: #endif /* SYSV */
                    377:                if (timeout) {
                    378:                        if (i == 0 && string != laststring)
                    379:                                fprintf(stderr, "\r\nwaiting for %s ", string);
                    380:                        else
                    381:                                fprintf(stderr, ".");
                    382:                        fflush(stderr);
                    383:                }
                    384:                if (timeout)
                    385:                        sleep (1);
                    386:                if (++i > timeout)
                    387:                        break;
                    388:        }
                    389:        laststring = string;
                    390:        return( pid != pidfound );
                    391: }
                    392: 
                    393: Error(fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
                    394:        char    *fmt;
                    395: {
                    396:        extern char     *sys_errlist[];
                    397: 
                    398:        fprintf(stderr, "%s:  ", program);
                    399:        if (errno > 0 && errno < sys_nerr)
                    400:          fprintf (stderr, "%s (errno %d):  ", sys_errlist[errno], errno);
                    401:        fprintf(stderr, fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
                    402: }
                    403: 
                    404: Fatal(fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
                    405:        char    *fmt;
                    406: {
                    407:        Error(fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
                    408:        exit(ERR_EXIT);
                    409: }
                    410: 
                    411: startServer(server)
                    412:        char *server[];
                    413: {
                    414:        int     serverpid;
                    415: 
                    416:        serverpid = vfork();
                    417:        switch(serverpid) {
                    418:        case 0:
                    419:                close(0);
                    420:                close(1);
                    421: 
                    422:                /*
                    423:                 * don't hang on read/write to control tty
                    424:                 */
                    425: #ifdef SIGTTIN
                    426:                (void) signal(SIGTTIN, SIG_IGN);
                    427: #endif
                    428: #ifdef SIGTTOU
                    429:                (void) signal(SIGTTOU, SIG_IGN);
                    430: #endif
                    431: 
                    432:                /*
                    433:                 * prevent server from getting sighup from vhangup()
                    434:                 * if client is xterm -L
                    435:                 */
                    436:                setpgrp(0,getpid());
                    437: 
                    438:                Execute (server);
                    439:                Error ("no server \"%s\" in PATH\n", server[0]);
                    440:                {
                    441:                    char **cpp;
                    442: 
                    443:                    fprintf (stderr,
                    444: "\nUse the -- option, or make sure that %s is in your path and\n",
                    445:                             bindir);
                    446:                    fprintf (stderr,
                    447: "that \"%s\" is a program or a link to the right type of server\n",
                    448:                             server[0]);
                    449:                    fprintf (stderr,
                    450: "for your display.  Possible server names include:\n\n");
                    451:                    for (cpp = server_names; *cpp; cpp++) {
                    452:                        fprintf (stderr, "    %s\n", *cpp);
                    453:                    }
                    454:                    fprintf (stderr, "\n");
                    455:                }
                    456:                exit (ERR_EXIT);
                    457: 
                    458:                break;
                    459:        case -1:
                    460:                break;
                    461:        default:
                    462:                /*
                    463:                 * don't nice server
                    464:                 */
                    465: #ifdef PRIO_PROCESS
                    466:                setpriority( PRIO_PROCESS, serverpid, -1 );
                    467: #endif
                    468: 
                    469:                errno = 0;
                    470:                if (! processTimeout(serverpid, 0, "")) {
                    471:                        serverpid = -1;
                    472:                        break;
                    473:                }
                    474:                /*
                    475:                 * kludge to avoid race with TCP, giving server time to
                    476:                 * set his socket options before we try to open it
                    477:                 */
                    478:                sleep(5);
                    479: 
                    480:                if (waitforserver(serverpid) == 0) {
                    481:                        Error("unable to connect to X server\r\n");
                    482:                        shutdown(serverpid, -1);
                    483:                        serverpid = -1;
                    484:                }
                    485:                break;
                    486:        }
                    487: 
                    488:        return(serverpid);
                    489: }
                    490: 
                    491: startClient(client)
                    492:        char *client[];
                    493: {
                    494:        int     clientpid;
                    495: 
                    496:        if ((clientpid = vfork()) == 0) {
                    497:                setuid(getuid());
                    498:                setpgrp(0, getpid());
                    499:                environ = newenviron;
                    500:                Execute (client);
                    501:                Error ("no program named \"%s\" in PATH\r\n", client[0]);
                    502:                fprintf (stderr,
                    503: "\nSpecify a program on the command line or make sure that %s\r\n", bindir);
                    504:                fprintf (stderr,
                    505: "is in your path.\r\n");
                    506:                fprintf (stderr, "\n");
                    507:                exit (ERR_EXIT);
                    508:        }
                    509:        return (clientpid);
                    510: }
                    511: 
                    512: #ifdef SYSV
                    513: #define killpg(pgrp, sig) kill(-(pgrp), sig)
                    514: #endif /* SYSV */
                    515: 
                    516: static jmp_buf close_env;
                    517: 
                    518: static int ignorexio (dpy)
                    519:     Display *dpy;
                    520: {
                    521:     fprintf (stderr, "%s:  connection to X server lost.\r\n", program);
                    522:     longjmp (close_env, 1);
                    523:     return;
                    524: }
                    525: 
                    526: static
                    527: shutdown(serverpid, clientpid)
                    528:        int     serverpid, clientpid;
                    529: {
                    530:        /* have kept display opened, so close it now */
                    531:        if (clientpid > 0) {
                    532:                XSetIOErrorHandler (ignorexio);
                    533:                if (! setjmp(close_env)) {
                    534:                    XCloseDisplay(xd);
                    535:                }
                    536: 
                    537:                /* HUP all local clients to allow them to clean up */
                    538:                errno = 0;
                    539:                if ((killpg(clientpid, SIGHUP) != 0) &&
                    540:                    (errno != ESRCH))
                    541:                        Error("can't send HUP to process group %d\r\n",
                    542:                                clientpid);
                    543:        }
                    544: 
                    545:        if (serverpid < 0)
                    546:                return;
                    547:        errno = 0;
                    548:        if (killpg(serverpid, SIGTERM) < 0) {
                    549:                if (errno == EPERM)
                    550:                        Fatal("Can't kill X server\r\n");
                    551:                if (errno == ESRCH)
                    552:                        return;
                    553:        }
                    554:        if (! processTimeout(serverpid, 10, "X server to shut down")) {
                    555:            fprintf (stderr, "\r\n");
                    556:            return;
                    557:        }
                    558: 
                    559:        fprintf(stderr, 
                    560:        "\r\n%s:  X server slow to shut down, sending KILL signal.\r\n",
                    561:                program);
                    562:        fflush(stderr);
                    563:        errno = 0;
                    564:        if (killpg(serverpid, SIGKILL) < 0) {
                    565:                if (errno == ESRCH)
                    566:                        return;
                    567:        }
                    568:        if (processTimeout(serverpid, 3, "server to die")) {
                    569:                fprintf (stderr, "\r\n");
                    570:                Fatal("Can't kill server\r\n");
                    571:        }
                    572:        fprintf (stderr, "\r\n");
                    573:        return;
                    574: }
                    575: 
                    576: 
                    577: /*
                    578:  * make a new copy of environment that has room for DISPLAY
                    579:  */
                    580: 
                    581: set_environment ()
                    582: {
                    583:     int nenvvars;
                    584:     char **newPtr, **oldPtr;
                    585:     static char displaybuf[256];
                    586: 
                    587:     /* count number of environment variables */
                    588:     for (oldPtr = environ; *oldPtr; oldPtr++) ;
                    589: 
                    590:     nenvvars = (oldPtr - environ);
                    591:     newenviron = (char **) malloc ((nenvvars + 2) * sizeof(char **));
                    592:     if (!newenviron) {
                    593:        fprintf (stderr,
                    594:                 "%s:  unable to allocate %d pointers for environment\n",
                    595:                 program, nenvvars + 2);
                    596:        exit (1);
                    597:     }
                    598: 
                    599:     /* put DISPLAY=displayname as first element */
                    600:     strcpy (displaybuf, "DISPLAY=");
                    601:     strcpy (displaybuf + 8, displayname);
                    602:     newPtr = newenviron;
                    603:     *newPtr++ = displaybuf;
                    604: 
                    605:     /* copy pointers to other variables */
                    606:     for (oldPtr = environ; *oldPtr; oldPtr++) {
                    607:        if (strncmp (*oldPtr, "DISPLAY=", 8) != 0) {
                    608:            *newPtr++ = *oldPtr;
                    609:        }
                    610:     }
                    611:     *newPtr = NULL;
                    612:     return;
                    613: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.