> On Apr 23, 2020, at 7:27 AM, Lassi Kortela <xxxxxx@lassi.io> wrote:
>
>>> I suspect that if the current working directory is specified in terms
>>> of parameter-like semantics then it should be possible to make use of
>>> openat() etc behind the scenes
>> Gambit does some of this; I suggest grepping the source code
>
> All of the calls are in os_files.c:
>
> $ grep -nF 'at (' lib/os_files.c
> 542: new_dir = openat (dir, start, O_DIRECTORY);
> 587: fd = openat (dir, path2, flags, mode);
> 621: result = mkfifoat (dir, path2, mode);
> 655: result = mkdirat (dir, path2, mode);
> 686: result = unlinkat (dir, path2, 0);
> 724: result = linkat (olddir, oldpath2, newdir, newpath2, 0);
> 760: result = symlinkat (target, dir, path2);
> 797: result = readlinkat (dir, path2, buf, bufsize);
> 893: result = linkat (olddir, oldpath2, newdir, newpath2, 0);
> 900: result = unlinkat (olddir, oldpath2, 0);
> 911: result = renameat (olddir, oldpath2, newdir, newpath2);
> 962: int fd = openat (dir, path2, O_DIRECTORY);
> 1001: result = fstatat (dir, path2, statbuf, follow ? 0 : AT_SYMLINK_NOFOLLOW);
Interestingly the use of the “at” system calls was added to Gambit to handle filenames that are longer than PATH_MAX. It allows accessing files that are very deeply nested. It uses openat() on successive chunks of the path <= PATH_MAX to reach deeply nested files.
In the following example Gambit handles a path of length 10009 on linux (well beyond the typical 1024 character limit) whereas most other Scheme implementations give an error (I tested Chicken, Chez and Guile):
% cat long.scm
(define deep-dir
(string-append "/tmp"
(apply string-append
(vector->list (make-vector 5000 "/x")))))
(define path (string-append deep-dir "/file"))
(write (list (string-length path) (read (open-input-file path))))
(newline)
% gsi long.scm
(10009 hello!)
% csi -quiet long.scm
Error: (open-input-file) cannot open file - File name too long: "/tmp/.../x/x/x/x/file"
...
% scheme --quiet --script long.scm
Exception in open-input-file: failed for /tmp/.../x/x/x/x/file: file name too long
% guile long.scm
...
ERROR: In procedure open-file:
ERROR: In procedure open-file: File name too long: "/tmp/.../x/x/x/x/file"
Marc