From: <[EMAIL PROTECTED]> Sent: Friday, January 19, 2001 12:46 PM
> > ++1. If you get Windows working, I'll do Unix when you are done. How about the other way around? Here's the proof-of-concept on unix; I don't promise it's complete, and don't promise it compiles, but it underscores the concept. Windows is obviously much trickier... I'm working that up now, repleat with the open a file from an apr_finfo_t (of course, we already get stats from an open apr_file_t). Since both apr_finfo_t and apr_file_t will capture a filename, they are -interchangable-. One thing I don't like, looking at this, is that we pass 'our own' apr_finfo_t structure, which means it is just as likely to be passed on the stack. That's not healthy for later opening the file from the apr_finfo_t, yet we have 'resolved' not to actually copy these filenames. I imagine it really ought to be one or the other, we do or we don't copy the name, therefore we musn't or must allocate an apr_finfo_t from the pool. Bill Index: include/apr_file_info.h =================================================================== RCS file: /home/cvs/apr/include/apr_file_info.h,v retrieving revision 1.1 diff -u -r1.1 apr_file_info.h --- include/apr_file_info.h 2001/01/19 17:29:44 1.1 +++ include/apr_file_info.h 2001/01/20 01:02:55 @@ -136,14 +136,40 @@ typedef struct apr_finfo_t apr_finfo_t; +#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 /* if dev is case insensitive */ +#define APR_FINFO_FCASE 0x02000000 /* filename in proper 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 file information structure. This is analogous to the POSIX * stat structure. */ struct apr_finfo_t { - /** The access permissions of the file. Currently this mimics Unix - * access rights. - */ + /** Allocates memory and closes lingering handles in the specified pool */ + apr_pool_t *cntxt; + /** The bitmask describing valid fields of this apr_finfo_t structure + * including all available 'wanted' fields and potentially more */ + apr_int32_t valid; + /** The access permissions of the file. Mimics Unix access rights. */ apr_fileperms_t protection; /** The type of file. One of APR_NOFILE, APR_REG, APR_DIR, APR_CHR, * APR_BLK, APR_PIPE, APR_LNK, APR_SOCK @@ -153,18 +179,28 @@ apr_uid_t user; /** The group id that owns the file */ apr_gid_t group; - /** The inode of the file. (Not portable?) */ + /** The inode of the file. */ apr_ino_t inode; - /** The id of the device the file is on. (Not portable?) */ + /** The id of the device the file is on. */ apr_dev_t device; /** The size of the file */ apr_off_t size; + /** The space allocated for the file */ + apr_off_t csize; + /** The storage size consumed by the file */ + apr_off_t csize; /** The time the file was last accessed */ apr_time_t atime; /** The time the file was last modified */ apr_time_t mtime; /** The time the file was last changed */ apr_time_t ctime; + /** The full pathname of the file */ + char *filespec; + /** The file's name alone, in filesystem case */ + char *filename; + /** The file's handle, if accessed (can be submitted to apr_duphandle) */ + apr_file_t *filehand; }; /** @@ -173,11 +209,12 @@ * @param finfo Where to store the information about the file, which is * never touched if the call fails. * @param fname The name of the file to stat. + * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ values * @param cont the pool to use to allocate the new file. - * @deffunc apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, apr_pool_t *cont) + * @deffunc apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, apr_int32_t wanted, apr_pool_t *cont) */ APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname, - apr_pool_t *cont); + apr_int32_t wanted, apr_pool_t *cont); /** * get the specified file's stats. The file is specified by filename, @@ -186,11 +223,14 @@ * @param finfo Where to store the information about the file, which is * never touched if the call fails. * @param fname The name of the file to stat. + * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ values * @param cont the pool to use to allocate the new file. - * @deffunc apr_status_t apr_lstat(apr_finfo_t *finfo, const char *fname, apr_pool_t *cont) + * @deffunc apr_status_t apr_lstat(apr_finfo_t *finfo, const char *fname, apr_int32_t wanted, apr_pool_t *cont) + * @tip This function is depreciated, it's equivilant to calling apr_stat with + * the wanted flag value APR_FINFO_LINK */ APR_DECLARE(apr_status_t) apr_lstat(apr_finfo_t *finfo, const char *fname, - apr_pool_t *cont); + apr_int32_t wanted, apr_pool_t *cont); /** * Open the specified directory. Index: include/apr_file_io.h =================================================================== RCS file: /home/cvs/apr/include/apr_file_io.h,v retrieving revision 1.87 diff -u -r1.87 apr_file_io.h --- include/apr_file_io.h 2001/01/19 17:29:44 1.87 +++ include/apr_file_io.h 2001/01/20 01:02:55 @@ -521,10 +521,12 @@ /** * get the specified file's stats. * @param finfo Where to store the information about the file. + * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ values * @param thefile The file to get information about. - * @deffunc apr_status_t apr_getfileinfo(apr_finfo_t *finfo, apr_file_t *thefile) + * @deffunc apr_status_t apr_getfileinfo(apr_finfo_t *finfo, apr_int32_t wanted, apr_file_t *thefile) */ -APR_DECLARE(apr_status_t) apr_getfileinfo(apr_finfo_t *finfo, +APR_DECLARE(apr_status_t) apr_getfileinfo(apr_finfo_t *finfo, + apr_int32_t wanted, apr_file_t *thefile); #ifdef __cplusplus Index: file_io/unix/filestat.c =================================================================== RCS file: /home/cvs/apr/file_io/unix/filestat.c,v retrieving revision 1.33 diff -u -r1.33 filestat.c --- file_io/unix/filestat.c 2000/11/14 06:40:03 1.33 +++ file_io/unix/filestat.c 2001/01/20 01:02:55 @@ -55,6 +55,7 @@ #include "fileio.h" #include "apr_file_io.h" #include "apr_general.h" +#include "apr_strings.h" #include "apr_errno.h" static apr_filetype_e filetype_from_mode(int mode) @@ -80,11 +81,14 @@ return type; } -apr_status_t apr_getfileinfo(apr_finfo_t *finfo, apr_file_t *thefile) +apr_status_t apr_getfileinfo(apr_finfo_t *finfo, apr_int32_t wanted, + apr_file_t *thefile) { struct stat info; if (fstat(thefile->filedes, &info) == 0) { + finfo->cntxt = thefile->cntxt; + finfo->valid = APR_FINFO_MIN| APR_FINFO_IDENT | APR_FINFO_OWNER | APR_FINFO_PROT; finfo->protection = apr_unix_mode2perms(info.st_mode); finfo->filetype = filetype_from_mode(info.st_mode); finfo->user = info.st_uid; @@ -92,9 +96,18 @@ finfo->size = info.st_size; finfo->inode = info.st_ino; finfo->device = info.st_dev; + finfo->nlinks = info.st_nlink; apr_ansi_time_to_apr_time(&finfo->atime, info.st_atime); apr_ansi_time_to_apr_time(&finfo->mtime, info.st_mtime); apr_ansi_time_to_apr_time(&finfo->ctime, info.st_ctime); + finfo->filepath = thefile->fname; + if (wanted & APR_FINFO_CSIZE) { + finfo->csize = info.st_blocks * 512; + finfo->valid |= APR_FINFO_CSIZE; + } + if (finfo->filetype = APR_LNK) + finfo->valid |= APR_FINFO_LINK + } return APR_SUCCESS; } else { @@ -111,11 +124,20 @@ return APR_SUCCESS; } -apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, apr_pool_t *cont) +apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, + apr_int32_t wanted, apr_pool_t *cont) { struct stat info; + int srv; - if (stat(fname, &info) == 0) { + if (wanted & APR_FINFO_LINK) + srv = lstat(fname, &info); + else + srv = stat(fname,info); + + if (srv == 0) { + finfo->cntxt = cont; + finfo->valid = APR_FINFO_MIN| APR_FINFO_IDENT | APR_FINFO_OWNER | APR_FINFO_PROT; finfo->protection = apr_unix_mode2perms(info.st_mode); finfo->filetype = filetype_from_mode(info.st_mode); finfo->user = info.st_uid; @@ -123,9 +145,18 @@ finfo->size = info.st_size; finfo->inode = info.st_ino; finfo->device = info.st_dev; + finfo->nlinks = info.st_nlink; apr_ansi_time_to_apr_time(&finfo->atime, info.st_atime); apr_ansi_time_to_apr_time(&finfo->mtime, info.st_mtime); apr_ansi_time_to_apr_time(&finfo->ctime, info.st_ctime); + finfo->filepath = fname; + if (wanted & APR_FINFO_CSIZE) { + finfo->csize = info.st_blocks * 512; + finfo->valid |= APR_FINFO_CSIZE; + } + if (finfo->filetype = APR_LNK) + finfo->valid |= APR_FINFO_LINK + } return APR_SUCCESS; } else { @@ -163,24 +194,12 @@ } } -apr_status_t apr_lstat(apr_finfo_t *finfo, const char *fname, apr_pool_t *cont) +/* Perhaps this becomes nothing but a macro? + */ +apr_status_t apr_lstat(apr_finfo_t *finfo, const char *fname, + apr_int32_t wanted, apr_pool_t *cont) { - struct stat info; + return apr_stat(finfo, fname, wanted | APR_FINFO_LINK, cont); +} - if (lstat(fname, &info) == 0) { - finfo->protection = apr_unix_mode2perms(info.st_mode); - finfo->filetype = filetype_from_mode(info.st_mode); - finfo->user = info.st_uid; - finfo->group = info.st_gid; - finfo->size = info.st_size; - finfo->inode = info.st_ino; - finfo->device = info.st_dev; - apr_ansi_time_to_apr_time(&finfo->atime, info.st_atime); - apr_ansi_time_to_apr_time(&finfo->mtime, info.st_mtime); - apr_ansi_time_to_apr_time(&finfo->ctime, info.st_ctime); - return APR_SUCCESS; - } - else { - return errno; - } }