summaryrefslogtreecommitdiff
path: root/file_io
diff options
context:
space:
mode:
authorstoddard <stoddard@13f79535-47bb-0310-9956-ffa450edef68>2000-02-01 00:15:11 +0000
committerstoddard <stoddard@13f79535-47bb-0310-9956-ffa450edef68>2000-02-01 00:15:11 +0000
commit656aab20e12cf63a32092ab2fe284c9c11d7cae0 (patch)
tree9a03a38b50235dd669ade04a1655e934b9f5520d /file_io
parentfc290625a518f3046e8fe1978e002df0fd6bd798 (diff)
downloadlibapr-656aab20e12cf63a32092ab2fe284c9c11d7cae0.tar.gz
Reimplement ap_stat using native Windows calls. This is good for a 10% performance
boost serving a 500 byte static file. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@59637 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'file_io')
-rw-r--r--file_io/win32/filestat.c73
1 files changed, 66 insertions, 7 deletions
diff --git a/file_io/win32/filestat.c b/file_io/win32/filestat.c
index 8ad786e5b..52e0b363f 100644
--- a/file_io/win32/filestat.c
+++ b/file_io/win32/filestat.c
@@ -58,15 +58,12 @@
#include "apr_file_io.h"
#include "apr_general.h"
#include "apr_errno.h"
+#include "apr_time.h"
#include <sys/stat.h>
-#define S_ISLNK(m) (0)
-#ifndef S_ISREG
-#define S_ISREG(m) (((m)&(S_IFMT)) == (S_IFREG))
-#endif
-#ifndef S_ISDIR
-#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR)
-#endif
+#define S_ISLNK(m) (0)
+#define S_ISREG(m) (((m) & (S_IFMT)) == S_IFREG)
+#define S_ISDIR(m) (((m) & (S_IFDIR)) == S_IFDIR)
static ap_filetype_e filetype_from_mode(int mode)
{
@@ -81,6 +78,27 @@ static ap_filetype_e filetype_from_mode(int mode)
return type;
}
+BOOLEAN is_exe(const char* fname, ap_context_t *cont) {
+ const char* exename;
+ const char* ext;
+ exename = strrchr(fname, '/');
+ if (!exename) {
+ exename = strrchr(fname, '\\');
+ }
+ if (!exename) {
+ exename = fname;
+ }
+ else {
+ exename++;
+ }
+ ext = strrchr(exename, '.');
+
+ if (ext && (!strcasecmp(ext,".exe") || !strcasecmp(ext,".com") ||
+ !strcasecmp(ext,".bat") || !strcasecmp(ext,".cmd"))) {
+ return TRUE;
+ }
+ return FALSE;
+}
ap_status_t ap_getfileinfo(ap_finfo_t *finfo, struct file_t *thefile)
{
@@ -110,6 +128,46 @@ ap_status_t ap_getfileinfo(ap_finfo_t *finfo, struct file_t *thefile)
}
ap_status_t ap_stat(ap_finfo_t *finfo, const char *fname, ap_context_t *cont)
{
+ WIN32_FILE_ATTRIBUTE_DATA FileInformation;
+
+ memset(finfo,'\0', sizeof(*finfo));
+
+ if (!GetFileAttributesEx(fname, GetFileExInfoStandard, &FileInformation)) {
+ return GetLastError();
+ }
+ /* Filetype - Directory or file? */
+ if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ finfo->protection |= S_IFDIR;
+ finfo->filetype = APR_DIR;
+ }
+ else {
+ finfo->protection |= S_IFREG;
+ finfo->filetype = APR_REG;
+ }
+ /* Read, write execute for owner */
+ if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
+ finfo->protection |= S_IREAD;
+ }
+ else {
+ finfo->protection |= S_IREAD;
+ finfo->protection |= S_IWRITE;
+ }
+ /* Is this an executable? Guess based on the file extension. */
+ if (is_exe(fname, cont)) {
+ finfo->protection |= S_IEXEC;
+ }
+ /* File times */
+ FileTimeToAprTime(&finfo->atime, &FileInformation.ftLastAccessTime);
+ FileTimeToAprTime(&finfo->ctime, &FileInformation.ftCreationTime);
+ FileTimeToAprTime(&finfo->mtime, &FileInformation.ftLastWriteTime);
+
+ /* File size
+ * Note: This cannot handle files greater than can be held by an int */
+ finfo->size = FileInformation.nFileSizeLow;
+
+ return APR_SUCCESS;
+#if 0
+ /* ap_stat implemented using stat() */
struct stat info;
int rv = stat(fname, &info);
if (rv == 0) {
@@ -127,5 +185,6 @@ ap_status_t ap_stat(ap_finfo_t *finfo, const char *fname, ap_context_t *cont)
else {
return errno;
}
+#endif
}