SA_RESTART не определен в Linux, прекрасно компилируется в Solaris - PullRequest
1 голос
/ 22 марта 2012

Отказ от ответственности: Это для класса программирования, но это , а не ответ или цель задания.

У нас есть доступ к нескольким * 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, то это должно отсутствовать в обеих системах, нет?

UPDATE:

Я использовал gcc -M, чтобы определить, какие файлы включены в мою компиляцию на каждой машине, а затем использовал grep, чтобы попытаться найти определение. Пока это мои результаты:

(На Солярисе)

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$

Так что нет никакого определения для SA_RESTART ни в одном из файлов, включаемых в Linux (компилятор сказал мне это для начала), поэтому вопрос - ПОЧЕМУ?

Обновление # 2: содержимое /usr/include/sys/signal.h в Linux просто `#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 Ответ

7 голосов
/ 22 марта 2012

Это связано с вашим флагом -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.

...