Hello,

as solution to rhbz #441807 (/bin/ls fails in a directory with >6M files)
I propose tiny patch for ls - work with constant amount of memory when not 
sorting and using one_per_line format, no matter how many files are in the 
directory.

Tested with directory of about 10000 files.

Git version:
$ ulimit -v 102400
$ ls -U1 | wc -l
ls: memory exhausted
0

Patched version:
$ ulimit -v 102400
$ ls -U1 | wc -l
102402


Greetings
Kamil Dudka
From 92a29217298044c1b9298d557ac6fd683effbd41 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <[EMAIL PROTECTED]>
Date: Wed, 30 Jul 2008 12:40:49 +0200
Subject: [PATCH] ls: now works with constant amount of memory when not sorting and using
one_per_line format, no matter how many files are in the directory
* ls.c (write_out_current_files): New function for immediately write out
of files in the table.
ls.c (print_dir): Write out files immediately if possible.
* NEWS: Mention the change.

---
 NEWS     |    3 +++
 src/ls.c |   16 ++++++++++++++++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/NEWS b/NEWS
index 5796dfa..46d1fe8 100644
--- a/NEWS
+++ b/NEWS
@@ -55,6 +55,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   specifiers, and no longer prints fields that resulted entirely from
   padding the input out to the least common multiple width.
 
+  ls now works with constant amount of memory when not sorting and using
+  one_per_line format, no matter how many files are in the directory
+
 ** Changes in behavior
 
   stat's --context (-Z) option has always been a no-op.
diff --git a/src/ls.c b/src/ls.c
index 4b69f7d..439a17a 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -220,6 +220,7 @@ static void get_link_name (char const *filename, struct fileinfo *f,
 			   bool command_line_arg);
 static void indent (size_t from, size_t to);
 static size_t calculate_columns (bool by_columns);
+static void write_out_current_files (void);
 static void print_current_files (void);
 static void print_dir (char const *name, char const *realname,
 		       bool command_line_arg);
@@ -2402,6 +2403,8 @@ print_dir (char const *name, char const *realname, bool command_line_arg)
 #endif
 	      total_blocks += gobble_file (next->d_name, type, D_INO (next),
 					   false, name);
+              if (format == one_per_line && sort_type == sort_none)
+                write_out_current_files ();
 	    }
 	}
       else if (errno != 0)
@@ -3239,6 +3242,19 @@ sort_files (void)
 			[directories_first]);
 }
 
+/* Sort files in the table and write out immediately.  */
+
+static void
+write_out_current_files (void)
+{
+  if (cwd_n_used)
+    {
+      sort_files ();
+      print_current_files ();
+      clear_files ();
+    }
+}
+
 /* List all the files now in the table.  */
 
 static void
-- 
1.5.4.1

_______________________________________________
Bug-coreutils mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to