SA_RESTART未在Linux下定义,在Solaris中编译良好

时间:2012-03-22 18:57:59

标签: linux solaris signals c99

免责声明:这适用于编程课程,但 <=> 分配的答案或目的。

我们可以在我的大学访问多个类似* nix的服务器,并鼓励他们在每个服务器上编译我们的项目,以了解不同环境如何改变事物。我目前正在做一个涉及信号的项目,而且我遇到了一些我无法解决的问题。

在基于Solaris的服务器下,一切正常:

xxxxxxx@xxx:~/proj6$ make gcc-new
rm -f ./pr6
gcc -std=c99 -Wall -Wextra -D_POSIX_C_SOURCE=200112L -D_POSIX_PTHREAD_SEMANTICS -o pr6 pr6.2.c pr6_ctime.c pr6_signal.c
 pr6_signal.c:64: warning: unused parameter 'sig'
 pr6_signal.c:64: warning: unused parameter 'func'

在基于Linux的服务器下,我看到了:

xxxxxxx@xxxxx:~/proj6$ make gcc-new
rm -f ./pr6
gcc -std=c99 -Wall -Wextra -D_POSIX_C_SOURCE=200112L -D_POSIX_PTHREAD_SEMANTICS  -o pr6  pr6.2.c pr6_ctime.c pr6_signal.c
pr6_signal.c: In function âinstall_signal_handlerâ:
pr6_signal.c:45: error: âSA_RESTARTâ undeclared (first use in this function)
pr6_signal.c:45: error: (Each undeclared identifier is reported only once
pr6_signal.c:45: error: for each function it appears in.)
pr6_signal.c: In function âreinstall_signal_handlerâ:
pr6_signal.c:64: warning: unused parameter âsigâ
pr6_signal.c:64: warning: unused parameter âfuncâ
make: *** [gcc-new] Error 1

我已经摆弄了c99,POSIX 2001-12和POSIX pthread的不同组合无济于事。我不明白为什么SA_RESTART不会在Linux下定义,因为它是POSIX标准的一部分,我在GCC中包含了这个标志。如果我忘了#include某些内容,那么两个系统都应该没有,不是吗?

更新:

我使用gcc -M来确定每台计算机上的编译中包含哪些文件,然后使用grep来尝试查找定义。到目前为止,这些是我的结果:

(在Solaris上)

xxxxxxx@xxx:~/proj6$ grep "SA_RESTART" /usr/include/sys/signal.h
#define SA_RESTART      0x000004
xxxxxxx@xxx:~/proj6$ grep "SA_RESTART" ./linux-signal.h
xxxxxxx@xxx:~/proj6$



xxxxxxx@xxx:~/proj6$ grep "#include" ./linux-signal.h
#include <features.h>
#include <bits/sigset.h>                /* __sigset_t, __sig_atomic_t.  */
#include <bits/types.h>
#include <bits/signum.h>
xxxxxxx@xxx:~/proj6$ grep "#include" /usr/include/sys/signal.h
#include <sys/feature_tests.h>
#include <sys/iso/signal_iso.h>
#include <sys/siginfo.h>
#include <sys/ucontext.h>
#include <sys/t_lock.h>

(在Linux上)

xxxxxxx@xxxxx:~/proj6$ grep "SA_RESTART" /usr/include/features.h
xxxxxxx@xxxxx:~/proj6$ grep "SA_RESTART" /usr/include/bits/sigset.h 
xxxxxxx@xxxxx:~/proj6$ grep "SA_RESTART" /usr/include/bits/types.h
xxxxxxx@xxxxx:~/proj6$ grep "SA_RESTART" /usr/include/bits/signum.h
xxxxxxx@xxxxx:~/proj6$

所以在Linux下包含的任何文件中没有SA_RESTART的定义(编译器告诉我这个开头)所以问题是为什么?

更新#2:Linux上/usr/include/sys/signal.h的内容只是`#include

更新#3:grep -r SA_RESTART /usr/include

的输出
/usr/include/bits/sigaction.h:# define SA_RESTART   0x10000000 /* Restart syscall on signal return.  */
/usr/include/asm-generic/signal.h: * SA_RESTART flag to get restarting signals (which were the default long ago)
/usr/include/asm-generic/signal.h:#define SA_RESTART    0x10000000
Binary file /usr/include/c++/3.4.6/x86_64-redhat-linux/bits/stdc++.h.gch/O2g matches
Binary file /usr/include/c++/3.4.6/x86_64-redhat-linux/bits/stdc++.h.gch/O0g matches
/usr/include/mysql/my_pthread.h:  as Mac OS X, sigset() results in flags such as SA_RESTART being set, and
/usr/include/asm/signal.h: * SA_RESTART flag to get restarting signals (which were the default long ago)
/usr/include/asm/signal.h:#define SA_RESTART    0x10000000u
grep: warning: /usr/include/gphoto2/gphoto2: recursive directory loop

/usr/include/valgrind/vki/vki-ppc64-linux.h:#define VKI_SA_RESTART      0x10000000u
/usr/include/valgrind/vki/vki-darwin.h:#define VKI_SA_RESTART   SA_RESTART
/usr/include/valgrind/vki/vki-ppc32-linux.h:#define VKI_SA_RESTART              0x10000000
/usr/include/valgrind/vki/vki-x86-linux.h:#define VKI_SA_RESTART                0x10000000u
/usr/include/valgrind/vki/vki-s390x-linux.h: * SA_RESTART flag to get restarting signals (which were the default long ago)
/usr/include/valgrind/vki/vki-s390x-linux.h:#define VKI_SA_RESTART      0x10000000
/usr/include/valgrind/vki/vki-amd64-linux.h:#define VKI_SA_RESTART              0x10000000
/usr/include/valgrind/vki/vki-arm-linux.h:#define VKI_SA_RESTART                0x10000000u

所以它驻留在一个名为sigaction.h的文件中(这很有意义)并且该文件被包含在内(用gcc -M验证),为什么编译器会抱怨?

1 个答案:

答案 0 :(得分:7)

这是由于你的-D标志:

#include <signal.h>
#include <stdio.h>

int main(void) {
#ifdef SA_RESTART
    puts("have SA_RESTART");
#else
    puts("no SA_RESTART");
#endif
    return 0;
}

$ cc foo.c && ./a.out
have SA_RESTART
$ gcc -std=c99 -Wall -Wextra -D_POSIX_C_SOURCE=200112L -D_POSIX_PTHREAD_SEMANTICS foo.c && ./a.out
no SA_RESTART
$ gcc -std=c99 -Wall -Wextra -D_POSIX_C_SOURCE=200809L -D_POSIX_PTHREAD_SEMANTICS foo.c && ./a.out
have SA_RESTART

特别是,“200112L”的意思是“不要给我SA_RESTART”。请参阅/usr/include/features.h