Return to dir.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard |
1.1 ! misho 1: /* ! 2: +----------------------------------------------------------------------+ ! 3: | PHP Version 5 | ! 4: +----------------------------------------------------------------------+ ! 5: | Copyright (c) 1997-2012 The PHP Group | ! 6: +----------------------------------------------------------------------+ ! 7: | This source file is subject to version 3.01 of the PHP license, | ! 8: | that is bundled with this package in the file LICENSE, and is | ! 9: | available through the world-wide-web at the following url: | ! 10: | http://www.php.net/license/3_01.txt | ! 11: | If you did not receive a copy of the PHP license and are unable to | ! 12: | obtain it through the world-wide-web, please send a note to | ! 13: | license@php.net so we can mail you a copy immediately. | ! 14: +----------------------------------------------------------------------+ ! 15: | Author: Thies C. Arntzen <thies@thieso.net> | ! 16: +----------------------------------------------------------------------+ ! 17: */ ! 18: ! 19: /* $Id: dir.c 321634 2012-01-01 13:15:04Z felipe $ */ ! 20: ! 21: /* {{{ includes/startup/misc */ ! 22: ! 23: #include "php.h" ! 24: #include "fopen_wrappers.h" ! 25: #include "file.h" ! 26: #include "php_dir.h" ! 27: #include "php_string.h" ! 28: #include "php_scandir.h" ! 29: #include "basic_functions.h" ! 30: ! 31: #ifdef HAVE_DIRENT_H ! 32: #include <dirent.h> ! 33: #endif ! 34: ! 35: #if HAVE_UNISTD_H ! 36: #include <unistd.h> ! 37: #endif ! 38: ! 39: #include <errno.h> ! 40: ! 41: #ifdef PHP_WIN32 ! 42: #include "win32/readdir.h" ! 43: #endif ! 44: ! 45: ! 46: #ifdef HAVE_GLOB ! 47: #ifndef PHP_WIN32 ! 48: #include <glob.h> ! 49: #else ! 50: #include "win32/glob.h" ! 51: #endif ! 52: #endif ! 53: ! 54: typedef struct { ! 55: int default_dir; ! 56: } php_dir_globals; ! 57: ! 58: #ifdef ZTS ! 59: #define DIRG(v) TSRMG(dir_globals_id, php_dir_globals *, v) ! 60: int dir_globals_id; ! 61: #else ! 62: #define DIRG(v) (dir_globals.v) ! 63: php_dir_globals dir_globals; ! 64: #endif ! 65: ! 66: #if 0 ! 67: typedef struct { ! 68: int id; ! 69: DIR *dir; ! 70: } php_dir; ! 71: ! 72: static int le_dirp; ! 73: #endif ! 74: ! 75: static zend_class_entry *dir_class_entry_ptr; ! 76: ! 77: #define FETCH_DIRP() \ ! 78: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &id) == FAILURE) { \ ! 79: return; \ ! 80: } \ ! 81: if (ZEND_NUM_ARGS() == 0) { \ ! 82: myself = getThis(); \ ! 83: if (myself) { \ ! 84: if (zend_hash_find(Z_OBJPROP_P(myself), "handle", sizeof("handle"), (void **)&tmp) == FAILURE) { \ ! 85: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find my handle property"); \ ! 86: RETURN_FALSE; \ ! 87: } \ ! 88: ZEND_FETCH_RESOURCE(dirp, php_stream *, tmp, -1, "Directory", php_file_le_stream()); \ ! 89: } else { \ ! 90: ZEND_FETCH_RESOURCE(dirp, php_stream *, 0, DIRG(default_dir), "Directory", php_file_le_stream()); \ ! 91: } \ ! 92: } else { \ ! 93: dirp = (php_stream *) zend_fetch_resource(&id TSRMLS_CC, -1, "Directory", NULL, 1, php_file_le_stream()); \ ! 94: if (!dirp) \ ! 95: RETURN_FALSE; \ ! 96: } ! 97: ! 98: /* {{{ arginfo */ ! 99: ZEND_BEGIN_ARG_INFO_EX(arginfo_dir, 0, 0, 0) ! 100: ZEND_ARG_INFO(0, dir_handle) ! 101: ZEND_END_ARG_INFO() ! 102: /* }}} */ ! 103: ! 104: static const zend_function_entry php_dir_class_functions[] = { ! 105: PHP_FALIAS(close, closedir, arginfo_dir) ! 106: PHP_FALIAS(rewind, rewinddir, arginfo_dir) ! 107: PHP_NAMED_FE(read, php_if_readdir, arginfo_dir) ! 108: {NULL, NULL, NULL} ! 109: }; ! 110: ! 111: ! 112: static void php_set_default_dir(int id TSRMLS_DC) ! 113: { ! 114: if (DIRG(default_dir)!=-1) { ! 115: zend_list_delete(DIRG(default_dir)); ! 116: } ! 117: ! 118: if (id != -1) { ! 119: zend_list_addref(id); ! 120: } ! 121: ! 122: DIRG(default_dir) = id; ! 123: } ! 124: ! 125: PHP_RINIT_FUNCTION(dir) ! 126: { ! 127: DIRG(default_dir) = -1; ! 128: return SUCCESS; ! 129: } ! 130: ! 131: PHP_MINIT_FUNCTION(dir) ! 132: { ! 133: static char dirsep_str[2], pathsep_str[2]; ! 134: zend_class_entry dir_class_entry; ! 135: ! 136: INIT_CLASS_ENTRY(dir_class_entry, "Directory", php_dir_class_functions); ! 137: dir_class_entry_ptr = zend_register_internal_class(&dir_class_entry TSRMLS_CC); ! 138: ! 139: #ifdef ZTS ! 140: ts_allocate_id(&dir_globals_id, sizeof(php_dir_globals), NULL, NULL); ! 141: #endif ! 142: ! 143: dirsep_str[0] = DEFAULT_SLASH; ! 144: dirsep_str[1] = '\0'; ! 145: REGISTER_STRING_CONSTANT("DIRECTORY_SEPARATOR", dirsep_str, CONST_CS|CONST_PERSISTENT); ! 146: ! 147: pathsep_str[0] = ZEND_PATHS_SEPARATOR; ! 148: pathsep_str[1] = '\0'; ! 149: REGISTER_STRING_CONSTANT("PATH_SEPARATOR", pathsep_str, CONST_CS|CONST_PERSISTENT); ! 150: ! 151: #ifdef HAVE_GLOB ! 152: ! 153: #ifdef GLOB_BRACE ! 154: REGISTER_LONG_CONSTANT("GLOB_BRACE", GLOB_BRACE, CONST_CS | CONST_PERSISTENT); ! 155: #else ! 156: # define GLOB_BRACE 0 ! 157: #endif ! 158: ! 159: #ifdef GLOB_MARK ! 160: REGISTER_LONG_CONSTANT("GLOB_MARK", GLOB_MARK, CONST_CS | CONST_PERSISTENT); ! 161: #else ! 162: # define GLOB_MARK 0 ! 163: #endif ! 164: ! 165: #ifdef GLOB_NOSORT ! 166: REGISTER_LONG_CONSTANT("GLOB_NOSORT", GLOB_NOSORT, CONST_CS | CONST_PERSISTENT); ! 167: #else ! 168: # define GLOB_NOSORT 0 ! 169: #endif ! 170: ! 171: #ifdef GLOB_NOCHECK ! 172: REGISTER_LONG_CONSTANT("GLOB_NOCHECK", GLOB_NOCHECK, CONST_CS | CONST_PERSISTENT); ! 173: #else ! 174: # define GLOB_NOCHECK 0 ! 175: #endif ! 176: ! 177: #ifdef GLOB_NOESCAPE ! 178: REGISTER_LONG_CONSTANT("GLOB_NOESCAPE", GLOB_NOESCAPE, CONST_CS | CONST_PERSISTENT); ! 179: #else ! 180: # define GLOB_NOESCAPE 0 ! 181: #endif ! 182: ! 183: #ifdef GLOB_ERR ! 184: REGISTER_LONG_CONSTANT("GLOB_ERR", GLOB_ERR, CONST_CS | CONST_PERSISTENT); ! 185: #else ! 186: # define GLOB_ERR 0 ! 187: #endif ! 188: ! 189: #ifndef GLOB_ONLYDIR ! 190: # define GLOB_ONLYDIR (1<<30) ! 191: # define GLOB_EMULATE_ONLYDIR ! 192: # define GLOB_FLAGMASK (~GLOB_ONLYDIR) ! 193: #else ! 194: # define GLOB_FLAGMASK (~0) ! 195: #endif ! 196: ! 197: /* This is used for checking validity of passed flags (passing invalid flags causes segfault in glob()!! */ ! 198: #define GLOB_AVAILABLE_FLAGS (0 | GLOB_BRACE | GLOB_MARK | GLOB_NOSORT | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ERR | GLOB_ONLYDIR) ! 199: ! 200: REGISTER_LONG_CONSTANT("GLOB_ONLYDIR", GLOB_ONLYDIR, CONST_CS | CONST_PERSISTENT); ! 201: REGISTER_LONG_CONSTANT("GLOB_AVAILABLE_FLAGS", GLOB_AVAILABLE_FLAGS, CONST_CS | CONST_PERSISTENT); ! 202: ! 203: #endif /* HAVE_GLOB */ ! 204: ! 205: return SUCCESS; ! 206: } ! 207: /* }}} */ ! 208: ! 209: /* {{{ internal functions */ ! 210: static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject) ! 211: { ! 212: char *dirname; ! 213: int dir_len; ! 214: zval *zcontext = NULL; ! 215: php_stream_context *context = NULL; ! 216: php_stream *dirp; ! 217: ! 218: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dirname, &dir_len, &zcontext) == FAILURE) { ! 219: RETURN_NULL(); ! 220: } ! 221: ! 222: context = php_stream_context_from_zval(zcontext, 0); ! 223: ! 224: dirp = php_stream_opendir(dirname, ENFORCE_SAFE_MODE|REPORT_ERRORS, context); ! 225: ! 226: if (dirp == NULL) { ! 227: RETURN_FALSE; ! 228: } ! 229: ! 230: dirp->flags |= PHP_STREAM_FLAG_NO_FCLOSE; ! 231: ! 232: php_set_default_dir(dirp->rsrc_id TSRMLS_CC); ! 233: ! 234: if (createobject) { ! 235: object_init_ex(return_value, dir_class_entry_ptr); ! 236: add_property_stringl(return_value, "path", dirname, dir_len, 1); ! 237: add_property_resource(return_value, "handle", dirp->rsrc_id); ! 238: php_stream_auto_cleanup(dirp); /* so we don't get warnings under debug */ ! 239: } else { ! 240: php_stream_to_zval(dirp, return_value); ! 241: } ! 242: } ! 243: /* }}} */ ! 244: ! 245: /* {{{ proto mixed opendir(string path[, resource context]) ! 246: Open a directory and return a dir_handle */ ! 247: PHP_FUNCTION(opendir) ! 248: { ! 249: _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); ! 250: } ! 251: /* }}} */ ! 252: ! 253: /* {{{ proto object dir(string directory[, resource context]) ! 254: Directory class with properties, handle and class and methods read, rewind and close */ ! 255: PHP_FUNCTION(getdir) ! 256: { ! 257: _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); ! 258: } ! 259: /* }}} */ ! 260: ! 261: /* {{{ proto void closedir([resource dir_handle]) ! 262: Close directory connection identified by the dir_handle */ ! 263: PHP_FUNCTION(closedir) ! 264: { ! 265: zval *id = NULL, **tmp, *myself; ! 266: php_stream *dirp; ! 267: int rsrc_id; ! 268: ! 269: FETCH_DIRP(); ! 270: ! 271: if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) { ! 272: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid Directory resource", dirp->rsrc_id); ! 273: RETURN_FALSE; ! 274: } ! 275: ! 276: rsrc_id = dirp->rsrc_id; ! 277: zend_list_delete(dirp->rsrc_id); ! 278: ! 279: if (rsrc_id == DIRG(default_dir)) { ! 280: php_set_default_dir(-1 TSRMLS_CC); ! 281: } ! 282: } ! 283: /* }}} */ ! 284: ! 285: #if defined(HAVE_CHROOT) && !defined(ZTS) && ENABLE_CHROOT_FUNC ! 286: /* {{{ proto bool chroot(string directory) ! 287: Change root directory */ ! 288: PHP_FUNCTION(chroot) ! 289: { ! 290: char *str; ! 291: int ret, str_len; ! 292: ! 293: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { ! 294: RETURN_FALSE; ! 295: } ! 296: ! 297: ret = chroot(str); ! 298: if (ret != 0) { ! 299: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno); ! 300: RETURN_FALSE; ! 301: } ! 302: ! 303: php_clear_stat_cache(1, NULL, 0 TSRMLS_CC); ! 304: ! 305: ret = chdir("/"); ! 306: ! 307: if (ret != 0) { ! 308: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno); ! 309: RETURN_FALSE; ! 310: } ! 311: ! 312: RETURN_TRUE; ! 313: } ! 314: /* }}} */ ! 315: #endif ! 316: ! 317: /* {{{ proto bool chdir(string directory) ! 318: Change the current directory */ ! 319: PHP_FUNCTION(chdir) ! 320: { ! 321: char *str; ! 322: int ret, str_len; ! 323: ! 324: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { ! 325: RETURN_FALSE; ! 326: } ! 327: ! 328: if (strlen(str) != str_len) { ! 329: RETURN_FALSE; ! 330: } ! 331: ! 332: if ((PG(safe_mode) && !php_checkuid(str, NULL, CHECKUID_CHECK_FILE_AND_DIR)) || php_check_open_basedir(str TSRMLS_CC)) { ! 333: RETURN_FALSE; ! 334: } ! 335: ret = VCWD_CHDIR(str); ! 336: ! 337: if (ret != 0) { ! 338: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno); ! 339: RETURN_FALSE; ! 340: } ! 341: ! 342: if (BG(CurrentStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentStatFile), strlen(BG(CurrentStatFile)))) { ! 343: efree(BG(CurrentStatFile)); ! 344: BG(CurrentStatFile) = NULL; ! 345: } ! 346: if (BG(CurrentLStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentLStatFile), strlen(BG(CurrentLStatFile)))) { ! 347: efree(BG(CurrentLStatFile)); ! 348: BG(CurrentLStatFile) = NULL; ! 349: } ! 350: ! 351: RETURN_TRUE; ! 352: } ! 353: /* }}} */ ! 354: ! 355: /* {{{ proto mixed getcwd(void) ! 356: Gets the current directory */ ! 357: PHP_FUNCTION(getcwd) ! 358: { ! 359: char path[MAXPATHLEN]; ! 360: char *ret=NULL; ! 361: ! 362: if (zend_parse_parameters_none() == FAILURE) { ! 363: return; ! 364: } ! 365: ! 366: #if HAVE_GETCWD ! 367: ret = VCWD_GETCWD(path, MAXPATHLEN); ! 368: #elif HAVE_GETWD ! 369: ret = VCWD_GETWD(path); ! 370: #endif ! 371: ! 372: if (ret) { ! 373: RETURN_STRING(path, 1); ! 374: } else { ! 375: RETURN_FALSE; ! 376: } ! 377: } ! 378: /* }}} */ ! 379: ! 380: /* {{{ proto void rewinddir([resource dir_handle]) ! 381: Rewind dir_handle back to the start */ ! 382: PHP_FUNCTION(rewinddir) ! 383: { ! 384: zval *id = NULL, **tmp, *myself; ! 385: php_stream *dirp; ! 386: ! 387: FETCH_DIRP(); ! 388: ! 389: if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) { ! 390: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid Directory resource", dirp->rsrc_id); ! 391: RETURN_FALSE; ! 392: } ! 393: ! 394: php_stream_rewinddir(dirp); ! 395: } ! 396: /* }}} */ ! 397: ! 398: /* {{{ proto string readdir([resource dir_handle]) ! 399: Read directory entry from dir_handle */ ! 400: PHP_NAMED_FUNCTION(php_if_readdir) ! 401: { ! 402: zval *id = NULL, **tmp, *myself; ! 403: php_stream *dirp; ! 404: php_stream_dirent entry; ! 405: ! 406: FETCH_DIRP(); ! 407: ! 408: if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) { ! 409: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid Directory resource", dirp->rsrc_id); ! 410: RETURN_FALSE; ! 411: } ! 412: ! 413: if (php_stream_readdir(dirp, &entry)) { ! 414: RETURN_STRINGL(entry.d_name, strlen(entry.d_name), 1); ! 415: } ! 416: RETURN_FALSE; ! 417: } ! 418: /* }}} */ ! 419: ! 420: #ifdef HAVE_GLOB ! 421: /* {{{ proto array glob(string pattern [, int flags]) ! 422: Find pathnames matching a pattern */ ! 423: PHP_FUNCTION(glob) ! 424: { ! 425: int cwd_skip = 0; ! 426: #ifdef ZTS ! 427: char cwd[MAXPATHLEN]; ! 428: char work_pattern[MAXPATHLEN]; ! 429: char *result; ! 430: #endif ! 431: char *pattern = NULL; ! 432: int pattern_len; ! 433: long flags = 0; ! 434: glob_t globbuf; ! 435: int n; ! 436: int ret; ! 437: zend_bool basedir_limit = 0; ! 438: ! 439: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &pattern, &pattern_len, &flags) == FAILURE) { ! 440: return; ! 441: } ! 442: ! 443: if (strlen(pattern) != pattern_len) { ! 444: RETURN_FALSE; ! 445: } ! 446: ! 447: if (pattern_len >= MAXPATHLEN) { ! 448: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN); ! 449: RETURN_FALSE; ! 450: } ! 451: ! 452: if ((GLOB_AVAILABLE_FLAGS & flags) != flags) { ! 453: php_error_docref(NULL TSRMLS_CC, E_WARNING, "At least one of the passed flags is invalid or not supported on this platform"); ! 454: RETURN_FALSE; ! 455: } ! 456: ! 457: #ifdef ZTS ! 458: if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) { ! 459: result = VCWD_GETCWD(cwd, MAXPATHLEN); ! 460: if (!result) { ! 461: cwd[0] = '\0'; ! 462: } ! 463: #ifdef PHP_WIN32 ! 464: if (IS_SLASH(*pattern)) { ! 465: cwd[2] = '\0'; ! 466: } ! 467: #endif ! 468: cwd_skip = strlen(cwd)+1; ! 469: ! 470: snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern); ! 471: pattern = work_pattern; ! 472: } ! 473: #endif ! 474: ! 475: ! 476: memset(&globbuf, 0, sizeof(glob_t)); ! 477: globbuf.gl_offs = 0; ! 478: if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) { ! 479: #ifdef GLOB_NOMATCH ! 480: if (GLOB_NOMATCH == ret) { ! 481: /* Some glob implementation simply return no data if no matches ! 482: were found, others return the GLOB_NOMATCH error code. ! 483: We don't want to treat GLOB_NOMATCH as an error condition ! 484: so that PHP glob() behaves the same on both types of ! 485: implementations and so that 'foreach (glob() as ...' ! 486: can be used for simple glob() calls without further error ! 487: checking. ! 488: */ ! 489: goto no_results; ! 490: } ! 491: #endif ! 492: RETURN_FALSE; ! 493: } ! 494: ! 495: /* now catch the FreeBSD style of "no matches" */ ! 496: if (!globbuf.gl_pathc || !globbuf.gl_pathv) { ! 497: no_results: ! 498: if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { ! 499: struct stat s; ! 500: ! 501: if (0 != VCWD_STAT(pattern, &s) || S_IFDIR != (s.st_mode & S_IFMT)) { ! 502: RETURN_FALSE; ! 503: } ! 504: } ! 505: array_init(return_value); ! 506: return; ! 507: } ! 508: ! 509: array_init(return_value); ! 510: for (n = 0; n < globbuf.gl_pathc; n++) { ! 511: if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { ! 512: if (PG(safe_mode) && (!php_checkuid_ex(globbuf.gl_pathv[n], NULL, CHECKUID_CHECK_FILE_AND_DIR, CHECKUID_NO_ERRORS))) { ! 513: basedir_limit = 1; ! 514: continue; ! 515: } else if (php_check_open_basedir_ex(globbuf.gl_pathv[n], 0 TSRMLS_CC)) { ! 516: basedir_limit = 1; ! 517: continue; ! 518: } ! 519: } ! 520: /* we need to do this everytime since GLOB_ONLYDIR does not guarantee that ! 521: * all directories will be filtered. GNU libc documentation states the ! 522: * following: ! 523: * If the information about the type of the file is easily available ! 524: * non-directories will be rejected but no extra work will be done to ! 525: * determine the information for each file. I.e., the caller must still be ! 526: * able to filter directories out. ! 527: */ ! 528: if (flags & GLOB_ONLYDIR) { ! 529: struct stat s; ! 530: ! 531: if (0 != VCWD_STAT(globbuf.gl_pathv[n], &s)) { ! 532: continue; ! 533: } ! 534: ! 535: if (S_IFDIR != (s.st_mode & S_IFMT)) { ! 536: continue; ! 537: } ! 538: } ! 539: add_next_index_string(return_value, globbuf.gl_pathv[n]+cwd_skip, 1); ! 540: } ! 541: ! 542: globfree(&globbuf); ! 543: ! 544: if (basedir_limit && !zend_hash_num_elements(Z_ARRVAL_P(return_value))) { ! 545: zval_dtor(return_value); ! 546: RETURN_FALSE; ! 547: } ! 548: } ! 549: /* }}} */ ! 550: #endif ! 551: ! 552: /* {{{ proto array scandir(string dir [, int sorting_order [, resource context]]) ! 553: List files & directories inside the specified path */ ! 554: PHP_FUNCTION(scandir) ! 555: { ! 556: char *dirn; ! 557: int dirn_len; ! 558: long flags = 0; ! 559: char **namelist; ! 560: int n, i; ! 561: zval *zcontext = NULL; ! 562: php_stream_context *context = NULL; ! 563: ! 564: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &dirn, &dirn_len, &flags, &zcontext) == FAILURE) { ! 565: return; ! 566: } ! 567: ! 568: if (strlen(dirn) != dirn_len) { ! 569: RETURN_FALSE; ! 570: } ! 571: ! 572: if (dirn_len < 1) { ! 573: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Directory name cannot be empty"); ! 574: RETURN_FALSE; ! 575: } ! 576: ! 577: if (zcontext) { ! 578: context = php_stream_context_from_zval(zcontext, 0); ! 579: } ! 580: ! 581: if (!flags) { ! 582: n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasort); ! 583: } else { ! 584: n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasortr); ! 585: } ! 586: if (n < 0) { ! 587: php_error_docref(NULL TSRMLS_CC, E_WARNING, "(errno %d): %s", errno, strerror(errno)); ! 588: RETURN_FALSE; ! 589: } ! 590: ! 591: array_init(return_value); ! 592: ! 593: for (i = 0; i < n; i++) { ! 594: add_next_index_string(return_value, namelist[i], 0); ! 595: } ! 596: ! 597: if (n) { ! 598: efree(namelist); ! 599: } ! 600: } ! 601: /* }}} */ ! 602: ! 603: /* ! 604: * Local variables: ! 605: * tab-width: 4 ! 606: * c-basic-offset: 4 ! 607: * End: ! 608: * vim600: sw=4 ts=4 fdm=marker ! 609: * vim<600: sw=4 ts=4 ! 610: */