diff options
-rw-r--r-- | packaging/xinit.manifest | 5 | ||||
-rw-r--r-- | packaging/xinit.spec | 58 | ||||
-rw-r--r-- | xinit.c | 119 |
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 @@ -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) { |