大神们可知为何以下linux程序代码中fileno()获取fpout的文件描述符时返回-1错误吗?打印fd总是-1,fpout是fmemopen()打开的内存流文件指针,莫非fileno()就是不能获取fmemopen()内存流式文件的文件描述符?#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int fd;
int err_no;
FILE *fpout;
char buffer[256];
char buf[2048];
char *buf1;
char *cmd = "cat /proc/meminfo";

buf1 =  "This is testing for fputs...\n";
int i = 0;
for(i=0; i < 29; i++){
buf[i] = buf1[i];
}

printf("cmd is: %s\n", cmd);
fpout = fmemopen(buf, 2048, "a+");
fd = fileno(fpout);
printf("fpout pointer value is: %d\n", fpout);
err_no = fprintf(fpout, "This is testing for fputs...\n");
printf("fprintf return value is: %d\n", err_no);        fseek(fpout, 0, SEEK_SET);
fgets(buffer, 255, fpout);
printf("get string is: %s\n", buffer );
memset(buffer, 0, 256);

printf("fd no. is: %d\n", fd);
printf("stdout no. is: %d\n", fileno(stdout));
dup2(fd,1);
printf("after dup2, fd no. is: %d\n", fd);
printf("after dup2, stdout no. is: %d\n", fileno(stdout));
system(cmd);

while (fgets(buffer, sizeof(buffer), fpout)) {
printf("%s", buffer);


fclose(fpout);

return 0;
}

解决方案 »

  1.   

    fileno() 不能获取 fmemopen()内存流式文件的文件描述符, 因为 fmemopen()内存流式文件根本没有文件描述符,fmemopen() 初始化FILE 结构体时 可能是默认写成-1的。
      

  2.   

    但这个似乎说不过去啊,在Linux编程下很多东西以文件方式操作,基本都是有文件描述符的,包括stdin, stdout, stderr,都是内存流式文件,它们默认描述符是0,1,2。暂时网上都搜不到有资料介绍说fmemopen()创建的内存流式文件没有文件描述符,纳闷了。
      

  3.   

    你想啊!FILE 结构体是对文件描述符的封装,里面有个字段来存储文件描述符,最重要的是 FILE 结构体是在应用层的,而文件描述符操作的是内核层数据,fmemopen() 打开的内存流文件指针,实际上所有的数据都是在应用层的内存中,有必要使用文件描述符从内核层来控制应用层的内存吗?所以直接填 -1。
    并且 fmemopen 是应用层函数,应该没有对应的 系统调用,没有系统调用的话和内核没多大关系,当然没有文件描述符
      

  4.   

    嗯,好吧,只能是暂时不用它了。因为原来有段代码是为了截获execvp()调用命令时的屏幕打印,用pipe()建个管道,fork()了个子进程,然后把管道写入的文件描述符dup2映射到子进程文件描述符表的标准输出stdout,然后父进程从管道的读取文件描述符读出数据。但我觉得这样fork来fork去还用管道是不是比较麻烦,为何不在当前进程建个内存流文件,把它描述符dup2到stdout,然后我直接system()调用命令就可以截获它的屏幕输出了,结果失败了。 我比较纳闷的是既然pipe()创建的管道文件也是内存流形式的文件吧,那为什么它就有文件描述符呢,这就不清楚pipe()里面做了什么向内核申请到了文件描述符了,有空再研究吧。