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

Tuesday, 23 August 2011

Round and round the garden

Go was playing up on FreeBSD (or maybe I've learned enough to cure that now, not sure yet) so I decided to get a Qemu image of some Linux up and running.

Debian was the one that finally worked.

Now, I use Plan 9 as my working environment. I run a Qemu image of it on a FreeBSD machine in the Co-lo which I connect to with drawterm.
I need to be able to run commands on the Debian from within the Plan 9, usually via win, so I can plumb the error messages (e.g. file.go:23).

I made a diagram of what I ended up with.
diagram

So today I tried to compile some C.
cc1: error: file.c: Value too large for defined data type
A fantastic error message if ever I saw one.
naturally someone else has already had that error and consequently I discovered that GCC can't compile code if it resides on a Samba share because the inode numbers are too big.

The solution is to remap the inode numbers in mount.

So the mount command in the diagram is out of date, it is now

# mount -t smbfs //10.0.2.2/kam /mnt/kam2 \
nounix,noserverino,uid=1000,gid=1000,credential=/root/kam.password


Also I had to use the IP address rather than the hostname, even with an entry in /etc/hosts. I probably need a WINS file somewhere, cba with that

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 !