在PHP中重新创建POSIX开放行为

时间:2017-03-22 13:10:10

标签: php posix fopen

我正在用PHP编写服务器(特别是SFTP服务器)。底层协议提供了与POSIX open函数具有相同语义的工具(特别是它支持O_READ,O_WRITE,O_RDWR,O_CREAT,O_APPEND,O_EXCL)。

然而,在流上运行的PHP fopen使用不同的语义('r','r +','w'....)。

是否有一种商定的方式来解释前者的语义,使用后者的实现?

1 个答案:

答案 0 :(得分:2)

PHP source code拯救了将fopen()模式映射到open()组合的标记。

反过来说,open()个标记的所有组合都不会映射到现有的fopen()模式。有些组合可能无效;我不知道open()如何对待他们。

/* parse standard "fopen" modes into open() flags */
PHPAPI int php_stream_parse_fopen_modes(const char *mode, int *open_flags)
{
    int flags;

    switch (mode[0]) {
        case 'r':
            flags = 0;
            break;
        case 'w':
            flags = O_TRUNC|O_CREAT;
            break;
        case 'a':
            flags = O_CREAT|O_APPEND;
            break;
        case 'x':
            flags = O_CREAT|O_EXCL;
            break;
        case 'c':
            flags = O_CREAT;
            break;
        default:
            /* unknown mode */
            return FAILURE;
    }

    if (strchr(mode, '+')) {
        flags |= O_RDWR;
    } else if (flags) {
        flags |= O_WRONLY;
    } else {
        flags |= O_RDONLY;
    }

#if defined(O_CLOEXEC)
    if (strchr(mode, 'e')) {
        flags |= O_CLOEXEC;
    }
#endif

#if defined(O_NONBLOCK)
    if (strchr(mode, 'n')) {
        flags |= O_NONBLOCK;
    }
#endif

#if defined(_O_TEXT) && defined(O_BINARY)
    if (strchr(mode, 't')) {
        flags |= _O_TEXT;
    } else {
        flags |= O_BINARY;
    }
#endif

    *open_flags = flags;
    return SUCCESS;
}