Make filestat.c thread-safe

This commit is contained in:
Sascha Schumann 1999-12-12 16:48:54 +00:00
parent d9258da42e
commit 61a6a92618
2 changed files with 68 additions and 54 deletions

View file

@ -34,6 +34,8 @@
#ifndef _BASIC_FUNCTIONS_H #ifndef _BASIC_FUNCTIONS_H
#define _BASIC_FUNCTIONS_H #define _BASIC_FUNCTIONS_H
#include <sys/stat.h>
#include "zend_highlight.h" #include "zend_highlight.h"
extern php3_module_entry basic_functions_module; extern php3_module_entry basic_functions_module;
@ -103,6 +105,12 @@ PHP_FUNCTION(getservbyport);
PHP_FUNCTION(getprotobyname); PHP_FUNCTION(getprotobyname);
PHP_FUNCTION(getprotobynumber); PHP_FUNCTION(getprotobynumber);
#if MSVC5
typedef unsigned int php_stat_len;
#else
typedef int php_stat_len;
#endif
typedef struct { typedef struct {
HashTable *user_shutdown_function_names; HashTable *user_shutdown_function_names;
HashTable putenv_ht; HashTable putenv_ht;
@ -113,9 +121,17 @@ typedef struct {
char str_ebuf[40]; char str_ebuf[40];
zval **array_walk_func_name; zval **array_walk_func_name;
zval **user_compare_func_name; zval **user_compare_func_name;
/* pageinfo.c */
long page_uid; long page_uid;
long page_inode; long page_inode;
long page_mtime; long page_mtime;
/* filestat.c */
char *CurrentStatFile;
php_stat_len CurrentStatLength;
struct stat sb;
struct stat lsb;
} php_basic_globals; } php_basic_globals;
#ifdef ZTS #ifdef ZTS

View file

@ -69,20 +69,9 @@
# endif # endif
#endif #endif
#include "php_filestat.h" #include "ext/standard/basic_functions.h"
#ifndef THREAD_SAFE #include "php_filestat.h"
static char *CurrentStatFile=NULL;
# if MSVC5
static unsigned int CurrentStatLength=0;
# else
static int CurrentStatLength=0;
# endif
static struct stat sb;
#if HAVE_SYMLINK
static struct stat lsb;
#endif
#endif
#ifndef S_ISDIR #ifndef S_ISDIR
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) #define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
@ -97,16 +86,20 @@ static struct stat lsb;
PHP_RINIT_FUNCTION(filestat) PHP_RINIT_FUNCTION(filestat)
{ {
CurrentStatFile=NULL; BLS_FETCH();
CurrentStatLength=0;
BG(CurrentStatFile)=NULL;
BG(CurrentStatLength)=0;
return SUCCESS; return SUCCESS;
} }
PHP_RSHUTDOWN_FUNCTION(filestat) PHP_RSHUTDOWN_FUNCTION(filestat)
{ {
if (CurrentStatFile) { BLS_FETCH();
efree (CurrentStatFile);
if (BG(CurrentStatFile)) {
efree (BG(CurrentStatFile));
} }
return SUCCESS; return SUCCESS;
} }
@ -394,35 +387,40 @@ PHP_FUNCTION(touch)
PHP_FUNCTION(clearstatcache) PHP_FUNCTION(clearstatcache)
{ {
if (CurrentStatFile) { BLS_FETCH();
efree(CurrentStatFile);
CurrentStatFile = NULL; if (BG(CurrentStatFile)) {
efree(BG(CurrentStatFile));
BG(CurrentStatFile) = NULL;
} }
} }
static void _php3_stat(const char *filename, int type, pval *return_value) static void _php3_stat(const char *filename, int type, pval *return_value)
{ {
struct stat *stat_sb = &sb; struct stat *stat_sb;
BLS_FETCH();
if (!CurrentStatFile || strcmp(filename,CurrentStatFile)) { stat_sb = &BG(sb);
if (!CurrentStatFile
|| strlen(filename) > CurrentStatLength) { if (!BG(CurrentStatFile) || strcmp(filename,BG(CurrentStatFile))) {
if (CurrentStatFile) efree(CurrentStatFile); if (!BG(CurrentStatFile)
CurrentStatLength = strlen(filename); || strlen(filename) > BG(CurrentStatLength)) {
CurrentStatFile = estrndup(filename,CurrentStatLength); if (BG(CurrentStatFile)) efree(BG(CurrentStatFile));
BG(CurrentStatLength) = strlen(filename);
BG(CurrentStatFile) = estrndup(filename,BG(CurrentStatLength));
} else { } else {
strcpy(CurrentStatFile,filename); strcpy(BG(CurrentStatFile),filename);
} }
#if HAVE_SYMLINK #if HAVE_SYMLINK
lsb.st_mode = 0; /* mark lstat buf invalid */ BG(lsb).st_mode = 0; /* mark lstat buf invalid */
#endif #endif
if (stat(CurrentStatFile,&sb)==-1) { if (stat(BG(CurrentStatFile),&BG(sb))==-1) {
if (type != 15 || errno != ENOENT) { /* fileexists() test must print no error */ if (type != 15 || errno != ENOENT) { /* fileexists() test must print no error */
php_error(E_NOTICE,"stat failed for %s (errno=%d - %s)",CurrentStatFile,errno,strerror(errno)); php_error(E_NOTICE,"stat failed for %s (errno=%d - %s)",BG(CurrentStatFile),errno,strerror(errno));
} }
efree(CurrentStatFile); efree(BG(CurrentStatFile));
CurrentStatFile=NULL; BG(CurrentStatFile)=NULL;
RETURN_FALSE; RETURN_FALSE;
} }
} }
@ -434,9 +432,9 @@ static void _php3_stat(const char *filename, int type, pval *return_value)
/* do lstat if the buffer is empty */ /* do lstat if the buffer is empty */
if (!lsb.st_mode) { if (!BG(lsb).st_mode) {
if (lstat(CurrentStatFile,&lsb) == -1) { if (lstat(BG(CurrentStatFile),&BG(lsb)) == -1) {
php_error(E_NOTICE,"lstat failed for %s (errno=%d - %s)",CurrentStatFile,errno,strerror(errno)); php_error(E_NOTICE,"lstat failed for %s (errno=%d - %s)",BG(CurrentStatFile),errno,strerror(errno));
RETURN_FALSE; RETURN_FALSE;
} }
} }
@ -445,49 +443,49 @@ static void _php3_stat(const char *filename, int type, pval *return_value)
switch(type) { switch(type) {
case 0: /* fileperms */ case 0: /* fileperms */
RETURN_LONG((long)sb.st_mode); RETURN_LONG((long)BG(sb).st_mode);
case 1: /* fileinode */ case 1: /* fileinode */
RETURN_LONG((long)sb.st_ino); RETURN_LONG((long)BG(sb).st_ino);
case 2: /* filesize */ case 2: /* filesize */
RETURN_LONG((long)sb.st_size); RETURN_LONG((long)BG(sb).st_size);
case 3: /* fileowner */ case 3: /* fileowner */
RETURN_LONG((long)sb.st_uid); RETURN_LONG((long)BG(sb).st_uid);
case 4: /* filegroup */ case 4: /* filegroup */
RETURN_LONG((long)sb.st_gid); RETURN_LONG((long)BG(sb).st_gid);
case 5: /* fileatime */ case 5: /* fileatime */
RETURN_LONG((long)sb.st_atime); RETURN_LONG((long)BG(sb).st_atime);
case 6: /* filemtime */ case 6: /* filemtime */
RETURN_LONG((long)sb.st_mtime); RETURN_LONG((long)BG(sb).st_mtime);
case 7: /* filectime */ case 7: /* filectime */
RETURN_LONG((long)sb.st_ctime); RETURN_LONG((long)BG(sb).st_ctime);
case 8: /* filetype */ case 8: /* filetype */
#if HAVE_SYMLINK #if HAVE_SYMLINK
if (S_ISLNK(lsb.st_mode)) { if (S_ISLNK(BG(lsb).st_mode)) {
RETURN_STRING("link",1); RETURN_STRING("link",1);
} }
#endif #endif
switch(sb.st_mode&S_IFMT) { switch(BG(sb).st_mode&S_IFMT) {
case S_IFIFO: RETURN_STRING("fifo",1); case S_IFIFO: RETURN_STRING("fifo",1);
case S_IFCHR: RETURN_STRING("char",1); case S_IFCHR: RETURN_STRING("char",1);
case S_IFDIR: RETURN_STRING("dir",1); case S_IFDIR: RETURN_STRING("dir",1);
case S_IFBLK: RETURN_STRING("block",1); case S_IFBLK: RETURN_STRING("block",1);
case S_IFREG: RETURN_STRING("file",1); case S_IFREG: RETURN_STRING("file",1);
} }
php_error(E_WARNING,"Unknown file type (%d)",sb.st_mode&S_IFMT); php_error(E_WARNING,"Unknown file type (%d)",BG(sb).st_mode&S_IFMT);
RETURN_STRING("unknown",1); RETURN_STRING("unknown",1);
case 9: /*is writable*/ case 9: /*is writable*/
RETURN_LONG((sb.st_mode&S_IWRITE)!=0); RETURN_LONG((BG(sb).st_mode&S_IWRITE)!=0);
case 10: /*is readable*/ case 10: /*is readable*/
RETURN_LONG((sb.st_mode&S_IREAD)!=0); RETURN_LONG((BG(sb).st_mode&S_IREAD)!=0);
case 11: /*is executable*/ case 11: /*is executable*/
RETURN_LONG((sb.st_mode&S_IEXEC)!=0 && !S_ISDIR(sb.st_mode)); RETURN_LONG((BG(sb).st_mode&S_IEXEC)!=0 && !S_ISDIR(BG(sb).st_mode));
case 12: /*is file*/ case 12: /*is file*/
RETURN_LONG(S_ISREG(sb.st_mode)); RETURN_LONG(S_ISREG(BG(sb).st_mode));
case 13: /*is dir*/ case 13: /*is dir*/
RETURN_LONG(S_ISDIR(sb.st_mode)); RETURN_LONG(S_ISDIR(BG(sb).st_mode));
case 14: /*is link*/ case 14: /*is link*/
#if HAVE_SYMLINK #if HAVE_SYMLINK
RETURN_LONG(S_ISLNK(lsb.st_mode)); RETURN_LONG(S_ISLNK(BG(lsb).st_mode));
#else #else
RETURN_FALSE; RETURN_FALSE;
#endif #endif
@ -495,7 +493,7 @@ static void _php3_stat(const char *filename, int type, pval *return_value)
RETURN_TRUE; /* the false case was done earlier */ RETURN_TRUE; /* the false case was done earlier */
case 16: /* lstat */ case 16: /* lstat */
#if HAVE_SYMLINK #if HAVE_SYMLINK
stat_sb = &lsb; stat_sb = &BG(lsb);
#endif #endif
/* FALLTHROUGH */ /* FALLTHROUGH */
case 17: /* stat */ case 17: /* stat */