大神們可知為何以下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;
}
uj5u.com熱心網友回復:
fileno() 不能獲取 fmemopen()記憶體流式檔案的檔案描述符, 因為 fmemopen()記憶體流式檔案根本沒有檔案描述符,fmemopen() 初始化FILE 結構體時 可能是默認寫成-1的。uj5u.com熱心網友回復:
但這個似乎說不過去啊,在Linux編程下很多東西以檔案方式操作,基本都是有檔案描述符的,包括stdin, stdout, stderr,都是記憶體流式檔案,它們默認描述符是0,1,2。暫時網上都搜不到有資料介紹說fmemopen()創建的記憶體流式檔案沒有檔案描述符,納悶了。uj5u.com熱心網友回復:
你想啊!FILE 結構體是對檔案描述符的封裝,里面有個欄位來存盤檔案描述符,最重要的是 FILE 結構體是在應用層的,而檔案描述符操作的是內核層資料,fmemopen() 打開的記憶體流檔案指標,實際上所有的資料都是在應用層的記憶體中,有必要使用檔案描述符從內核層來控制應用層的記憶體嗎?所以直接填 -1。并且 fmemopen 是應用層函式,應該沒有對應的 系統呼叫,沒有系統呼叫的話和內核沒多大關系,當然沒有檔案描述符
uj5u.com熱心網友回復:
嗯,好吧,只能是暫時不用它了。因為原來有段代碼是為了截獲execvp()呼叫命令時的螢屏列印,用pipe()建個管道,fork()了個子行程,然后把管道寫入的檔案描述符dup2映射到子行程檔案描述符表的標準輸出stdout,然后父行程從管道的讀取檔案描述符讀出資料。但我覺得這樣fork來fork去還用管道是不是比較麻煩,為何不在當前行程建個記憶體流檔案,把它描述符dup2到stdout,然后我直接system()呼叫命令就可以截獲它的螢屏輸出了,結果失敗了。 我比較納悶的是既然pipe()創建的管道檔案也是記憶體流形式的檔案吧,那為什么它就有檔案描述符呢,這就不清楚pipe()里面做了什么向內核申請到了檔案描述符了,有空再研究吧。轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/120165.html
標籤:應用程序開發區
上一篇:服務行程延遲問題
下一篇:xftp閃退
