On Wed, Jun 07, 2023 at 04:59:11PM +1000, raf <[email protected]> wrote:
> On Tue, Jun 06, 2023 at 06:49:35PM -0700, Ken Cunningham > <[email protected]> wrote: > > > > On Jun 6, 2023, at 6:28 PM, raf via macports-users > > > <[email protected]> wrote: > > > > > > On Wed, Jun 07, 2023 at 11:09:13AM +1000, raf via macports-users > > > <[email protected]> wrote: > > > > > >> Yay! It worked. Many thanks. I'll fix my Makefile for the upcoming > > >> version > > >> of rawhide and create the Portfile for that. > > > > > > I spoke too soon. The compilation worked, but when I ran the > > > program to list everything in my home directory, there were > > > many many "Bad file descriptor" errors for fstatat(). It's > > > happening for everything immediately below the current > > > directory. Any ideas? > > > > > > cheers, > > > raf > And with debugging on, everything looks correct until > the error: > > openat(parent_fd=3, path=.git) > openat: dir_fd 4 > fdopendir(dir_fd=4) > dir entry ./.git/branches > fstatat(parent_fd=4, path=branches) > rh: fstatat ./.git/branches: Bad file descriptor > > The "bad" file descriptor is 4 which was returned by openat. > That's what it looks like on other systems that work. Mysterious. Looking at the source for legacysupport, I think I can see the deliberate use of an invalid file descriptor. There must be a reason for it, but I don't understand what is intended. In atcalls.c: int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags) { ERR_ON(EINVAL, flags & ~AT_SYMLINK_NOFOLLOW); if (flags & AT_SYMLINK_NOFOLLOW) { return ATCALL(dirfd, pathname, lstat(pathname, buf)); } else { return ATCALL(dirfd, pathname, stat(pathname, buf)); } } In common-priv.h is the _ATCALL macro: #define _ATCALL(fd, p, onerr, what) \ ({ typeof(what) __result; \ int oldCWD = -1; \ if (fd != AT_FDCWD && p[0] != '/') { \ oldCWD = open(".", O_RDONLY); \ if (best_fchdir(-1) < 0 && oldCWD != -1) { \ close(oldCWD); oldCWD = -1; \ } \ if (best_fchdir(fd) < 0) { \ PROTECT_ERRNO(best_fchdir(oldCWD)); \ if (oldCWD != -1) PROTECT_ERRNO(close(oldCWD)); \ return onerr; \ } \ } \ __result = (what); \ if (fd != AT_FDCWD && p[0] != '/') { \ PROTECT_ERRNO(best_fchdir(oldCWD)); \ if (oldCWD != -1) PROTECT_ERRNO(close(oldCWD)); \ } \ __result; \ }) #define ATCALL(fd, p, what) _ATCALL(fd, p, -1, what) The call to best_fchdir(-1) would presumably set errno to "Bad File Descriptor". But I don't see why best_fchdir(fd) or the stat() would fail, so that shouldn't matter. Maybe I need to failover to stat() when fstatat() fails with EBADF? No. I made fstatat() failover to stat(), but then openat() resulted in Bad File Descriptor. So I made openat() failover to open(), but then fdopendir() started saying that a directory was "Not a directory". This approach isn't working. I think I should give up on getting it working on 10.6.8. cheers, raf
