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

View file

@ -69,20 +69,9 @@
# endif
#endif
#include "php_filestat.h"
#include "ext/standard/basic_functions.h"
#ifndef THREAD_SAFE
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
#include "php_filestat.h"
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
@ -97,16 +86,20 @@ static struct stat lsb;
PHP_RINIT_FUNCTION(filestat)
{
CurrentStatFile=NULL;
CurrentStatLength=0;
BLS_FETCH();
BG(CurrentStatFile)=NULL;
BG(CurrentStatLength)=0;
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(filestat)
{
if (CurrentStatFile) {
efree (CurrentStatFile);
BLS_FETCH();
if (BG(CurrentStatFile)) {
efree (BG(CurrentStatFile));
}
return SUCCESS;
}
@ -394,35 +387,40 @@ PHP_FUNCTION(touch)
PHP_FUNCTION(clearstatcache)
{
if (CurrentStatFile) {
efree(CurrentStatFile);
CurrentStatFile = NULL;
BLS_FETCH();
if (BG(CurrentStatFile)) {
efree(BG(CurrentStatFile));
BG(CurrentStatFile) = NULL;
}
}
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)) {
if (!CurrentStatFile
|| strlen(filename) > CurrentStatLength) {
if (CurrentStatFile) efree(CurrentStatFile);
CurrentStatLength = strlen(filename);
CurrentStatFile = estrndup(filename,CurrentStatLength);
stat_sb = &BG(sb);
if (!BG(CurrentStatFile) || strcmp(filename,BG(CurrentStatFile))) {
if (!BG(CurrentStatFile)
|| strlen(filename) > BG(CurrentStatLength)) {
if (BG(CurrentStatFile)) efree(BG(CurrentStatFile));
BG(CurrentStatLength) = strlen(filename);
BG(CurrentStatFile) = estrndup(filename,BG(CurrentStatLength));
} else {
strcpy(CurrentStatFile,filename);
strcpy(BG(CurrentStatFile),filename);
}
#if HAVE_SYMLINK
lsb.st_mode = 0; /* mark lstat buf invalid */
BG(lsb).st_mode = 0; /* mark lstat buf invalid */
#endif
if (stat(CurrentStatFile,&sb)==-1) {
if (stat(BG(CurrentStatFile),&BG(sb))==-1) {
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);
CurrentStatFile=NULL;
efree(BG(CurrentStatFile));
BG(CurrentStatFile)=NULL;
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 */
if (!lsb.st_mode) {
if (lstat(CurrentStatFile,&lsb) == -1) {
php_error(E_NOTICE,"lstat failed for %s (errno=%d - %s)",CurrentStatFile,errno,strerror(errno));
if (!BG(lsb).st_mode) {
if (lstat(BG(CurrentStatFile),&BG(lsb)) == -1) {
php_error(E_NOTICE,"lstat failed for %s (errno=%d - %s)",BG(CurrentStatFile),errno,strerror(errno));
RETURN_FALSE;
}
}
@ -445,49 +443,49 @@ static void _php3_stat(const char *filename, int type, pval *return_value)
switch(type) {
case 0: /* fileperms */
RETURN_LONG((long)sb.st_mode);
RETURN_LONG((long)BG(sb).st_mode);
case 1: /* fileinode */
RETURN_LONG((long)sb.st_ino);
RETURN_LONG((long)BG(sb).st_ino);
case 2: /* filesize */
RETURN_LONG((long)sb.st_size);
RETURN_LONG((long)BG(sb).st_size);
case 3: /* fileowner */
RETURN_LONG((long)sb.st_uid);
RETURN_LONG((long)BG(sb).st_uid);
case 4: /* filegroup */
RETURN_LONG((long)sb.st_gid);
RETURN_LONG((long)BG(sb).st_gid);
case 5: /* fileatime */
RETURN_LONG((long)sb.st_atime);
RETURN_LONG((long)BG(sb).st_atime);
case 6: /* filemtime */
RETURN_LONG((long)sb.st_mtime);
RETURN_LONG((long)BG(sb).st_mtime);
case 7: /* filectime */
RETURN_LONG((long)sb.st_ctime);
RETURN_LONG((long)BG(sb).st_ctime);
case 8: /* filetype */
#if HAVE_SYMLINK
if (S_ISLNK(lsb.st_mode)) {
if (S_ISLNK(BG(lsb).st_mode)) {
RETURN_STRING("link",1);
}
#endif
switch(sb.st_mode&S_IFMT) {
switch(BG(sb).st_mode&S_IFMT) {
case S_IFIFO: RETURN_STRING("fifo",1);
case S_IFCHR: RETURN_STRING("char",1);
case S_IFDIR: RETURN_STRING("dir",1);
case S_IFBLK: RETURN_STRING("block",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);
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*/
RETURN_LONG((sb.st_mode&S_IREAD)!=0);
RETURN_LONG((BG(sb).st_mode&S_IREAD)!=0);
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*/
RETURN_LONG(S_ISREG(sb.st_mode));
RETURN_LONG(S_ISREG(BG(sb).st_mode));
case 13: /*is dir*/
RETURN_LONG(S_ISDIR(sb.st_mode));
RETURN_LONG(S_ISDIR(BG(sb).st_mode));
case 14: /*is link*/
#if HAVE_SYMLINK
RETURN_LONG(S_ISLNK(lsb.st_mode));
RETURN_LONG(S_ISLNK(BG(lsb).st_mode));
#else
RETURN_FALSE;
#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 */
case 16: /* lstat */
#if HAVE_SYMLINK
stat_sb = &lsb;
stat_sb = &BG(lsb);
#endif
/* FALLTHROUGH */
case 17: /* stat */