昨天准备做一个程序,PHP的串口扩展程序,用来做串口打开的,于是用dio_fdopen来新建一个文件:
view plaincopy to clipboardprint?
1.
2.<?php
3. $ff = dio_fdopen(1);
4. ?>
每个打开的文件都会被分配一个文件描述符.[1]stdin, stdout, 和stderr的文件描述符分别是0, 1, 和 2. 对于正在打开的额外文件, 保留了描述符3到9. 在某些时候将这些格外的文件描述符分配给stdin, stdout, 或者是stderr作为临时的副本链接是非常有用的.
view plaincopy to clipboardprint?
1.<?php
2.$ff = dio_fdopen(21);
3.?>
返回:Bad file descriptor。
查看PHP扩展的源代码,如下:
PHP的最新扩展:dio_open代码片段摘录。
view plaincopy to clipboardprint?
1. /* {{{ proto resource dio_fdopen(int fd)
2. Returns a resource for the specified file descriptor. */
3.PHP_FUNCTION(dio_fdopen)
4.{
5. php_fd_t *f;
6. long lfd;
7. int fd;
8.
9. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &lfd) == FAILURE) {
10. return;
11. }
12.
13. fd = (int)lfd;
14.
15. if ((fcntl(fd, F_GETFL, 0) == -1) && (errno == EBADF)) {
16. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad file descriptor %d", fd);
17. RETURN_FALSE;
18. }
19.
20. if (!new_php_fd(&f, fd)) {
21. RETURN_FALSE;
22. }
23.
24. ZEND_REGISTER_RESOURCE(return_value, f, le_fd);
25.}
返回错误在这一块,如下:
view plaincopy to clipboardprint?
1.if ((fcntl(fd, F_GETFL, 0) == -1) && (errno == EBADF)) {
2. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad file descriptor %d", fd);
3. RETURN_FALSE;
4. }
这儿涉及到fcntl函数的调用返回有问题,查其相关参数:
F_GETFL : 用来读取open系统调用第二个参数设置的标志,即文件的打开方式(O_RDONLY,O_WRONLY,O_APPEND等),它不需要第三个参数。实际上上这时函数返回的是file结构中的flags域。
其相当于只是创建了一个文件,并未确定这个文件的状态。在C里会补上一个 O_RDWR,
fd = open ("hole", O_CREAT, S_IRWXU | S_IRWXG) ;
变为:
fd = open ("hole", O_CREAT | O_RDWR, S_IRWXU | S_IRWXG) ;
fcntl这个系统调用功能比较多,可以执行多种操作,其内核函数在fs/fcntl.c中定义:
1.入口参数:
(1)fd:欲访问文件的文件描述符
(2)cmd:要执行的操作的命令,这个参数定义了10个标志,下面介绍其中的5个,
F_DUPFD、F_GETFD、F_SETFD、F_GETFL和 F_SETFL
(3)arg:可选,主要根据第二个命令来决定是否需要
2.出口参数:根据第二个参数的不同,这个返回值也不一样。
3.函数功能:
第二个参数是F_DUPFD,则进行复制文件描述符的操作。它需要用到第三个参数arg,这时arg是一个文件描述符,fcntl(fd,F_DUPFD,arg)在files_struct结构中从指定的arg开始搜索空闲的文件描述符,找到第一个后,将fd的内容复制进来,然后将新找到的文件描述符返回。
第二个参数是F_GETFD,则返回files_struct结构中close_on_exec的值。无需第三个参数。
第二个参数是F_SETFD,则需要第三个参数,若arg最低位为1,则对close_on_exec置位,否则清除close_on_exec。
第二个参数是F_GETFL,则用来读取open系统调用第二个参数设置的标志,即文件的打开方式(O_RDONLY,O_WRONLY,O_APPEND等),它不需要第三个参数。实际上上这时函数返回的是file结构中的flags域。
第二个参数是F_SETFL,则用来对open系统调用第二个参数设置的标志进行改变,但是它只能对O_APPEND和O_NONBLOCK标志进行改变,这时需要第三个参数arg,用来确定如何改变。函数返回0表示操作成功,否则返回-1,并置一个错