unix信号程序中遇到的一个问题[随解决,但不明道理]

发表于:2007-05-25来源:作者:点击数: 标签:Unix问题程序遇到信号
在编程中遇到的一个可笑的问题,虽然解决,但是根本不知为什么能够解决,两种代码在功能上是完全 等效的,且全部符合语法规范,但是前者的错误及其荒谬,而后者却可以很好的执行,真是怪事!!!!!! 在编程中遇到的一个可笑的问题,虽然解决,但是根本不知为什么能够解决

编程中遇到的一个可笑的问题,虽然解决,但是根本不知为什么能够解决,两种代码在功能上是完全

等效的,且全部符合语法规范,但是前者的错误及其荒谬,而后者却可以很好的执行,真是怪事!!!!!!

在编程中遇到的一个可笑的问题,虽然解决,但是根本不知为什么能够解决,两种代码在功能上是完全

等效的,且全部符合语法规范,但是前者的错误及其荒谬,而后者却可以很好的执行,真是怪事!!!!!!

求高手关于问题的答案,谁可以解释这种现象?

系统:solaris linux(问题是一样的)
工具:gclearcase/" target="_blank" >cc

-------------------------一个模拟system()的函数版本1-----------------------------------

#include"sysError.h"

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

int debug;
extern int errno;

int systemexec(const char* cmdstring){
 
 pid_t pid;
 int status;
 struct sigaction ignore,saveintr,savequit;
 sigset_t childmask,savemask;
 
 if(cmdstring ==NULL)
  err_sys("fork error");
 
 ignore.sa_handler=SIG_IGN;
 sigemptyset(&ignore.sa_mask);
 ignore.sa_flags =0;
 
 if(sigaction(SIGINT,&ignore, &saveintr)<0)
  return -1;
 if(sigaction(SIGQUIT,&ignore,&savequit)<0)
  return -1;
 
 sigemptyset(&childmask);
 sigaddset(&childmask,SIGCHLD);
 
 if(sigprocmask(SIG_BLOCK,&childmask,&savemask)<0)
  return -1;
 
 if(pid=fork()<0)//使用if else语句,出错!!!!!!!改用switch则可以正常的运行
  err_sys("fork error");
 
 else if(pid == 0){
    
  sigaction(SIGINT,&saveintr,NULL);
  sigaction(SIGQUIT,&savequit,NULL);
  
  sigprocmask(SIG_SETMASK,&savemask,NULL);
  
  system("/bin/sh -c date");
  //_exit(127);
     
 }
 else{
  while(waitpid(pid,&status,0)<0)
   if(errno=EINTR){
    status=-1;
    break;
   }
  
 }
 

 if(sigaction(SIGINT,&saveintr,NULL)<0)
  return (-1);
 if(sigaction(SIGQUIT,&savequit,NULL)<0)
  return (-1);
 if(sigprocmask(SIG_SETMASK,&savemask,NULL)<0)
  return (-1);
 return (status);
 
}

int main(){
 
 printf("the system was called now\n");
 if ((debug=systemexec("date"))<0)
  printf("the system call error is %d\n",debug);
 
 printf("\n");
}
----------------------------------------------------------------------------------------

运行的结果:


五月  4日  2 00:27:04 CST 2005
the system call error is -1073746636

-bash-2.05b$ 五月  4日  2 00:27:04 CST 2005
the system call error is -1073746636

1:子进程运行了两次,且execl函数不能返回;
2:(调试时出现SIG_TARP硬件中断信号,试过多种处理方法,比如阻塞,忽略都不能奏效) 

-----------------------------修改后的代码--------------------------------------------
#include "sysError.h"

#include<errno.h>
#include<stdlib.h>
#include<stdio.h>

#include<signal.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>


int debug;
int systemexec(const char* cmdstring){
 
 pid_t pid;
 int status;

 char* cmd=cmdstring;
 struct sigaction ignore,saveintr,savequit;
 
 sigset_t childmask,savemask;
 
 if(cmdstring ==NULL)
  err_sys("the command paramter error");
 
 ignore.sa_handler=SIG_IGN;
 sigemptyset(&ignore.sa_mask);
 ignore.sa_flags=0;
 
 if(sigaction(SIGINT,&ignore,&saveintr)<0)
  return -1;
 if(sigaction(SIGQUIT,&ignore,&savequit)<0)
  return -1;
 
 sigemptyset(&childmask);
 sigaddset(&childmask,SIGCHLD);
 
 if(sigprocmask(SIG_BLOCK,&childmask,&savemask)<0)
  return -1;
 
 switch(pid=fork()){//使用switch语句,运行结果正常...
 case -1:
  
  status=-1;
  printf("the fork operation error");
  break;
 
 case 0:
  
  sigaction(SIGINT,&saveintr,NULL);
  sigaction(SIGQUIT,&savequit,NULL);
  
  sigprocmask(SIG_SETMASK,&savemask,NULL);
  
  execl("/bin/sh","sh","-c" ,cmd ,(char*)0);
  _exit(127);
  
 default:
  
  while(waitpid(pid,&status,0)<0)
   if(errno=EINTR){
    status=-1;
    break;
   }


  if(sigaction(SIGINT,&saveintr,NULL)<0)
   return (-1);
  if(sigaction(SIGQUIT,&savequit,NULL)<0)
   return (-1);
  if(sigprocmask(SIG_SETMASK,&savemask,NULL)<0)
   return (-1);
   
 }
  return (status);

}
 
int main(){
 
 if ((debug=systemexec("date"))<0)
  printf("the system call error is %d\n",debug);
 
 printf("\n");
}
------------------------------------------------------------------------------------
运行结果:

五月  4日 2 00:34:12 CST 2005

运行正常,测试正常:


------------------------------------------------------------------------------------ 

原文转自:http://www.ltesting.net

评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)