clean up xwayland lock/socket init code

This commit is contained in:
Mike Blumenkrantz 2015-07-02 13:55:42 -04:00
parent 2fe9f7c5e8
commit fa3c3b0e22
1 changed files with 55 additions and 50 deletions

View File

@ -28,31 +28,32 @@ struct _E_XWayland_Server
static E_XWayland_Server *exs; static E_XWayland_Server *exs;
/* local functions */ /* local functions */
static Eina_Bool static int
_lock_create(char *lock) _lock_create(int lock)
{ {
char pid[16], *end; char pid[16], *end;
int fd, size; int fd, size;
pid_t opid; pid_t opid;
fd = open(lock, (O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL), 0444); /* assemble lock file name */
snprintf(exs->lock, sizeof(exs->lock), "/tmp/.X%d-lock", lock);
fd = open(exs->lock, (O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL), 0444);
if ((fd < 0) && (errno == EEXIST)) if ((fd < 0) && (errno == EEXIST))
{ {
fd = open(lock, (O_CLOEXEC | O_RDONLY)); fd = open(exs->lock, (O_CLOEXEC | O_RDONLY));
if ((fd < 0) || (read(fd, pid, 11) != 11)) if ((fd < 0) || (read(fd, pid, 11) != 11))
{ {
ERR("Could not read XWayland lock file: %m"); ERR("Could not read XWayland lock file: %m");
if (fd >= 0) close(fd); if (fd >= 0) close(fd);
errno = EEXIST; return EEXIST;
return EINA_FALSE;
} }
opid = strtol(pid, &end, 0); opid = strtol(pid, &end, 0);
if ((end != (pid + 10))) if ((end != (pid + 10)))
{ {
if (fd >= 0) close(fd); if (fd >= 0) close(fd);
errno = EEXIST; return EEXIST;
return EINA_FALSE;
} }
if ((kill(opid, 0) < 0) && (errno == ESRCH)) if ((kill(opid, 0) < 0) && (errno == ESRCH))
@ -60,35 +61,31 @@ _lock_create(char *lock)
/* close stale lock file */ /* close stale lock file */
if (fd >= 0) close(fd); if (fd >= 0) close(fd);
if (unlink(lock)) if (unlink(exs->lock))
errno = EEXIST; return EEXIST;
else return EAGAIN;
errno = EAGAIN;
return EINA_FALSE;
} }
close(fd); close(fd);
errno = EEXIST; return EEXIST;
return EINA_FALSE;
} }
else if (fd < 0) else if (fd < 0)
{ {
ERR("Could not create XWayland lock file: %m"); ERR("Could not create XWayland lock file: %m");
return EINA_FALSE; return 0;
} }
/* use the pid of the wayland compositor */ /* use the pid of the wayland compositor */
size = snprintf(pid, sizeof(pid), "%10d\n", getpid()); size = snprintf(pid, sizeof(pid), "%10d\n", getpid());
if (write(fd, pid, size) != size) if (write(fd, pid, size) != size)
{ {
unlink(lock); unlink(exs->lock);
close(fd); close(fd);
return EINA_FALSE; return 0;
} }
close(fd); close(fd);
return EINA_TRUE; return 1;
} }
static int static int
@ -269,6 +266,28 @@ _cb_signal_event(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
return ECORE_CALLBACK_CANCEL; return ECORE_CALLBACK_CANCEL;
} }
static Eina_Bool
setup_lock(void)
{
do
{
/* try to create the xserver lock file */
switch (_lock_create(exs->disp))
{
case EEXIST:
exs->disp++;
case EAGAIN:
continue;
case 0:
free(exs);
return EINA_FALSE;
default:
return EINA_TRUE;
}
} while (1);
return EINA_FALSE;
}
/* module functions */ /* module functions */
E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "XWayland" }; E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "XWayland" };
@ -292,44 +311,30 @@ e_modapi_init(E_Module *m)
/* default display to zero */ /* default display to zero */
exs->disp = 0; exs->disp = 0;
lock: do
/* assemble lock file name */
snprintf(exs->lock, sizeof(exs->lock), "/tmp/.X%d-lock", exs->disp);
/* try to create the xserver lock file */
if (!_lock_create(exs->lock))
{ {
if (errno == EAGAIN) if (!setup_lock()) return NULL;
goto lock;
else if (errno == EEXIST) /* try to bind abstract socket */
exs->abs_fd = _abstract_socket_bind(exs->disp);
if ((exs->abs_fd < 0) && (errno == EADDRINUSE))
{ {
exs->disp++; exs->disp++;
goto lock; unlink(exs->lock);
continue;
} }
else
/* try to bind unix socket */
exs->unx_fd = _unix_socket_bind(exs->disp);
if (exs->unx_fd < 0)
{ {
unlink(exs->lock);
close(exs->abs_fd);
free(exs); free(exs);
return NULL; return NULL;
} }
} break;
} while (1);
/* try to bind abstract socket */
exs->abs_fd = _abstract_socket_bind(exs->disp);
if ((exs->abs_fd < 0) && (errno == EADDRINUSE))
{
exs->disp++;
unlink(exs->lock);
goto lock;
}
/* try to bind unix socket */
if ((exs->unx_fd = _unix_socket_bind(exs->disp)) < 0)
{
unlink(exs->lock);
close(exs->abs_fd);
free(exs);
return NULL;
}
/* assemble x11 display name and set it */ /* assemble x11 display name and set it */
snprintf(disp, sizeof(disp), ":%d", exs->disp); snprintf(disp, sizeof(disp), ":%d", exs->disp);