[PATCH] urxvtd, getopt and mlock

Russell Harmon russ at eatnumber1.com
Thu Jan 22 22:02:38 CET 2009


I merged the getopt_long patch and the mlock patches (since they
modified the same code).

I cleaned up the patch a bit. It now is enabled via the configure
script with the --enable-mlock flag, the flag is now -m/--mlock
(instead of -l/--lock).

The configure script also now checks for the presence of mlockall, and
checks that glibc is >= 2.5 (the version the mlockall bug was fixed),
and disables the mlockall if it is not met. It does the same for
getopt_long and the use of getopt.

I also added documentation for --mlock to the manpage.

I renamed --opendisplay to --open-display (opendisplay is improper
english). The documentation does not mention it, but --opendisplay
will still work for backward compatibility.

Note that for the manpages, I updated the rxvtd.1.pod file, so the
rxvtd.1.man.in file will need to be regenerated.

-Russell Harmon


Index: configure.ac
===================================================================
RCS file: /schmorpforge/rxvt-unicode/configure.ac,v
retrieving revision 1.105
diff -u -4 -p -r1.105 configure.ac
--- configure.ac	27 Jan 2008 22:48:31 -0000	1.105
+++ configure.ac	22 Jan 2009 20:58:44 -0000
@@ -139,8 +139,9 @@ AC_ARG_ENABLE(everything,
        support_8bitctrls=no
        support_iso14755=no
        support_styles=no
        support_perl=no
+       support_mlock=no
        codesets=
     fi
     if test x$enableval = xyes; then
        support_frills=yes
@@ -167,8 +168,9 @@ AC_ARG_ENABLE(everything,
        #support_8bitctrls=yes
        support_iso14755=yes
        support_styles=yes
        support_perl=yes
+       support_mlock=yes
        codesets=all
     fi
   ])

@@ -393,8 +395,14 @@ AC_ARG_ENABLE(pointer-blank,
   [if test x$enableval = xyes -o x$enableval = xno; then
     support_pointer_blank=$enableval
   fi])

+AC_ARG_ENABLE(mlock,
+  [  --enable-mlock          enable the --mlock option in rxvtd],
+  [if test x$enableval = xyes -o x$enableval = xno; then
+    support_mlock=$enableval
+  fi])
+
 AC_ARG_WITH(term,
   [  --with-term=NAME        set the terminal to NAME (default: rxvt)],
   [if test x$withval != x; then
     AC_DEFINE_UNQUOTED(TERMENV, "$withval",Set TERM to the value
given by configure) term="$withval"
@@ -464,8 +472,28 @@ AC_CHECK_HEADERS( \
 	wchar.h \
 	cwchar \
 )

+if test x$support_mlock = xyes; then
+    dnl# glibc versions < 2.5.20 don't work with mlockall
+    AC_CACHE_CHECK([for glibc >= 2.5], rxvt_mlock,
+    [AC_RUN_IFELSE([
+      AC_LANG_PROGRAM([
+#include <stdlib.h>
+      ],[
+#if ! ( ( defined(__GLIBC__) && defined(__GLIBC_MINOR__) ) && (
__GLIBC__ > 2 || ( __GLIBC__ == 2 && __GLIBC_MINOR__ >= 5 ) ) )
+        return 1;
+#endif
+      ])],
+      [],[support_mlock=no]
+    )])
+fi
+if test x$support_mlock = xyes; then
+    AC_CHECK_FUNCS(mlockall)
+fi
+
+AC_CHECK_FUNCS(getopt_long)
+
 AC_CACHE_CHECK([for XPointer], rxvt_cv_xpointer,
 [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <X11/Xlib.h>]],
[[XPointer dummy;]])],[rxvt_cv_xpointer=yes],[rxvt_cv_xpointer=no])])
 if test x$rxvt_cv_xpointer = xyes; then
   AC_DEFINE(HAVE_XPOINTER, 1, Define if you have XPointer typedef)
@@ -768,8 +796,11 @@ if test x$RESFALLBACK != x; then
 fi
 echo
 echo "  embedded perl:              $support_perl"
 echo "  libafterimage:              $support_afterimage"
+if test x$support_mlock != x; then
+  echo "  mlock:                      $support_mlock"
+fi
 dnl echo "  AfterStep integration:      $support_afterstep"
 echo
 if test x$support_xim = xyes -a x$rxvt_cv_func_xlocale = xno; then
   echo ".----------------------------------------------------------------."
Index: doc/rxvtd.1.pod
===================================================================
RCS file: /schmorpforge/rxvt-unicode/doc/rxvtd.1.pod,v
retrieving revision 1.5
diff -u -4 -p -r1.5 rxvtd.1.pod
--- doc/rxvtd.1.pod	19 Feb 2008 19:24:30 -0000	1.5
+++ doc/rxvtd.1.pod	22 Jan 2009 20:58:44 -0000
@@ -3,9 +3,9 @@
 @@RXVT_NAME@@d - @@RXVT_NAME@@ terminal daemon

 =head1 SYNOPSIS

-B<@@RXVT_NAME@@d> [-q|--quiet] [-o|--opendisplay] [-f|--fork]
+B<@@RXVT_NAME@@d> [-q|--quiet] [-o|--opendisplay] [-f|--fork] [-m|--mlock]

 B<@@RXVT_NAME@@d> -q -o -f    # for .xsession use

 =head1 DESCRIPTION
@@ -39,9 +39,9 @@ options is not yet supported.
 Normally, B<@@RXVT_NAME@@d> outputs the message C<< rxvt-unicode daemon
 listening on <path> >> after binding to its control socket. This option
 will suppress this message (errors and warnings will still be logged).

-=item B<-o>, B<--opendisplay>
+=item B<-o>, B<--open-display>

 This forces B<@@RXVT_NAME@@d> to open a connection to the current
 C<$DISPLAY> and keep it open.

@@ -53,8 +53,17 @@ B<@@RXVT_NAME@@d> will be killed automat

 This makes B<@@RXVT_NAME@@d> fork after it has bound itself to its control
 socket.

+=item B<-m>, B<--mlock>
+
+This makes B<@@RXVT_NAME@@d> call mlockall(2) on itself. This locks
+B<@@RXVT_NAME@@d> in RAM and prevents it from being swapped out to disk.
+
+Note: In order to use this feature, your system administrator must have set
+your user's RLIMIT_MEMLOCK to a size greater than or equal to the size of the
+B<@@RXVT_NAME@@d> binary (or to unlimited). See /etc/security/limits.conf
+
 =back

 =head1 EXAMPLES

Index: src/rxvtd.C
===================================================================
RCS file: /schmorpforge/rxvt-unicode/src/rxvtd.C,v
retrieving revision 1.46
diff -u -4 -p -r1.46 rxvtd.C
--- src/rxvtd.C	15 Jun 2008 13:54:15 -0000	1.46
+++ src/rxvtd.C	22 Jan 2009 20:58:44 -0000
@@ -32,8 +32,16 @@
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/un.h>

+#ifdef HAVE_MLOCKALL
+#include <sys/mman.h>
+#endif
+
+#ifdef HAVE_GETOPT_LONG
+#include <getopt.h>
+#endif
+
 #include <cerrno>

 #include "rxvt.h"
 #include "rxvtdaemon.h"
@@ -216,28 +224,90 @@ void server::read_cb (ev::io &w, int rev
     return err ();
 }

 int opt_fork, opt_opendisplay, opt_quiet;
+#ifdef HAVE_MLOCKALL
+int opt_lock;
+#endif

 int
 main (int argc, const char *const *argv)
 {
   rxvt_init ();

+#ifdef HAVE_GETOPT_LONG
+  static struct option long_options[] = {
+	{"fork", no_argument, NULL, 'f'},
+	{"opendisplay", no_argument, NULL, 'o'},
+	{"open-display", no_argument, NULL, 'o'},
+	{"quiet", no_argument, NULL, 'q'},
+#ifdef HAVE_MLOCKALL
+	{"mlock", no_argument, NULL, 'm'},
+#endif
+	{"help", no_argument, NULL, 'h'},
+	{0, 0, 0, 0}
+  };
+
+  char c;
+  while ((c = getopt_long (argc, (char* const*) argv, "foqmh", long_options,
+    NULL)) != -1)
+    {
+      switch(c)
+		{
+		  case 'f':
+	        opt_fork = 1;
+		  	break;
+		  case 'o':
+	        opt_opendisplay = 1;
+		    break;
+		  case 'q':
+    	    opt_quiet = 1;
+		    break;
+#ifdef HAVE_MLOCKALL
+		  case 'm':
+	        opt_lock = 1;
+		    break;
+#endif
+		  case 'h':
+			printf("Usage: %s [options]\n", argv[0]);
+			printf("  %-3s %-15s %s\n", "-f,", "--fork", "Fork to background.");
+			printf("  %-3s %-15s %s\n", "-o,", "--open-display",
+				   "Open the display and keep it open (daemon will terminate"
+				   " with X).");
+#ifdef HAVE_MLOCKALL
+			printf("  %-3s %-15s %s\n", "-m,", "--mlock",
+				   "Lock the daemon in RAM and prevent it from being swapped "
+				   "out.");
+#endif
+			printf("  %-3s %-15s %s\n", "-q,", "--quiet", "Print less output.");
+			return EXIT_SUCCESS;
+          case '?':
+            return EXIT_FAILURE;
+		  default:
+			return EXIT_FAILURE;
+		}
+    }
+#else // HAVE_GETOPT_LONG
   for (int i = 1; i < argc; i++)
     {
       if (!strcmp (argv [i], "-f") || !strcmp (argv [i], "--fork"))
         opt_fork = 1;
-      else if (!strcmp (argv [i], "-o") || !strcmp (argv [i], "--opendisplay"))
+      else if (!strcmp (argv [i], "-o") || !strcmp (argv [i], "--opendisplay")
+          || !strcmp (argv [i], "--open-display"))
         opt_opendisplay = 1;
       else if (!strcmp (argv [i], "-q") || !strcmp (argv [i], "--quiet"))
         opt_quiet = 1;
+#ifdef HAVE_MLOCKALL
+      else if (!strcmp (argv [i], "-m") || !strcmp (argv [i], "--mlock"))
+        opt_lock = 1;
+#endif
       else
         {
           rxvt_log ("%s: unknown option '%s', aborting.\n", argv [0],
argv [i]);
           return EXIT_FAILURE;
         }
     }
+#endif // HAVE_GETOPT_LONG

   // optionally open display and never release it.
   if (opt_opendisplay)
     if (const char *dpy = getenv ("DISPLAY"))
@@ -255,12 +325,23 @@ main (int argc, const char *const *argv)
     }

   free (sockname);

+  pid_t pid = 0;
   if (opt_fork)
     {
-      pid_t pid = fork ();
+      pid = fork ();
+    }

+#ifdef HAVE_MLOCKALL
+  // Optionally preform a mlockall so this process does not get swapped out.
+  if (opt_lock && pid == 0)
+    if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
+      perror("unable to lock into ram");
+#endif
+
+  if (opt_fork)
+    {
       if (pid < 0)
         {
           rxvt_log ("unable to fork daemon, aborting.\n");
           return EXIT_FAILURE;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rxvt-unicode_mlock+getopt.patch
Type: application/octet-stream
Size: 8056 bytes
Desc: not available
URL: <http://lists.schmorp.de/pipermail/rxvt-unicode/attachments/20090122/7dfb38ab/attachment.obj>


More information about the rxvt-unicode mailing list