[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Revised 003b, 099u :-)



OK, I finally got correct versions of Konev's ported patches together
with the annotations.

-- 
Don't say I didn't warn you.
$Id: 003b_xfs_fixes.diff 2151 2005-01-24 16:54:48Z branden $

This patch by Branden Robinson, Matthieu Herrb, and Nikita V. Youshchenko.

os/utils.c:
  - Handle pid files the way most other Unix daemons do.  Use Matthieu
    Herrb's version of StorePid(), which refuses to open pre-existing pid
    files, and is more careful with the type of Pid_t.
  - Allow the user to specify the pid filename on the command line with a
    "-pid" option (courtesy of Nikita V. Youshchenko).
  - Add RemovePid() function which removes the process ID file, and
    register it with atexit() so that it is automatically invoked when xfs
    exits.
  - Sort options in usage message alphabetically.
  - Refer to "user ID" and "process ID" in diagnostic messages, not
    "userid" and "process-id".
  - Remove duplicate unconditional #include of stdlib.h.
  - Wrap long lines.
  - Whitespace police.

xfs.man:
  - Document the new "-pid" option (courtesy of Nikita V. Youshchenko).
  - Add "FUTURE DIRECTIONS" section.
  - Perform massive cleanup and reformatting.

Not submitted upstream yet.

Index: xc/programs/xfs/os/utils.c
===================================================================
--- xc/programs/xfs/os/utils.c	(revision 309)
+++ xc/programs/xfs/os/utils.c	(working copy)
@@ -3,7 +3,7 @@
  * misc os utilities
  */
 /*
- 
+
 Copyright 1990, 1991, 1998  The Open Group
 
 Permission to use, copy, modify, distribute, and sell this software and its
@@ -27,7 +27,7 @@
 in this Software without prior written authorization from The Open Group.
 
  * Copyright 1990, 1991 Network Computing Devices;
- * Portions Copyright 1987 by Digital Equipment Corporation 
+ * Portions Copyright 1987 by Digital Equipment Corporation
  *
  * Permission to use, copy, modify, distribute, and sell this software and
  * its documentation for any purpose is hereby granted without fee, provided
@@ -90,8 +90,6 @@
 #define SIGNALS_RESET_WHEN_CAUGHT
 #endif
 
-#include <stdlib.h>
-
 extern char *configfilename;
 static Bool dropPriv = FALSE; /* whether or not to drop root privileges */
 #ifdef DEFAULT_DAEMON
@@ -116,7 +114,8 @@
 static char *pidFile = XFSPIDDIR "/xfs.pid";
 static int  pidFd;
 static FILE *pidFilePtr;
-static int  StorePid (void);
+static long StorePid (void);
+static void RemovePid (void);
 
 /* ARGSUSED */
 SIGVAL
@@ -219,7 +218,9 @@
 static void
 usage(void)
 {
-    fprintf(stderr, "usage: %s [-config config_file] [-port tcp_port] [-droppriv] [-daemon] [-nodaemon] [-user user_name] [-ls listen_socket]\n",
+    fprintf(stderr, "usage: %s [-config config_file] [-daemon] [-droppriv]"
+                   " [-ls listen_socket] [-nodaemon] [-pid pid_file]"
+                   " [-port tcp_port] [-user user_name]\n",
 	    progname);
     exit(1);
 }
@@ -242,7 +243,7 @@
  *
  * [] denotes optional and ... denotes repitition.
  *
- * The string must be _exactly_ in the above format. 
+ * The string must be _exactly_ in the above format.
  */
 
 void
@@ -260,7 +261,7 @@
 	    count++;
 	ptr++;
     }
-  
+
     OldListenCount = count + 1;
     OldListen = (OldListenRec *) malloc (
 	OldListenCount * sizeof (OldListenRec));
@@ -349,6 +350,11 @@
 		configfilename = argv[++i];
 	    else
 		usage();
+       } else if (!strcmp(argv[i], "-pid")) {
+           if (argv[i + 1])
+               pidFile = argv[++i];
+           else
+               usage();
 	}
 #ifdef MEMBUG
 	else if ( strcmp( argv[i], "-alloc") == 0)
@@ -392,7 +398,7 @@
 FSalloc (unsigned long amount)
 {
     register pointer  ptr;
-	
+
     if ((long)amount < 0)
 	return 0;
     if (amount == 0)
@@ -462,21 +468,21 @@
 	FatalError("out of memory\n");
     return 0;
 }
-                    
+
 /*****************
  *  FSfree
- *    calls free 
- *****************/    
+ *    calls free
+ *****************/
 
 void
 FSfree(pointer ptr)
 {
 #ifdef MEMBUG
     if (ptr)
-	ffree((char *)ptr); 
+       ffree((char *)ptr);
 #else
     if (ptr)
-	free((char *)ptr); 
+       free((char *)ptr);
 #endif
 }
 
@@ -511,11 +517,12 @@
 	    }
 #endif /* QNX4 */
 	    if (setuid(pwent->pw_uid)) {
-		FatalError("fatal: couldn't set userid to %s user\n", user);
+               FatalError("fatal: couldn't set user ID to %s user\n", user);
 	    }
 	}
     } else if (dropPriv || userId) {
-	FatalError("fatal: -droppriv or -user flag specified, but xfs not run as root\n");
+       FatalError("fatal: -droppriv or -user flag specified, but xfs not"
+                  " invoked by root user\n");
     }
 }
 
@@ -523,48 +530,76 @@
 void
 SetDaemonState(void)
 {
-    int	    oldpid;
+    long       oldpid;
 
     if (becomeDaemon) {
 	BecomeDaemon();
 	if ((oldpid = StorePid ())) {
 	    if (oldpid == -1)
-		ErrorF ("error opening process-id file %s\n", pidFile);
+               ErrorF ("error opening process ID file %s\n", pidFile);
 	    else
 		ErrorF ("process-id file %s indicates another xfs is "
-			  "running (pid %d); exiting\n", pidFile, oldpid);
+                         "running (pid %ld); exiting\n", pidFile, oldpid);
 	    exit(1);
 	}
+       if (atexit (RemovePid))
+           ErrorF ("could not register RemovePid() with atexit()\n");
     }
 }
 
 
-static int
+static long
+/*
+ * Create and populate file storing process ID.
+ */
 StorePid (void)
 {
-    int		oldpid;
+    long       oldpid;
+    char       pidstr[11]; /* enough space for a 32-bit pid plus \0 */
+    size_t     pidstrlen;
 
-    if (pidFile[0] != '\0') {
-	pidFd = open (pidFile, O_RDWR);
-	if (pidFd == -1 && errno == ENOENT)
-	    pidFd = open (pidFile, O_RDWR|O_CREAT, 0666);
-	if (pidFd == -1 || !(pidFilePtr = fdopen (pidFd, "r+")))
+    if (pidFile[0] != '\0')
+    {
+       pidFd = open (pidFile, O_WRONLY|O_CREAT|O_EXCL, 0666);
+       if (pidFd == -1)
 	{
-	    ErrorF ("cannot open process-id file %s: %s\n", pidFile,
-		    strerror (errno));
-	    return -1;
+           if (errno == EEXIST)
+           {
+               /* pidFile already exists; see if we can open it */
+               pidFilePtr = fopen (pidFile, "r");
+               if (pidFilePtr == NULL)
+               {
+                   ErrorF ("cannot open process ID file %s for reading: "
+                           "%s\n", pidFile, strerror (errno));
+                   return -1;
+               }
+               if (fscanf (pidFilePtr, "%ld\n", &oldpid) != 1)
+               {
+                   ErrorF ("existing process ID file %s empty or contains "
+                           "garbage\n", pidFile);
+                   oldpid = -1;
+               }
+               fclose (pidFilePtr);
+               return oldpid;
+           }
+               else
+           {
+               ErrorF ("cannot fdopen process ID file %s for writing: "
+                       "%s\n", pidFile, strerror (errno));
+               return -1;
+           }
 	}
-	if (fscanf (pidFilePtr, "%d\n", &oldpid) != 1)
-	    oldpid = -1;
-	if (fseek (pidFilePtr, 0L, SEEK_SET) == -1)
+       if ((pidFilePtr = fdopen (pidFd, "w")) == NULL)
 	{
-	    ErrorF ("cannot seek process-id file %s: %s\n", pidFile,
-		     strerror (errno));
-	    return -1;
+               ErrorF ("cannot open process ID file %s for writing: %s\n",
+                       pidFile, strerror (errno));
+               return -1;
 	}
-	if (fprintf (pidFilePtr, "%5ld\n", (long) getpid ()) != 6)
+       (void) snprintf (pidstr, 11, "%ld", (long) getpid());
+       pidstrlen = strlen (pidstr);
+       if (fprintf (pidFilePtr, "%s\n", pidstr) != ( pidstrlen + 1))
 	{
-	    ErrorF ("cannot write to process-id file %s: %s\n", pidFile,
+           ErrorF ("cannot write to process ID file %s: %s\n", pidFile,
 		    strerror (errno));
 	    return -1;
 	}
@@ -573,3 +608,19 @@
     }
     return 0;
 }
+
+
+/*
+ * Remove process ID file.  This function should be registered with atexit().
+ */
+static void
+RemovePid (void)
+{
+#ifdef DEBUG
+    fprintf (stderr, "unlinking process ID file %s\n", pidFile);
+#endif
+    if (unlink (pidFile))
+       if (errno != ENOENT)
+           ErrorF ("cannot remove process ID file %s: %s\n", pidFile,
+                   strerror (errno));
+}
Index: xc/programs/xfs/xfs.man
===================================================================
--- xc/programs/xfs/xfs.man	(revision 309)
+++ xc/programs/xfs/xfs.man	(working copy)
@@ -37,206 +37,320 @@
 .\" suitability of this software for any purpose.  It is provided "as is"
 .\" without express or implied warranty.
 .\" $Xorg: xfs.man,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $
-.TH XFS 1 __xorgversion__
+.TH xfs __mansuffix__ __xorgversion__
 .SH NAME
 xfs \- X font server
 .SH SYNOPSIS
-.B "xfs"
-[\-config \fIconfiguration_file\fP]
-[\-daemon]
-[\-droppriv]
-[\-ls \fIlisten_socket\fP]
-[\-nodaemon]
-[\-port \fItcp_port\fP]
-[\-user \fIusername\fP]
+.B xfs
+[
+.BI "\-config " configuration_file
+]
+[
+.B \-daemon
+]
+[
+.B \-droppriv
+]
+[
+.BI "\-ls " listen_socket
+]
+[
+.B \-nodaemon
+]
+[
+.BI "\-pid " pid_file
+]
+[
+.BI "\-port " tcp_port
+]
+[
+.BI "\-user " username
+]
 .SH DESCRIPTION
+.B xfs
+is the X Window System font server.
+It supplies fonts to X Window System display servers.
+The server is usually run by a system administrator, and started via
+.BR init (__osadmmansuffix__).
+Users may also wish to start private font servers for specific sets of
+fonts.
 .PP
-.I Xfs
-is the X Window System font server.  It supplies fonts to X Window
-System display servers.
-.SH "STARTING THE SERVER"
-The server is usually run by a system administrator, and started via 
-boot files like \fI/etc/rc.local\fR.  Users may also wish to start
-private font servers for specific sets of fonts.
-.SH "OPTIONS"
-.TP 8
-.B \-config configuration_file
-Specifies the configuration file the font server will use.  If this
-parameter is not specified, the default file, \fI/usr/X11R6/lib/X11/fs/config\fR
+To connect to a font server, see the documentation for your X server; it
+likely supports the syntax documented in the \(lqFONT SERVER NAMES\(rq
+section of
+.BR X (__miscmansuffix__).
+.SH OPTIONS
+.TP
+.BI "\-config " configuration_file
+specifies the configuration file
+.B xfs
+will use.
+If this parameter is not specified, the default file,
+.IR __projectroot__/lib/X11/fs/config ,
 will be used.
-.TP 8
-.B \-ls listen_socket
-Specifies a file descriptor which is already set up to be used as the
-listen socket.  This option is only intended to be used by the font server
-itself when automatically spawning another copy of itself to handle
-additional connections.
-.TP 8
-.B \-port tcp_port
-Specifies the TCP port number on which the server will listen for connections.
-The default port number is 7100.
-.TP 8
+.TP
 .B \-daemon
-Instructs xfs to fork and go into the background automatically at
-startup  If this option is not specified, xfs will run as a regular
-process (unless xfs was built to daemonize by default).
-.TP 8
+instructs
+.B xfs
+to fork and go into the background automatically at startup.
+If this option is not specified,
+.B xfs
+will run as a regular process (unless it was built to daemonize by
+default).
+When running as a daemon,
+.B xfs
+will attempt to create a file in which it stores its process ID, and will
+delete that file upon exit; see
+.BR \-pid .
+.TP
 .B \-droppriv
-If specified, xfs will attempt to run as user and group \fIxfs\fR (unless
-the
+instructs
+.B xfs
+to attempt to run as user and group
+.I xfs
+(unless the
 .B \-user
-option is used). This
-has been implemented for security reasons, as xfs may have undiscovered
-buffer overflows or other paths for possible exploit, both local and
-remote.  With this option, you may also wish to specify
-"no-listen = tcp"
-in the config file, which ensures that xfs will not to use a TCP port at all.
-.TP 8
+option is used).
+This has been implemented for security reasons, as
+.B xfs
+may have undiscovered buffer overflows or other paths for possible exploit,
+both local and remote.
+When using this option, you may also wish to specify \(oqno\-listen =
+tcp\(cq in the config file, which ensures that
+.B xfs
+will not to use a TCP port at all.
+By default,
+.B xfs
+runs with the user and group IDs of the user who invoked it.
+.TP
+.BI "\-ls " listen_socket
+specifies a file descriptor which is already set up to be used as the
+listen socket.
+This option is only intended to be used by the font server itself when
+automatically spawning another copy of itself to handle additional
+connections.
+.TP
 .B \-nodaemon
-When xfs is built to daemonize (run in the background) by default,
-this prevents that and starts xfs up as a regular process.
-.TP 8
-.B \-user username
-This is equivalent to
+instructs
+.B xfs
+not to daemonize (fork and detach from its controlling terminal).
+This option only has an effect if
+.B xfs
+is built to daemonize by default, which is not the stock configuration.
+.TP
+.BI "\-pid " pid_file
+instructs
+.B xfs
+to save its process ID into
+.IR pid_file ,
+instead of the default,
+.IR /var/run/xfs.pid .
+If
+.B xfs
+is not running as a daemon, this option has no effect.
+.TP
+.BI "\-port " tcp_port
+specifies the TCP port number on which the server will listen for
+connections.
+The default port number is 7100.
+This option is ignored if
+.B xfs
+is configured to not listen to TCP transports at all (see \(lqConfiguration
+File Format\(rq below).
+.TP
+.BI "\-user " username
+instructs
+.B xfs
+to run as the user
+.IR username.
+See
 .B \-droppriv
-except that xfs will run as user \fIusername\fR.
-.SH "SIGNALS"
-.TP 8
-.I SIGTERM
-This causes the font server to exit cleanly.
-.TP 8
-.I SIGUSR1
-This signal is used to cause the server to re-read its configuration file.
-.TP 8
-.I SIGUSR2
-This signal is used to cause the server to flush any cached data it
-may have.
-.TP 8
-.I SIGHUP
-This signal is used to cause the server to reset, closing all active
-connections and re-reading the configuration file.
-.SH "CONFIGURATION"
+for why this may be desired.
+By default,
+.B xfs
+runs with the user and group IDs of the user who invoked it.
+.SH "INPUT FILES"
+.B xfs
+reads and serves any font file format recognized by the X server itself.
+It locates font files through the specification of a
+.IR catalogue ,
+which is delcared in
+.BR xfs 's
+configuration file.
+.SS "Configuration File Format"
+.B xfs
+reads its configuration from
+.I __projectroot__/lib/X11/fs/config
+by default (see the
+.B \-config
+option in the \(lqOPTIONS\(rq section above).
 The configuration language is a list of keyword and value pairs.
-Each keyword is followed by an '=' and then the desired value.
+Each keyword is followed by an equals sign (\(oq=\(cq) and then the desired
+value.
 .PP
 Recognized keywords include:
-.sp
-.\" .IP "cache-size (cardinal)"
-.\" Size in bytes of the font server cache.
-.IP "catalogue (list of string)"
-Ordered list of font path element names.
-Use of the keyword "catalogue" is very misleading at present,
-the current implementation only supports a single catalogue ("all"),
+.TP
+.BR alternate\-servers " (list of \fIstring\fPs)"
+lists alternate servers for this font server.
+See the \(lqFONT SERVER NAMES\(rq section of
+.BR X (__miscmansuffix__)
+for the syntax of the string.
+.\" .TP
+.\" .BR cache\-size " (\fIcardinal\fP)"
+.\" determines the size (in bytes) of the font server cache.
+.TP
+.BR catalogue " (list of \fIstring\fPs)"
+declares as ordered list of font path element names from which fonts will
+be served.
+Use of the keyword \(oqcatalogue\(cq is very misleading at present: the
+current implementation only supports a single catalogue (\(oqall\(cq),
 containing all of the specified fonts.
-.IP "alternate-servers (list of string)"
-List of alternate servers for this font server.
-.IP "client-limit (cardinal)"
-Number of clients this font server will support 
-before refusing service.  This is useful for tuning 
-the load on each individual font server.
-.IP "clone-self (boolean)"
-Whether this font server should attempt to clone itself
-when it reachs the client-limit.
-.IP "default-point-size (cardinal)"
-The default pointsize (in decipoints) for fonts that 
-don't specify.  The default is 120.
-.IP "default-resolutions (list of resolutions)"
-Resolutions the server supports by default.
-This information may be used as a hint for 
-pre-rendering, and substituted for scaled fonts 
-which do not specify a resolution.
-A resolution is a comma-separated pair of x and y resolutions in
-pixels per inch.
+.TP
+.BR client\-limit " (\fIcardinal\fP)"
+determines the number of clients this font server will support before
+refusing service.
+This is useful for tuning the load on each individual font server.
+.TP
+.BR clone\-self " (\fIboolean\fP)"
+indicates whether this font server should attempt to clone itself when the
+number of connected clients reaches the
+.BR client\-limit .
+.TP
+.BR default\-point\-size " (\fIcardinal\fP)"
+The default pointsize (in decipoints) for font requests that don't specify
+a point size.
+The default is 120.
+.TP
+.BR default\-resolutions " (list of \fIresolution\fPs)"
+indicates the resolutions the server supports by default.
+This information may be used as a hint for pre-rendering, and substituted
+into requests for scaled fonts which do not specify a resolution.
+A
+.I resolution
+is a comma-separated pair of horizontal and vertical resolutions in pixels
+per inch.
 Multiple resolutions are separated by commas.
-.IP "error-file (string)"
-Filename of the error file.  All warnings and errors
-will be logged here.
-.IP "no-listen (trans-type)"
-Disable a transport  type. For example, TCP/IP connections can
-be disabled with no-listen tcp
-.IP "port (cardinal)"
-TCP port on which the server will listen for connections.
-.IP "use-syslog (boolean)"
-Whether syslog(3) (on supported systems) is to be used 
-for errors.
-.IP "deferglyphs (string)"
-Set the mode for delayed fetching and caching of glyphs.  Value is
-"none", meaning deferred glyphs is disabled, "all", meaning it is
-enabled for all fonts, and "16", meaning it is enabled only for
-16-bits fonts.
-.\" .IP "trusted-clients (list of string)"
-.\" Those clients the fontserver will talk to.  Others
-.\" will be refused for the initial connection.  An empty
-.\" list means the server will talk to any client.
-.SH "EXAMPLE"
+.TP
+.BR deferglyphs " (\fIstring\fP)"
+sets the mode for delayed fetching and caching of glyphs.
+.I string
+should be one of \(oqnone\(cq, meaning glyphs deferment is disabled,
+\(oqall\(cq, meaning it is enabled for all fonts, and \(oq16\(cq, meaning
+it is enabled only for 16-bit fonts.
+.TP
+.BR error\-file " (\fIstring\fP)"
+indicates the filename of the error file.
+All warnings and errors will be logged here, unless
+.B use\-syslog
+is set to a true value (see below).
+.TP
+.BR no\-listen " (\fItrans-type\fP)"
+disables the specified transport type.
+For example, TCP/IP connections can be disabled with \(oqno\-listen =
+tcp\(cq.
+.TP
+.BR port " (\fIcardinal\fP)"
+indicates the TCP port on which the server will listen for connections.
+.\" .TP
+.\" .BR trusted-clients " (list of \fIstring\fPs)"
+.\" idefntifies the clients the font server will talk to.
+.\" Others will be refused for the initial connection.
+.\" An empty list means the server will talk to any client.
+.TP
+.BR use\-syslog " (\fIboolean\fP)"
+determines whether errors and diagnostics should be reported via
+.BR syslog (__oslibmansuffix__)
+(on supported systems) instead of being written to the
+.B error\-file
+(see above).
+.SS "Example Configuration File"
 .nf
 XCOMM
 XCOMM sample font server configuration file
 XCOMM
 
-XCOMM allow a max of 10 clients to connect to this font server
-client-limit = 10
+XCOMM allow a max of 10 clients to connect to this font server.
+client\-limit = 10
 
-XCOMM when a font server reaches its limit, start up a new one
-clone-self = on
+XCOMM When a font server reaches the above limit, start up a new one.
+clone\-self = on
 
-XCOMM alternate font servers for clients to use
-alternate-servers = hansen:7101,hansen:7102
+XCOMM Identify alternate font servers for clients to use.
+alternate\-servers = hansen:7101,hansen:7102
 
-XCOMM where to look for fonts
-XCOMM the first is a set of Speedo outlines, the second is a set of 
-XCOMM misc bitmaps and the last is a set of 100dpi bitmaps
+XCOMM Look for fonts in the following directories.  The first is a set of
+XCOMM Speedo outlines, the second is a set of misc bitmaps (such as terminal
+XCOMM and cursor fonts), and the last is a set of 100dpi bitmaps.
 XCOMM
 catalogue = /usr/X11R6/lib/X11/fonts/speedo,
-	/usr/X11R6/lib/X11/fonts/misc,
-	/usr/X11R6/lib/X11/fonts/100dpi/
+            /usr/X11R6/lib/X11/fonts/misc,
+            /usr/X11R6/lib/X11/fonts/100dpi/
 
 XCOMM in 12 points, decipoints
-default-point-size = 120
+default\-point\-size = 120
 
 XCOMM 100 x 100 and 75 x 75
-default-resolutions = 100,100,75,75
-use-syslog = off
+default\-resolutions = 100,100,75,75
+
+XCOMM Specify our log filename.
+error\-file = /var/log/xfs.log
+
+XCOMM Direct diagnostics to our own log file instead of using syslog.
+use\-syslog = off
 .fi
-.sp
-.SH "FONT SERVER NAMES"
-One of the following forms can be used to name a font server that
-accepts TCP connections:
-.sp
-.nf
-    tcp/\fIhostname\fP:\fIport\fP
-    tcp/\fIhostname\fP:\fIport\fP/\fIcataloguelist\fP
-.fi
-.PP
-The \fIhostname\fP specifies the name (or decimal numeric address)
-of the machine on which the font server is running.  The \fIport\fP
-is the decimal TCP port on which the font server is listening for connections.
-The \fIcataloguelist\fP specifies a list of catalogue names,
-with '+' as a separator.
-.PP
-Examples: \fItcp/fs.x.org:7100\fP, \fItcp/18.30.0.212:7101/all\fP.
-.PP
-One of the following forms can be used to name a font server that
-accepts DECnet connections:
-.sp
-.nf
-    decnet/\fInodename\fP::font$\fIobjname\fP
-    decnet/\fInodename\fP::font$\fIobjname\fP/\fIcataloguelist\fP
-.fi
-.PP
-The \fInodename\fP specifies the name (or decimal numeric address)
-of the machine on which the font server is running.
-The \fIobjname\fP is a normal, case-insensitive DECnet object name.
-The \fIcataloguelist\fP specifies a list of catalogue names,
-with '+' as a separator.
-.PP
-Examples: \fIDECnet/SRVNOD::FONT$DEFAULT\fP, \fIdecnet/44.70::font$special/symbols\fP.
-.SH "SEE ALSO"
-X(__miscmansuffix__), \fIThe X Font Service Protocol\fP,
-.br
-\fIFont server implementation overview\fP
+.SH "OUTPUT FILES"
+When operating in daemon mode,
+.B xfs
+sends diagnostic messages (errors and warnings) to the system log via the
+.B syslog
+C library function by default.
+However, these messages can be sent to an alternate location via the
+.B error\-file
+and
+.B use\-syslog
+configuration variables; see \(lqConfiguration File Format\(rq, above.
+.SH "ASYNCHRONOUS EVENTS"
+.B xfs
+handles the following signals specially:
+.TP
+.I SIGTERM
+causes the font server to exit cleanly.
+.TP
+.I SIGUSR1
+causes
+.B xfs
+to re-read its configuration file.
+.TP
+.I SIGUSR2
+causes
+.B xfs
+to flush any cached data it may have.
+.TP
+.I SIGHUP
+causes
+.B xfs
+to reset, closing all active connections and re-reading the configuration
+file.
 .SH BUGS
 Multiple catalogues should be supported.
+.SH "FUTURE DIRECTIONS"
+Significant further development of
+.B xfs
+is unlikely.
+One of the original motivations behind it was the single-threaded nature of
+the X server \(em a user's X session could seem to \(oqfreeze up\(cq while
+the X server took a moment to rasterize a font.
+This problem with the X server, which remains single-threaded in all
+popular implementations to this day, has been mitigated on two fronts:
+machines have gotten much faster, and client-side font rendering
+(particularly via the Xft library) is the norm in contemporary software.
 .SH AUTHORS
 Dave Lemke, Network Computing Devices, Inc
 .br
 Keith Packard, Massachusetts Institute of Technology
+.SH "SEE ALSO"
+.BR X (__miscmansuffix__),
+.BR init (__osadmmansuffix__),
+.BR syslog (__oslibmansuffix__),
+.IR "The X Font Service Protocol" ,
+.I Font Server Implementation Overview
$Id: 099u_mkdirhier_rewrite.diff 2171 2005-02-08 07:13:50Z branden $

Reimplement mkdirhier; see Debian #141347 and #232357 for some reasons why.

This shell script and manpage by Branden Robinson.

Not submitted upstream to XFree86 or X.Org.

Index: xc/config/util/mkdirhier.sh
===================================================================
--- xc/config/util/mkdirhier.sh	(revision 309)
+++ xc/config/util/mkdirhier.sh	(working copy)
@@ -1,67 +1,94 @@
 #!/bin/sh
-# $Xorg: mkdirhier.sh,v 1.3 2000/08/17 19:41:53 cpqbld Exp $
-# Courtesy of Paul Eggert
 
-newline='
-'
-IFS=$newline
+# Copyright 2005 Branden Robinson.
 
-case ${1--} in
--*) echo >&2 "mkdirhier: usage: mkdirhier directory ..."; exit 1
-esac
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following condition:
+#
+#     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
+# SOFTWARE IN THE PUBLIC INTEREST, INC. 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.
 
-status=
+# I rewrote Paul Eggert's script in POSIX shell because it was a little
+# odd, and did not confine itself to puritantical pre-POSIX conventions.
+# For example, in one place it used:
+#   case ${1--} in
+#   -*)
+# to test for $1 being null, presumably due to fears that test -n and -z
+# will not be available.  Yet later in the script, test -n was used.
+#
+# This seemed quite silly.  I decided to rewrite it since I am arrgoant
+# enough to think I know what I'm doing in POSIX shell.
+#
+# If someone needs a pre-POSIX version of mkdirhier, they'll probably need to
+# turn to someone else, as I have no idea where such a thing is specified.
 
-for directory
-do
-	case $directory in
-	'')
-		echo >&2 "mkdirhier: empty directory name"
-		status=1
-		continue;;
-	*"$newline"*)
-		echo >&2 "mkdirhier: directory name contains a newline: \`\`$directory''"
-		status=1
-		continue;;
-	///*) prefix=/;; # See Posix 2.3 "path".
-	//*) prefix=//;;
-	/*) prefix=/;;
-	-*) prefix=./;;
-	*) prefix=
-	esac
+set -e
 
-	IFS=/
-	set x $directory
-	case $2 in
-	    */*)	# IFS parsing is broken
-		IFS=' '
-		set x `echo $directory | tr / ' '`
-		;;
-	esac
-	IFS=$newline
-	shift
+PROGNAME=${0##*/}
+STATUS=0
 
-	for filename
-	do
-		path=$prefix$filename
-		prefix=$path/
-		shift
+usage() {
+    cat <<EOF
+usage: $PROGNAME DIRECTORY ...
+Create each directory DIRECTORY, also creating intermediate directories in the
+specified hierarchy as necessary.
 
-		test -d "$path" || {
-			paths=$path
-			for filename
-			do
-				if [ -n "$filename" -a "$filename" != "." ]; then
-					path=$path/$filename
-					paths=$paths$newline$path
-				fi
-			done
+Note: Use "mkdir -p" instead of "$PROGNAME" if the system supports it.
+EOF
+}
 
-			mkdir $paths || status=$?
+makedir () {
+    FUNC_STATUS=0
+    # Does the desired directory already exist?
+    if ! [ -d "$1" ]; then
+        # Is a directory hierarchy specified (i.e., are any slashes in the
+        # argument)?
+        PARENT=${1%/*}
+        if [ -n "$PARENT" ] && [ "$PARENT" != "$1" ]; then
+            # Yes; does the desired directory's immediate parent exist?
+            if ! [ -d "$PARENT" ]; then
+                # No; push it onto the stack.  If that fails, return
+                # immediately, as we know later calls will also fail.  E.g., if
+                # we are asked to create /usr/bin/foo/bar/baz/quux and
+                # /usr/bin/foo fails, we don't have to even try anything deeper
+                # in the hierarchy.
+                if ! makedir "$PARENT"; then
+                    return $FUNC_STATUS
+                fi
+            fi
+        fi
+        mkdir "$1" || FUNC_STATUS=$?
+    fi
+    return $FUNC_STATUS
+}
 
-			break
-		}
-	done
-  done
+if [ -z "$1" ]; then
+    usage >&2
+    exit 64
+fi
 
-exit $status
+while [ -n "$1" ]; do
+    ARG="$1"
+    makedir "$ARG" || \
+    {
+        STATUS=$?
+        echo "$PROGNAME: could not create directory \"$ARG\"" >&2
+    }
+    shift
+done
+
+exit $STATUS
+
+# vim:set ai et sts=4 sw=4 tw=80:
Index: xc/config/util/mkdirhier.man
===================================================================
--- xc/config/util/mkdirhier.man	(revision 309)
+++ xc/config/util/mkdirhier.man	(working copy)
@@ -1,42 +1,111 @@
-.\" $Xorg: mkdirhier.man,v 1.4 2001/02/09 02:03:17 xorgcvs Exp $
-.\" Copyright (c) 1993, 1994, 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.
-.\" 
+.\" Copyright 2005 Branden Robinson.
+.\"
+.\" Permission is hereby granted, free of charge, to any person obtaining a
+.\" copy of this software and associated documentation files (the "Software"),
+.\" to deal in the Software without restriction, including without limitation
+.\" the rights to use, copy, modify, merge, publish, distribute, sublicense,
+.\" and/or sell copies of the Software, and to permit persons to whom the
+.\" Software is furnished to do so, subject to the following condition:
+.\"
+.\"     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 
-.\" dealing in this Software without prior written authorization from The 
-.\" Open Group.
-.\"
-.\" $XFree86: xc/config/util/mkdirhier.man,v 1.2 2001/01/27 18:19:55 dawes Exp $
-.\"
-.TH MKDIRHIER 1 __xorgversion__
+.\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+.\" SOFTWARE IN THE PUBLIC INTEREST, INC. 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.
+.TH mkdirhier __mansuffix__ __xorgversion__
 .SH NAME
-mkdirhier \- makes a directory hierarchy
+mkdirhier \- create a directory hierarchy
 .SH SYNOPSIS
 .B mkdirhier
-directory ...
+.I directory
+\&...
 .SH DESCRIPTION
-The
-.I mkdirhier
-command creates the specified directories. Unlike
-.I mkdir
-if any of the parent directories of the specified directory
-do not exist, it creates them as well.
+.B mkdirhier
+creates the specified directories.
+Unlike some versions of
+.BR mkdir ,
+if any of the parent directories of the specified directory do not exist,
+.B mkdirhier
+creates them as well.
+.PP
+.B mkdirhier
+is a wrapper for
+.BR mkdir ;
+systems with
+.BR mkdir (__osmansuffix__)
+implementations conformant with the Single Unix Specification may simply
+use
+.B mkdir \-p
+instead \(em this includes all systems using the GNU Core Utilities'
+version of
+.BR mkdir .
+.SH DIAGNOSTICS
+If
+.B mkdirhier
+is not supplied with any arguments, a usage message is printed.
+.PP
+.B mkdirhier
+prefixes its diagnostic messages with the name under which it was invoked,
+followed by a colon (\(oq:\(cq) so that its messages can be distingushed
+from others.
+.TP
+.B could not create directory \(dq\fIdirectory\fP\(dq
+indicates that there was a failure while creating
+.IR directory .
+This message will likely be preceded by a diagnostic message from
+.BR mkdir .
+.SH "EXIT STATUS"
+.TP
+.B 64
+.B mkdirhier
+was not given any directory names to create.
+.PP
+.B mkdirhier
+otherwise exits with the exit status of the last
+.B mkdir
+command that failed.
+.SH BUGS
+.B mkdirhier
+does not create all the requested directories as an atomic operation;
+therefore, it is is susceptible to race conditions.
+For example, if
+.B mkdirhier
+is directed to create a hierarchy
+.I a/b/c/d
+and any of
+.IR a/ ,
+.IR b/ ,
+or
+.I c/
+do not yet exist, any of the newly-created directories can be removed
+and/or replaced by a symbolic link to another location in the window of
+time after
+.B mkdirhier
+creates a directory and the directory immediately below it.
+This means that failures can be provoked (since
+.B mkdir
+will fail to create a directory in a directory that does not already
+exist),
+or directories may be created in unexpected locations.
+The same limitation holds for multiple directory arguments to
+.BR mkdirhier ;
+given two arguments
+.I a/b/c/d
+and
+.IR a/b/c/f ,
+it is possible for the directory hierarchy
+.I a/b/c
+to be disrupted in the time between the processing of the two arguments.
+To avoid these problems, use
+.B mkdir \-p
+instead, or do not use
+.B mkdirhier
+to create directories in parts of the filesystem where untrusted users can
+manipulate them.
 .SH "SEE ALSO"
-mkdir(1)
+.BR mkdir (__osmansuffix__)

Reply to: