Skip to content

Commit

Permalink
Make filestat.c thread-safe
Browse files Browse the repository at this point in the history
  • Loading branch information
Sascha Schumann committed Dec 12, 1999
1 parent d9258da commit 61a6a92
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 55 deletions.
16 changes: 16 additions & 0 deletions ext/standard/basic_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down
108 changes: 53 additions & 55 deletions ext/standard/filestat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;

if (!CurrentStatFile || strcmp(filename,CurrentStatFile)) {
if (!CurrentStatFile
|| strlen(filename) > CurrentStatLength) {
if (CurrentStatFile) efree(CurrentStatFile);
CurrentStatLength = strlen(filename);
CurrentStatFile = estrndup(filename,CurrentStatLength);
struct stat *stat_sb;
BLS_FETCH();

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;
}
}
Expand All @@ -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;
}
}
Expand All @@ -445,57 +443,57 @@ 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
case 15: /*file exists*/
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 */
Expand Down

0 comments on commit 61a6a92

Please sign in to comment.