📄 filestat.c
字号:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); RETURN_FALSE; } RETURN_TRUE;}/* }}} */#if HAVE_UTIME/* {{{ proto bool touch(string filename [, int time [, int atime]]) Set modification time of file */PHP_FUNCTION(touch){ pval **filename, **filetime, **fileatime; int ret; struct stat sb; FILE *file; struct utimbuf newtimebuf; struct utimbuf *newtime = NULL; int ac = ZEND_NUM_ARGS(); if (ac == 1 && zend_get_parameters_ex(1, &filename) != FAILURE) {#ifndef HAVE_UTIME_NULL newtime = &newtimebuf; newtime->modtime = newtime->actime = time(NULL);#endif } else if (ac == 2 && zend_get_parameters_ex(2, &filename, &filetime) != FAILURE) { convert_to_long_ex(filetime); newtime = &newtimebuf; newtime->modtime = newtime->actime = Z_LVAL_PP(filetime); } else if (ac == 3 && zend_get_parameters_ex(3, &filename, &filetime, &fileatime) != FAILURE) { convert_to_long_ex(fileatime); convert_to_long_ex(filetime); newtime = &newtimebuf; newtime->actime = Z_LVAL_PP(fileatime); newtime->modtime = Z_LVAL_PP(filetime); } else { WRONG_PARAM_COUNT; } convert_to_string_ex(filename); if (PG(safe_mode) &&(!php_checkuid(Z_STRVAL_PP(filename), NULL, CHECKUID_CHECK_FILE_AND_DIR))) { RETURN_FALSE; } /* Check the basedir */ if (php_check_open_basedir(Z_STRVAL_PP(filename) TSRMLS_CC)) { RETURN_FALSE; } /* create the file if it doesn't exist already */ ret = VCWD_STAT(Z_STRVAL_PP(filename), &sb); if (ret == -1) { file = VCWD_FOPEN(Z_STRVAL_PP(filename), "w"); if (file == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create file %s because %s", Z_STRVAL_PP(filename), strerror(errno)); RETURN_FALSE; } fclose(file); } ret = VCWD_UTIME(Z_STRVAL_PP(filename), newtime); if (ret == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Utime failed: %s", strerror(errno)); RETURN_FALSE; } RETURN_TRUE;}/* }}} */#endif/* {{{ proto void clearstatcache(void) Clear file stat cache */PHP_FUNCTION(clearstatcache){ if (BG(CurrentStatFile)) { efree(BG(CurrentStatFile)); BG(CurrentStatFile) = NULL; }}/* }}} */#define IS_LINK_OPERATION(__t) ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT)#define IS_EXISTS_CHECK(__t) ((__t) == FS_EXISTS || (__t) == FS_IS_W || (__t) == FS_IS_R || (__t) == FS_IS_X || (__t) == FS_IS_FILE || (__t) == FS_IS_DIR || (__t) == FS_IS_LINK)/* {{{ php_stat */static void php_stat(const char *filename, php_stat_len filename_length, int type, pval *return_value TSRMLS_DC){ zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev, *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks; struct stat *stat_sb; int rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */ char *stat_sb_names[13]={"dev", "ino", "mode", "nlink", "uid", "gid", "rdev", "size", "atime", "mtime", "ctime", "blksize", "blocks"}; if (!filename_length) { RETURN_FALSE; } if (PG(safe_mode) &&(!php_checkuid_ex(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR, IS_EXISTS_CHECK(type) ? CHECKUID_NO_ERRORS : 0))) { RETURN_FALSE; } if (php_check_open_basedir_ex(filename, IS_EXISTS_CHECK(type) ? 0 : 1 TSRMLS_CC)) { RETURN_FALSE; }#ifndef PHP_WIN32 switch (type) { case FS_IS_W: RETURN_BOOL (!VCWD_ACCESS(filename, W_OK)); case FS_IS_R: RETURN_BOOL (!VCWD_ACCESS(filename, R_OK)); case FS_IS_X: RETURN_BOOL (!VCWD_ACCESS(filename, X_OK)); case FS_EXISTS: RETURN_BOOL (!VCWD_ACCESS(filename, F_OK)); }#endif stat_sb = &BG(sb); if (!BG(CurrentStatFile) || strcmp(filename, BG(CurrentStatFile))) { if (!BG(CurrentStatFile) || filename_length > BG(CurrentStatLength)) { if (BG(CurrentStatFile)) { efree(BG(CurrentStatFile)); } BG(CurrentStatLength) = filename_length; BG(CurrentStatFile) = estrndup(filename, filename_length); } else { memcpy(BG(CurrentStatFile), filename, filename_length+1); }#if HAVE_SYMLINK BG(lsb).st_mode = 0; /* mark lstat buf invalid */#endif if (VCWD_STAT(BG(CurrentStatFile), &BG(sb)) == -1) { if (!IS_LINK_OPERATION(type) && (!IS_EXISTS_CHECK(type) || (errno != ENOENT && errno != ENOTDIR))) { /* fileexists() test must print no error */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Stat failed for %s (errno=%d - %s)", BG(CurrentStatFile), errno, strerror(errno)); } /* This could be null if a failed stat leads to a user error handler which calls a failed stat */ if (BG(CurrentStatFile)) { efree(BG(CurrentStatFile)); BG(CurrentStatFile) = NULL; }#if HAVE_SYMLINK if (!IS_LINK_OPERATION(type)) /* Don't require success for link operation */#endif RETURN_FALSE; } }#if HAVE_SYMLINK if (IS_LINK_OPERATION(type) && !BG(lsb).st_mode) { /* do lstat if the buffer is empty */ if (VCWD_LSTAT(filename, &BG(lsb)) == -1) { if (!IS_EXISTS_CHECK(type) || (errno != ENOENT && errno != ENOTDIR)) { /* fileexists() test must print no error */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Lstat failed for %s (errno=%d - %s)", BG(CurrentStatFile), errno, strerror(errno)); } RETURN_FALSE; } }#endif#ifndef NETWARE if (type >= FS_IS_W && type <= FS_IS_X) { if(BG(sb).st_uid==getuid()) { rmask=S_IRUSR; wmask=S_IWUSR; xmask=S_IXUSR; } else if(BG(sb).st_gid==getgid()) { rmask=S_IRGRP; wmask=S_IWGRP; xmask=S_IXGRP; } else { int groups, n, i; gid_t *gids; groups = getgroups(0, NULL); if(groups) { gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0); n=getgroups(groups, gids); for(i=0;i<n;i++){ if(BG(sb).st_gid==gids[i]) { rmask=S_IRGRP; wmask=S_IWGRP; xmask=S_IXGRP; break; } } efree(gids); } } }#endif switch (type) { case FS_PERMS: RETURN_LONG((long)BG(sb).st_mode); case FS_INODE: RETURN_LONG((long)BG(sb).st_ino); case FS_SIZE: RETURN_LONG((long)BG(sb).st_size); case FS_OWNER: RETURN_LONG((long)BG(sb).st_uid); case FS_GROUP: RETURN_LONG((long)BG(sb).st_gid); case FS_ATIME:#ifdef NETWARE RETURN_LONG((long)(BG(sb).st_atime).tv_sec);#else RETURN_LONG((long)BG(sb).st_atime);#endif case FS_MTIME:#ifdef NETWARE RETURN_LONG((long)(BG(sb).st_mtime).tv_sec);#else RETURN_LONG((long)BG(sb).st_mtime);#endif case FS_CTIME:#ifdef NETWARE RETURN_LONG((long)(BG(sb).st_ctime).tv_sec);#else RETURN_LONG((long)BG(sb).st_ctime);#endif case FS_TYPE:#if HAVE_SYMLINK if (S_ISLNK(BG(lsb).st_mode)) { RETURN_STRING("link", 1); }#endif switch(BG(sb).st_mode&S_IFMT) { case S_IFIFO: RETURN_STRING("fifo", 1); case S_IFCHR: RETURN_STRING("char", 1); case S_IFDIR: RETURN_STRING("dir", 1); case S_IFBLK: RETURN_STRING("block", 1); case S_IFREG: RETURN_STRING("file", 1);#if defined(S_IFSOCK) && !defined(ZEND_WIN32)&&!defined(__BEOS__) case S_IFSOCK: RETURN_STRING("socket", 1);#endif } php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown file type (%d)", BG(sb).st_mode&S_IFMT); RETURN_STRING("unknown", 1); case FS_IS_W:#ifdef NETWARE RETURN_LONG(0);#endif if (getuid()==0) { RETURN_TRUE; /* root */ } RETURN_BOOL((BG(sb).st_mode & wmask) != 0); case FS_IS_R:#ifdef NETWARE RETURN_LONG(0);#endif if (getuid()==0) { RETURN_TRUE; /* root */ } RETURN_BOOL((BG(sb).st_mode&rmask)!=0); case FS_IS_X:#ifdef NETWARE RETURN_LONG(0);#endif if (getuid()==0) { xmask = S_IXROOT; /* root */ } RETURN_BOOL((BG(sb).st_mode&xmask)!=0 && !S_ISDIR(BG(sb).st_mode)); case FS_IS_FILE: RETURN_BOOL(S_ISREG(BG(sb).st_mode)); case FS_IS_DIR: RETURN_BOOL(S_ISDIR(BG(sb).st_mode)); case FS_IS_LINK:#if HAVE_SYMLINK RETURN_BOOL(S_ISLNK(BG(lsb).st_mode));#else RETURN_FALSE;#endif case FS_EXISTS: RETURN_TRUE; /* the false case was done earlier */ case FS_LSTAT:#if HAVE_SYMLINK stat_sb = &BG(lsb);#endif /* FALLTHROUGH */ case FS_STAT: array_init(return_value); MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb->st_dev); MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb->st_ino); MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb->st_mode); MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb->st_nlink); MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb->st_uid); MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb->st_gid);#ifdef HAVE_ST_RDEV MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb->st_rdev); #else MAKE_LONG_ZVAL_INCREF(stat_rdev, -1); #endif MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size);#ifdef NETWARE MAKE_LONG_ZVAL_INCREF(stat_atime, (stat_sb->st_atime).tv_sec); MAKE_LONG_ZVAL_INCREF(stat_mtime, (stat_sb->st_mtime).tv_sec); MAKE_LONG_ZVAL_INCREF(stat_ctime, (stat_sb->st_ctime).tv_sec);#else MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb->st_atime); MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb->st_mtime); MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb->st_ctime);#endif#ifdef HAVE_ST_BLKSIZE MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb->st_blksize); #else MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);#endif#ifdef HAVE_ST_BLOCKS MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb->st_blocks);#else MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);#endif /* Store numeric indexes in propper order */ zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL); zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL); /* Store string indexes referencing the same zval*/ zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *) &stat_dev, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *) &stat_ino, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *) &stat_mode, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *) &stat_nlink, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *) &stat_uid, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *) &stat_gid, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *) &stat_rdev, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *) &stat_size, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *) &stat_atime, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *) &stat_mtime, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *) &stat_ctime, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *) &stat_blksize, sizeof(zval *), NULL); zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *) &stat_blocks, sizeof(zval *), NULL); return; } php_error_docref(NULL TSRMLS_CC, E_WARNING, "Didn't understand stat call"); RETURN_FALSE;}/* }}} *//* another quickie macro to make defining similar functions easier */#define FileFunction(name, funcnum) \void name(INTERNAL_FUNCTION_PARAMETERS) { \ pval **filename; \ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) { \ WRONG_PARAM_COUNT; \ } \ convert_to_string_ex(filename); \ php_stat(Z_STRVAL_PP(filename), (php_stat_len) Z_STRLEN_PP(filename), funcnum, return_value TSRMLS_CC); \}/* {{{ proto int fileperms(string filename) Get file permissions */FileFunction(PHP_FN(fileperms), FS_PERMS)/* }}} *//* {{{ proto int fileinode(string filename) Get file inode */FileFunction(PHP_FN(fileinode), FS_INODE)/* }}} *//* {{{ proto int filesize(string filename) Get file size */FileFunction(PHP_FN(filesize), FS_SIZE)/* }}} *//* {{{ proto int fileowner(string filename) Get file owner */FileFunction(PHP_FN(fileowner), FS_OWNER)/* }}} *//* {{{ proto int filegroup(string filename) Get file group */FileFunction(PHP_FN(filegroup), FS_GROUP)/* }}} *//* {{{ proto int fileatime(string filename) Get last access time of file */FileFunction(PHP_FN(fileatime), FS_ATIME)/* }}} *//* {{{ proto int filemtime(string filename) Get last modification time of file */FileFunction(PHP_FN(filemtime), FS_MTIME)/* }}} *//* {{{ proto int filectime(string filename) Get inode modification time of file */FileFunction(PHP_FN(filectime), FS_CTIME)/* }}} *//* {{{ proto string filetype(string filename) Get file type */FileFunction(PHP_FN(filetype), FS_TYPE)/* }}} *//* {{{ proto bool is_writable(string filename) Returns true if file can be written */FileFunction(PHP_FN(is_writable), FS_IS_W)/* }}} *//* {{{ proto bool is_readable(string filename) Returns true if file can be read */FileFunction(PHP_FN(is_readable), FS_IS_R)/* }}} *//* {{{ proto bool is_executable(string filename) Returns true if file is executable */FileFunction(PHP_FN(is_executable), FS_IS_X)/* }}} *//* {{{ proto bool is_file(string filename) Returns true if file is a regular file */FileFunction(PHP_FN(is_file), FS_IS_FILE)/* }}} *//* {{{ proto bool is_dir(string filename) Returns true if file is directory */FileFunction(PHP_FN(is_dir), FS_IS_DIR)/* }}} *//* {{{ proto bool is_link(string filename) Returns true if file is symbolic link */FileFunction(PHP_FN(is_link), FS_IS_LINK)/* }}} *//* {{{ proto bool file_exists(string filename) Returns true if filename exists */FileFunction(PHP_FN(file_exists), FS_EXISTS)/* }}} *//* {{{ proto array lstat(string filename) Give information about a file or symbolic link */FileFunction(php_if_lstat, FS_LSTAT)/* }}} *//* {{{ proto array stat(string filename) Give information about a file */FileFunction(php_if_stat, FS_STAT)/* }}} *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -