Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > C/C++ > unix信号程序中遇到的一个问题[随解决,但不明道理]
【标  题】:unix信号程序中遇到的一个问题[随解决,但不明道理]
【关键字】:unix
【来  源】:http://blog.chinaunix.net/article.php?articleId=28456&blogId=7004

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

Your Ad Here

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

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

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

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

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

系统:solaris linux(问题是一样的)
工具:gcc

-------------------------一个模拟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

运行正常,测试正常:


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

vim 使用经验:【上一篇】
JavaScript Toolbox:【下一篇】
【相关文章】
  • 在Dos、Unix下回车Return键的解释:0x0d+0x0a,0x0a
  • hp unix的ctrl-c中断程序
  • unix 与c++学习资源
  • 同样的程序,在UNIX不能通过?
  • unix下的基本系统数据类型
  • unix系统调用一览
  • Unix进程的环境
  • Unix的历史发展
  • UNIX学习之UNIX编程资料大收集一
  • UNIX学习之UNIX编程资料大收集二
  • 【随机文章】
  • linux线程,进程经典文章
  • Linux技巧集
  • apach+mysql+php 不能解析php文件.帮帮忙!
  • The code to get the size of kernel stack
  • 研究起Swing来了
  • 【原创】Liferay Portal学习笔记(二):使用CMS
  • 图标替换工具
  • 用MDaemon搭建邮件服务器
  • Python 笔记3:无可比拟的参数机制
  • SQLET - 开放源码的中文搜索引擎
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 bbb软讯网络 All Rigths Reserved.