Changeset 866 for trunk/xcache.c


Ignore:
Timestamp:
2012-03-29T11:24:40+02:00 (2 years ago)
Author:
moo
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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; 
Note: See TracChangeset for help on using the changeset viewer.