[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
xreadlink.c initial buffer size guesstimate
From: |
Liyang HU |
Subject: |
xreadlink.c initial buffer size guesstimate |
Date: |
Fri, 12 Jan 2007 01:29:10 +0000 |
User-agent: |
Mutt/1.4.1i |
Hallo,
I've been getting ``ls: memory exhausted'' messages, which I eventually
tracked down to xreadlink() attempting to allocate several hundred MB of
memory, since that's what lstat() returns[0] for the symlink's st_size.
In actuality, the length of the symlink were mostly under 128 bytes.
It seems a rather large amount of memory to allocate as an initial attempt.
Sometimes ls worked, other times, memory exhaustion. :(
According to:
http://www.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
(It seems that) POSIX demands {SYMLINK_MAX} to be 255 bytes; SUS v3 says
{SYMLINK_MAX} has to be at least what POSIX says. So 256 bytes seems a much
more sensible maximal initial value.
And anyway, even the comments in xreadlink.c say:
SIZE is a hint as to how long the link is expected to be;
typically it is taken from st_size. It need not be correct.
And sometimes it isn't, with comedic effect[1]. So it wouldn't hurt to set
the /initial/ buffer size within somewhat more likely limits, right?
Patch to CVS HEAD, xreadlink.c rev 1.22 below. I haven't tested it. :-/
SYMLINK_MAX didn't seem like it was easily available, so I've substituted
PATH_MAX instead. Good enough for an initial guess. They ought to be around
the same order of magnitude at least.
Cheers,
/Liyang
[0] I know, lstat() should report the on-disk usage of the symlink; however
I thought of more nefarious uses for st_size. Consider my FS braindead if
you will, but xreadlink() needn't fail...
[1] ls --color=auto fails, but plain /bin/ls doesn't. Took a while to figure
out what was going on... (and I only did because I cheated and ltraced the
bugger.)
----8<----
--- xreadlink.c.orig 2007-01-12 00:56:50.000000000 +0000
+++ xreadlink.c 2007-01-12 01:14:40.000000000 +0000
@@ -31,6 +31,8 @@
#include <stdlib.h>
#include <unistd.h>
+#include "pathmax.h"
+
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
@@ -38,6 +40,7 @@
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
#endif
+#define MAXINIT PATH_MAX
#define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX)
#include "xalloc.h"
@@ -54,8 +57,9 @@
xreadlink (char const *file, size_t size)
{
/* The initial buffer size for the link value. A power of 2
- detects arithmetic overflow earlier, but is not required. */
- size_t buf_size = size < MAXSIZE ? size + 1 : MAXSIZE;
+ detects arithmetic overflow earlier, but is not required.
+ Take size only as a hint; don't go overboard with the xmalloc(). */
+ size_t buf_size = size < MAXINIT ? size + 1 : MAXINIT;
while (1)
{
This message has been checked for viruses but the contents of an attachment
may still contain software viruses, which could damage your computer system:
you are advised to perform your own checks. Email communications with the
University of Nottingham may be monitored as permitted by UK legislation.