Add GETFILEINFO attribute to retrieve a file's i-node number
The code in COPYFILE has a difficult time determining whether it is about to destroy its input file because it has been given the same file as both input and output.
It would be useful for the Lisp code to be able to determine if two existing files have the same i-node number once any links have been resolved and the true-name of the files have been determined.
There is no interface that easily provides for enquiring if (SAMEFILEP file1 file2) however the (GETFILEINFO file attribute) interface can be extended to ask about the i-node number. Unfortunately, an i-node number is likely to be 64-bits and Lisp does not deal in 64-bit values so it is easiest to break this up into two separate calls to get the lower and upper halves of the i-node number as two FIXP values. This can be implemented as, for example:
(GETFILEINFO "file1" 'INODE-LO)
(GETFILEINFO "file1" 'INODE-HI)
so that SAMEFILEP can be defined as
(DEFINEQ (SAMEFILEP (FILE1 FILE2)
(AND (EQUAL (GETFILEINFO FILE1 'INODE-LO) (GETFILEINFO FILE2 'INODE-LO))
(EQUAL (GETFILEINFO FILE1 'INODE-HI) (GETFILEINFO FILE2 'INODE-HI)))))
In most cases we expect SAMEFILEP to return NIL, so checking INODE-LO first will be quicker as it is mostly likely to be different, and will short-circuit the AND.
As with all other attributes, it is an error to ask for the inode number of a file for which does not exist.
Should it be an error if the file doesn't exist, or distinguished values that the predicate could recognize. MIN.FIXP and/or MAX.FIXP ?
EQUAL is a good test--the CORE device might just return its internal file identifier.
PSEUDOHOST might need to pass this down to the method of the target device.
Do files accessed via PUP or XNS on file servers also have INodes? Remote mounted drives /mnt/c/?
Also, what happens if you happen with older maikos? Does the LO and High return NIL or a bumber or error?
Could something like this be used to test if {DSK}<dir>foo is hard-linked (or samefilep for a hard or soft link?) to foo.~NN~?
@rmkaplan - the check whether the file exists (and error if it doesn't) is common for all GETATTRIBUTE calls whether or not the file is on a Unix file system (e.g., (GETATTRIBUTE "{core}foo" 'LENGTH) will result in an error if foo doesn't exist) - I don't think i-node queries should behave differently from attribute queries on DSK or any other device.
@masinter - asking for an attribute that isn't recognized by the Lisp code, or asking for an attribute that is not supported on a particular file device both get a NIL response (that's been there forever). In a sysout that knows about the INODE queries with a Maiko that doesn't it gets a NIL result.
Yes, you can tell if a name is hard-linked to another name - they'll have the same i-node number, and it turns out that because the Maiko code lets the OS resolve symbolic links it will also give you the i-node number for the target file rather than the i-node number of the link itself.
If an OS's remote mounted file system provides an i-node number in response to an fstat() syscall it will get i-node numbers for those too (just as it gets the length of a file from the fstat syscall).
It should bind the results of the GETFILEINFO for the INODE-LO for each file and make sure they're not NIL before doing the EQUAL check. So, more like (pardon any paren errors...):
(DEFINEQ (SAMEFILEP (FILE1 FILE2)
(LET ((LO1 (GETFILEINFO FILE1 'INODE-LO))
(LO2 (GETFILEINFO FILE2 'INODE-LO))
(AND LO1 (EQUAL LO1 LO2)
(EQUAL (GETFILEINFO FILE1 'INODE-HI) (GETFILEINFO FILE2 'INODE-HI))))))
Isn't the point that there are 2 calls to GETFILEINFO that whose values together stand one-to-one with a particular physical file and can be tested with EQUAL? For Unix the values are or are derived from the i-node. For the CORE device, for example, I think the first call could just return its COREFILEINFOBLK pointer, the second could return NIL.
On Aug 19, 2025, at 7:27 PM, Nick Briggs @.***> wrote:
nbriggs left a comment (Interlisp/medley#2263) https://github.com/Interlisp/medley/issues/2263#issuecomment-3203944518 @rmkaplan https://github.com/rmkaplan - the check whether the file exists (and error if it doesn't) is common for all GETATTRIBUTE calls whether or not the file is on a Unix file system (e.g., (GETATTRIBUTE "{core}foo" 'LENGTH) will result in an error if foo doesn't exist) - I don't think i-node queries should behave differently from attribute queries on DSK or any other device.
@masinter https://github.com/masinter - asking for an attribute that isn't recognized by the Lisp code, or asking for an attribute that is not supported on a particular file device both get a NIL response (that's been there forever). In a sysout that knows about the INODE queries with a Maiko that doesn't it gets a NIL result.
Yes, you can tell if a name is hard-linked to another name - they'll have the same i-node number, and it turns out that because the Maiko code lets the OS resolve symbolic links it will also give you the i-node number for the target file rather than the i-node number of the link itself.
If an OS's remote mounted file system provides an i-node number in response to an fstat() syscall it will get i-node numbers for those too (just as it gets the length of a file from the fstat syscall).
— Reply to this email directly, view it on GitHub https://github.com/Interlisp/medley/issues/2263#issuecomment-3203944518, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQSTUJP3BOY6FCXWIHPMAQL3OPMK3AVCNFSM6AAAAACEG2J6RGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTEMBTHE2DINJRHA. You are receiving this because you were mentioned.
@rmkaplan - if someone wants to implement an i-node-like attribute query for the CORE device that's great -- and it could work as you suggested, but that wasn't part of my proposal. Since there aren't issues with hard/soft links (and multiple names for for a single file on {DSK} and {UNIX}) for CORE files it should be the case that (EQUAL (INFILEP FILE1) (INFILEP FILE2)) (or some minor variant of that) should tell one that the user gave the same file name for source and destination.
@rmkaplan - by the way, the PSEUDOHOST code doesn't need to do anything extra -- the PSEUDOHOST mapped file name will have been resolved to {dsk} or {unix} by the time it gets to Maiko and it will just get the right i-node number(s) as if no mapping were involved.
SAMEFILEP should be device independent, so that COPYFILE doesn't have to discriminate. It should be something like (CL:WHEN ( AND (EQUAL (INFILEP FROMFILE)(INFILEP TOFILE))) (SAMEFILEP FROMFILE TOFILE)) (ERROR ...)
On Aug 19, 2025, at 9:38 PM, Nick Briggs @.***> wrote:
nbriggs left a comment (Interlisp/medley#2263) https://github.com/Interlisp/medley/issues/2263#issuecomment-3204161986 @rmkaplan https://github.com/rmkaplan - if someone wants to implement an i-node-like attribute query for the CORE device that's great -- and it could work as you suggested, but that wasn't part of my proposal. Since there aren't issues with hard/soft links (and multiple names for for a single file on {DSK} and {UNIX}) for CORE files it should be the case that (EQUAL (INFILEP FILE1) (INFILEP FILE2)) (or some minor variant of that) should tell one that the user gave the same file name for source and destination.
— Reply to this email directly, view it on GitHub https://github.com/Interlisp/medley/issues/2263#issuecomment-3204161986, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQSTUJO2I5PD67XNH3HVWKL3OP3VHAVCNFSM6AAAAACEG2J6RGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTEMBUGE3DCOJYGY. You are receiving this because you were mentioned.