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;
- }
}