Changeset 866 in svn


Ignore:
Timestamp:
2012-03-29T09:24:40Z (3 years ago)
Author:
Xuefer
Message:

is non-unicode only; prepare for handling include_path + stat=0; project state is now unstable

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/processor/processor.m4

    r859 r866  
    11281128    PROCESS(long, ttl)
    11291129    PROCESS(zend_ulong, hits)
    1130 #ifdef IS_UNICODE
    1131     PROCESS(zend_uchar, name_type)
    1132 #endif
    1133     dnl {{{ name
    1134     DISABLECHECK(`
    1135 #ifdef IS_UNICODE
    1136         if (src->name_type == IS_UNICODE) {
    1137             PROCESS(int32_t, name.ustr.len)
    1138         }
    1139         else {
    1140             PROCESS(int, name.str.len)
    1141         }
    1142 #else
    1143         PROCESS(int, name.str.len)
    1144 #endif
    1145         IFRESTORE(`COPY(name.str.val)', `
    1146 #ifdef IS_UNICODE
    1147             PROC_ZSTRING_L(name_type, name.uni.val, name.uni.len)
    1148 #else
    1149             PROC_STRING_L(name.str.val, name.str.len)
    1150 #endif
    1151         ')
    1152     ')
    1153     DONE(name)
    1154     dnl }}}
     1130    DONE(name) dnl handle in xc_entry_php_t and xc_entry_var_t
    11551131')
    11561132dnl }}}
    11571133DEF_STRUCT_P_FUNC(`xc_entry_php_t', , `dnl {{{
    11581134    STRUCT(xc_entry_t, entry)
     1135    DISABLECHECK(`
     1136        PROCESS(int, entry.name.str.len)
     1137        IFRESTORE(`COPY(entry.name.str.val)', `
     1138            PROC_STRING_L(entry.name.str.val, entry.name.str.len)
     1139        ')
     1140    ')
     1141
    11591142    IFCALCCOPY(`COPY(php)', `STRUCT_P(xc_entry_data_php_t, php)')
    11601143
     
    11821165    STRUCT(xc_entry_t, entry)
    11831166
     1167#ifdef IS_UNICODE
     1168    PROCESS(zend_uchar, name_type)
     1169#endif
     1170    dnl {{{ entry.name
     1171    DISABLECHECK(`
     1172#ifdef IS_UNICODE
     1173        if (src->name_type == IS_UNICODE) {
     1174            PROCESS(int32_t, entry.name.ustr.len)
     1175        }
     1176        else {
     1177            PROCESS(int, entry.name.str.len)
     1178        }
     1179#else
     1180        PROCESS(int, entry.name.str.len)
     1181#endif
     1182        IFRESTORE(`COPY(entry.name.str.val)', `
     1183#ifdef IS_UNICODE
     1184            PROC_ZSTRING_L(name_type, entry.name.uni.val, entry.name.uni.len)
     1185#else
     1186            PROC_STRING_L(entry.name.str.val, entry.name.str.len)
     1187#endif
     1188        ')
     1189    ')
     1190    dnl }}}
     1191
    11841192    IFDPRINT(`INDENT()`'fprintf(stderr, "zval:value");')
    11851193    STRUCT_P_EX(zval_ptr, dst->value, src->value, `value', `', `&')
  • trunk/xcache.c

    r865 r866  
    199199            }
    200200#endif
    201 
     201            assert(IS_ABSOLUTE_PATH(entry1->name.str.val, entry1->name.str.len));
     202            assert(IS_ABSOLUTE_PATH(entry2->name.str.val, entry2->name.str.len));
     203
     204            if (entry1->name.str.len != entry2->name.str.len) {
     205                return 0;
     206            }
     207            return memcmp(entry1->name.str.val, entry2->name.str.val, entry1->name.str.len + 1) == 0;
     208
     209        case XC_TYPE_VAR:
    202210#ifdef IS_UNICODE
    203             if (entry1->name_type == IS_UNICODE) {
    204                 assert(IS_ABSOLUTE_PATH(entry1->name.ustr.val, entry1->name.ustr.len));
    205             }
    206             else
    207 #endif
    208             {
    209                 assert(IS_ABSOLUTE_PATH(entry1->name.str.val, entry1->name.str.len));
    210             }
    211 
    212 #ifdef IS_UNICODE
    213             if (entry2->name_type == IS_UNICODE) {
    214                 assert(IS_ABSOLUTE_PATH(entry2->name.ustr.val, entry2->name.ustr.len));
    215             }
    216             else
    217 #endif
    218             {
    219                 assert(IS_ABSOLUTE_PATH(entry2->name.str.val, entry2->name.str.len));
    220             }
    221             /* fall */
    222 
    223         case XC_TYPE_VAR:
    224             do {
    225 #ifdef IS_UNICODE
    226                 if (entry1->name_type != entry2->name_type) {
     211            if (entry1->name_type != entry2->name_type) {
     212                return 0;
     213            }
     214            else if (entry1->name_type == IS_UNICODE) {
     215                if (entry1->name.ustr.len != entry2->name.ustr.len) {
    227216                    return 0;
    228217                }
    229                 else if (entry1->name_type == IS_UNICODE) {
    230                     if (entry1->name.ustr.len != entry2->name.ustr.len) {
    231                         return 0;
    232                     }
    233                     return memcmp(entry1->name.ustr.val, entry2->name.ustr.val, (entry1->name.ustr.len + 1) * sizeof(UChar)) == 0;
     218                return memcmp(entry1->name.ustr.val, entry2->name.ustr.val, (entry1->name.ustr.len + 1) * sizeof(UChar)) == 0;
     219            }
     220            else
     221#endif
     222            {
     223                if (entry1->name.str.len != entry2->name.str.len) {
     224                    return 0;
    234225                }
    235                 else
    236 #endif
    237                 {
    238                     if (entry1->name.str.len != entry2->name.str.len) {
    239                         return 0;
    240                     }
    241                     return memcmp(entry1->name.str.val, entry2->name.str.val, entry1->name.str.len + 1) == 0;
    242                 }
    243 
    244             } while(0);
     226                return memcmp(entry1->name.str.val, entry2->name.str.val, entry1->name.str.len + 1) == 0;
     227            }
     228            break;
     229
    245230        default:
    246231            assert(0);
     
    448433
    449434/* helper function that loop through each entry */
    450 #define XC_ENTRY_APPLY_FUNC(name) int name(xc_entry_t *entry TSRMLS_DC)
     435#define XC_ENTRY_APPLY_FUNC(name) zend_bool name(xc_entry_t *entry TSRMLS_DC)
    451436typedef XC_ENTRY_APPLY_FUNC((*cache_apply_dmz_func_t));
    452437static void xc_entry_apply_dmz(xc_entry_type_t type, xc_cache_t *cache, cache_apply_dmz_func_t apply_func TSRMLS_DC) /* {{{ */
     
    874859}
    875860/* }}} */
    876 static int xc_stat(const char *filename, const char *include_path, struct stat *pbuf TSRMLS_DC) /* {{{ */
    877 {
    878     char filepath[MAXPATHLEN];
    879     char *paths, *path;
    880     char *tokbuf;
    881     int size = strlen(include_path) + 1;
    882     char tokens[] = { DEFAULT_DIR_SEPARATOR, '\0' };
    883     int ret;
    884     ALLOCA_FLAG(use_heap)
    885 
    886     paths = (char *)my_do_alloca(size, use_heap);
    887     memcpy(paths, include_path, size);
    888 
    889     for (path = php_strtok_r(paths, tokens, &tokbuf); path; path = php_strtok_r(NULL, tokens, &tokbuf)) {
    890         if (snprintf(filepath, sizeof(filepath), "%s/%s", path, filename) < MAXPATHLEN - 1) {
    891             if (VCWD_STAT(filepath, pbuf) == 0) {
    892                 ret = SUCCESS;
    893                 goto finish;
    894             }
    895         }
    896     }
    897 
    898     /* fall back to current directory */
    899     if (zend_is_executing(TSRMLS_C)) {
    900         const char *executed_filename = zend_get_executed_filename(TSRMLS_C);
    901         if (executed_filename && executed_filename[0] != '[') {
    902             int len = strlen(executed_filename);
    903             while ((--len >= 0) && !IS_SLASH(executed_filename[len])) {
    904                 /* skipped */
    905             }
    906             if (len > 0 && len + strlen(filename) + 1 < MAXPATHLEN - 1) {
    907                 strcpy(filepath, executed_filename);
    908                 strcpy(filepath + len + 1, filename);
    909                 if (VCWD_STAT(filepath, pbuf) == 0) {
    910                     ret = SUCCESS;
    911                     goto finish;
    912                 }
    913             }
    914         }
    915     }
    916 
    917     ret = FAILURE;
    918 
    919 finish:
    920     my_free_alloca(paths, use_heap);
    921 
    922     return ret;
    923 }
    924 /* }}} */
    925861
    926862#define HASH(i) (i)
    927863#define HASH_ZSTR_L(t, s, l) HASH(zend_u_inline_hash_func((t), (s), ((l) + 1) * sizeof(UChar)))
    928 #define HASH_STR_S(s, l) HASH(zend_inline_hash_func((s), (l)))
     864#define HASH_STR_S(s, l) HASH(zend_inline_hash_func((char *) (s), (l)))
    929865#define HASH_STR_L(s, l) HASH_STR_S((s), (l) + 1)
    930866#define HASH_STR(s) HASH_STR_L((s), strlen((s)) + 1)
     
    944880    return UNISW(NOTHING, UG(unicode) ? HASH_ZSTR_L(entry->name_type, entry->name.uni.val, entry->name.uni.len) :)
    945881        HASH_STR_L(entry->name.str.val, entry->name.str.len);
    946 }
    947 /* }}} */
    948 static inline xc_hash_value_t xc_entry_hash_php_basename(xc_entry_php_t *entry_php TSRMLS_DC) /* {{{ */
    949 {
    950 #ifdef IS_UNICODE
    951     if (UG(unicode) && entry_php->entry.name_type == IS_UNICODE) {
    952         zstr basename;
    953         size_t basename_len;
    954         php_u_basename(entry_php->entry.name.ustr.val, entry_php->entry.name.ustr.len, NULL, 0, &basename.u, &basename_len TSRMLS_CC);
    955         return HASH_ZSTR_L(IS_UNICODE, basename, basename_len);
    956     }
    957     else
    958 #endif
    959     {
    960         char *basename;
    961         xc_hash_value_t h;
    962         size_t basename_len;
    963 #ifdef ZEND_ENGINE_2
    964         php_basename(entry_php->entry.name.str.val, entry_php->entry.name.str.len, "", 0, &basename, &basename_len TSRMLS_CC);
    965 #else
    966         basename = php_basename(entry_php->entry.name.str.val, entry_php->entry.name.str.len, "", 0);
    967         basename_len = strlen(basename);
    968 #endif
    969         h = HASH_STR_L(basename, basename_len);
    970         efree(basename);
    971         return h;
    972     }
    973882}
    974883/* }}} */
     
    991900/* }}} */
    992901
     902#define XC_INCLUDE_PATH_XSTAT_FUNC(name) zend_bool name(const char *absolute_path, size_t absolute_path_len, void *data TSRMLS_DC)
     903typedef XC_INCLUDE_PATH_XSTAT_FUNC((*include_path_xstat_fun_t));
     904static zend_bool include_path_xstat(const char *filepath, char *opened_path_buffer, include_path_xstat_fun_t xstat_func, void *data TSRMLS_DC) /* {{{ */
     905{
     906    char *paths, *path;
     907    char *tokbuf;
     908    size_t absolute_path_len;
     909    int size = strlen(PG(include_path)) + 1;
     910    char tokens[] = { DEFAULT_DIR_SEPARATOR, '\0' };
     911    int ret;
     912    ALLOCA_FLAG(use_heap)
     913
     914    paths = (char *)my_do_alloca(size, use_heap);
     915    memcpy(paths, PG(include_path), size);
     916
     917    for (path = php_strtok_r(paths, tokens, &tokbuf); path; path = php_strtok_r(NULL, tokens, &tokbuf)) {
     918        absolute_path_len = snprintf(opened_path_buffer, MAXPATHLEN, "%s/%s", path, filepath);
     919        if (absolute_path_len < MAXPATHLEN - 1) {
     920            if (xstat_func(opened_path_buffer, absolute_path_len, data)) {
     921                ret = 1;
     922                goto finish;
     923            }
     924        }
     925    }
     926
     927    /* fall back to current directory */
     928    if (zend_is_executing(TSRMLS_C)) {
     929        const char *executed_filename = zend_get_executed_filename(TSRMLS_C);
     930        if (executed_filename && executed_filename[0] && executed_filename[0] != '[') {
     931            size_t filename_len = strlen(filepath);
     932            size_t dirname_len;
     933
     934            for (dirname_len = strlen(executed_filename) - 1; dirname_len > 0; --dirname_len) {
     935                if (IS_SLASH(executed_filename[dirname_len])) {
     936                    if (dirname_len + filename_len < MAXPATHLEN - 1) {
     937                        ++dirname_len; /* include tailing slash */
     938                        memcpy(opened_path_buffer, executed_filename, dirname_len);
     939                        memcpy(opened_path_buffer + dirname_len, filepath, filename_len);
     940                        absolute_path_len = dirname_len + filename_len;
     941                        if (xstat_func(opened_path_buffer, absolute_path_len, data) == 0) {
     942                            ret = 1;
     943                            goto finish;
     944                        }
     945                    }
     946                    break;
     947                }
     948            }
     949        }
     950    }
     951
     952    ret = FAILURE;
     953
     954finish:
     955    my_free_alloca(paths, use_heap);
     956
     957    return ret;
     958}
     959/* }}} */
     960static XC_INCLUDE_PATH_XSTAT_FUNC(xc_stat_file) /* {{{ */
     961{
     962    return VCWD_STAT(absolute_path, (struct stat *) data) == 0 ? 1 : 0;
     963}
     964/* }}} */
     965static int xc_stat(const char *filepath, char *opened_path_buffer, struct stat *pbuf TSRMLS_DC) /* {{{ */
     966{
     967    return include_path_xstat(filepath, opened_path_buffer, xc_stat_file, (void *) pbuf TSRMLS_DC)
     968        ? SUCCESS
     969        : FAILURE;
     970}
     971/* }}} */
    993972static int xc_entry_php_resolve_opened_path(xc_compiler_t *compiler TSRMLS_DC) /* {{{ */
    994973{
     
    998977}
    999978/* }}} */
     979static int xc_entry_php_quick_resolve_opened_path(xc_compiler_t *compiler, struct stat *statbuf TSRMLS_DC) /* {{{ */
     980{
     981    if (strcmp(SG(request_info).path_translated, compiler->filename) == 0) {
     982        /* sapi has already done this stat() for us */
     983        if (statbuf) {
     984            struct stat *sapi_stat = sapi_get_stat(TSRMLS_C);
     985            if (!sapi_stat) {
     986                return FAILURE;
     987            }
     988
     989            *statbuf = *sapi_stat;
     990        }
     991
     992        compiler->opened_path = expand_filepath(SG(request_info).path_translated, compiler->opened_path_buffer TSRMLS_CC);
     993        return SUCCESS;
     994    }
     995
     996    /* absolute path */
     997    if (IS_ABSOLUTE_PATH(compiler->filename, strlen(compiler->filename))) {
     998        if (statbuf && VCWD_STAT(compiler->filename, statbuf) != 0) {
     999            return FAILURE;
     1000        }
     1001        compiler->opened_path = expand_filepath(compiler->filename, compiler->opened_path_buffer TSRMLS_CC);
     1002        return SUCCESS;
     1003    }
     1004
     1005    /* relative path */
     1006    if (*compiler->filename == '.' && (IS_SLASH(compiler->filename[1]) || compiler->filename[1] == '.')) {
     1007        const char *ptr = compiler->filename + 1;
     1008        if (*ptr == '.') {
     1009            while (*(++ptr) == '.');
     1010            if (!IS_SLASH(*ptr)) {
     1011                return FAILURE;
     1012            }   
     1013        }
     1014
     1015        if (statbuf && VCWD_STAT(compiler->filename, statbuf) != 0) {
     1016            return FAILURE;
     1017        }
     1018
     1019        compiler->opened_path = expand_filepath(compiler->filename, compiler->opened_path_buffer TSRMLS_CC);
     1020        return SUCCESS;
     1021    }
     1022
     1023    return FAILURE;
     1024}
     1025/* }}} */
    10001026static int xc_entry_php_init_key(xc_compiler_t *compiler TSRMLS_DC) /* {{{ */
    10011027{
    10021028    if (XG(stat)) {
    1003         struct stat buf, *pbuf;
    1004 
    1005         if (strcmp(SG(request_info).path_translated, compiler->filename) == 0) {
    1006             /* sapi has already done this stat() for us */
    1007             pbuf = sapi_get_stat(TSRMLS_C);
    1008             if (pbuf) {
    1009                 goto stat_done;
    1010             }
    1011         }
    1012 
    1013         /* absolute path */
    1014         pbuf = &buf;
    1015         if (IS_ABSOLUTE_PATH(compiler->filename, strlen(compiler->filename))) {
    1016             if (VCWD_STAT(compiler->filename, pbuf) != 0) {
     1029        struct stat buf;
     1030        time_t delta;
     1031
     1032        if (xc_entry_php_quick_resolve_opened_path(compiler, &buf TSRMLS_CC) != SUCCESS) {
     1033            if (xc_stat(compiler->filename, compiler->opened_path_buffer, &buf TSRMLS_CC) != SUCCESS) {
    10171034                return FAILURE;
    10181035            }
    1019             goto stat_done;
    1020         }
    1021 
    1022         /* relative path */
    1023         if (*compiler->filename == '.' && (IS_SLASH(compiler->filename[1]) || compiler->filename[1] == '.')) {
    1024             const char *ptr = compiler->filename + 1;
    1025             if (*ptr == '.') {
    1026                 while (*(++ptr) == '.');
    1027                 if (!IS_SLASH(*ptr)) {
    1028                     goto not_relative_path;
    1029                 }   
    1030             }
    1031 
    1032             if (VCWD_STAT(compiler->filename, pbuf) != 0) {
    1033                 return FAILURE;
    1034             }
    1035             goto stat_done;
    1036         }
    1037 not_relative_path:
    1038 
    1039         /* use include_path */
    1040         if (xc_stat(compiler->filename, PG(include_path), pbuf TSRMLS_CC) != SUCCESS) {
     1036            compiler->opened_path = compiler->opened_path_buffer;
     1037        }
     1038
     1039        delta = XG(request_time) - buf.st_mtime;
     1040        if (abs(delta) < 2 && !xc_test) {
    10411041            return FAILURE;
    10421042        }
    10431043
    1044         /* fall */
    1045 
    1046 stat_done:
    1047         {
    1048             time_t delta = XG(request_time) - pbuf->st_mtime;
    1049             if (abs(delta) < 2 && !xc_test) {
    1050                 return FAILURE;
    1051             }
    1052         }
    1053 
    1054         compiler->new_entry.file_mtime   = pbuf->st_mtime;
    1055         compiler->new_entry.file_size    = pbuf->st_size;
     1044        compiler->new_entry.file_mtime   = buf.st_mtime;
     1045        compiler->new_entry.file_size    = buf.st_size;
    10561046#ifdef HAVE_INODE
    1057         compiler->new_entry.file_device  = pbuf->st_dev;
    1058         compiler->new_entry.file_inode   = pbuf->st_ino;
     1047        compiler->new_entry.file_device  = buf.st_dev;
     1048        compiler->new_entry.file_inode   = buf.st_ino;
    10591049#endif
    10601050    }
     
    10741064    }
    10751065
    1076     UNISW(NOTHING, compiler->new_entry.entry.name_type = IS_STRING;)
    1077     compiler->new_entry.entry.name.str.val = (char *) (compiler->opened_path ? compiler->opened_path : compiler->filename);
    1078     compiler->new_entry.entry.name.str.len = strlen(compiler->new_entry.entry.name.str.val);
     1066    fprintf(stderr, "-------- %s\n", compiler->opened_path);
    10791067
    10801068    {
     
    10871075            )
    10881076        {
    1089             basename_hash_value = xc_entry_hash_php_basename(&compiler->new_entry TSRMLS_CC);
     1077            const char *filename_end = compiler->filename + strlen(compiler->filename);
     1078            const char *basename = filename_end - 1;
     1079
     1080            /* scan till out of basename part */
     1081            while (basename >= compiler->filename && !IS_SLASH(*basename)) {
     1082                --basename;
     1083            }
     1084            /* get back to basename */
     1085            ++basename;
     1086
     1087            basename_hash_value = HASH_STR_L(basename, filename_end - basename);
    10901088        }
    10911089
     
    11241122    ulong           old_rsid = EG(regular_list).nNextFreeElement;
    11251123
    1126     stream = php_stream_open_wrapper(compiler->new_entry.entry.name.str.val, "rb", USE_PATH | REPORT_ERRORS | ENFORCE_SAFE_MODE | STREAM_DISABLE_OPEN_BASEDIR, NULL);
     1124    stream = php_stream_open_wrapper(ZEND_24(NOTHING, (char *)) compiler->filename, "rb", USE_PATH | REPORT_ERRORS | ENFORCE_SAFE_MODE | STREAM_DISABLE_OPEN_BASEDIR, NULL);
    11271125    if (!stream) {
    11281126        return FAILURE;
     
    18331831    stored_entry = NULL;
    18341832    stored_php = NULL;
     1833
     1834    if (compiler->opened_path) {
     1835        compiler->new_entry.entry.name.str.val = (char *) compiler->opened_path;
     1836        compiler->new_entry.entry.name.str.len = strlen(compiler->new_entry.entry.name.str.val);
     1837    }
     1838    else {
     1839        /* lookup in opened path */
     1840    }
     1841
    18351842    ENTER_LOCK_EX(cache) {
    1836         stored_entry = (xc_entry_php_t *) xc_entry_find_dmz(XC_TYPE_PHP, cache, compiler->entry_hash.entryslotid, (xc_entry_t *) &compiler->new_entry TSRMLS_CC);
     1843        if (XG(stat)) {
     1844            stored_entry = (xc_entry_php_t *) xc_entry_find_dmz(XC_TYPE_PHP, cache, compiler->entry_hash.entryslotid, (xc_entry_t *) &compiler->new_entry TSRMLS_CC);
     1845        }
     1846        else {
     1847            compiler->new_entry.entry.name.str.val = (char *) compiler->opened_path;
     1848            compiler->new_entry.entry.name.str.len = strlen(compiler->new_entry.entry.name.str.val);
     1849        }
     1850
    18371851        if (stored_entry) {
    18381852            xc_cache_hit_dmz(cache TSRMLS_CC);
     
    26702684
    26712685#ifdef IS_UNICODE
    2672     entry_var->entry.name_type = name->type;
     2686    entry_var->name_type = name->type;
    26732687#endif
    26742688    entry_var->entry.name = name->value;
  • trunk/xcache.h

    r860 r866  
    422422    long       ttl;
    423423
    424 #ifdef IS_UNICODE
    425     zend_uchar name_type;
    426 #endif
    427424    xc_entry_name_t name;
    428425};
     
    454451typedef struct {
    455452    xc_entry_t entry;
     453#ifdef IS_UNICODE
     454    zend_uchar name_type;
     455#endif
    456456    zval      *value;
    457457    zend_bool  have_references;
Note: See TracChangeset for help on using the changeset viewer.