Record of some of the computer tech I deal with so that it's documented at least somewhere.

Friday 19 August 2011

Unlimited length path names, how do they work ?!

On Linux
I'm sending an email, it is reporting an error.
I hit on the idea - I should include the pwd or else relative pathnames might be ambiguous.

"Error in ./config file" is too late for the user to realise they should have included full pathnames.

man 3 getcwd
char *getcwd(char *buf, size_t size);
...
If the current absolute pathname would require a buffer longer than size elements, NULL is returned, and errno is set to ERANGE; an application should check for this error, and allocate a larger buffer if necessary.

Further on :

Note that PATH_MAX need not be a compile-time constant; it may depend on the filesystem and may even be unlimited.

It is also very easily wrong. It is only defined as the maximum for the filesystem directory entry, not the path, it could be returned as ./././././././././././././././././ etc.

So we are limited by SIZE_MAX which is the upper bound on getcwd


char *
pwd() {
size_t buffsize = PATH_MAX;
char *buff = malloc(buffsize);
if(!buff) return NULL;

while(!getcwd(&buff, buffsize)) {
if(errno != ERANGE)
return NULL; // caller can deal with it

if(buffsize < (SIZE_MAX / 2)) { // prevent overflow
buffsize = buffsize * 2;
} else if(buffsize == SIZE_MAX) {
fprintf(stderr, "getcwd failed, path too long max %d\n", buffsize);
return NULL;
} else {
buffsize = SIZE_MAX; // getcwd limit
}

buff = realloc(buff, buffsize);
if(!buff) return NULL; // oom !
}
return buff;
}


Unlimited length path names, how do they work ?!

There is another way :
As an extension to the POSIX.1-2001 standard, Linux (libc4, libc5, glibc) getcwd() allocates the buffer dynamically using malloc() if buf is NULL on call. In this case, the allocated buffer has the length size unless size is zero, when buf is allocated as big as necessary.

I wonder how they deal with unlimited length path names, one time I shall look. In the meatime how can one code for UNLIMITED LENGTH PATHS !


No comments: