diff --git a/lib/savedir.c b/lib/savedir.c
index 95dc6c6..809306f 100644
--- a/lib/savedir.c
+++ b/lib/savedir.c
@@ -41,6 +41,59 @@
 # define NAME_SIZE_DEFAULT 512
 #endif
 
+typedef struct
+{
+  int off;
+#if D_INO_IN_DIRENT
+  ino_t ino;
+#endif
+} direntry_t;
+
+static int (*cmp)(const void *a, const void *b);
+static char *name_space;
+
+/* Compare the names of two directory entries */
+
+static int
+direntry_cmp_name (const void *a, const void *b)
+{
+  const direntry_t *dea = (const direntry_t *) a;
+  const direntry_t *deb = (const direntry_t *) b;
+
+  return strcmp(name_space + dea->off, name_space + deb->off);
+}
+
+#if D_INO_IN_DIRENT
+/* Compare the inode numbers of two directory entries */
+
+static int
+direntry_cmp_inode (const void *a, const void *b)
+{
+  const direntry_t *dea = (const direntry_t *) a;
+  const direntry_t *deb = (const direntry_t *) b;
+
+  return (int) (dea->ino - deb->ino);
+}
+#endif
+
+/* Set the directory sorting order */
+
+int
+set_savedir_sorting (char *order)
+{
+  if (strcmp(order, "none") == 0)
+    cmp = NULL;
+  else if (strcmp(order, "name") == 0)
+    cmp = direntry_cmp_name;
+#if D_INO_IN_DIRENT
+  else if (strcmp(order, "inode") == 0)
+    cmp = direntry_cmp_inode;
+#endif
+  else
+    return -1;
+  return 0;
+}
+
 /* Return a freshly allocated string containing the file names
    in directory DIRP, separated by '\0' characters;
    the end is marked by two '\0' characters in a row.
@@ -50,8 +103,12 @@
 char *
 streamsavedir (DIR *dirp)
 {
-  char *name_space;
+  char *sorted;
   size_t allocated = NAME_SIZE_DEFAULT;
+  direntry_t *entries;
+  size_t entries_allocated = NAME_SIZE_DEFAULT/sizeof(direntry_t);
+  size_t entries_used = 0;
+  size_t i;
   size_t used = 0;
   int save_errno;
 
@@ -59,6 +116,8 @@ streamsavedir (DIR *dirp)
     return NULL;
 
   name_space = xmalloc (allocated);
+  if (cmp)
+    entries = xmalloc (entries_allocated * sizeof(direntry_t));
 
   for (;;)
     {
@@ -91,9 +150,38 @@ streamsavedir (DIR *dirp)
               name_space = xrealloc (name_space, allocated);
             }
           memcpy (name_space + used, entry, entry_size);
+          if (cmp)
+            {
+              if (entries_allocated <= entries_used)
+                {
+                  if (2 * entries_allocated < entries_allocated)
+                    xalloc_die ();
+                  entries_allocated *= 2;
+                  entries = xrealloc (entries, entries_allocated * sizeof(direntry_t));
+                }
+              entries[entries_used].off = used;
+#if D_INO_IN_DIRENT
+              entries[entries_used].ino = dp->d_ino;
+#endif
+              entries_used++;
+            }
           used += entry_size;
         }
     }
+  if (cmp)
+    {
+      qsort (entries, entries_used, sizeof(direntry_t), cmp);
+      sorted = xmalloc (used + 1);
+      used = 0;
+      for (i = 0; i < entries_used; i++)
+        {
+          strcpy (sorted + used, name_space + entries[i].off);
+          used += strlen (sorted + used) + 1;
+        }
+      free (entries);
+      free (name_space);
+      name_space = sorted;
+    }
   name_space[used] = '\0';
   save_errno = errno;
   if (save_errno != 0)
diff --git a/lib/savedir.h b/lib/savedir.h
index aeb392c..b9af6e0 100644
--- a/lib/savedir.h
+++ b/lib/savedir.h
@@ -22,6 +22,7 @@
 #define _GL_SAVEDIR_H
 
 #include <dirent.h>
+int set_savedir_sorting (char *order);
 char *streamsavedir (DIR *dirp);
 char *savedir (char const *dir);
 char *fdsavedir (int fd); /* deprecated */
