summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packaging/xinit.spec11
-rw-r--r--xinit.c118
2 files changed, 126 insertions, 3 deletions
diff --git a/packaging/xinit.spec b/packaging/xinit.spec
index a6bc0b6..af6f5e0 100644
--- a/packaging/xinit.spec
+++ b/packaging/xinit.spec
@@ -1,12 +1,15 @@
Name: xinit
Version: 1.3.2
-Release: 0
+Release: 1
License: MIT
Summary: X Window System initializer
Url: http://xorg.freedesktop.org/
Group: System/X11/Utilities
Source0: http://xorg.freedesktop.org/releases/individual/app/%{name}-%{version}.tar.bz2
Source1001: xinit.manifest
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: dbus-devel
BuildRequires: libtool
BuildRequires: pkg-config
BuildRequires: pkgconfig(x11)
@@ -16,6 +19,8 @@ Requires: xauth
Requires: xmodmap
Requires: xrdb
Requires: xsetroot
+Requires: xorg-x11-server-utils
+Requires: xkeyboard-config
%description
The xinit program is used to start the X Window System server and a
@@ -29,7 +34,7 @@ terminate.
cp %{SOURCE1001} .
%build
-%configure --with-xinitdir=%{_sysconfdir}/X11/xinit/
+%configure --with-xinitdir=%{_sysconfdir}/X11/xinit/ CFLAGS="${CFLAGS} -D_F_EXIT_AFTER_XORG_AND_XCLIENT_LAUNCHED_ "
make %{?_smp_mflags}
%install
@@ -40,7 +45,7 @@ make %{?_smp_mflags}
%defattr(-,root,root)
%license COPYING
%config %{_sysconfdir}/X11/xinit/
-%{_bindir}/startx
+#%{_bindir}/startx
%{_bindir}/xinit
%{_mandir}/man1/startx.1%{?ext_man}
%{_mandir}/man1/xinit.1%{?ext_man}
diff --git a/xinit.c b/xinit.c
index 2ab817f..2c02402 100644
--- a/xinit.c
+++ b/xinit.c
@@ -40,6 +40,7 @@ in this Software without prior written authorization from The Open Group.
#include <errno.h>
#include <setjmp.h>
#include <stdarg.h>
+#include <grp.h>
#ifdef __APPLE__
#include <AvailabilityMacros.h>
@@ -95,6 +96,10 @@ static char *default_display = ":0"; /* choose most efficient */
static char *default_client[] = {"xterm", "-geometry", "+1+1", "-n", "login", NULL};
static char *serverargv[100];
static char *clientargv[100];
+#ifdef _F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
+static char *wmargv[100];
+static char **wm = wmargv;
+#endif//_F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
static char **server = serverargv + 2; /* make sure room for sh .xserverrc args */
static char **client = clientargv + 2; /* make sure room for sh .xinitrc args */
static char *displayNum = NULL;
@@ -103,12 +108,19 @@ static Display *xd = NULL; /* server connection */
int status;
int serverpid = -1;
int clientpid = -1;
+#ifdef _F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
+int wmpid = -1;
+#endif//_F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
volatile int gotSignal = 0;
static void Execute(char **vec);
static Bool waitforserver(void);
static Bool processTimeout(int timeout, char *string);
static int startServer(char *server[]);
+#ifdef _F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
+static void set_wm_user_groups();
+static int startWM(void);
+#endif//_F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
static int startClient(char *client[]);
static int ignorexio(Display *dpy);
static void shutdown(void);
@@ -291,7 +303,13 @@ main(int argc, char *argv[])
#endif
if (startServer(server) > 0
+#ifdef _F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
+ && startWM() > 0
+#endif//_F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
&& startClient(client) > 0) {
+#ifdef _F_EXIT_AFTER_XORG_AND_XCLIENT_LAUNCHED_
+ exit(0);
+#endif//_F_EXIT_AFTER_XORG_AND_XCLIENT_LAUNCHED_
pid = -1;
while (pid != clientpid && pid != serverpid
&& gotSignal == 0
@@ -473,6 +491,106 @@ startServer(char *server[])
return(serverpid);
}
+#ifdef _F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
+static void
+set_wm_user_groups()
+{
+ char *cp;
+ int uid = -1;
+ int gid = -1;
+
+ //get user id for wm
+ if(cp = getenv("WMUSERID"))
+ if (sscanf(cp, "%d", &uid) <= 0)
+ uid = -1;
+
+ //get group id for wm
+ if(cp = getenv("WMGROUPID"))
+ if (sscanf(cp, "%d", &gid) <= 0)
+ gid = -1;
+
+ //init groups
+ {
+ int res;
+ cp = getenv("WMUSER");
+
+ if(cp && (uid > 0) && (gid > 0))
+ {
+ res = initgroups(cp, (gid_t)gid);
+
+ if(res)
+ fprintf(stderr, "Failed to set groups !(errno=%d)\n", errno);
+ }
+ else
+ fprintf(stderr, "Failed to set groups !(getenv(WMUSER) : NULL)\n");
+ }
+
+ //set group id and effective group id
+ if((gid > 0) && setgid((gid_t)gid) && setegid((gid_t)gid))
+ fprintf(stderr, "Fail to set group id to %d. errno=%d\n", gid, errno);
+
+ //set user id and effective user id
+ if((uid > 0) && setuid((uid_t)uid) && seteuid((uid_t)uid))
+ fprintf(stderr, "Fail to set user id to %d. errno=%d\n", uid, errno);
+
+ //set USER environment variable
+ if(cp = getenv("WMUSER"))
+ setenv("USER", cp, 1);
+
+ //set HOME environment variable
+ if(cp = getenv("WMUSERHOME"))
+ setenv("HOME", cp, 1);
+}
+
+static int
+startWM(void)
+{
+ char *cp;
+ char wmrc_buf[256] = { 0, };
+
+ set_environment();
+
+ wmrc_buf[0] = '\0';
+ if ((cp = getenv("WMRC")) != NULL)
+ {
+ snprintf(wmrc_buf, sizeof(wmrc_buf), "%s", cp);
+ }
+ else
+ {
+ wmpid = 1;
+ return wmpid;
+ }
+
+ if(!access(wmrc_buf, F_OK))
+ wm[0] = wmrc_buf;
+ else
+ goto out;
+
+ wmpid = fork();
+
+ switch(wmpid) {
+ case 0:
+ setpgid(0,getpid());
+ set_wm_user_groups();
+
+ Execute(wm);
+
+ Error("unable to run wm\"%s\"", wm[0]);
+ exit(EXIT_FAILURE);
+ break;
+ case -1:
+ break;
+ default:
+ return wmpid;
+ }
+
+out:
+ wmpid = -1;
+
+ return(wmpid);
+}
+#endif//_F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
+
static void
setWindowPath(void)
{