Disclaimer: This is for a programming class, but it is not the answer or purpose of the assignment.
We have access to multiple *nix-like servers in my university, and are encouraged to compile our projects on each of them to see how different environments change things. I'm currently doing a project that involves signals and I've hit a difference that I cannot fix myself.
Under a Solaris based server, everything works:
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'
Under a Linux based server, I see this:
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
I've fiddled around with different combinations of c99, POSIX 2001-12, and POSIX pthread to no avail. I don't understand why it is that SA_RESTART
would not be defined under Linux as it is part of the POSIX standard and I've included that flag on GCC. If I forgot to #include something then it should be absent on both systems, no?
UPDATE:
I used gcc -M
to determine which files are included in my compile on each machine and then used grep
to try to find the definition. So far these are my results:
(On 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>
(On 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$
So there is no definition for SA_RESTART in any of the files being included under Linux (the compiler told me this to start with) so the question is WHY?
Update #2: contents of /usr/include/sys/signal.h
on Linux is just `#include
Update #3: output of 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
So it resides in a file called sigaction.h (which makes sense) and that file is being included (verified with gcc -M
), so why is the compiler complaining?
It's due to your -D flag:
#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
In particular, "200112L" means "don't give me SA_RESTART". See /usr/include/features.h
.
Edit: as Andrew Henle notes in a comment, this particular Linux features.h
is (or was back in 2012) just plain wrong here: see the SUS spec from 1997. Still, if it's wrong in whatever system you're using, you may need to work around that.