[问题]一个关于信号范例程序的小问题,请大虾们帮帮小弟!!

C、C++和Java语言
回复
lyh_blank
帖子: 4
注册时间: 2007-04-30 2:25
送出感谢: 0
接收感谢: 0

[问题]一个关于信号范例程序的小问题,请大虾们帮帮小弟!!

#1

帖子 lyh_blank » 2007-05-24 22:49

小弟才刚开始学linux的编程,最近在一本书中找到关于信号的一个范例程序,编译时发生了问题,一时无处寻师,希望请教各位高手帮忙解答。

范例程序:

代码: 全选

#include <unistd.h>
#include <signal.h>
#include <stdio.h>
void show_handler(struct sigaction * act)
{
   switch (act->sa_flags)
   {
      case SIG_DFL:              //此为第8行
      {
         printf("Default action\n");
         break;
      }
      case SIG_IGN:              //此为第13行
      {
         printf("Ignore the signal\n");
         break;
      }
      default:
      {
         printf("0x%x\n", act->sa_handler);
      }
   }
}

main()
{
   int i;
   struct sigaction act, oldact;
   act.sa_handler = show_handler;                    //此为第29行
   act.sa_flags = SA_ONESHOT | SA_NOMASK;
   sigaction(SIGUSR1, &act, &oldact);
   for(i=5; i<15; i++)
   {
      printf("sa_handler of signal %2d=",i);
      sigaction(i, NULL, &oldact);
   }
}


编译时出错:

代码: 全选

test.c: 在函数 ‘show_handler’ 中:              
test.c:8: 错误: 指针不能用作 case 常量
test.c:13: 错误: 指针不能用作 case 常量
test.c: 在函数 ‘main’ 中:
test.c:29: 警告: 从不兼容的指针类型赋值
Completed ... unsuccessful
Total time taken: 4 secs


我查了一下sigaction的数据结构:

代码: 全选

struct sigaction
{
  void (*sa_handler) (int);
  sigset_t sa_mask;
  int sa_flags;
  void (*sa_restorer) (void);
}

函数指针sa_handler的参数是int型的,而程序里却传入的一个sigaction结构体指针,会不会是这个问题呢?
头像
antonym55
帖子: 353
注册时间: 2007-04-03 9:52
送出感谢: 0
接收感谢: 0
联系:

#2

帖子 antonym55 » 2007-05-25 0:38

代码: 全选

$man sigaction


sa_flags specifies a set of flags which modify the behaviour of the
signal handling process. It is formed by the bitwise OR of zero or more
of the following:


SA_NOCLDSTOP
If signum is SIGCHLD, do not receive notification when
child processes stop (i.e., when they receive one of
SIGSTOP, SIGTSTP, SIGTTIN or SIGTTOU) or resume (i.e.,
they receive SIGCONT) (see wait(2)).

SA_NOCLDWAIT
(Linux 2.6 and later) If signum is SIGCHLD, do not trans‐
form children into zombies when they terminate. See also
waitpid(2).

SA_RESETHAND
Restore the signal action to the default state once the
signal handler has been called. SA_ONESHOT is an obso‐
lete, non-standard synonym for this flag.

SA_ONSTACK
Call the signal handler on an alternate signal stack pro‐
vided by sigaltstack(2). If an alternate stack is not
available, the default stack will be used.

SA_RESTART
Provide behaviour compatible with BSD signal semantics by
making certain system calls restartable across signals.

SA_NODEFER
Do not prevent the signal from being received from within
its own signal handler. SA_NOMASK is an obsolete, non-
standard synonym for this flag.

SA_SIGINFO
The signal handler takes 3 arguments, not one. In this
case, sa_sigaction should be set instead of sa_handler.
TODO LIST:
1.valgrind:
2.gcov:
3.cppuint:未在Linux中使用
4.PostgreSQL:unixODBC
5.Doxygen:UTF8 中文问题,生成LaTex文档问题
6.LaTex:明确安装问题,UTF8 中文字体问题
lyh_blank
帖子: 4
注册时间: 2007-04-30 2:25
送出感谢: 0
接收感谢: 0

#3

帖子 lyh_blank » 2007-05-25 2:31

奇怪了,程序中赋给sa_flags的值在手册里竟然没有,是书里弄错了吗?
lyh_blank
帖子: 4
注册时间: 2007-04-30 2:25
送出感谢: 0
接收感谢: 0

#4

帖子 lyh_blank » 2007-05-25 2:41

再问个很菜的问题,我用man指令没法查c语言的内容,好像是少装些东西,还请各位指点。
头像
arthur
帖子: 76
注册时间: 2006-08-13 16:06
送出感谢: 0
接收感谢: 0

#5

帖子 arthur » 2007-05-25 9:25

试一下安装manpages-dev包:

代码: 全选

sudo apt-get install manpages-dev


lyh_blank 写了:再问个很菜的问题,我用man指令没法查c语言的内容,好像是少装些东西,还请各位指点。
头像
arthur
帖子: 76
注册时间: 2006-08-13 16:06
送出感谢: 0
接收感谢: 0

#6

帖子 arthur » 2007-05-25 9:55

看一下SIG_DEL和SIG_IGN在signal.h中的定义:

代码: 全选

#define SIG_DFL   ( (__sighandler_t)0)   /* default signal handling */
#define SIG_IGN   ( (__sighandler_t)1)   /* ignore signal */


再看一下__sighandler_t的定义:

代码: 全选

/* Type of a signal handler.  */
typedef void (*__sighandler_t) (int);


不难发现SIG_DEF和SIG_IGN都是一个指向函数的指针,所以产生了这里的错误:

代码: 全选

test.c:8: 错误: 指针不能用作 case 常量
test.c:13: 错误: 指针不能用作 case 常量


看sa_handler的定义,是一个接受一个int型参数的函数指针:

代码: 全选

void (*sa_handler) (int); 


再看你自己写的show_handler的定义,是一个接受一个struct sigaction型的函数:

代码: 全选

void show_handler(struct sigaction * act) 


这肯定导致:

代码: 全选

act.sa_handler = show_handler;  

产生 警告:

代码: 全选

test.c:29: 警告: 从不兼容的指针类型赋值 

[/code]
lyh_blank
帖子: 4
注册时间: 2007-04-30 2:25
送出感谢: 0
接收感谢: 0

#7

帖子 lyh_blank » 2007-05-25 11:02

谢谢,man的问题解决了,而程序看来满是漏洞,或许我在照办范例之前应当深究一下里面变量或函数所涉及的数据结构。
再次表示感谢。
头像
arthur
帖子: 76
注册时间: 2006-08-13 16:06
送出感谢: 0
接收感谢: 0

#8

帖子 arthur » 2007-05-25 11:12

不用客气,大家相互学习。
回复

回到 “C/C++/Java”