int
main(int argc, char *argv[])
{
    int         i, oldumask;

    argcGlobal = argc;
    argvGlobal = argv;

    configfilename = NULL;

    /* init stuff */
    ProcessCmdLine(argc, argv);

    /*
     * Do this first thing, to get any options that only take effect at
     * startup time.  It is read again each time the server resets.
     */
    if (ReadConfigFile(configfilename) != FSSuccess) {
	FatalError("couldn't read config file\n");
    }
    InitErrors();

    /* make sure at least world write access is disabled */
    if (((oldumask = umask(022)) & 002) == 002)
	(void)umask(oldumask);

    SetDaemonState();
    SetUserId();

    while (1) {
	serverGeneration++;
	OsInit();
	if (serverGeneration == 1) {
	    /* do first time init */
	    CreateSockets(OldListenCount, OldListen);
	    InitProcVectors();
	    clients = (ClientPtr *) fsalloc(MAXCLIENTS * sizeof(ClientPtr));
	    if (!clients)
		FatalError("couldn't create client array\n");
	    for (i = MINCLIENT; i < MAXCLIENTS; i++)
		clients[i] = NullClient;
	    /* make serverClient */
	    serverClient = (ClientPtr) fsalloc(sizeof(ClientRec));
	    if (!serverClient)
		FatalError("couldn't create server client\n");
	}
	ResetSockets();

	/* init per-cycle stuff */
	InitClient(serverClient, SERVER_CLIENT, (pointer) 0);

	clients[SERVER_CLIENT] = serverClient;
	currentMaxClients = MINCLIENT;
	currentClient = serverClient;

	if (!InitClientResources(serverClient))
	    FatalError("couldn't init server resources\n");

	InitAtoms();
	InitFonts();
	SetConfigValues();
	if (!create_connection_block())
	    FatalError("couldn't create connection block\n");

#ifdef DEBUG
	fprintf(stderr, "Entering Dispatch loop\n");
#endif

	Dispatch();

#ifdef DEBUG
	fprintf(stderr, "Leaving Dispatch loop\n");
#endif

	/* clean up per-cycle stuff */
	if ((dispatchException & DE_TERMINATE) || drone_server)
	    break;
	fsfree(ConnectionInfo);
	/* note that we're parsing it again, for each time the server resets */
	if (ReadConfigFile(configfilename) != FSSuccess)
	    FatalError("couldn't read config file\n");
    }

    CloseSockets();
    CloseErrors();
    exit(0);
}
Beispiel #2
0
int
CloneMyself(void)
{
    int         child;
    char        old_listen_arg[256];
    char	*arg_ptr = old_listen_arg;
    int         i, j;
    int         lastfdesc;
    char	portnum[20];

    assert(!drone_server);	/* a drone shouldn't hit this */

    if (!CloneSelf)
	return -1;

#ifdef __UNIXOS2__
    NoticeF("cloning of font server not supported under OS/2!\n");
    return(-1);
#endif

    old_listen_arg[0] = '\0';

    lastfdesc = sysconf(_SC_OPEN_MAX) - 1;
    if ( (lastfdesc < 0) || (lastfdesc > MAXSOCKS)) {
	lastfdesc = MAXSOCKS;
    }

    NoticeF("attempting clone...\n");
    chdir("/");
    child = fork();
    if (child == -1) {
	/* failed to fork */
	ErrorF("clone failed to fork()\n");
	return -1;
    }
    /*
     * Note:  they still share the same process group, and killing the parent
     * will take out all the kids as well.  this is considered a feature (at
     * least until i'm convinced otherwise)
     */
    if (child == 0) {
	StopListening();
	NoticeF("clone: child becoming drone\n");
	drone_server = TRUE;
	return 1;
    } else {			/* parent */
	NoticeF("clone: parent revitalizing as %s\n", progname);
	CloseErrors();
	/* XXX should we close stdio as well? */
	for (i = 3; i < lastfdesc; i++)
	{
	    for (j = 0; j < ListenTransCount; j++)
		if (ListenTransFds[j] == i)
		    break;
	    
	    if (j >= ListenTransCount)
		(void) close(i);
	}

	for (i = 0; i < ListenTransCount; i++)
	{
	    int trans_id, fd;
	    char *port;

	    if (!_FontTransGetReopenInfo (ListenTransConns[i],
		&trans_id, &fd, &port))
		continue;

	    sprintf (arg_ptr, "%d/%d/%s", trans_id, fd, port);
	    arg_ptr += strlen (arg_ptr);
	    free (port);

	    if (i < ListenTransCount - 1)
	    {
		strcat (arg_ptr, ",");
		arg_ptr++;
	    }
	}

	sprintf (portnum, "%d", ListenPort);
	if (*old_listen_arg != '\0')
	    execlp(progname, progname,
		   "-ls", old_listen_arg,
		   "-cf", configfilename,
		   "-port", portnum,
		   (void *)NULL);

	InitErrors();		/* reopen errors, since we don't want to lose
				 * this */
	Error("clone failed");
	FatalError("failed to clone self\n");
    }
    /* NOTREACHED */
    return 0;
}