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.