summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--startx.cpp66
-rw-r--r--startx.man140
-rw-r--r--xinit.c638
-rw-r--r--xinit.man192
-rw-r--r--xinitrc.cpp33
5 files changed, 1069 insertions, 0 deletions
diff --git a/startx.cpp b/startx.cpp
new file mode 100644
index 0000000..3044ad6
--- /dev/null
+++ b/startx.cpp
@@ -0,0 +1,66 @@
+XCOMM!/bin/sh
+
+XCOMM $Xorg: startx.cpp,v 1.3 2000/08/17 19:54:29 cpqbld Exp $
+XCOMM
+XCOMM This is just a sample implementation of a slightly less primitive
+XCOMM interface than xinit. It looks for user .xinitrc and .xserverrc
+XCOMM files, then system xinitrc and xserverrc files, else lets xinit choose
+XCOMM its default. The system xinitrc should probably do things like check
+XCOMM for .Xresources files and merge them in, startup up a window manager,
+XCOMM and pop a clock and serveral xterms.
+XCOMM
+XCOMM Site administrators are STRONGLY urged to write nicer versions.
+XCOMM
+
+userclientrc=$HOME/.xinitrc
+userserverrc=$HOME/.xserverrc
+sysclientrc=XINITDIR/xinitrc
+sysserverrc=XINITDIR/xserverrc
+clientargs=""
+serverargs=""
+
+if [ -f $userclientrc ]; then
+ clientargs=$userclientrc
+else if [ -f $sysclientrc ]; then
+ clientargs=$sysclientrc
+fi
+fi
+
+if [ -f $userserverrc ]; then
+ serverargs=$userserverrc
+else if [ -f $sysserverrc ]; then
+ serverargs=$sysserverrc
+fi
+fi
+
+whoseargs="client"
+while [ "x$1" != "x" ]; do
+ case "$1" in
+ /''*|\.*) if [ "$whoseargs" = "client" ]; then
+ clientargs="$1"
+ else
+ serverargs="$1"
+ fi ;;
+ --) whoseargs="server" ;;
+ *) if [ "$whoseargs" = "client" ]; then
+ clientargs="$clientargs $1"
+ else
+ serverargs="$serverargs $1"
+ fi ;;
+ esac
+ shift
+done
+
+xinit $clientargs -- $serverargs
+
+/*
+ * various machines need special cleaning up
+ */
+#ifdef macII
+Xrepair
+screenrestore
+#endif
+
+#ifdef sun
+kbd_mode -a
+#endif
diff --git a/startx.man b/startx.man
new file mode 100644
index 0000000..5d36ed8
--- /dev/null
+++ b/startx.man
@@ -0,0 +1,140 @@
+.\" $Xorg: startx.man,v 1.4 2001/02/09 02:05:49 xorgcvs Exp $
+.\" Copyright 1993, 1998 The Open Group
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of The Open Group shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from The Open Group.
+.TH STARTX 1 "Release 6.4" "X Version 11"
+.SH NAME
+startx \- initialize an X session
+.SH SYNOPSIS
+.B startx
+[ [
+.I client
+]
+.I options
+\&\.\|.\|. ] [
+.B \-\^\-
+[
+.I server
+]
+.I options
+\&.\|.\|. ]
+.SH DESCRIPTION
+NOTE: The \fIstartx\fP script supplied with the X11 distribution is a sample
+designed more as a base for customization than as a
+finished product. Site administrators are urged to customize it for
+their site. And to update this manual page when they do!
+.PP
+The \fIstartx\fP script is a front end to \fIxinit\fP that provides a
+somewhat nicer user interface for running a single session of the X
+Window System. It is typically run with no arguments.
+.PP
+To determine the client to run,
+.I startx
+first looks for a file called
+.I .xinitrc
+in the user's home directory. If that is not found, it uses
+the file
+.I xinitrc
+in the
+.I xinit
+library directory.
+If command line client options are given, they override this
+behavior.
+To determine the server to run,
+.I startx
+first looks for a file called
+.I .xserverrc
+in the user's home directory. If that is not found, it uses
+the file
+.I xserverrc
+in the
+.I xinit
+library directory.
+If command line server options are given, they override this
+behavior. Users rarely need to provide a
+.I .xserverrc
+file.
+See the
+.IR xinit (1)
+manual page for more details on the arguments.
+.PP
+The
+.I .xinitrc
+is typically a shell script which starts many clients according to the
+user's preference. When this shell script exits,
+.I startx
+kills the server and performs any other session shutdown needed.
+Most of the clients started by
+.I .xinitrc
+should be run in the background. The last client should run in the
+foreground; when it exits, the session will exit. People often choose
+a session manager, window manager, or \fIxterm\fP as the ``magic'' client.
+.SH EXAMPLE
+.PP
+Below is a sample \fI\.xinitrc\fP that starts several applications and
+leaves the window manager running as the ``last'' application. Assuming that
+the window manager has been configured properly, the user
+then chooses the ``Exit'' menu item to shut down X.
+.sp
+.in +4
+.nf
+xrdb \-load $HOME/.Xresources
+xsetroot \-solid gray &
+xbiff \-geometry \-430+5 &
+oclock \-geometry 75x75\-0\-0 &
+xload \-geometry \-80\-0 &
+xterm \-geometry +0+60 \-ls &
+xterm \-geometry +0\-100 &
+xconsole \-geometry \-0+0 \-fn 5x7 &
+exec twm
+.fi
+.in -4
+.SH "ENVIRONMENT VARIABLES"
+.TP 25
+DISPLAY
+This variable gets set to the name of the display to which clients should
+connect. Note that this gets
+.I set,
+not read.
+.SH FILES
+.TP 25
+.I $(HOME)/.xinitrc
+Client to run. Typically a shell script which runs many programs in
+the background.
+.TP 25
+.I $(HOME)/.xserverrc
+Server to run. The default is
+.I X.
+.TP 25
+.I <XRoot>/lib/X11/xinit/xinitrc
+Client to run if the user has no
+.I .xinitrc
+file. <XRoot> refers to the root of the X11 install tree.
+.TP 25
+.I <XRoot>/lib/X11/xinit/xserverrc
+Client to run if the user has no
+.I .xserverrc
+file. This is only needed if the server needs special arguments or is
+not named. <XRoot> refers to the root of the X11 install tree.
+.SH "SEE ALSO"
+.IR xinit (1)
diff --git a/xinit.c b/xinit.c
new file mode 100644
index 0000000..30d8c19
--- /dev/null
+++ b/xinit.c
@@ -0,0 +1,638 @@
+/* $Xorg: xinit.c,v 1.5 2001/02/09 02:05:49 xorgcvs Exp $ */
+
+/*
+
+Copyright 1986, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#include <X11/Xlib.h>
+#include <X11/Xos.h>
+#include <X11/Xmu/SysUtil.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#ifndef SYSV
+#include <sys/wait.h>
+#endif
+#include <errno.h>
+#include <setjmp.h>
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#else
+extern char *getenv();
+#endif
+extern char **environ;
+char **newenviron = NULL;
+
+#ifndef SHELL
+#define SHELL "sh"
+#endif
+
+#ifndef HAS_VFORK
+#define vfork() fork()
+#else
+#if defined(sun) && !defined(SVR4)
+#include <vfork.h>
+#endif
+#endif
+
+/* A/UX setpgid incorrectly removes the controlling terminal.
+ Per Posix, only setsid should do that. */
+#if !defined(X_NOT_POSIX) && !defined(macII)
+#define setpgrp setpgid
+#endif
+
+char *bindir = BINDIR;
+char *server_names[] = {
+#if defined(ultrix) && defined(mips)
+ "Xdec Digital color display on DECstation",
+#endif
+#ifdef sun /* Sun */
+ "Xsun Sun BW2, CG2, CG3, CG4, or CG6 on Sun 2, 3, 4, or 386i",
+ "Xsunmono Sun BW2 on Sun 2, 3, 4, or 386i ",
+ "Xsun24 Sun BW2, CG2, CG3, CG4, CG6, or CG8 on Sun 4",
+#endif
+#ifdef hpux /* HP */
+ "Xhp HP monochrome and colors displays on 9000/300 series",
+#endif
+#ifdef ibm /* IBM */
+ "Xibm IBM AED, APA, 8514a, megapel, VGA displays on PC/RT",
+#endif
+#ifdef macII /* MacII */
+ "XmacII Apple monochrome display on Macintosh II",
+#endif
+#ifdef XFREE86
+ "XF86_SVGA SVGA color display on i386 PC",
+ "XF86_Mono monochrome display on i386 PC",
+ "XF86_VGA16 16 color VGA display on i386 PC",
+ "XF86_S3 S3 color display on i386 PC",
+ "XF86_8514 IBM 8514/A color display on i386 PC",
+ "XF86_Mach8 ATI Mach8 color display on i386 PC",
+ "XF86_Mach32 ATI Mach32 color display on i386 PC",
+ "XF86_Mach64 ATI Mach64 color display on i386 PC",
+ "XF86_P9000 Weitek P9000 color display on i386 PC",
+ "XF86_AGX IIT AGX color display on i386 PC",
+ "XF86_W32 Tseng ET4000/W32 color display on i386 PC",
+ "XF86_I128 #9 I128 color display on i386 PC",
+#endif
+ NULL};
+
+#ifndef XINITRC
+#define XINITRC ".xinitrc"
+#endif
+char xinitrcbuf[256];
+
+#ifndef XSERVERRC
+#define XSERVERRC ".xserverrc"
+#endif
+char xserverrcbuf[256];
+
+#define TRUE 1
+#define FALSE 0
+#define OK_EXIT 0
+#define ERR_EXIT 1
+
+char *default_server = "X";
+char *default_display = ":0"; /* choose most efficient */
+char *default_client[] = {"xterm", "-geometry", "+1+1", "-n", "login", NULL};
+char *serverargv[100];
+char *clientargv[100];
+char **server = serverargv + 2; /* make sure room for sh .xserverrc args */
+char **client = clientargv + 2; /* make sure room for sh .xinitrc args */
+char *displayNum;
+char *program;
+Display *xd; /* server connection */
+#ifndef SYSV
+#if defined(SVR4) || defined(_POSIX_SOURCE) || defined(CSRG_BASED)
+int status;
+#else
+union wait status;
+#endif
+#endif /* SYSV */
+int serverpid = -1;
+int clientpid = -1;
+
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+
+
+static void shutdown();
+static void set_environment();
+
+#ifdef SIGNALRETURNSINT
+#define SIGVAL int
+#else
+#define SIGVAL void
+#endif
+
+SIGVAL sigCatch(sig)
+ int sig;
+{
+ signal(SIGQUIT, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
+ Error("unexpected signal %d\r\n", sig);
+ shutdown();
+ exit(1);
+}
+
+SIGVAL sigAlarm(sig)
+ int sig;
+{
+#if defined(SYSV) || defined(SVR4) || defined(linux)
+ signal (sig, sigAlarm);
+#endif
+}
+
+SIGVAL
+sigUsr1(sig)
+ int sig;
+{
+#if defined(SYSV) || defined(SVR4) || defined(linux)
+ signal (sig, sigUsr1);
+#endif
+}
+
+static void Execute (vec)
+ char **vec; /* has room from up above */
+{
+ execvp (vec[0], vec);
+ if (access (vec[0], R_OK) == 0) {
+ vec--; /* back it up to stuff shell in */
+ vec[0] = SHELL;
+ execvp (vec[0], vec);
+ }
+ return;
+}
+
+main(argc, argv)
+int argc;
+register char **argv;
+{
+ register char **sptr = server;
+ register char **cptr = client;
+ register char **ptr;
+ int pid;
+ int client_given = 0, server_given = 0;
+ int client_args_given = 0, server_args_given = 0;
+ int start_of_client_args, start_of_server_args;
+
+ program = *argv++;
+ argc--;
+
+ /*
+ * copy the client args.
+ */
+ if (argc == 0 ||
+ (**argv != '/' && **argv != '.')) {
+ for (ptr = default_client; *ptr; )
+ *cptr++ = *ptr++;
+#ifdef sun
+ /*
+ * If running on a sun, and if WINDOW_PARENT isn't defined,
+ * that means SunWindows isn't running, so we should pass
+ * the -C flag to xterm so that it sets up a console.
+ */
+ if ( getenv("WINDOW_PARENT") == NULL )
+ *cptr++ = "-C";
+#endif /* sun */
+ } else {
+ client_given = 1;
+ }
+ start_of_client_args = (cptr - client);
+ while (argc && strcmp(*argv, "--")) {
+ client_args_given++;
+ *cptr++ = *argv++;
+ argc--;
+ }
+ *cptr = NULL;
+ if (argc) {
+ argv++;
+ argc--;
+ }
+
+ /*
+ * Copy the server args.
+ */
+ if (argc == 0 ||
+ (**argv != '/' && **argv != '.')) {
+ *sptr++ = default_server;
+ } else {
+ server_given = 1;
+ *sptr++ = *argv++;
+ argc--;
+ }
+ if (argc > 0 && (argv[0][0] == ':' && isdigit(argv[0][1])))
+ displayNum = *argv;
+ else
+ displayNum = *sptr++ = default_display;
+
+ start_of_server_args = (sptr - server);
+ while (--argc >= 0) {
+ server_args_given++;
+ *sptr++ = *argv++;
+ }
+ *sptr = NULL;
+
+ /*
+ * if no client arguments given, check for a startup file and copy
+ * that into the argument list
+ */
+ if (!client_given) {
+ char *cp;
+ Bool required = False;
+
+ xinitrcbuf[0] = '\0';
+ if ((cp = getenv ("XINITRC")) != NULL) {
+ strcpy (xinitrcbuf, cp);
+ required = True;
+ } else if ((cp = getenv ("HOME")) != NULL) {
+ (void) sprintf (xinitrcbuf, "%s/%s", cp, XINITRC);
+ }
+ if (xinitrcbuf[0]) {
+ if (access (xinitrcbuf, F_OK) == 0) {
+ client += start_of_client_args - 1;
+ client[0] = xinitrcbuf;
+ } else if (required) {
+ fprintf (stderr,
+ "%s: warning, no client init file \"%s\"\n",
+ program, xinitrcbuf);
+ }
+ }
+ }
+
+ /*
+ * if no server arguments given, check for a startup file and copy
+ * that into the argument list
+ */
+ if (!server_given) {
+ char *cp;
+ Bool required = False;
+
+ xserverrcbuf[0] = '\0';
+ if ((cp = getenv ("XSERVERRC")) != NULL) {
+ strcpy (xserverrcbuf, cp);
+ required = True;
+ } else if ((cp = getenv ("HOME")) != NULL) {
+ (void) sprintf (xserverrcbuf, "%s/%s", cp, XSERVERRC);
+ }
+ if (xserverrcbuf[0]) {
+ if (access (xserverrcbuf, F_OK) == 0) {
+ server += start_of_server_args - 1;
+ server[0] = xserverrcbuf;
+ } else if (required) {
+ fprintf (stderr,
+ "%s: warning, no server init file \"%s\"\n",
+ program, xserverrcbuf);
+ }
+ }
+ }
+
+
+ /*
+ * put the display name into the environment
+ */
+ set_environment ();
+
+ /*
+ * Start the server and client.
+ */
+ signal(SIGQUIT, sigCatch);
+ signal(SIGINT, sigCatch);
+ signal(SIGHUP, sigCatch);
+ signal(SIGPIPE, sigCatch);
+ signal(SIGALRM, sigAlarm);
+ signal(SIGUSR1, sigUsr1);
+ if (startServer(server) > 0
+ && startClient(client) > 0) {
+ pid = -1;
+ while (pid != clientpid && pid != serverpid)
+ pid = wait(NULL);
+ }
+ signal(SIGQUIT, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
+
+ shutdown();
+
+ if (serverpid < 0 )
+ Fatal("Server error.\n");
+ if (clientpid < 0)
+ Fatal("Client error.\n");
+ exit(OK_EXIT);
+}
+
+
+/*
+ * waitforserver - wait for X server to start up
+ */
+
+waitforserver()
+{
+ int ncycles = 120; /* # of cycles to wait */
+ int cycles; /* Wait cycle count */
+
+ for (cycles = 0; cycles < ncycles; cycles++) {
+ if ((xd = XOpenDisplay(displayNum))) {
+ return(TRUE);
+ }
+ else {
+#define MSG "X server to begin accepting connections"
+ if (!processTimeout (1, MSG))
+ break;
+#undef MSG
+ }
+ }
+
+ fprintf (stderr, "giving up.\r\n");
+ return(FALSE);
+}
+
+/*
+ * return TRUE if we timeout waiting for pid to exit, FALSE otherwise.
+ */
+processTimeout(timeout, string)
+ int timeout;
+ char *string;
+{
+ int i = 0, pidfound = -1;
+ static char *laststring;
+
+ for (;;) {
+#ifdef SYSV
+ alarm(1);
+ if ((pidfound = wait(NULL)) == serverpid)
+ break;
+ alarm(0);
+#else /* SYSV */
+#if defined(SVR4) || defined(_POSIX_SOURCE)
+ if ((pidfound = waitpid(serverpid, &status, WNOHANG)) == serverpid)
+ break;
+#else
+ if ((pidfound = wait3(&status, WNOHANG, NULL)) == serverpid)
+ break;
+#endif
+#endif /* SYSV */
+ if (timeout) {
+ if (i == 0 && string != laststring)
+ fprintf(stderr, "\r\nwaiting for %s ", string);
+ else
+ fprintf(stderr, ".");
+ fflush(stderr);
+ }
+ if (timeout)
+ sleep (1);
+ if (++i > timeout)
+ break;
+ }
+ if ( i > 0 ) fputc( '\n', stderr ); /* tidy up after message */
+ laststring = string;
+ return( serverpid != pidfound );
+}
+
+startServer(server)
+ char *server[];
+{
+ serverpid = vfork();
+ switch(serverpid) {
+ case 0:
+ /*
+ * don't hang on read/write to control tty
+ */
+#ifdef SIGTTIN
+ (void) signal(SIGTTIN, SIG_IGN);
+#endif
+#ifdef SIGTTOU
+ (void) signal(SIGTTOU, SIG_IGN);
+#endif
+ /*
+ * ignore SIGUSR1 in child. The server
+ * will notice this and send SIGUSR1 back
+ * at xinit when ready to accept connections
+ */
+ (void) signal(SIGUSR1, SIG_IGN);
+ /*
+ * prevent server from getting sighup from vhangup()
+ * if client is xterm -L
+ */
+ setpgrp(0,getpid());
+
+ Execute (server);
+ Error ("no server \"%s\" in PATH\n", server[0]);
+ {
+ char **cpp;
+
+ fprintf (stderr,
+"\nUse the -- option, or make sure that %s is in your path and\n",
+ bindir);
+ fprintf (stderr,
+"that \"%s\" is a program or a link to the right type of server\n",
+ server[0]);
+ fprintf (stderr,
+"for your display. Possible server names include:\n\n");
+ for (cpp = server_names; *cpp; cpp++) {
+ fprintf (stderr, " %s\n", *cpp);
+ }
+ fprintf (stderr, "\n");
+ }
+ exit (ERR_EXIT);
+
+ break;
+ case -1:
+ break;
+ default:
+ /*
+ * don't nice server
+ */
+#ifdef PRIO_PROCESS
+ setpriority( PRIO_PROCESS, serverpid, -1 );
+#endif
+
+ errno = 0;
+ if (! processTimeout(0, "")) {
+ serverpid = -1;
+ break;
+ }
+ /*
+ * kludge to avoid race with TCP, giving server time to
+ * set his socket options before we try to open it,
+ * either use the 15 second timeout, or await SIGUSR1.
+ *
+ * If your machine is substantially slower than 15 seconds,
+ * you can easily adjust this value.
+ */
+ alarm (15);
+ pause ();
+ alarm (0);
+
+ if (waitforserver() == 0) {
+ Error("unable to connect to X server\r\n");
+ shutdown();
+ serverpid = -1;
+ }
+ break;
+ }
+
+ return(serverpid);
+}
+
+startClient(client)
+ char *client[];
+{
+ if ((clientpid = vfork()) == 0) {
+ setuid(getuid());
+ setpgrp(0, getpid());
+ environ = newenviron;
+ Execute (client);
+ Error ("no program named \"%s\" in PATH\r\n", client[0]);
+ fprintf (stderr,
+"\nSpecify a program on the command line or make sure that %s\r\n", bindir);
+ fprintf (stderr,
+"is in your path.\r\n");
+ fprintf (stderr, "\n");
+ exit (ERR_EXIT);
+ }
+ return (clientpid);
+}
+
+#if !defined(X_NOT_POSIX) || defined(SYSV)
+#define killpg(pgrp, sig) kill(-(pgrp), sig)
+#endif
+
+static jmp_buf close_env;
+
+static int ignorexio (dpy)
+ Display *dpy;
+{
+ fprintf (stderr, "%s: connection to X server lost.\r\n", program);
+ longjmp (close_env, 1);
+ /*NOTREACHED*/
+}
+
+static
+void shutdown()
+{
+ /* have kept display opened, so close it now */
+ if (clientpid > 0) {
+ XSetIOErrorHandler (ignorexio);
+ if (! setjmp(close_env)) {
+ XCloseDisplay(xd);
+ }
+
+ /* HUP all local clients to allow them to clean up */
+ errno = 0;
+ if ((killpg(clientpid, SIGHUP) != 0) &&
+ (errno != ESRCH))
+ Error("can't send HUP to process group %d\r\n",
+ clientpid);
+ }
+
+ if (serverpid < 0)
+ return;
+ errno = 0;
+ if (killpg(serverpid, SIGTERM) < 0) {
+ if (errno == EPERM)
+ Fatal("Can't kill X server\r\n");
+ if (errno == ESRCH)
+ return;
+ }
+ if (! processTimeout(10, "X server to shut down")) {
+ fprintf (stderr, "\r\n");
+ return;
+ }
+
+ fprintf(stderr,
+ "\r\n%s: X server slow to shut down, sending KILL signal.\r\n",
+ program);
+ fflush(stderr);
+ errno = 0;
+ if (killpg(serverpid, SIGKILL) < 0) {
+ if (errno == ESRCH)
+ return;
+ }
+ if (processTimeout(3, "server to die")) {
+ fprintf (stderr, "\r\n");
+ Fatal("Can't kill server\r\n");
+ }
+ fprintf (stderr, "\r\n");
+ return;
+}
+
+
+/*
+ * make a new copy of environment that has room for DISPLAY
+ */
+
+static void set_environment ()
+{
+ int nenvvars;
+ char **newPtr, **oldPtr;
+ static char displaybuf[256];
+
+ /* count number of environment variables */
+ for (oldPtr = environ; *oldPtr; oldPtr++) ;
+
+ nenvvars = (oldPtr - environ);
+ newenviron = (char **) malloc ((nenvvars + 2) * sizeof(char **));
+ if (!newenviron) {
+ fprintf (stderr,
+ "%s: unable to allocate %d pointers for environment\n",
+ program, nenvvars + 2);
+ exit (1);
+ }
+
+ /* put DISPLAY=displayname as first element */
+ strcpy (displaybuf, "DISPLAY=");
+ strcpy (displaybuf + 8, displayNum);
+ newPtr = newenviron;
+ *newPtr++ = displaybuf;
+
+ /* copy pointers to other variables */
+ for (oldPtr = environ; *oldPtr; oldPtr++) {
+ if (strncmp (*oldPtr, "DISPLAY=", 8) != 0) {
+ *newPtr++ = *oldPtr;
+ }
+ }
+ *newPtr = NULL;
+ return;
+}
+
+Fatal(fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
+ char *fmt;
+{
+ Error(fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
+ exit(ERR_EXIT);
+}
+
+Error(fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
+ char *fmt;
+{
+ fprintf(stderr, "%s: ", program);
+ fprintf (stderr, "%s (errno %d): ", strerror(errno), errno);
+ fprintf(stderr, fmt, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
+}
diff --git a/xinit.man b/xinit.man
new file mode 100644
index 0000000..23e2315
--- /dev/null
+++ b/xinit.man
@@ -0,0 +1,192 @@
+.\" $Xorg: xinit.man,v 1.4 2001/02/09 02:05:49 xorgcvs Exp $
+.\" Copyright 1988, 1998 The Open Group
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of The Open Group shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from The Open Group.
+.TH XINIT 1 "Release 6.4" "X Version 11"
+.SH NAME
+xinit \- X Window System initializer
+.SH SYNOPSIS
+.B xinit
+[ [
+.I client
+]
+.I options
+] [
+.B \-\^\-
+[
+.I server
+] [
+.I display
+]
+.I options
+]
+.SH DESCRIPTION
+The \fIxinit\fP program is used to start the X Window System server and a first
+client program on systems that
+cannot start X directly from \fI/etc/init\fP or in environments
+that use multiple window systems. When this first client exits,
+\fIxinit\fP will kill the X server and then terminate.
+.PP
+If no specific client program is given on the command line,
+\fIxinit\fP will look for a file in the user's home directory
+called \fI.xinitrc\fP to run as a shell script to start up client programs.
+If no such file exists, \fIxinit\fP will use the following as a default:
+.sp
+ xterm \-geometry +1+1 \-n login \-display :0
+.sp
+.PP
+If no specific server program is given on the command line,
+\fIxinit\fP will look for a file in the user's home directory
+called \fI.xserverrc\fP to run as a shell script to start up the server.
+If no such file exists, \fIxinit\fP will use the following as a default:
+.sp
+ X :0
+.sp
+Note that this assumes that there is a program named \fIX\fP in the current
+search path. However, servers are usually named \fIXdisplaytype\fP where
+\fIdisplaytype\fP is the type of graphics display which is driven by this
+server. The site administrator should, therefore, make a link to the
+appropriate type of server on the machine, or create a shell script that
+runs \fIxinit\fP with the appropriate server.
+.PP
+An important point is that programs which are run by \fI\.xinitrc\fP
+should be run in the background if they do
+not exit right away, so that they don't prevent other programs from
+starting up.
+However, the last long-lived program started (usually
+a window manager or terminal emulator) should be
+left in the foreground so that the script won't exit (which
+indicates that the user is done and that \fIxinit\fP should exit).
+.PP
+An alternate client and/or server may be specified on the
+command line. The desired client program and its arguments should be given
+as the first command line arguments to \fIxinit\fP. To specify a particular
+server command line, append a double dash (\-\^\-) to the \fIxinit\fP command
+line (after any client and arguments) followed by the desired server command.
+.PP
+Both the client program name and the server program name must begin with a
+slash (/) or a period (.). Otherwise, they are treated as an arguments to be
+appended to their respective startup lines. This makes it possible to
+add arguments (for example, foreground and background colors) without
+having to retype the whole command line.
+.PP
+If an explicit server name is not given and the first argument following the
+double dash (\-\^\-) is a colon followed by a digit, \fIxinit\fP will use that
+number as the display
+number instead of zero. All remaining arguments are appended to the server
+command line.
+.PP
+.SH EXAMPLES
+Below are several examples of how command line arguments in \fIxinit\fP are
+used.
+.TP 8
+.B "xinit"
+This will start up a server named \fIX\fP and run the user's \fI\.xinitrc\fP,
+if it exists, or else start an \fIxterm\fP.
+.TP 8
+.B "xinit \-\^\- /usr/X11R6/bin/Xqdss :1"
+This is how one could start a specific type of server on an alternate display.
+.TP 8
+.B "xinit \-geometry =80x65+10+10 \-fn 8x13 \-j \-fg white \-bg navy"
+This will start up a server named \fIX\fP, and will append the given
+arguments to the default \fIxterm\fP command. It will ignore \fI\.xinitrc\fP.
+.TP 8
+.B "xinit \-e widgets \-\^\- ./Xsun \-l \-c"
+This will use the command \fI\.\/Xsun \-l \-c\fP to start the server and will
+append the arguments \fI\-e widgets\fP to the default \fIxterm\fP command.
+.TP 8
+.B "xinit /usr/ucb/rsh fasthost cpupig \-display ws:1 \-\^\- :1 \-a 2 \-t 5"
+This will start a server named \fIX\fP on display 1 with the arguments
+\fI\-a 2 \-t 5\fP. It will then start a remote shell on the machine
+\fBfasthost\fP in which it will run the command \fIcpupig\fP, telling it
+to display back on the local workstation.
+.PP
+Below is a sample \fI\.xinitrc\fP that starts a clock, several terminals, and
+leaves the window manager running as the ``last'' application. Assuming that
+the window manager has been configured properly, the user
+then chooses the ``Exit'' menu item to shut down X.
+.sp
+.in +8
+.nf
+xrdb \-load $HOME/.Xresources
+xsetroot \-solid gray &
+xclock \-g 50x50\-0+0 \-bw 0 &
+xload \-g 50x50\-50+0 \-bw 0 &
+xterm \-g 80x24+0+0 &
+xterm \-g 80x24+0\-0 &
+twm
+.fi
+.in -8
+.sp
+Sites that want to create a common startup environment could simply create
+a default \fI\.xinitrc\fP that references a site-wide startup file:
+.sp
+.in +8
+.nf
+#!/bin/sh
+\&. /usr/local/lib/site.xinitrc
+.fi
+.in -8
+.sp
+Another approach is to write a script that starts \fIxinit\fP with a specific
+shell script. Such scripts are usually named \fIx11\fP, \fIxstart\fP, or
+\fIstartx\fP and are a convenient way to provide a simple interface for
+novice users:
+.sp
+.in +8
+.nf
+#!/bin/sh
+xinit /usr/local/lib/site.xinitrc \-\^\- /usr/X11R6/bin/X bc
+.fi
+.in -8
+.sp
+.SH "ENVIRONMENT VARIABLES"
+.TP 15
+.B DISPLAY
+This variable gets set to the name of the display to which clients should
+connect.
+.TP 15
+.B XINITRC
+This variable specifies an init file containing shell commands to start up the
+initial windows. By default, \fI\.xinitrc\fP in the home directory will be
+used.
+.SH FILES
+.TP 15
+.I .xinitrc
+default client script
+.TP 15
+.I xterm
+client to run if \fI.xinitrc\fP does not exist
+.TP 15
+.I .xserverrc
+default server script
+.TP 15
+.I X
+server to run if \fI.xserverrc\fP does not exist
+.SH "SEE ALSO"
+.IR X (1),
+.IR startx (1),
+.IR Xserver (1),
+.IR xterm (1)
+.SH AUTHOR
+Bob Scheifler, MIT Laboratory for Computer Science
diff --git a/xinitrc.cpp b/xinitrc.cpp
new file mode 100644
index 0000000..641eede
--- /dev/null
+++ b/xinitrc.cpp
@@ -0,0 +1,33 @@
+XCOMM!/bin/sh
+XCOMM $Xorg: xinitrc.cpp,v 1.3 2000/08/17 19:54:30 cpqbld Exp $
+
+userresources=$HOME/.Xresources
+usermodmap=$HOME/.Xmodmap
+sysresources=XINITDIR/.Xresources
+sysmodmap=XINITDIR/.Xmodmap
+
+XCOMM merge in defaults and keymaps
+
+if [ -f $sysresources ]; then
+ xrdb -merge $sysresources
+fi
+
+if [ -f $sysmodmap ]; then
+ xmodmap $sysmodmap
+fi
+
+if [ -f $userresources ]; then
+ xrdb -merge $userresources
+fi
+
+if [ -f $usermodmap ]; then
+ xmodmap $usermodmap
+fi
+
+XCOMM start some nice programs
+
+twm &
+xclock -geometry 50x50-1+1 &
+xterm -geometry 80x50+494+51 &
+xterm -geometry 80x20+494-0 &
+exec xterm -geometry 80x66+0+0 -name login