在搜索网站时,我发现用户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)/*~
答案 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。