Apache源码分析——APR(3) 文件操作(1)

文件操作可是一个大的问题,因此这里采用各个击破,一个一个模块来分析。而其实文件操作也只是IO操作的一部分。

文件操作,必须得知道操作的文件是哪个撒,因此就有了文件路径,本文就先来看看apr中对文件的路径是怎么处理的。

 

在srclib\apr\include\arch\win32\apr_arch_file_io.h文件中定义了对路径的一些处理函数。

其中有两个比较不错的宏:

/* Win32 Exceptions:
 *
 * Note that trailing spaces and trailing periods are never recorded
 * in the file system, except by a very obscure bug where any file
 * that is created with a trailing space or period, followed by the 
 * ':' stream designator on an NTFS volume can never be accessed again.
 * In other words, don't ever accept them when designating a stream!
 *
 * An interesting side effect is that two or three periods are both 
 * treated as the parent directory, although the fourth and on are
 * not [strongly suggest all trailing periods are trimmed off, or
 * down to two if there are no other characters.]
 *
 * Leading spaces and periods are accepted, however.
 * The * ? < > codes all have wildcard side effects
 * The " / \ : are exclusively component separator tokens 
 * The system doesn't accept | for any (known) purpose 
 * Oddly, \x7f _is_ acceptable ;)
 */

/* apr_c_is_fnchar[] maps Win32's file name and shell escape symbols
 *
 *   element & 1 == valid file name character [excluding delimiters]
 *   element & 2 == character should be shell (caret) escaped from cmd.exe
 *
 * this must be in-sync with Apache httpd's gen_test_char.c for cgi escaping.
 */

const char apr_c_is_fnchar[256] =
{/* Reject all ctrl codes... Escape \n and \r (ascii 10 and 13)      */
    0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 /*   ! " # $ % & ' ( ) * + , - . /  0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
    1,1,2,1,3,3,3,3,3,3,2,1,1,1,1,0, 1,1,1,1,1,1,1,1,1,1,0,3,2,1,2,2,
 /* @ A B C D E F G H I J K L M N O  P Q R S T U V W X Y Z [ \ ] ^ _ */
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,3,2,3,3,1,
 /* ` a b c d e f g h i j k l m n o  p q r s t u v w x y z { | } ~   */
    3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,3,2,3,3,1,
 /* High bit codes are accepted (subject to utf-8->Unicode xlation)  */
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};

#define IS_FNCHAR(c) (apr_c_is_fnchar[(unsigned char)(c)] & 1)
#define IS_SHCHAR(c) ((apr_c_is_fnchar[(unsigned char)(c)] & 2) == 2)


大家都知道 在windows中 命令行 不接受路径中有空格等一些特殊的字符,这里就是判断下某个字符是不是可以被命令行接受的字符,而且有些字符本身就是不能出现在文件路径中的,都是需要判断滴。

 

下面看下此文件中的第一个函数:

 

apr_status_t filepath_root_test(char *path, apr_pool_t *p)
{
    apr_status_t rv;
     rv = GetDriveType(path);

    if (rv == DRIVE_UNKNOWN || rv == DRIVE_NO_ROOT_DIR)
        return APR_EBADPATH;
    return APR_SUCCESS;
}

此函数来获取路径中的驱动器类型,从而来判断路径的合法性,别传了一个根本就不存在滴路径,那就不好玩了。

 

在看接下来的两个函数

apr_status_t filepath_drive_get(char **rootpath, char drive, 
                                apr_int32_t flags, apr_pool_t *p);

apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p);

这两个函数是对路径进行了一个转换,确保访问中路径正确性。

而后的

apr_status_t file_cleanup(void *);

是对文件操作的收尾工作,做了一些清理,不过这个清理,感觉挺好,把标准io句柄都设置了不可用的文件句柄,可谓彻底撒。

 

这个代码让我看到Apache中的严谨,和自己写代码的拙劣,自己都没有这么严格来判断和转换过程序中的路径,反正认为打开失败了系统会返回错误的,其实想想很多时候我都是想期待操作是成功的,Apache中的这样处理,可以接收好几种路径的写法,真可谓用心良苦!


 


apr_status_t file_cleanup(void *);


 

 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值