在 PHP 中重新创建 POSIX 打开行为
Recreating POSIX open behaviour in PHP
我正在 PHP 中编写服务器(特别是 SFTP 服务器)。底层协议提供了与 POSIX open 函数具有相同语义的工具(具体来说它支持 O_READ、O_WRITE、O_RDWR、O_CREAT , O_APPEND, O_EXCL).
但是 PHP 的 fopen,对流进行操作,使用不同的语义('r'、'r+'、'w'...)。
是否有一致的方式来使用后者的实现来解释前者的语义?
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;
}
我正在 PHP 中编写服务器(特别是 SFTP 服务器)。底层协议提供了与 POSIX open 函数具有相同语义的工具(具体来说它支持 O_READ、O_WRITE、O_RDWR、O_CREAT , O_APPEND, O_EXCL).
但是 PHP 的 fopen,对流进行操作,使用不同的语义('r'、'r+'、'w'...)。
是否有一致的方式来使用后者的实现来解释前者的语义?
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;
}