2012-08-09 13:15:30 -07:00
|
|
|
#include "entrance.h"
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
typedef struct Entrance_Xserver_
|
|
|
|
{
|
|
|
|
const char *dname;
|
|
|
|
Entrance_X_Cb start;
|
|
|
|
} Entrance_Xserver;
|
|
|
|
|
|
|
|
Entrance_Xserver *_xserver;
|
|
|
|
Ecore_Event_Handler *_handler_start;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* man Xserver
|
|
|
|
* SIGUSR1 This signal is used quite differently from either of the
|
|
|
|
* above. When the server starts, it checks to see if it has inherite
|
|
|
|
* SIGUSR1 as SIG_IGN instead of the usual SIG_DFL. In this case, the server
|
|
|
|
* sends a SIGUSR1 to its parent process after it has set up the various
|
|
|
|
* connection schemes. Xdm uses this feature to recognize when connecting to
|
|
|
|
* the server is possible.
|
|
|
|
* */
|
|
|
|
static void
|
|
|
|
_env_set(const char *dname)
|
|
|
|
{
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
snprintf(buf, sizeof(buf), "DISPLAY=%s", dname);
|
|
|
|
putenv(strdup(buf));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2014-01-08 15:04:44 -08:00
|
|
|
_xserver_start(void)
|
2012-08-09 13:15:30 -07:00
|
|
|
{
|
|
|
|
char *buf = NULL;
|
|
|
|
char **args = NULL;
|
|
|
|
pid_t pid;
|
|
|
|
|
2013-09-03 11:08:37 -07:00
|
|
|
PT("Launching xserver\n");
|
2012-08-09 13:15:30 -07:00
|
|
|
pid = fork();
|
|
|
|
if (!pid)
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
int num_token = 0;
|
|
|
|
entrance_close_log();
|
|
|
|
signal(SIGTTIN, SIG_IGN);
|
|
|
|
signal(SIGTTOU, SIG_IGN);
|
|
|
|
signal(SIGUSR1, SIG_IGN);
|
|
|
|
|
|
|
|
if (!(buf = strdup(entrance_config->command.xinit_args)))
|
|
|
|
goto xserver_error;
|
|
|
|
token = strtok(buf, " ");
|
|
|
|
while(token)
|
|
|
|
{
|
|
|
|
++num_token;
|
|
|
|
token = strtok(NULL, " ");
|
|
|
|
}
|
|
|
|
if (buf) free(buf);
|
|
|
|
if (num_token)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
if (!(buf = strdup(entrance_config->command.xinit_args)))
|
|
|
|
goto xserver_error;
|
|
|
|
if (!(args = calloc(num_token + 2, sizeof(char *))))
|
|
|
|
{
|
|
|
|
if (buf) free(buf);
|
|
|
|
goto xserver_error;
|
|
|
|
}
|
|
|
|
args[0] = (char *)entrance_config->command.xinit_path;
|
|
|
|
token = strtok(buf, " ");
|
|
|
|
++num_token;
|
|
|
|
for(i = 1; i < num_token; ++i)
|
|
|
|
{
|
|
|
|
if (token)
|
|
|
|
args[i] = token;
|
|
|
|
token = strtok(NULL, " ");
|
|
|
|
}
|
|
|
|
args[num_token] = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!(args = calloc(2, sizeof(char*))))
|
|
|
|
goto xserver_error;
|
|
|
|
args[0] = (char *)entrance_config->command.xinit_path;
|
|
|
|
args[1] = NULL;
|
|
|
|
}
|
|
|
|
execv(args[0], args);
|
|
|
|
if (buf) free(buf);
|
|
|
|
if (args) free(args);
|
2012-09-11 12:29:11 -07:00
|
|
|
PT("Couldn't launch Xserver ...\n");
|
2012-08-09 13:15:30 -07:00
|
|
|
}
|
|
|
|
return pid;
|
|
|
|
xserver_error:
|
|
|
|
_exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
2013-10-29 11:26:56 -07:00
|
|
|
_xserver_started(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
|
2012-08-09 13:15:30 -07:00
|
|
|
{
|
2012-09-11 12:29:11 -07:00
|
|
|
PT("xserver started\n");
|
2012-08-09 13:15:30 -07:00
|
|
|
_env_set(_xserver->dname);
|
|
|
|
_xserver->start(_xserver->dname);
|
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
entrance_xserver_init(Entrance_X_Cb start, const char *dname)
|
|
|
|
{
|
|
|
|
int pid;
|
|
|
|
char buf[64];
|
|
|
|
sigset_t newset;
|
|
|
|
sigemptyset(&newset);
|
|
|
|
|
|
|
|
_xserver = calloc(1, sizeof(Entrance_Xserver));
|
|
|
|
_xserver->dname = eina_stringshare_add(dname);
|
|
|
|
_xserver->start = start;
|
|
|
|
pid = _xserver_start();
|
|
|
|
snprintf(buf, sizeof(buf), "ENTRANCE_XPID=%d", pid);
|
|
|
|
putenv(strdup(buf));
|
2013-09-03 11:08:37 -07:00
|
|
|
PT("xserver adding signal user handler\n");
|
2012-08-09 13:15:30 -07:00
|
|
|
_handler_start = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
|
|
|
|
_xserver_started,
|
|
|
|
NULL);
|
|
|
|
return pid;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-01-08 15:04:44 -08:00
|
|
|
entrance_xserver_end(void)
|
2012-08-09 13:15:30 -07:00
|
|
|
{
|
2014-02-06 18:03:08 -08:00
|
|
|
const char *xpid;
|
2012-09-11 12:29:11 -07:00
|
|
|
PT("xserver end\n");
|
2014-02-06 18:03:08 -08:00
|
|
|
xpid = getenv("ENTRANCE_XPID");
|
|
|
|
if (xpid)
|
|
|
|
kill(atoi(xpid), SIGTERM);
|
|
|
|
|
2012-08-09 13:15:30 -07:00
|
|
|
unsetenv("ENTRANCE_XPID");
|
2014-03-07 04:40:32 -08:00
|
|
|
while (waitpid(-1, NULL, WNOHANG) > 0);
|
2012-08-09 13:15:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-01-08 15:04:44 -08:00
|
|
|
entrance_xserver_shutdown(void)
|
2012-08-09 13:15:30 -07:00
|
|
|
{
|
|
|
|
eina_stringshare_del(_xserver->dname);
|
|
|
|
free(_xserver);
|
|
|
|
ecore_event_handler_del(_handler_start);
|
|
|
|
}
|
|
|
|
|