summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packaging/xinit.manifest5
-rw-r--r--packaging/xinit.spec58
-rw-r--r--xinit.c119
3 files changed, 182 insertions, 0 deletions
diff --git a/packaging/xinit.manifest b/packaging/xinit.manifest
new file mode 100644
index 0000000..017d22d
--- /dev/null
+++ b/packaging/xinit.manifest
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
diff --git a/packaging/xinit.spec b/packaging/xinit.spec
new file mode 100644
index 0000000..4f3f83b
--- /dev/null
+++ b/packaging/xinit.spec
@@ -0,0 +1,58 @@
+%bcond_with x
+
+Name: xinit
+Version: 1.3.2
+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)
+BuildRequires: pkgconfig(xorg-macros) >= 1.8
+Requires: setxkbmap
+Requires: xauth
+Requires: xmodmap
+Requires: xrdb
+Requires: xsetroot
+Requires: xorg-x11-server-utils
+
+%if !%{with x}
+ExclusiveArch:
+%endif
+
+%description
+The xinit program is used to start the X Window System server and a
+first client program on systems that are not using a display manager
+such as xdm or in environments that use multiple window systems.
+When this first client exits, xinit will kill the X server and then
+terminate.
+
+%prep
+%setup -q
+cp %{SOURCE1001} .
+
+%build
+%configure --with-xinitdir=%{_sysconfdir}/X11/xinit/ CFLAGS="${CFLAGS} -D_F_EXIT_AFTER_XORG_AND_XCLIENT_LAUNCHED_ "
+make %{?_smp_mflags}
+
+%install
+%make_install
+rm -f %{buildroot}/usr/bin/startx
+
+%files
+%manifest %{name}.manifest
+%defattr(-,root,root)
+%license COPYING
+%config %{_sysconfdir}/X11/xinit/
+%{_bindir}/xinit
+%{_mandir}/man1/startx.1%{?ext_man}
+%{_mandir}/man1/xinit.1%{?ext_man}
+
+%changelog
diff --git a/xinit.c b/xinit.c
index 18e3e10..ee480c4 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,6 +108,9 @@ static Display *xd = NULL; /* server connection */
int status;
pid_t serverpid = -1;
pid_t clientpid = -1;
+#ifdef _F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
+pid_t wmpid = -1;
+#endif//_F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
volatile int gotSignal = 0;
static void Execute(char **vec);
@@ -110,6 +118,11 @@ static Bool waitforserver(void);
static Bool processTimeout(int timeout, const char *string);
static pid_t startServer(char *server[]);
static pid_t startClient(char *client[]);
+#ifdef _F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
+static void set_wm_user_groups();
+static pid_t startWM(void);
+#endif//_F_LAUNCH_WM_AFTER_LAUNCHING_SERVER_
+
static int ignorexio(Display *dpy);
static void shutdown(void);
static void set_environment(void);
@@ -291,7 +304,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
@@ -474,6 +493,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 pid_t
+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)
{