mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Make filestat.c thread-safe
This commit is contained in:
parent
d9258da42e
commit
61a6a92618
2 changed files with 68 additions and 54 deletions
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue