Skip to content

Commit 61a6a92

Browse files
author
Sascha Schumann
committed
Make filestat.c thread-safe
1 parent d9258da commit 61a6a92

File tree

2 files changed

+69
-55
lines changed

2 files changed

+69
-55
lines changed

ext/standard/basic_functions.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#ifndef _BASIC_FUNCTIONS_H
3535
#define _BASIC_FUNCTIONS_H
3636

37+
#include <sys/stat.h>
38+
3739
#include "zend_highlight.h"
3840

3941
extern php3_module_entry basic_functions_module;
@@ -103,6 +105,12 @@ PHP_FUNCTION(getservbyport);
103105
PHP_FUNCTION(getprotobyname);
104106
PHP_FUNCTION(getprotobynumber);
105107

108+
#if MSVC5
109+
typedef unsigned int php_stat_len;
110+
#else
111+
typedef int php_stat_len;
112+
#endif
113+
106114
typedef struct {
107115
HashTable *user_shutdown_function_names;
108116
HashTable putenv_ht;
@@ -113,9 +121,17 @@ typedef struct {
113121
char str_ebuf[40];
114122
zval **array_walk_func_name;
115123
zval **user_compare_func_name;
124+
125+
/* pageinfo.c */
116126
long page_uid;
117127
long page_inode;
118128
long page_mtime;
129+
130+
/* filestat.c */
131+
char *CurrentStatFile;
132+
php_stat_len CurrentStatLength;
133+
struct stat sb;
134+
struct stat lsb;
119135
} php_basic_globals;
120136

121137
#ifdef ZTS

ext/standard/filestat.c

Lines changed: 53 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,9 @@
6969
# endif
7070
#endif
7171

72-
#include "php_filestat.h"
72+
#include "ext/standard/basic_functions.h"
7373

74-
#ifndef THREAD_SAFE
75-
static char *CurrentStatFile=NULL;
76-
# if MSVC5
77-
static unsigned int CurrentStatLength=0;
78-
# else
79-
static int CurrentStatLength=0;
80-
# endif
81-
static struct stat sb;
82-
#if HAVE_SYMLINK
83-
static struct stat lsb;
84-
#endif
85-
#endif
74+
#include "php_filestat.h"
8675

8776
#ifndef S_ISDIR
8877
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
@@ -97,16 +86,20 @@ static struct stat lsb;
9786

9887
PHP_RINIT_FUNCTION(filestat)
9988
{
100-
CurrentStatFile=NULL;
101-
CurrentStatLength=0;
89+
BLS_FETCH();
90+
91+
BG(CurrentStatFile)=NULL;
92+
BG(CurrentStatLength)=0;
10293
return SUCCESS;
10394
}
10495

10596

10697
PHP_RSHUTDOWN_FUNCTION(filestat)
10798
{
108-
if (CurrentStatFile) {
109-
efree (CurrentStatFile);
99+
BLS_FETCH();
100+
101+
if (BG(CurrentStatFile)) {
102+
efree (BG(CurrentStatFile));
110103
}
111104
return SUCCESS;
112105
}
@@ -394,35 +387,40 @@ PHP_FUNCTION(touch)
394387

395388
PHP_FUNCTION(clearstatcache)
396389
{
397-
if (CurrentStatFile) {
398-
efree(CurrentStatFile);
399-
CurrentStatFile = NULL;
390+
BLS_FETCH();
391+
392+
if (BG(CurrentStatFile)) {
393+
efree(BG(CurrentStatFile));
394+
BG(CurrentStatFile) = NULL;
400395
}
401396
}
402397

403398

404399
static void _php3_stat(const char *filename, int type, pval *return_value)
405400
{
406-
struct stat *stat_sb = &sb;
407-
408-
if (!CurrentStatFile || strcmp(filename,CurrentStatFile)) {
409-
if (!CurrentStatFile
410-
|| strlen(filename) > CurrentStatLength) {
411-
if (CurrentStatFile) efree(CurrentStatFile);
412-
CurrentStatLength = strlen(filename);
413-
CurrentStatFile = estrndup(filename,CurrentStatLength);
401+
struct stat *stat_sb;
402+
BLS_FETCH();
403+
404+
stat_sb = &BG(sb);
405+
406+
if (!BG(CurrentStatFile) || strcmp(filename,BG(CurrentStatFile))) {
407+
if (!BG(CurrentStatFile)
408+
|| strlen(filename) > BG(CurrentStatLength)) {
409+
if (BG(CurrentStatFile)) efree(BG(CurrentStatFile));
410+
BG(CurrentStatLength) = strlen(filename);
411+
BG(CurrentStatFile) = estrndup(filename,BG(CurrentStatLength));
414412
} else {
415-
strcpy(CurrentStatFile,filename);
413+
strcpy(BG(CurrentStatFile),filename);
416414
}
417415
#if HAVE_SYMLINK
418-
lsb.st_mode = 0; /* mark lstat buf invalid */
416+
BG(lsb).st_mode = 0; /* mark lstat buf invalid */
419417
#endif
420-
if (stat(CurrentStatFile,&sb)==-1) {
418+
if (stat(BG(CurrentStatFile),&BG(sb))==-1) {
421419
if (type != 15 || errno != ENOENT) { /* fileexists() test must print no error */
422-
php_error(E_NOTICE,"stat failed for %s (errno=%d - %s)",CurrentStatFile,errno,strerror(errno));
420+
php_error(E_NOTICE,"stat failed for %s (errno=%d - %s)",BG(CurrentStatFile),errno,strerror(errno));
423421
}
424-
efree(CurrentStatFile);
425-
CurrentStatFile=NULL;
422+
efree(BG(CurrentStatFile));
423+
BG(CurrentStatFile)=NULL;
426424
RETURN_FALSE;
427425
}
428426
}
@@ -434,9 +432,9 @@ static void _php3_stat(const char *filename, int type, pval *return_value)
434432

435433
/* do lstat if the buffer is empty */
436434

437-
if (!lsb.st_mode) {
438-
if (lstat(CurrentStatFile,&lsb) == -1) {
439-
php_error(E_NOTICE,"lstat failed for %s (errno=%d - %s)",CurrentStatFile,errno,strerror(errno));
435+
if (!BG(lsb).st_mode) {
436+
if (lstat(BG(CurrentStatFile),&BG(lsb)) == -1) {
437+
php_error(E_NOTICE,"lstat failed for %s (errno=%d - %s)",BG(CurrentStatFile),errno,strerror(errno));
440438
RETURN_FALSE;
441439
}
442440
}
@@ -445,57 +443,57 @@ static void _php3_stat(const char *filename, int type, pval *return_value)
445443

446444
switch(type) {
447445
case 0: /* fileperms */
448-
RETURN_LONG((long)sb.st_mode);
446+
RETURN_LONG((long)BG(sb).st_mode);
449447
case 1: /* fileinode */
450-
RETURN_LONG((long)sb.st_ino);
448+
RETURN_LONG((long)BG(sb).st_ino);
451449
case 2: /* filesize */
452-
RETURN_LONG((long)sb.st_size);
450+
RETURN_LONG((long)BG(sb).st_size);
453451
case 3: /* fileowner */
454-
RETURN_LONG((long)sb.st_uid);
452+
RETURN_LONG((long)BG(sb).st_uid);
455453
case 4: /* filegroup */
456-
RETURN_LONG((long)sb.st_gid);
454+
RETURN_LONG((long)BG(sb).st_gid);
457455
case 5: /* fileatime */
458-
RETURN_LONG((long)sb.st_atime);
456+
RETURN_LONG((long)BG(sb).st_atime);
459457
case 6: /* filemtime */
460-
RETURN_LONG((long)sb.st_mtime);
458+
RETURN_LONG((long)BG(sb).st_mtime);
461459
case 7: /* filectime */
462-
RETURN_LONG((long)sb.st_ctime);
460+
RETURN_LONG((long)BG(sb).st_ctime);
463461
case 8: /* filetype */
464462
#if HAVE_SYMLINK
465-
if (S_ISLNK(lsb.st_mode)) {
463+
if (S_ISLNK(BG(lsb).st_mode)) {
466464
RETURN_STRING("link",1);
467465
}
468466
#endif
469-
switch(sb.st_mode&S_IFMT) {
467+
switch(BG(sb).st_mode&S_IFMT) {
470468
case S_IFIFO: RETURN_STRING("fifo",1);
471469
case S_IFCHR: RETURN_STRING("char",1);
472470
case S_IFDIR: RETURN_STRING("dir",1);
473471
case S_IFBLK: RETURN_STRING("block",1);
474472
case S_IFREG: RETURN_STRING("file",1);
475473
}
476-
php_error(E_WARNING,"Unknown file type (%d)",sb.st_mode&S_IFMT);
474+
php_error(E_WARNING,"Unknown file type (%d)",BG(sb).st_mode&S_IFMT);
477475
RETURN_STRING("unknown",1);
478476
case 9: /*is writable*/
479-
RETURN_LONG((sb.st_mode&S_IWRITE)!=0);
477+
RETURN_LONG((BG(sb).st_mode&S_IWRITE)!=0);
480478
case 10: /*is readable*/
481-
RETURN_LONG((sb.st_mode&S_IREAD)!=0);
479+
RETURN_LONG((BG(sb).st_mode&S_IREAD)!=0);
482480
case 11: /*is executable*/
483-
RETURN_LONG((sb.st_mode&S_IEXEC)!=0 && !S_ISDIR(sb.st_mode));
481+
RETURN_LONG((BG(sb).st_mode&S_IEXEC)!=0 && !S_ISDIR(BG(sb).st_mode));
484482
case 12: /*is file*/
485-
RETURN_LONG(S_ISREG(sb.st_mode));
483+
RETURN_LONG(S_ISREG(BG(sb).st_mode));
486484
case 13: /*is dir*/
487-
RETURN_LONG(S_ISDIR(sb.st_mode));
485+
RETURN_LONG(S_ISDIR(BG(sb).st_mode));
488486
case 14: /*is link*/
489487
#if HAVE_SYMLINK
490-
RETURN_LONG(S_ISLNK(lsb.st_mode));
488+
RETURN_LONG(S_ISLNK(BG(lsb).st_mode));
491489
#else
492490
RETURN_FALSE;
493491
#endif
494492
case 15: /*file exists*/
495493
RETURN_TRUE; /* the false case was done earlier */
496494
case 16: /* lstat */
497495
#if HAVE_SYMLINK
498-
stat_sb = &lsb;
496+
stat_sb = &BG(lsb);
499497
#endif
500498
/* FALLTHROUGH */
501499
case 17: /* stat */

0 commit comments

Comments
 (0)