Thanks, everyone, who's commented so far... here's the plan; apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, apr_int32_t wantthis, apr_pool_t *p)
wantthis is the bit flag of attributes we are interested in. Some will always be returned, and the apr_stat function can always return anything _they comes for free_. apr_stat will reply in a new member value, finfo_valid, to describe the results returned. It will only fail for the current reasons. If it can't get a particular result, it just goes on, and it's the caller's job to check finfo.valid. #define APR_FINFO_LINK 0x00000001 #define APR_FINFO_MTIME 0x00000010 #define APR_FINFO_CTIME 0x00000020 #define APR_FINFO_ATIME 0x00000040 #define APR_FINFO_SIZE 0x00000100 #define APR_FINFO_ASIZE 0x00000200 #define APR_FINFO_CSIZE 0x00000400 #define APR_FINFO_DEV 0x00001000 #define APR_FINFO_INODE 0x00002000 #define APR_FINFO_TYPE 0x00008000 #define APR_FINFO_USER 0x00010000 #define APR_FINFO_GROUP 0x00020000 #define APR_FINFO_UPROT 0x00100000 #define APR_FINFO_GPROT 0x00200000 #define APR_FINFO_WPROT 0x00400000 #define APR_FINFO_ICASE 0x01000000 /* dev is case insensitive */ #define APR_FINFO_FCASE 0x02000000 /* retrieve filename case */ #define APR_FINFO_MIN 0x00008170 /* minimal: type, dates and size */ #define APR_FINFO_IDENT 0x00003000 /* dev and inode */ #define APR_FINFO_OWNER 0x00030000 /* user and group */ #define APR_FINFO_PROT 0x00700000 /* all protections */ The first flag, APR_FINFO_LINK, superceeds the apr_lstat call. If that flag is set in finfo.valid, the call returned the stat of the link. On systems that don't support them, dev should then be derived from a hash of the mount point and inode should be derived from a hash of the full pathname. If they come free, great. Otherwise we may need to parse, or cycle through the tree. Don't ask unless you are willing to wait; canonical will walk the whole tree anyways and work these out in a more optimal fashion. Same goes for user/group/protections. Some unices don't support group concepts at all, and both prot and owner fields get very expensive on win32. Again, if it doesn't matter, don't ask. The rest should be blatently obvious, except the APR_FINFO_xCASE The ICASE/FCASE flags should help somewhat to get the proper case in an optimal fashion. The fileinfo structure grows char *filespec, which caches the name that was passed (for free). If APR_FINFO_FCASE is specified, the char *filename member contains the file's name (no path). If the case matched, this is optimized to be the offset into filespec. Just what it does depends on the flags; user requests neither [they don't care] *filename is null user requests APR_FINFO_ICASE [just asking about the device] test dev for case sensitivity, set .valid |= APR_FINFO_ICASE if so *filename is null user requests APR_FINFO_FCASE [doesn't know the case] test dev for case sensitivity, set .valid |= APR_FINFO_ICASE if so *filename is set to its true case plus .valid |= APR_FINFO_FCASE user requests APR_FINFO_FCASE && APR_FINFO_ICASE [user remembers the dev] if user sets finfo.dev [known to be case insensitive] and dev = finfo.dev we _skip_ the dev case sensitivity test and set .valid |= APR_FINFO_ICASE *filename is set to its true case and .valid |= APR_FINFO_FCASE So this will help optimize any application that has performance issues and a strong requirement to know the true file name (such as... apache ;-?) Combinations will impact performance. Asking on win32 for dev/inode and the fcase effectively requires two stats. Ask for just what you need. I'm suggesting we add asize (allocated size, e.g. for filesystems with preallocation) and csize (the actual size consumed on disk.) Apache may have no application, but other applications may. These may not come for free on all platforms. size itself is the number of bytes you get when you read the file byte for byte from front to the end. asize is the maximum allocated extent. And csize may factor compressions, and offset by blocking. Expensive calculations if you have to chase down the dev, unknowable on some platforms. So let's hear it... this should be committed today to get us out of the mess we are in with Win32. I'll offer the 'patch' on the first hurrah.