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
|
#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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue