2016-02-12 49 views
0

在搜索網站,我深受用戶2253605 和2135159.我也嘗試了兩種不同版本的gcc發現了兩個其他類似(乍)的問題。這開始是一個難以在應用程序中跟蹤問題以保持各種形式的數據在不同媒體上同步的問題。 I 最終將其解釋爲說明問題的幾行代碼。另外,不同的open()返回0

這一個是非常明確和令人費解。我一直無法找到我的系統打開文件 並返回非零文件描述符的情況。它有時會真正打開指定的文件 ,並允許後續讀取()發生而不會出錯。但是通過第三次open() 後續的read()失敗,指定一個無效參數,該參數只能是一個零值文件 描述符。

下面的代碼試圖打開5個不同的文件,存在4個文件和一個不存在的。

前4開全部返回零(stdin)的文件描述符值。

stdin沒有關閉,在第一次打開()之前或之後的任何一個open()調用中,將會掛起一個read(),直到按下enter鍵爲止將掛起 。

即使標準輸入被關閉,零應只針對首開()返回。 文件描述符正在設置,並且當嘗試使用不存在文件的open()時, 它將返回一個錯誤。

我不敢相信gcc無法打開文件。我想我有一些O/S編譯器配置 問題(lib)或者我可能看不到樹的森林。

這是在Ubuntu 12.04 LTS 64位和64位的gcc-4.6也對GCC-4.7。閃存驅動器是 格式化的ext4。 x86_64英特爾處理器。下面還顯示了2/10/16 上用於gccc-4.7的安裝命令。 gcc-4.6和gcc-4.7都給出了相同的結果。生成文件 在最後。

有人知道這裏發生了什麼?

終端輸出如代碼所示。

#include <stdio.h> 
    #include <fcntl.h> 
    #include <unistd.h  
    #include <errno.h> 

    int main() 

    { 
     long ret_val; 

     char cpy_buf[4096]; 

     char s_ary[20][80] = 

     { 
      "/media/FLASH16GB_2/Test_dir/t_dir/dm1", //0  exists 
      "/media/FLASH16GB_2/Test_dir/t_dir/dm2", //1  exists 
      "/media/FLASH16GB_2/Test_dir/t_dir/dm3", //2  exists 
      "/media/FLASH16GB_2/Test_dir/t_dir/dm4", //3  exists 
      "/media/FLASH16GB_2/Test_dir/t_dir/dm5", //4 does not exist 
     }; 

     char *s1; 
     long s_fh_1, s_fh_2, s_fh_3, s_fh_4, s_fh_5; 

     s_fh_1 = 10000; 

     s1 = &s_ary[0][0]; 

     if (s_fh_1 = open(s1 , O_RDONLY) < 0)   // &s_ary[0][0] 
      { 
       printf("Error opening source file, name=%s, line# = %i, errno = %i \n",&s_ary[0][0], __LINE__ , errno); 
       return -1; 
      } 

     if (s_fh_2 = open(&s_ary[1][0], O_RDONLY) < 0) 
      { 
       printf("Error opening source file, name=%s, line# = %i, errno = %i \n",&s_ary[1][0], __LINE__ , errno); 
       return -1; 
      } 

     if (s_fh_3 = open(&s_ary[2][0], O_RDONLY,0) < 0) 
      { 
       printf("Error opening source file, name=%s, line# = %i, errno = %i \n",&s_ary[2][0], __LINE__ , errno); 
       return -1; 
      } 

     if (s_fh_4 = open(&s_ary[3][0], O_RDONLY,0) < 0) 
      { 
       printf("Error opening source file, name=%s, line# = %i, errno = %i \n",&s_ary[3][0], __LINE__ , errno); 
       return -1; 
      } 

     printf("s_fh_1 = %li, s_fh_2 = %li, s_fh_3 = %li, s_fh_4 = %li \n", s_fh_1, s_fh_2, s_fh_3, s_fh_4); 



     if (s_fh_5 = open(&s_ary[4][0], O_RDONLY,0) < 0) 
      { 
       printf("Error opening source file, name=%s, line# = %i, errno = %i \n",&s_ary[4][0], __LINE__ , errno); 
       return -1; 
      } 

     return 0; 
    } 

終端輸出:

$ make 

    gcc -g -c -std=iso9899:1999 -o obj/bug_tst_sync_m.o bug_tst_sync_m.c -I../include 

    gcc -o bug_tst_sync_m obj/bug_tst_sync_m.o -I../include -L /usr/lib64/X11 -lX11 -lm 

    $ ./bug_tst_sync_m 

    s_fh_1 = 0, s_fh_2 = 0, s_fh_3 = 0, s_fh_4 = 0 

    Error opening source file, name=/media/FLASH16GB_2/Test_dir/t_dir/dm5, line# = 88, errno = 2 

    $ 

    $ 

上2_10_16用gcc-4.7安裝命令。

update-alternatives --display gcc 

    sudo add-apt-repository ppa:ubuntu-toolchain-r/test 
    sudo apt-get update 
    sudo apt-get install gcc-4.7 


    sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 60 
    sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 40 
    sudo update-alternatives --config gcc 

生成文件

### where to look for include files (locally and globally ? -I /usr/include/X11) 
    IDIR =../include 

    ### compiler to runand generate debugging info (no -g for production release code) 
    CC=gcc -g 

    ### list of dependencies 
    CFLAGS=-I$(IDIR) 

    ### where to put object modules 
    ODIR=obj 

    ### where to look for local library files locally (or write?) 
    LDIR = -L /usr/lib64/X11 -lX11 

    ### libraries to include m=-lm includes the math libarary, math lib = -lm 
    LIBS=-lm 

    ### list of all dependency files (.h files) 
    _DEPS = queues.h InterlockedExchange.h 
    DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) 

    ### list of all object files 
    _OBJ = bug_tst_sync_m.o 
    OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) 

    ### compiles object modules and produces debug info 
    $(ODIR)/%.o: %.c $(DEPS) 
     $(CC) -c -std=iso9899:1999 -o [email protected] $< $(CFLAGS) 

    ### left side of colon is executable name 
    ### this line links objects and creates the executable 
    bug_tst_sync_m: $(OBJ) 
     gcc -o [email protected] $^ $(CFLAGS) $(LDIR) $(LIBS) 

    ### this gets run if you type "make clean". it deletes source backup and object files. 
    ### run this then next make does everything. Without this you get situations that 
    .PHONY: clean 

    clean: 
     rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 
+0

從下'strace'投放過程的輸出後。看到實際的'open()'系統調用的返回值會非常有用。您可以使用'-o/output/file/name'選項將'strace'的輸出保存到文件中。 –

回答

1

您的問題是operator precedence<結合不同於=更難;

if (s_fh_1 = open(s1 , O_RDONLY) < 0) 

變得

if (s_fh_1 = (open(s1 , O_RDONLY) < 0)) 

這意味着,如果打開返回一個大於或等於零,s_fh_1將爲0

+1

而解決的辦法是使用'if((s_fh_1 = open(s1,O_RDONLY))<0)'代替。 – jamieguinan

+1

謝謝。那些該死的樹再次做到了!我想我在30年前學習C時遇到了類似的問題。變老和生鏽是皮特。 – mike243