MFH: ws + sync

This commit is contained in:
Jani Taskinen 2009-05-18 16:10:09 +00:00
parent 82c49a50f4
commit 9ece649f7c
5 changed files with 201 additions and 229 deletions

View file

@ -1,4 +1,4 @@
/* /*
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 5 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
@ -86,7 +86,7 @@ static int ps_files_valid_key(const char *key)
} }
len = p - key; len = p - key;
if (len == 0) { if (len == 0) {
ret = 0; ret = 0;
} }
@ -100,7 +100,7 @@ static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, cons
const char *p; const char *p;
int i; int i;
int n; int n;
key_len = strlen(key); key_len = strlen(key);
if (key_len <= data->dirdepth || if (key_len <= data->dirdepth ||
buflen < (strlen(data->basedir) + 2 * data->dirdepth + key_len + 5 + sizeof(FILE_PREFIX))) { buflen < (strlen(data->basedir) + 2 * data->dirdepth + key_len + 5 + sizeof(FILE_PREFIX))) {
@ -120,18 +120,18 @@ static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, cons
memcpy(buf + n, key, key_len); memcpy(buf + n, key, key_len);
n += key_len; n += key_len;
buf[n] = '\0'; buf[n] = '\0';
return buf; return buf;
} }
#ifndef O_BINARY #ifndef O_BINARY
#define O_BINARY 0 # define O_BINARY 0
#endif #endif
static void ps_files_close(ps_files *data) static void ps_files_close(ps_files *data)
{ {
if (data->fd != -1) { if (data->fd != -1) {
#ifdef PHP_WIN32 #ifdef PHP_WIN32
/* On Win32 locked files that are closed without being explicitly unlocked /* On Win32 locked files that are closed without being explicitly unlocked
will be unlocked only when "system resources become available". */ will be unlocked only when "system resources become available". */
flock(data->fd, LOCK_UN); flock(data->fd, LOCK_UN);
@ -177,13 +177,12 @@ static void ps_files_open(ps_files *data, const char *key TSRMLS_DC)
return; return;
} }
if ( if (
S_ISLNK(sbuf.st_mode) && S_ISLNK(sbuf.st_mode) &&
( (
php_check_open_basedir(buf TSRMLS_CC) || php_check_open_basedir(buf TSRMLS_CC) ||
(PG(safe_mode) && !php_checkuid(buf, NULL, CHECKUID_CHECK_FILE_AND_DIR)) (PG(safe_mode) && !php_checkuid(buf, NULL, CHECKUID_CHECK_FILE_AND_DIR))
) )
) { ) {
close(data->fd); close(data->fd);
return; return;
} }
@ -200,8 +199,7 @@ static void ps_files_open(ps_files *data, const char *key TSRMLS_DC)
} }
#endif #endif
} else { } else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "open(%s, O_RDWR) failed: %s (%d)", buf, php_error_docref(NULL TSRMLS_CC, E_WARNING, "open(%s, O_RDWR) failed: %s (%d)", buf, strerror(errno), errno);
strerror(errno), errno);
} }
} }
} }
@ -230,7 +228,7 @@ static int ps_files_cleanup_dir(const char *dirname, int maxlifetime TSRMLS_DC)
/* Prepare buffer (dirname never changes) */ /* Prepare buffer (dirname never changes) */
memcpy(buf, dirname, dirname_len); memcpy(buf, dirname, dirname_len);
buf[dirname_len] = PHP_DIR_SEPARATOR; buf[dirname_len] = PHP_DIR_SEPARATOR;
while (php_readdir_r(dir, (struct dirent *) dentry, &entry) == 0 && entry) { while (php_readdir_r(dir, (struct dirent *) dentry, &entry) == 0 && entry) {
/* does the file start with our prefix? */ /* does the file start with our prefix? */
if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1)) { if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1)) {
@ -245,7 +243,7 @@ static int ps_files_cleanup_dir(const char *dirname, int maxlifetime TSRMLS_DC)
buf[dirname_len + entry_len + 1] = '\0'; buf[dirname_len + entry_len + 1] = '\0';
/* check whether its last access was more than maxlifet ago */ /* check whether its last access was more than maxlifet ago */
if (VCWD_STAT(buf, &sbuf) == 0 && if (VCWD_STAT(buf, &sbuf) == 0 &&
#ifdef NETWARE #ifdef NETWARE
(now - sbuf.st_mtime.tv_sec) > maxlifetime) { (now - sbuf.st_mtime.tv_sec) > maxlifetime) {
#else #else
@ -285,7 +283,7 @@ PS_OPEN_FUNC(files)
return FAILURE; return FAILURE;
} }
} }
/* split up input parameter */ /* split up input parameter */
last = save_path; last = save_path;
p = strchr(save_path, ';'); p = strchr(save_path, ';');
@ -305,7 +303,7 @@ PS_OPEN_FUNC(files)
return FAILURE; return FAILURE;
} }
} }
if (argc > 2) { if (argc > 2) {
errno = 0; errno = 0;
filemode = strtol(argv[1], NULL, 8); filemode = strtol(argv[1], NULL, 8);
@ -316,17 +314,16 @@ PS_OPEN_FUNC(files)
} }
save_path = argv[argc - 1]; save_path = argv[argc - 1];
data = emalloc(sizeof(*data)); data = ecalloc(1, sizeof(*data));
memset(data, 0, sizeof(*data));
data->fd = -1; data->fd = -1;
data->dirdepth = dirdepth; data->dirdepth = dirdepth;
data->filemode = filemode; data->filemode = filemode;
data->basedir_len = strlen(save_path); data->basedir_len = strlen(save_path);
data->basedir = estrndup(save_path, data->basedir_len); data->basedir = estrndup(save_path, data->basedir_len);
PS_SET_MOD_DATA(data); PS_SET_MOD_DATA(data);
return SUCCESS; return SUCCESS;
} }
@ -387,7 +384,7 @@ PS_READ_FUNC(files)
efree(*val); efree(*val);
return FAILURE; return FAILURE;
} }
return SUCCESS; return SUCCESS;
} }
@ -401,11 +398,8 @@ PS_WRITE_FUNC(files)
return FAILURE; return FAILURE;
} }
/* /* Truncate file if the amount of new data is smaller than the existing data set. */
* truncate file, if the amount of new data is smaller than
* the existing data set.
*/
if (vallen < (int)data->st_size) { if (vallen < (int)data->st_size) {
ftruncate(data->fd, 0); ftruncate(data->fd, 0);
} }
@ -440,11 +434,10 @@ PS_DESTROY_FUNC(files)
if (data->fd != -1) { if (data->fd != -1) {
ps_files_close(data); ps_files_close(data);
if (VCWD_UNLINK(buf) == -1) { if (VCWD_UNLINK(buf) == -1) {
/* This is a little safety check for instances when we are dealing with a regenerated session /* This is a little safety check for instances when we are dealing with a regenerated session
* that was not yet written to disk * that was not yet written to disk. */
*/
if (!VCWD_ACCESS(buf, F_OK)) { if (!VCWD_ACCESS(buf, F_OK)) {
return FAILURE; return FAILURE;
} }
@ -454,14 +447,14 @@ PS_DESTROY_FUNC(files)
return SUCCESS; return SUCCESS;
} }
PS_GC_FUNC(files) PS_GC_FUNC(files)
{ {
PS_FILES_DATA; PS_FILES_DATA;
/* we don't perform any cleanup, if dirdepth is larger than 0. /* we don't perform any cleanup, if dirdepth is larger than 0.
we return SUCCESS, since all cleanup should be handled by we return SUCCESS, since all cleanup should be handled by
an external entity (i.e. find -ctime x | xargs rm) */ an external entity (i.e. find -ctime x | xargs rm) */
if (data->dirdepth == 0) { if (data->dirdepth == 0) {
*nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime TSRMLS_CC); *nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime TSRMLS_CC);
} }

View file

@ -1,4 +1,4 @@
/* /*
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 5 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
@ -42,9 +42,7 @@
/* For php_uint32 */ /* For php_uint32 */
#include "ext/standard/basic_functions.h" #include "ext/standard/basic_functions.h"
/* /* This list holds all data associated with one session. */
* this list holds all data associated with one session
*/
typedef struct ps_sd { typedef struct ps_sd {
struct ps_sd *next; struct ps_sd *next;
@ -67,21 +65,21 @@ typedef struct {
static ps_mm *ps_mm_instance = NULL; static ps_mm *ps_mm_instance = NULL;
#if 0 #if 0
#define ps_mm_debug(a) printf a # define ps_mm_debug(a) printf a
#else #else
#define ps_mm_debug(a) # define ps_mm_debug(a)
#endif #endif
static inline php_uint32 ps_sd_hash(const char *data, int len) static inline php_uint32 ps_sd_hash(const char *data, int len)
{ {
php_uint32 h; php_uint32 h;
const char *e = data + len; const char *e = data + len;
for (h = 2166136261U; data < e; ) { for (h = 2166136261U; data < e; ) {
h *= 16777619; h *= 16777619;
h ^= *data++; h ^= *data++;
} }
return h; return h;
} }
@ -91,10 +89,10 @@ static void hash_split(ps_mm *data)
ps_sd **nhash; ps_sd **nhash;
ps_sd **ohash, **ehash; ps_sd **ohash, **ehash;
ps_sd *ps, *next; ps_sd *ps, *next;
nmax = ((data->hash_max + 1) << 1) - 1; nmax = ((data->hash_max + 1) << 1) - 1;
nhash = mm_calloc(data->mm, nmax + 1, sizeof(*data->hash)); nhash = mm_calloc(data->mm, nmax + 1, sizeof(*data->hash));
if (!nhash) { if (!nhash) {
/* no further memory to expand hash table */ /* no further memory to expand hash table */
return; return;
@ -119,9 +117,9 @@ static ps_sd *ps_sd_new(ps_mm *data, const char *key)
php_uint32 hv, slot; php_uint32 hv, slot;
ps_sd *sd; ps_sd *sd;
int keylen; int keylen;
keylen = strlen(key); keylen = strlen(key);
sd = mm_malloc(data->mm, sizeof(ps_sd) + keylen); sd = mm_malloc(data->mm, sizeof(ps_sd) + keylen);
if (!sd) { if (!sd) {
TSRMLS_FETCH(); TSRMLS_FETCH();
@ -132,24 +130,25 @@ static ps_sd *ps_sd_new(ps_mm *data, const char *key)
hv = ps_sd_hash(key, keylen); hv = ps_sd_hash(key, keylen);
slot = hv & data->hash_max; slot = hv & data->hash_max;
sd->ctime = 0; sd->ctime = 0;
sd->hv = hv; sd->hv = hv;
sd->data = NULL; sd->data = NULL;
sd->alloclen = sd->datalen = 0; sd->alloclen = sd->datalen = 0;
memcpy(sd->key, key, keylen + 1); memcpy(sd->key, key, keylen + 1);
sd->next = data->hash[slot]; sd->next = data->hash[slot];
data->hash[slot] = sd; data->hash[slot] = sd;
data->hash_cnt++; data->hash_cnt++;
if (!sd->next) { if (!sd->next) {
if (data->hash_cnt >= data->hash_max) if (data->hash_cnt >= data->hash_max) {
hash_split(data); hash_split(data);
}
} }
ps_mm_debug(("inserting %s(%p) into slot %d\n", key, sd, slot)); ps_mm_debug(("inserting %s(%p) into slot %d\n", key, sd, slot));
return sd; return sd;
@ -161,19 +160,22 @@ static void ps_sd_destroy(ps_mm *data, ps_sd *sd)
slot = ps_sd_hash(sd->key, strlen(sd->key)) & data->hash_max; slot = ps_sd_hash(sd->key, strlen(sd->key)) & data->hash_max;
if (data->hash[slot] == sd) if (data->hash[slot] == sd) {
data->hash[slot] = sd->next; data->hash[slot] = sd->next;
else { } else {
ps_sd *prev; ps_sd *prev;
/* There must be some entry before the one we want to delete */ /* There must be some entry before the one we want to delete */
for (prev = data->hash[slot]; prev->next != sd; prev = prev->next); for (prev = data->hash[slot]; prev->next != sd; prev = prev->next);
prev->next = sd->next; prev->next = sd->next;
} }
data->hash_cnt--; data->hash_cnt--;
if (sd->data)
if (sd->data) {
mm_free(data->mm, sd->data); mm_free(data->mm, sd->data);
}
mm_free(data->mm, sd); mm_free(data->mm, sd);
} }
@ -184,22 +186,25 @@ static ps_sd *ps_sd_lookup(ps_mm *data, const char *key, int rw)
hv = ps_sd_hash(key, strlen(key)); hv = ps_sd_hash(key, strlen(key));
slot = hv & data->hash_max; slot = hv & data->hash_max;
for (prev = NULL, ret = data->hash[slot]; ret; prev = ret, ret = ret->next) for (prev = NULL, ret = data->hash[slot]; ret; prev = ret, ret = ret->next) {
if (ret->hv == hv && !strcmp(ret->key, key)) if (ret->hv == hv && !strcmp(ret->key, key)) {
break; break;
}
}
if (ret && rw && ret != data->hash[slot]) { if (ret && rw && ret != data->hash[slot]) {
/* Move the entry to the top of the linked list */ /* Move the entry to the top of the linked list */
if (prev) {
if (prev)
prev->next = ret->next; prev->next = ret->next;
}
ret->next = data->hash[slot]; ret->next = data->hash[slot];
data->hash[slot] = ret; data->hash[slot] = ret;
} }
ps_mm_debug(("lookup(%s): ret=%p,hv=%u,slot=%d\n", key, ret, hv, slot)); ps_mm_debug(("lookup(%s): ret=%p,hv=%u,slot=%d\n", key, ret, hv, slot));
return ret; return ret;
} }
@ -236,14 +241,17 @@ static void ps_mm_destroy(ps_mm *data)
/* This function is called during each module shutdown, /* This function is called during each module shutdown,
but we must not release the shared memory pool, when but we must not release the shared memory pool, when
an Apache child dies! */ an Apache child dies! */
if (data->owner != getpid()) return; if (data->owner != getpid()) {
return;
}
for (h = 0; h < data->hash_max + 1; h++) for (h = 0; h < data->hash_max + 1; h++) {
for (sd = data->hash[h]; sd; sd = next) { for (sd = data->hash[h]; sd; sd = next) {
next = sd->next; next = sd->next;
ps_sd_destroy(data, sd); ps_sd_destroy(data, sd);
} }
}
mm_free(data->mm, data->hash); mm_free(data->mm, data->hash);
mm_destroy(data->mm); mm_destroy(data->mm);
free(data); free(data);
@ -258,17 +266,17 @@ PHP_MINIT_FUNCTION(ps_mm)
int ret; int ret;
ps_mm_instance = calloc(sizeof(*ps_mm_instance), 1); ps_mm_instance = calloc(sizeof(*ps_mm_instance), 1);
if (!ps_mm_instance) { if (!ps_mm_instance) {
return FAILURE; return FAILURE;
} }
if (!(euid_len = slprintf(euid, sizeof(euid), "%d", geteuid()))) { if (!(euid_len = slprintf(euid, sizeof(euid), "%d", geteuid()))) {
return FAILURE; return FAILURE;
} }
/* Directory + '/' + File + Module Name + Effective UID + \0 */ /* Directory + '/' + File + Module Name + Effective UID + \0 */
ps_mm_path = emalloc(save_path_len + 1 + (sizeof(PS_MM_FILE) - 1) + mod_name_len + euid_len + 1); ps_mm_path = emalloc(save_path_len + 1 + (sizeof(PS_MM_FILE) - 1) + mod_name_len + euid_len + 1);
memcpy(ps_mm_path, PS(save_path), save_path_len); memcpy(ps_mm_path, PS(save_path), save_path_len);
if (PS(save_path)[save_path_len - 1] != DEFAULT_SLASH) { if (PS(save_path)[save_path_len - 1] != DEFAULT_SLASH) {
ps_mm_path[save_path_len] = DEFAULT_SLASH; ps_mm_path[save_path_len] = DEFAULT_SLASH;
@ -282,15 +290,15 @@ PHP_MINIT_FUNCTION(ps_mm)
ps_mm_path[save_path_len + euid_len] = '\0'; ps_mm_path[save_path_len + euid_len] = '\0';
ret = ps_mm_initialize(ps_mm_instance, ps_mm_path); ret = ps_mm_initialize(ps_mm_instance, ps_mm_path);
efree(ps_mm_path); efree(ps_mm_path);
if (ret != SUCCESS) { if (ret != SUCCESS) {
free(ps_mm_instance); free(ps_mm_instance);
ps_mm_instance = NULL; ps_mm_instance = NULL;
return FAILURE; return FAILURE;
} }
php_session_register_module(&ps_mod_mm); php_session_register_module(&ps_mod_mm);
return SUCCESS; return SUCCESS;
} }
@ -307,12 +315,12 @@ PHP_MSHUTDOWN_FUNCTION(ps_mm)
PS_OPEN_FUNC(mm) PS_OPEN_FUNC(mm)
{ {
ps_mm_debug(("open: ps_mm_instance=%p\n", ps_mm_instance)); ps_mm_debug(("open: ps_mm_instance=%p\n", ps_mm_instance));
if (!ps_mm_instance) if (!ps_mm_instance) {
return FAILURE; return FAILURE;
}
PS_SET_MOD_DATA(ps_mm_instance); PS_SET_MOD_DATA(ps_mm_instance);
return SUCCESS; return SUCCESS;
} }
@ -330,7 +338,7 @@ PS_READ_FUNC(mm)
int ret = FAILURE; int ret = FAILURE;
mm_lock(data->mm, MM_LOCK_RD); mm_lock(data->mm, MM_LOCK_RD);
sd = ps_sd_lookup(data, key, 0); sd = ps_sd_lookup(data, key, 0);
if (sd) { if (sd) {
*vallen = sd->datalen; *vallen = sd->datalen;
@ -341,7 +349,7 @@ PS_READ_FUNC(mm)
} }
mm_unlock(data->mm); mm_unlock(data->mm);
return ret; return ret;
} }
@ -360,8 +368,9 @@ PS_WRITE_FUNC(mm)
if (sd) { if (sd) {
if (vallen >= sd->alloclen) { if (vallen >= sd->alloclen) {
if (data->mm) if (data->mm) {
mm_free(data->mm, sd->data); mm_free(data->mm, sd->data);
}
sd->alloclen = vallen + 1; sd->alloclen = vallen + 1;
sd->data = mm_malloc(data->mm, sd->alloclen); sd->data = mm_malloc(data->mm, sd->alloclen);
@ -379,7 +388,7 @@ PS_WRITE_FUNC(mm)
} }
mm_unlock(data->mm); mm_unlock(data->mm);
return sd ? SUCCESS : FAILURE; return sd ? SUCCESS : FAILURE;
} }
@ -387,28 +396,29 @@ PS_DESTROY_FUNC(mm)
{ {
PS_MM_DATA; PS_MM_DATA;
ps_sd *sd; ps_sd *sd;
mm_lock(data->mm, MM_LOCK_RW); mm_lock(data->mm, MM_LOCK_RW);
sd = ps_sd_lookup(data, key, 0); sd = ps_sd_lookup(data, key, 0);
if (sd) if (sd) {
ps_sd_destroy(data, sd); ps_sd_destroy(data, sd);
}
mm_unlock(data->mm); mm_unlock(data->mm);
return SUCCESS; return SUCCESS;
} }
PS_GC_FUNC(mm) PS_GC_FUNC(mm)
{ {
PS_MM_DATA; PS_MM_DATA;
time_t limit; time_t limit;
ps_sd **ohash, **ehash; ps_sd **ohash, **ehash;
ps_sd *sd, *next; ps_sd *sd, *next;
*nrdels = 0; *nrdels = 0;
ps_mm_debug(("gc\n")); ps_mm_debug(("gc\n"));
time(&limit); time(&limit);
limit -= maxlifetime; limit -= maxlifetime;
@ -416,7 +426,7 @@ PS_GC_FUNC(mm)
mm_lock(data->mm, MM_LOCK_RW); mm_lock(data->mm, MM_LOCK_RW);
ehash = data->hash + data->hash_max + 1; ehash = data->hash + data->hash_max + 1;
for (ohash = data->hash; ohash < ehash; ohash++) for (ohash = data->hash; ohash < ehash; ohash++) {
for (sd = *ohash; sd; sd = next) { for (sd = *ohash; sd; sd = next) {
next = sd->next; next = sd->next;
if (sd->ctime < limit) { if (sd->ctime < limit) {
@ -425,9 +435,10 @@ PS_GC_FUNC(mm)
(*nrdels)++; (*nrdels)++;
} }
} }
}
mm_unlock(data->mm); mm_unlock(data->mm);
return SUCCESS; return SUCCESS;
} }

View file

@ -26,39 +26,31 @@ ps_module ps_mod_user = {
PS_MOD(user) PS_MOD(user)
}; };
#define SESS_ZVAL_LONG(val, a) \ #define SESS_ZVAL_LONG(val, a) \
{ \ { \
MAKE_STD_ZVAL(a); \ MAKE_STD_ZVAL(a); \
Z_TYPE_P(a) = IS_LONG; \ ZVAL_LONG(a, val); \
Z_LVAL_P(a) = val; \
} }
#define SESS_ZVAL_STRING(vl, a) \ #define SESS_ZVAL_STRING(vl, a) \
{ \ { \
int len = strlen(vl); \ char *__vl = vl; \
MAKE_STD_ZVAL(a); \ SESS_ZVAL_STRINGN(__vl, strlen(__vl), a); \
Z_TYPE_P(a) = IS_STRING; \
Z_STRLEN_P(a) = len; \
Z_STRVAL_P(a) = estrndup(vl, len); \
} }
#define SESS_ZVAL_STRINGN(vl, ln, a) \ #define SESS_ZVAL_STRINGN(vl, ln, a) \
{ \ { \
MAKE_STD_ZVAL(a); \ MAKE_STD_ZVAL(a); \
Z_TYPE_P(a) = IS_STRING; \ ZVAL_STRINGL(a, vl, ln, 1); \
Z_STRLEN_P(a) = ln; \
Z_STRVAL_P(a) = estrndup(vl, ln); \
} }
static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC) static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
{ {
int i; int i;
zval *retval = NULL; zval *retval = NULL;
MAKE_STD_ZVAL(retval); MAKE_STD_ZVAL(retval);
if (call_user_function(EG(function_table), NULL, func, retval, if (call_user_function(EG(function_table), NULL, func, retval, argc, argv TSRMLS_CC) == FAILURE) {
argc, argv TSRMLS_CC) == FAILURE) {
zval_ptr_dtor(&retval); zval_ptr_dtor(&retval);
retval = NULL; retval = NULL;
} }
@ -70,24 +62,23 @@ static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
return retval; return retval;
} }
#define STDVARS1 \ #define STDVARS1 \
zval *retval; \ zval *retval; \
int ret = FAILURE int ret = FAILURE
#define STDVARS \ #define STDVARS \
STDVARS1; \ STDVARS1; \
char *mdata = PS_GET_MOD_DATA(); \ char *mdata = PS_GET_MOD_DATA(); \
if (!mdata) \ if (!mdata) { return FAILURE; }
return FAILURE
#define PSF(a) PS(mod_user_names).name.ps_##a #define PSF(a) PS(mod_user_names).name.ps_##a
#define FINISH \ #define FINISH \
if (retval) { \ if (retval) { \
convert_to_long(retval); \ convert_to_long(retval); \
ret = Z_LVAL_P(retval); \ ret = Z_LVAL_P(retval); \
zval_ptr_dtor(&retval); \ zval_ptr_dtor(&retval); \
} \ } \
return ret return ret
PS_OPEN_FUNC(user) PS_OPEN_FUNC(user)
@ -95,21 +86,20 @@ PS_OPEN_FUNC(user)
zval *args[2]; zval *args[2];
static char dummy = 0; static char dummy = 0;
STDVARS1; STDVARS1;
SESS_ZVAL_STRING(save_path, args[0]); SESS_ZVAL_STRING((char*)save_path, args[0]);
SESS_ZVAL_STRING(session_name, args[1]); SESS_ZVAL_STRING((char*)session_name, args[1]);
retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC); retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC);
if (retval) { if (retval) {
/* This is necessary to fool the session module. Yes, it's safe to /* This is necessary to fool the session module. Yes, it's safe to
* use a static. Neither mod_user nor the session module itself will * use a static. Neither mod_user nor the session module itself will
* ever touch this pointer. It could be set to 0xDEADBEEF for all the * ever touch this pointer. It could be set to 0xDEADBEEF for all the
* difference it makes, but for the sake of paranoia it's set to some * difference it makes, but for the sake of paranoia it's set to some
* valid value. * valid value. */
*/
PS_SET_MOD_DATA(&dummy); PS_SET_MOD_DATA(&dummy);
} }
FINISH; FINISH;
} }
@ -129,10 +119,10 @@ PS_READ_FUNC(user)
zval *args[1]; zval *args[1];
STDVARS; STDVARS;
SESS_ZVAL_STRING(key, args[0]); SESS_ZVAL_STRING((char*)key, args[0]);
retval = ps_call_handler(PSF(read), 1, args TSRMLS_CC); retval = ps_call_handler(PSF(read), 1, args TSRMLS_CC);
if (retval) { if (retval) {
if (Z_TYPE_P(retval) == IS_STRING) { if (Z_TYPE_P(retval) == IS_STRING) {
*val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); *val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
@ -149,9 +139,9 @@ PS_WRITE_FUNC(user)
{ {
zval *args[2]; zval *args[2];
STDVARS; STDVARS;
SESS_ZVAL_STRING(key, args[0]); SESS_ZVAL_STRING((char*)key, args[0]);
SESS_ZVAL_STRINGN(val, vallen, args[1]); SESS_ZVAL_STRINGN((char*)val, vallen, args[1]);
retval = ps_call_handler(PSF(write), 2, args TSRMLS_CC); retval = ps_call_handler(PSF(write), 2, args TSRMLS_CC);
@ -163,7 +153,7 @@ PS_DESTROY_FUNC(user)
zval *args[1]; zval *args[1];
STDVARS; STDVARS;
SESS_ZVAL_STRING(key, args[0]); SESS_ZVAL_STRING((char*)key, args[0]);
retval = ps_call_handler(PSF(destroy), 1, args TSRMLS_CC); retval = ps_call_handler(PSF(destroy), 1, args TSRMLS_CC);

View file

@ -220,18 +220,18 @@ PHPAPI const ps_serializer *_php_find_ps_serializer(char *name TSRMLS_DC);
zval **struc; zval **struc;
#define PS_ENCODE_LOOP(code) do { \ #define PS_ENCODE_LOOP(code) do { \
HashTable *_ht = Z_ARRVAL_P(PS(http_session_vars)); \ HashTable *_ht = Z_ARRVAL_P(PS(http_session_vars)); \
int key_type; \ int key_type; \
\ \
for (zend_hash_internal_pointer_reset(_ht); \ for (zend_hash_internal_pointer_reset(_ht); \
(key_type = zend_hash_get_current_key_ex(_ht, &key, &key_length, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTANT; \ (key_type = zend_hash_get_current_key_ex(_ht, &key, &key_length, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTANT; \
zend_hash_move_forward(_ht)) { \ zend_hash_move_forward(_ht)) { \
if (key_type == HASH_KEY_IS_LONG) { \ if (key_type == HASH_KEY_IS_LONG) { \
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key); \ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key); \
continue; \ continue; \
} \ } \
key_length--; \ key_length--; \
if (php_get_session_var(key, key_length, &struc TSRMLS_CC) == SUCCESS) { \ if (php_get_session_var(key, key_length, &struc TSRMLS_CC) == SUCCESS) { \
code; \ code; \
} \ } \
} \ } \

View file

@ -132,15 +132,12 @@ PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) /* {{{ */
zval **sym_track = NULL; zval **sym_track = NULL;
IF_SESSION_VARS() { IF_SESSION_VARS() {
zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, (void *) &sym_track);
(void *) &sym_track);
} else { } else {
return; return;
} }
/* /* Set up a proper reference between $_SESSION["x"] and $x. */
* Set up a proper reference between $_SESSION["x"] and $x.
*/
if (PG(register_globals)) { if (PG(register_globals)) {
zval **sym_global = NULL; zval **sym_global = NULL;
@ -180,13 +177,12 @@ PHPAPI void php_set_session_var(char *name, size_t namelen, zval *state_val, php
{ {
if (PG(register_globals)) { if (PG(register_globals)) {
zval **old_symbol; zval **old_symbol;
if (zend_hash_find(&EG(symbol_table),name,namelen+1,(void *)&old_symbol) == SUCCESS) { if (zend_hash_find(&EG(symbol_table),name,namelen+1,(void *)&old_symbol) == SUCCESS) {
if ((Z_TYPE_PP(old_symbol) == IS_ARRAY && Z_ARRVAL_PP(old_symbol) == &EG(symbol_table)) || *old_symbol == PS(http_session_vars)) { if ((Z_TYPE_PP(old_symbol) == IS_ARRAY && Z_ARRVAL_PP(old_symbol) == &EG(symbol_table)) || *old_symbol == PS(http_session_vars)) {
return; return;
} }
/* /* A global symbol with the same name exists already. That
* A global symbol with the same name exists already. That
* symbol might have been created by other means (e.g. $_GET). * symbol might have been created by other means (e.g. $_GET).
* *
* hash_update in zend_set_hash_symbol is not good, because * hash_update in zend_set_hash_symbol is not good, because
@ -194,16 +190,13 @@ PHPAPI void php_set_session_var(char *name, size_t namelen, zval *state_val, php
* of a global variable) dangling. * of a global variable) dangling.
* *
* BTW: if you use register_globals references between * BTW: if you use register_globals references between
* session-vars won't work because of this very reason! * session-vars won't work because of this very reason! */
*/
REPLACE_ZVAL_VALUE(old_symbol,state_val,1); REPLACE_ZVAL_VALUE(old_symbol,state_val,1);
/* /* The following line will update the reference table used for
* The following line will update the reference table used for * unserialization. It is optional, because some storage
* unserialization. It is optional, because some storage * formats may not be able to represent references. */
* formats may not be able to represent references.
*/
if (var_hash) { if (var_hash) {
PHP_VAR_UNSERIALIZE_ZVAL_CHANGED(var_hash,state_val,*old_symbol); PHP_VAR_UNSERIALIZE_ZVAL_CHANGED(var_hash,state_val,*old_symbol);
@ -224,23 +217,18 @@ PHPAPI int php_get_session_var(char *name, size_t namelen, zval ***state_var TSR
int ret = FAILURE; int ret = FAILURE;
IF_SESSION_VARS() { IF_SESSION_VARS() {
ret = zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, ret = zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, (void **) state_var);
namelen+1, (void **) state_var);
/* /* If register_globals is enabled, and
* If register_globals is enabled, and
* if there is an entry for the slot in $_SESSION, and * if there is an entry for the slot in $_SESSION, and
* if that entry is still set to NULL, and * if that entry is still set to NULL, and
* if the global var exists, then * if the global var exists, then
* we prefer the same key in the global sym table * we prefer the same key in the global sym table. */
*/
if (PG(register_globals) && ret == SUCCESS if (PG(register_globals) && ret == SUCCESS && Z_TYPE_PP(*state_var) == IS_NULL) {
&& Z_TYPE_PP(*state_var) == IS_NULL) {
zval **tmp; zval **tmp;
if (zend_hash_find(&EG(symbol_table), name, namelen + 1, if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) {
(void **) &tmp) == SUCCESS) {
*state_var = tmp; *state_var = tmp;
} }
} }
@ -287,7 +275,7 @@ static char *php_session_encode(int *newlen TSRMLS_DC) /* {{{ */
ret = NULL; ret = NULL;
} }
} else { } else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot encode non-existent session"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot encode non-existent session");
} }
return ret; return ret;
} }
@ -378,17 +366,15 @@ PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS) /* {{{ */
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
if (zend_hash_find(&EG(symbol_table), "_SERVER", if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &array) == SUCCESS &&
sizeof("_SERVER"), (void **) &array) == SUCCESS &&
Z_TYPE_PP(array) == IS_ARRAY && Z_TYPE_PP(array) == IS_ARRAY &&
zend_hash_find(Z_ARRVAL_PP(array), "REMOTE_ADDR", zend_hash_find(Z_ARRVAL_PP(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &token) == SUCCESS
sizeof("REMOTE_ADDR"), (void **) &token) == SUCCESS) { ) {
remote_addr = Z_STRVAL_PP(token); remote_addr = Z_STRVAL_PP(token);
} }
/* maximum 15+19+19+10 bytes */ /* maximum 15+19+19+10 bytes */
spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);
tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);
switch (PS(hash_func)) { switch (PS(hash_func)) {
case PS_HASH_FUNC_MD5: case PS_HASH_FUNC_MD5:
@ -527,8 +513,7 @@ new_session:
/* Question: if you create a SID here, should you also try to read data? /* Question: if you create a SID here, should you also try to read data?
* I'm not sure, but while not doing so will remove one session operation * I'm not sure, but while not doing so will remove one session operation
* it could prove usefull for those sites which wish to have "default" * it could prove usefull for those sites which wish to have "default"
* session information * session information. */
*/
php_session_track_init(TSRMLS_C); php_session_track_init(TSRMLS_C);
PS(invalid_session_id) = 0; PS(invalid_session_id) = 0;
if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) { if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) {
@ -556,11 +541,10 @@ static int migrate_global(HashTable *ht, HashPosition *pos TSRMLS_DC) /* {{{ */
switch (n) { switch (n) {
case HASH_KEY_IS_STRING: case HASH_KEY_IS_STRING:
if (zend_hash_find(&EG(symbol_table), str, str_len, if (zend_hash_find(&EG(symbol_table), str, str_len, (void **) &val) == SUCCESS &&
(void **) &val) == SUCCESS val && Z_TYPE_PP(val) != IS_NULL
&& val && Z_TYPE_PP(val) != IS_NULL) { ) {
ZEND_SET_SYMBOL_WITH_LENGTH(ht, str, str_len, *val, ZEND_SET_SYMBOL_WITH_LENGTH(ht, str, str_len, *val, Z_REFCOUNT_PP(val) + 1, 1);
Z_REFCOUNT_PP(val) + 1 , 1);
ret = 1; ret = 1;
} }
break; break;
@ -587,11 +571,11 @@ static void php_session_save_current_state(TSRMLS_D) /* {{{ */
zend_hash_internal_pointer_reset_ex(ht, &pos); zend_hash_internal_pointer_reset_ex(ht, &pos);
while (zend_hash_get_current_data_ex(ht, while (zend_hash_get_current_data_ex(ht, (void **) &val, &pos) != FAILURE) {
(void **) &val, &pos) != FAILURE) {
if (Z_TYPE_PP(val) == IS_NULL) { if (Z_TYPE_PP(val) == IS_NULL) {
if (migrate_global(ht, &pos TSRMLS_CC)) if (migrate_global(ht, &pos TSRMLS_CC)) {
do_warn = 1; do_warn = 1;
}
} }
zend_hash_move_forward_ex(ht, &pos); zend_hash_move_forward_ex(ht, &pos);
} }
@ -648,6 +632,8 @@ static PHP_INI_MH(OnUpdateSaveHandler) /* {{{ */
} else { } else {
err_type = E_ERROR; err_type = E_ERROR;
} }
/* Do not output error when restoring ini options. */
if (stage != ZEND_INI_STAGE_DEACTIVATE) { if (stage != ZEND_INI_STAGE_DEACTIVATE) {
php_error_docref(NULL TSRMLS_CC, err_type, "Cannot find save handler '%s'", new_value); php_error_docref(NULL TSRMLS_CC, err_type, "Cannot find save handler '%s'", new_value);
} }
@ -674,6 +660,8 @@ static PHP_INI_MH(OnUpdateSerializer) /* {{{ */
} else { } else {
err_type = E_ERROR; err_type = E_ERROR;
} }
/* Do not output error when restoring ini options. */
if (stage != ZEND_INI_STAGE_DEACTIVATE) { if (stage != ZEND_INI_STAGE_DEACTIVATE) {
php_error_docref(NULL TSRMLS_CC, err_type, "Cannot find serialization handler '%s'", new_value); php_error_docref(NULL TSRMLS_CC, err_type, "Cannot find serialization handler '%s'", new_value);
} }
@ -723,6 +711,7 @@ static PHP_INI_MH(OnUpdateSaveDir) /* {{{ */
return FAILURE; return FAILURE;
} }
} }
OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
return SUCCESS; return SUCCESS;
} }
@ -1002,10 +991,7 @@ static ps_serializer ps_serializers[MAX_SERIALIZERS + 1] = {
PS_SERIALIZER_ENTRY(php_binary) PS_SERIALIZER_ENTRY(php_binary)
}; };
PHPAPI int php_session_register_serializer( PHPAPI int php_session_register_serializer(const char *name, int (*encode)(PS_SERIALIZER_ENCODE_ARGS), int (*decode)(PS_SERIALIZER_DECODE_ARGS)) /* {{{ */
const char *name,
int (*encode)(PS_SERIALIZER_ENCODE_ARGS),
int (*decode)(PS_SERIALIZER_DECODE_ARGS)) /* {{{ */
{ {
int ret = -1; int ret = -1;
int i; int i;
@ -1090,9 +1076,9 @@ static inline void strcpy_gmt(char *ubuf, time_t *when) /* {{{ */
} }
n = slprintf(buf, sizeof(buf), "%s, %02d %s %d %02d:%02d:%02d GMT", /* SAFE */ n = slprintf(buf, sizeof(buf), "%s, %02d %s %d %02d:%02d:%02d GMT", /* SAFE */
week_days[tm.tm_wday], tm.tm_mday, week_days[tm.tm_wday], tm.tm_mday,
month_names[tm.tm_mon], tm.tm_year + 1900, month_names[tm.tm_mon], tm.tm_year + 1900,
tm.tm_hour, tm.tm_min, tm.tm_hour, tm.tm_min,
tm.tm_sec); tm.tm_sec);
memcpy(ubuf, buf, n); memcpy(ubuf, buf, n);
ubuf[n] = '\0'; ubuf[n] = '\0';
@ -1188,8 +1174,7 @@ static int php_session_cache_limiter(TSRMLS_D) /* {{{ */
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C); int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);
if (output_start_filename) { if (output_start_filename) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent (output started at %s:%d)", php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent (output started at %s:%d)", output_start_filename, output_start_lineno);
output_start_filename, output_start_lineno);
} else { } else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent");
} }
@ -1229,8 +1214,7 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C); int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);
if (output_start_filename) { if (output_start_filename) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent by (output started at %s:%d)", php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent by (output started at %s:%d)", output_start_filename, output_start_lineno);
output_start_filename, output_start_lineno);
} else { } else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent");
} }
@ -1400,17 +1384,14 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */
lensess = strlen(PS(session_name)); lensess = strlen(PS(session_name));
/* /* Cookies are preferred, because initially
* Cookies are preferred, because initially * cookie and get variables will be available. */
* cookie and get variables will be available.
*/
if (!PS(id)) { if (!PS(id)) {
if (PS(use_cookies) && zend_hash_find(&EG(symbol_table), "_COOKIE", if (PS(use_cookies) && zend_hash_find(&EG(symbol_table), "_COOKIE", sizeof("_COOKIE"), (void **) &data) == SUCCESS &&
sizeof("_COOKIE"), (void **) &data) == SUCCESS &&
Z_TYPE_PP(data) == IS_ARRAY && Z_TYPE_PP(data) == IS_ARRAY &&
zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS
lensess + 1, (void **) &ppid) == SUCCESS) { ) {
PPID2SID; PPID2SID;
PS(apply_trans_sid) = 0; PS(apply_trans_sid) = 0;
PS(send_cookie) = 0; PS(send_cookie) = 0;
@ -1418,36 +1399,34 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */
} }
if (!PS(use_only_cookies) && !PS(id) && if (!PS(use_only_cookies) && !PS(id) &&
zend_hash_find(&EG(symbol_table), "_GET", zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void **) &data) == SUCCESS &&
sizeof("_GET"), (void **) &data) == SUCCESS &&
Z_TYPE_PP(data) == IS_ARRAY && Z_TYPE_PP(data) == IS_ARRAY &&
zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS
lensess + 1, (void **) &ppid) == SUCCESS) { ) {
PPID2SID; PPID2SID;
PS(send_cookie) = 0; PS(send_cookie) = 0;
} }
if (!PS(use_only_cookies) && !PS(id) && if (!PS(use_only_cookies) && !PS(id) &&
zend_hash_find(&EG(symbol_table), "_POST", zend_hash_find(&EG(symbol_table), "_POST", sizeof("_POST"), (void **) &data) == SUCCESS &&
sizeof("_POST"), (void **) &data) == SUCCESS &&
Z_TYPE_PP(data) == IS_ARRAY && Z_TYPE_PP(data) == IS_ARRAY &&
zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), zend_hash_find(Z_ARRVAL_PP(data), PS(session_name), lensess + 1, (void **) &ppid) == SUCCESS
lensess + 1, (void **) &ppid) == SUCCESS) { ) {
PPID2SID; PPID2SID;
PS(send_cookie) = 0; PS(send_cookie) = 0;
} }
} }
/* check the REQUEST_URI symbol for a string of the form /* Check the REQUEST_URI symbol for a string of the form
'<session-name>=<session-id>' to allow URLs of the form * '<session-name>=<session-id>' to allow URLs of the form
http://yoursite/<session-name>=<session-id>/script.php */ * http://yoursite/<session-name>=<session-id>/script.php */
if (!PS(use_only_cookies) && !PS(id) && PG(http_globals)[TRACK_VARS_SERVER] && if (!PS(use_only_cookies) && !PS(id) && PG(http_globals)[TRACK_VARS_SERVER] &&
zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "REQUEST_URI", zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &data) == SUCCESS &&
sizeof("REQUEST_URI"), (void **) &data) == SUCCESS &&
Z_TYPE_PP(data) == IS_STRING && Z_TYPE_PP(data) == IS_STRING &&
(p = strstr(Z_STRVAL_PP(data), PS(session_name))) && (p = strstr(Z_STRVAL_PP(data), PS(session_name))) &&
p[lensess] == '=') { p[lensess] == '='
) {
char *q; char *q;
p += lensess + 1; p += lensess + 1;
@ -1457,17 +1436,17 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */
} }
} }
/* check whether the current request was referred to by /* Check whether the current request was referred to by
an external site which invalidates the previously found id */ * an external site which invalidates the previously found id. */
if (PS(id) && if (PS(id) &&
PS(extern_referer_chk)[0] != '\0' && PS(extern_referer_chk)[0] != '\0' &&
PG(http_globals)[TRACK_VARS_SERVER] && PG(http_globals)[TRACK_VARS_SERVER] &&
zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_REFERER", zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_REFERER", sizeof("HTTP_REFERER"), (void **) &data) == SUCCESS &&
sizeof("HTTP_REFERER"), (void **) &data) == SUCCESS &&
Z_TYPE_PP(data) == IS_STRING && Z_TYPE_PP(data) == IS_STRING &&
Z_STRLEN_PP(data) != 0 && Z_STRLEN_PP(data) != 0 &&
strstr(Z_STRVAL_PP(data), PS(extern_referer_chk)) == NULL) { strstr(Z_STRVAL_PP(data), PS(extern_referer_chk)) == NULL
) {
efree(PS(id)); efree(PS(id));
PS(id) = NULL; PS(id) = NULL;
PS(send_cookie) = 1; PS(send_cookie) = 1;
@ -1540,8 +1519,7 @@ static PHP_FUNCTION(session_set_cookie_params)
zend_bool secure = 0, httponly = 0; zend_bool secure = 0, httponly = 0;
if (!PS(use_cookies) || if (!PS(use_cookies) ||
zend_parse_parameters(argc TSRMLS_CC, "Z|ssbb", &lifetime, &path, &path_len, zend_parse_parameters(argc TSRMLS_CC, "Z|ssbb", &lifetime, &path, &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) {
&domain, &domain_len, &secure, &httponly) == FAILURE) {
return; return;
} }
@ -1566,7 +1544,7 @@ static PHP_FUNCTION(session_set_cookie_params)
/* }}} */ /* }}} */
/* {{{ proto array session_get_cookie_params(void) /* {{{ proto array session_get_cookie_params(void)
Return the session cookie parameters */ Return the session cookie parameters */
static PHP_FUNCTION(session_get_cookie_params) static PHP_FUNCTION(session_get_cookie_params)
{ {
if (zend_parse_parameters_none() == FAILURE) { if (zend_parse_parameters_none() == FAILURE) {
@ -1830,7 +1808,8 @@ static void php_register_var(zval** entry TSRMLS_DC)
convert_to_string_ex(entry); convert_to_string_ex(entry);
if ((strcmp(Z_STRVAL_PP(entry), "HTTP_SESSION_VARS") != 0) && if ((strcmp(Z_STRVAL_PP(entry), "HTTP_SESSION_VARS") != 0) &&
(strcmp(Z_STRVAL_PP(entry), "_SESSION") != 0)) { (strcmp(Z_STRVAL_PP(entry), "_SESSION") != 0)
) {
PS_ADD_VARL(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry)); PS_ADD_VARL(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
} }
} }
@ -1923,9 +1902,8 @@ static PHP_FUNCTION(session_unset)
zend_hash_internal_pointer_reset_ex(ht, &pos); zend_hash_internal_pointer_reset_ex(ht, &pos);
while (zend_hash_get_current_key_ex(ht, &str, &str_len, &num_key, while (zend_hash_get_current_key_ex(ht, &str, &str_len, &num_key, 0, &pos) == HASH_KEY_IS_STRING) {
0, &pos) == HASH_KEY_IS_STRING) { zend_delete_global_variable(str, str_len - 1 TSRMLS_CC);
zend_delete_global_variable(str, str_len-1 TSRMLS_CC);
zend_hash_move_forward_ex(ht, &pos); zend_hash_move_forward_ex(ht, &pos);
} }
} }
@ -2113,7 +2091,7 @@ static const zend_function_entry session_functions[] = {
PHP_FE(session_get_cookie_params, arginfo_session_void) PHP_FE(session_get_cookie_params, arginfo_session_void)
PHP_FE(session_write_close, arginfo_session_void) PHP_FE(session_write_close, arginfo_session_void)
PHP_FALIAS(session_commit, session_write_close, arginfo_session_void) PHP_FALIAS(session_commit, session_write_close, arginfo_session_void)
{NULL, NULL, NULL} {NULL, NULL, NULL}
}; };
/* }}} */ /* }}} */