diff options
author | Dmitry Stogov <dmitry@php.net> | 2008-08-15 15:00:11 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2008-08-15 15:00:11 +0000 |
commit | 4ccb9037cce71f3a2fb65d075051286882e5c29c (patch) | |
tree | 4f793eea3f7ee777f9367ad6f33de49d5e2e32e4 /TSRM | |
parent | b76b5a6f17ee33e1994c5f3bf8355e5d7230027c (diff) | |
download | php-git-4ccb9037cce71f3a2fb65d075051286882e5c29c.tar.gz |
- [DOC] make stat, touch, filemtime, filemsize and related functions more portable (almost 100% equivalent to linux now)
- [DOC] add support for touch($dir)
- fix windows server 2008/vista support (#45447) (Pierre)
Diffstat (limited to 'TSRM')
-rw-r--r-- | TSRM/tsrm_virtual_cwd.c | 107 |
1 files changed, 92 insertions, 15 deletions
diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c index eacd21bc75..e249083534 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/TSRM/tsrm_virtual_cwd.c @@ -136,6 +136,33 @@ static int php_check_dots(const char *element, int n) free((s)->cwd); #ifdef TSRM_WIN32 + +#define SECS_BETWEEN_EPOCHS (__int64)11644473600 +#define SECS_TO_100NS (__int64)10000000 +static inline time_t FileTimeToUnixTime(const FILETIME FileTime) +{ + __int64 UnixTime; + long *nsec = NULL; + SYSTEMTIME SystemTime; + FileTimeToSystemTime(&FileTime, &SystemTime); + + UnixTime = ((__int64)FileTime.dwHighDateTime << 32) + + FileTime.dwLowDateTime; + + UnixTime -= (SECS_BETWEEN_EPOCHS * SECS_TO_100NS); + + if (nsec) { + *nsec = (UnixTime % SECS_TO_100NS) * (__int64)100; + } + + UnixTime /= SECS_TO_100NS; /* now convert to seconds */ + + if ((time_t)UnixTime != UnixTime) { + UnixTime = 0; + } + return (time_t)UnixTime; +} + CWD_API int php_sys_stat(const char *path, struct stat *buf) /* {{{ */ { WIN32_FILE_ATTRIBUTE_DATA data; @@ -195,24 +222,19 @@ CWD_API int php_sys_stat(const char *path, struct stat *buf) /* {{{ */ buf->st_mode |= (S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)); } } - } - buf->st_nlink = 1; + } + + buf->st_nlink = 1; t = data.nFileSizeHigh; t = t << 32; t |= data.nFileSizeLow; buf->st_size = t; - t = data.ftLastAccessTime.dwHighDateTime; - t = t << 32; - t |= data.ftLastAccessTime.dwLowDateTime; - buf->st_atime = (unsigned long)((t / 10000000) - 11644473600); - t = data.ftCreationTime.dwHighDateTime; - t = t << 32; - t |= data.ftCreationTime.dwLowDateTime; - buf->st_ctime = (unsigned long)((t / 10000000) - 11644473600); - t = data.ftLastWriteTime.dwHighDateTime; - t = t << 32; - t |= data.ftLastWriteTime.dwLowDateTime; - buf->st_mtime = (unsigned long)((t / 10000000) - 11644473600); + buf->st_atime = FileTimeToUnixTime(data.ftLastAccessTime); + buf->st_ctime = FileTimeToUnixTime(data.ftCreationTime); + buf->st_mtime = FileTimeToUnixTime(data.ftLastWriteTime); + if (buf->st_mtime != buf->st_atime) { + buf->st_atime = buf->st_mtime; + } return 0; } /* }}} */ @@ -279,8 +301,14 @@ CWD_API void virtual_cwd_startup(void) /* {{{ */ if (!result) { cwd[0] = '\0'; } - main_cwd_state.cwd = strdup(cwd); + main_cwd_state.cwd_length = strlen(cwd); +#ifdef TSRM_WIN32 + if (main_cwd_state.cwd_length >= 2 && cwd[1] == ':') { + cwd[0] = toupper(cwd[0]); + } +#endif + main_cwd_state.cwd = strdup(cwd); #ifdef ZTS ts_allocate_id(&cwd_globals_id, sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor); @@ -331,6 +359,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */ *length = state->cwd_length+1; retval = (char *) malloc(*length+1); memcpy(retval, state->cwd, *length); + retval[0] = toupper(retval[0]); retval[*length-1] = DEFAULT_SLASH; retval[*length] = '\0'; return retval; @@ -978,6 +1007,50 @@ CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC) /* {{{ */ /* }}} */ #if HAVE_UTIME +#ifdef TSRM_WIN32 +static void UnixTimeToFileTime(time_t t, LPFILETIME pft) /* {{{ */ +{ + // Note that LONGLONG is a 64-bit value + LONGLONG ll; + + ll = Int32x32To64(t, 10000000) + 116444736000000000; + pft->dwLowDateTime = (DWORD)ll; + pft->dwHighDateTime = ll >> 32; +} +/* }}} */ + +static int win32_utime(const char *filename, struct utimbuf *buf) /* {{{ */ +{ + FILETIME mtime, atime; + BOOL f; + HANDLE hFile; + + hFile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + + if ( hFile == INVALID_HANDLE_VALUE ) { + return -1; + } + + if (!buf) { + SYSTEMTIME st; + GetSystemTime(&st); + SystemTimeToFileTime(&st, &mtime); + atime = mtime; + } else { + UnixTimeToFileTime(buf->modtime, &mtime); + UnixTimeToFileTime(buf->actime, &atime); + } + if (!SetFileTime(hFile, NULL, &mtime, &atime)) { + CloseHandle(hFile); + return -1; + } + CloseHandle(hFile); + return 1; +} +/* }}} */ +#endif + CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC) /* {{{ */ { cwd_state new_state; @@ -989,7 +1062,11 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC) / return -1; } +#ifdef TSRM_WIN32 + ret = win32_utime(new_state.cwd, buf); +#else ret = utime(new_state.cwd, buf); +#endif CWD_STATE_FREE(&new_state); return ret; |