Exemple #1
0
void
SetDaemonState(void)
{
    int	    oldpid;

#ifdef XFS_INETD
    if (runFromInetd) {
	int inetdListener;

	/* fd's 0, 1, & 2 are the initial listen socket provided by inetd,
	 * so dup it and then clear them so stdin/out/err aren't in use.
	 */
	inetdListener = dup(0);
	if (inetdListener == -1) {
	    FatalError("failed to dup inetd socket: %s\n",
		       strerror(errno));
	}
	DetachStdio();

	/* Setup & pass the inetd socket back through the connection setup
	 * code the same way as a cloned listening port
	 */
	OldListenCount = 1;
	OldListen = _FontTransGetInetdListenInfo (inetdListener);
	if (OldListen == NULL) {
	    FatalError("failed to initialize OldListen to inetd socket: %s\n",
		       strerror(errno));
	}
	ListenPort = OldListen[0].portnum;
	NoticeF("accepting listener from inetd on fd %d, port %d\n",
		inetdListener, ListenPort);
	return;
    }
#endif /* XFS_INETD */

    if (becomeDaemon) {
	BecomeDaemon();
	if ((oldpid = StorePid ())) {
	    if (oldpid == -1)
		ErrorF ("error opening process-id file %s\n", pidFile);
	    else
		ErrorF ("process-id file %s indicates another xfs is "
			  "running (pid %d); exiting\n", pidFile, oldpid);
	    exit(1);
	}
    }
}
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;
}
Exemple #3
0
Dispatch()
{
    int         nready,
                result;
    int        *clientReady;
    ClientPtr   client;
    int		op;

    nextFreeClientID = MINCLIENT;
    nClients = 0;

    clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
    if (!clientReady)
	return;

    while (1) {
	/* wait for something */
	nready = WaitForSomething(clientReady);

	while (!dispatchException && (--nready >= 0)) {
	    client = currentClient = clients[clientReady[nready]];

	    /* Client can be NULL if CloseDownClient() is called during
	       this dispatchException loop. */
	    if (client == (ClientPtr)NULL) continue;

	    isItTimeToYield = FALSE;

	    while (!isItTimeToYield) {
		result = ReadRequest(client);
		if (result <= 0) {
		    if (result < 0)
			CloseDownClient(client);
		    break;
		}
		client->sequence++;

		if (result > (MAX_REQUEST_SIZE << 2))
		    result = FSBadLength;
		else
		{
		    op = MAJOROP;
		    if (op >= NUM_PROC_VECTORS)
			result = ProcBadRequest (client);
		    else
			result = (*client->requestVector[op]) (client);
		}
		if (result != FSSuccess) {
		    if (client->noClientException != FSSuccess)
			CloseDownClient(client);
		    break;
		}
	    }
	    FlushAllOutput ();
	}
	/* reset if server is a drone and has run out of clients */
	if (drone_server && nClients == 0) {
	    dispatchException |= DE_RESET;
	}
	if (dispatchException) {
	    /* re-read the config file */
	    if (dispatchException & DE_RECONFIG) {
		NoticeF("Re-reading config file\n");
		if (ReadConfigFile(configfilename) != FSSuccess)
		    ErrorF("couldn't parse config file\n");
		SetConfigValues();
		dispatchException &= ~DE_RECONFIG;
	    }
	    /* flush all the caches */
	    if (dispatchException & DE_FLUSH) {
		NoticeF("flushing all caches\n");
		CacheReset();
		dispatchException &= ~DE_FLUSH;
	    }
	    /* reset */
	    if (dispatchException & DE_RESET) {
		NoticeF("resetting\n");
		break;
	    }
	    /* die *now* */
	    if (dispatchException & DE_TERMINATE) {
		NoticeF("terminating\n");
		kill_all_clients();
		exit(0);
		break;
	    }
	}
    }
    kill_all_clients();
    dispatchException = 0;
}
Exemple #4
0
/*
 * creates the sockets for listening to clients
 *
 * only called when server first started
 */
void
CreateSockets(int old_listen_count, OldListenRec *old_listen)
{
    int	i;

    FD_ZERO(&AllSockets);
    FD_ZERO(&AllClients);
    FD_ZERO(&LastSelectMask);
    FD_ZERO(&ClientsWithInput);
    FD_ZERO(&WellKnownConnections);

    for (i = 0; i < MAXSOCKS; i++)
	ConnectionTranslation[i] = 0;

#ifdef XNO_SYSCONF	/* should only be on FreeBSD 1.x and NetBSD 0.x */
#undef _SC_OPEN_MAX
#endif
#ifdef _SC_OPEN_MAX
    lastfdesc = sysconf(_SC_OPEN_MAX) - 1;
#else
#if defined(hpux) || defined(__UNIXOS2__)
    lastfdesc = _NFILE - 1;
#else
    lastfdesc = getdtablesize() - 1;
#endif				/* hpux */
#endif

    if (lastfdesc > MAXSOCKS) {
	lastfdesc = MAXSOCKS;
    }

    if (old_listen_count > 0) {

	/*
	 * The font server cloned itself.  Re-use previously opened
	 * transports for listening.
	 */

	ListenTransConns = (XtransConnInfo *) malloc (
	    old_listen_count * sizeof (XtransConnInfo));

	ListenTransFds = (int *) malloc (old_listen_count * sizeof (int));

	ListenTransCount = 0;

	for (i = 0; i < old_listen_count; i++)
	{
	    char portnum[10];

	    if (old_listen[i].portnum != ListenPort)
		continue;		/* this should never happen */
	    else
		sprintf (portnum, "%d", old_listen[i].portnum);

	    if ((ListenTransConns[ListenTransCount] =
		_FontTransReopenCOTSServer (old_listen[i].trans_id,
		old_listen[i].fd, portnum)) != NULL)
	    {
		ListenTransFds[ListenTransCount] = old_listen[i].fd;
		FD_SET (old_listen[i].fd, &WellKnownConnections);

		NoticeF("reusing existing file descriptor %d\n",
		    old_listen[i].fd);

		ListenTransCount++;
	    }
	}
    } else {
	char port[20];
	int partial;

	sprintf (port, "%d", ListenPort);

	if ((_FontTransMakeAllCOTSServerListeners (port, &partial,
	    &ListenTransCount, &ListenTransConns) >= 0) &&
	    (ListenTransCount >= 1))
	{
	    ListenTransFds = (int *) malloc (ListenTransCount * sizeof (int));

	    for (i = 0; i < ListenTransCount; i++)
	    {
		int fd = _FontTransGetConnectionNumber (ListenTransConns[i]);

		ListenTransFds[i] = fd;
		FD_SET (fd, &WellKnownConnections);
	    }
	}
    }

    if (! XFD_ANYSET(&WellKnownConnections))
	FatalError("cannot establish any listening sockets\n");

    /* set up all the signal handlers */
    signal(SIGPIPE, SIG_IGN);
    signal(SIGHUP, AutoResetServer);
    signal(SIGINT, GiveUp);
    signal(SIGTERM, GiveUp);
    signal(SIGUSR1, ServerReconfig);
    signal(SIGUSR2, ServerCacheFlush);
    signal(SIGCHLD, CleanupChild);

    XFD_COPYSET (&WellKnownConnections, &AllSockets);
}
/*
 * creates the sockets for listening to clients
 *
 * only called when server first started
 */
void
CreateSockets(int old_listen_count, OldListenRec *old_listen)
{
    int	i;
    struct sigaction act;

    FD_ZERO(&AllSockets);
    FD_ZERO(&AllClients);
    FD_ZERO(&LastSelectMask);
    FD_ZERO(&ClientsWithInput);
    FD_ZERO(&WellKnownConnections);

    for (i = 0; i < MAXSOCKS; i++)
	ConnectionTranslation[i] = 0;

    lastfdesc = sysconf(_SC_OPEN_MAX) - 1;

    if ((lastfdesc < 0) || (lastfdesc > MAXSOCKS)) {
	lastfdesc = MAXSOCKS;
    }

    if (old_listen_count > 0) {

	/*
	 * The font server cloned itself.  Re-use previously opened
	 * transports for listening.
	 */

	ListenTransConns = (XtransConnInfo *) malloc (
	    old_listen_count * sizeof (XtransConnInfo));

	ListenTransFds = (int *) malloc (old_listen_count * sizeof (int));

	ListenTransCount = 0;

	for (i = 0; i < old_listen_count; i++)
	{
	    char portnum[10];

	    if (old_listen[i].portnum != ListenPort)
		continue;		/* this should never happen */
	    else
		sprintf (portnum, "%d", old_listen[i].portnum);

	    if ((ListenTransConns[ListenTransCount] =
		_FontTransReopenCOTSServer (old_listen[i].trans_id,
		old_listen[i].fd, portnum)) != NULL)
	    {
		ListenTransFds[ListenTransCount] = old_listen[i].fd;
		FD_SET (old_listen[i].fd, &WellKnownConnections);

		NoticeF("reusing existing file descriptor %d\n",
		    old_listen[i].fd);

		ListenTransCount++;
	    }
	}
    } else {
	char port[20];
	int partial;

	sprintf (port, "%d", ListenPort);

	if ((_FontTransMakeAllCOTSServerListeners (port, &partial,
	    &ListenTransCount, &ListenTransConns) >= 0) &&
	    (ListenTransCount >= 1))
	{
	    ListenTransFds = (int *) malloc (ListenTransCount * sizeof (int));

	    for (i = 0; i < ListenTransCount; i++)
	    {
		int fd = _FontTransGetConnectionNumber (ListenTransConns[i]);

		ListenTransFds[i] = fd;
		FD_SET (fd, &WellKnownConnections);
	    }
	}
    }

    if (! XFD_ANYSET(&WellKnownConnections))
	FatalError("cannot establish any listening sockets\n");

    /* set up all the signal handlers */
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_RESTART;
#define HANDLE_SIGNAL(s, h)	act.sa_handler = h; sigaction(s, &act, NULL)

    HANDLE_SIGNAL(SIGPIPE, SIG_IGN);
    HANDLE_SIGNAL(SIGHUP, AutoResetServer);
    HANDLE_SIGNAL(SIGINT, GiveUp);
    HANDLE_SIGNAL(SIGTERM, GiveUp);
    HANDLE_SIGNAL(SIGUSR1, ServerReconfig);
    HANDLE_SIGNAL(SIGUSR2, ServerCacheFlush);
    HANDLE_SIGNAL(SIGCHLD, CleanupChild);

    XFD_COPYSET (&WellKnownConnections, &AllSockets);
}