另一个不同的open()返回0

时间:2016-02-12 16:58:03

标签: gcc

在搜索网站时,我发现用户2253605还有另外两个类似的问题(乍一看) 我也尝试了两种不同版本的gcc。这开始很难 跟踪应用程序中的问题,以使各种形式的数据在不同媒体上保持同步。一世 最终将其归结为几行代码来说明问题。

这个非常明确且令人费解。我无法找到系统打开的情况 一个文件,并返回一个非零文件描述符。它有时会真正打开指定的文件 并允许后续的read()无错误地发生。但是通过第三次打开() 后续的read()失败,指定一个无效的参数,该参数只能是零值文件 描述符。

下面的代码尝试打开5个不同的文件,存在4个文件,而不存在的文件。

前4个打开都返回文件描述符值为零(stdin)。

stdin未关闭,在第一个open()之前或之后的任何一个open()调用之前是read(), 将挂起,直到输入被按下。

即使stdin已关闭,也只应为第一个open()返回零。该 正在设置文件描述符,并且当尝试不存在的文件的open()时, 它会返回错误。

我无法相信gcc无法打开文件。我想我有一些O / S编译器配置 问题(lib)或者我看不到森林的树木。

这是在uccntu 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都给出相同的结果。 makefile 最后。

有人知道这里发生了什么吗?

终端输出显示在代码下方。

    #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 $@ $< $(CFLAGS)

    ### left side of colon is executable name 
    ### this line links objects and creates the executable
    bug_tst_sync_m: $(OBJ)
        gcc -o $@ $^ $(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)/*~ 

1 个答案:

答案 0 :(得分:1)

您的问题是operator precedence<=更难绑定;

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

变为

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

这意味着,如果open返回一个大于或等于零的数字,s_fh_1将为0。