Annotation of 43BSDReno/contrib/isode-beta/others/X/xinit/xinit.c, revision 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.