Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Shell实现:信号处理:是否可以从wait()提前返回?_C_Linux_Shell_Unix_Signals - Fatal编程技术网

C Shell实现:信号处理:是否可以从wait()提前返回?

C Shell实现:信号处理:是否可以从wait()提前返回?,c,linux,shell,unix,signals,C,Linux,Shell,Unix,Signals,我正在为我的操作系统类做一个shell项目,我们正在做信号处理。作业要求我们捕获SIGINT和SIGTSTP,并将信号发送给子进程。这是我到目前为止得到的。如果您遇到未定义的变量或函数,我希望您能根据标识符理解其含义: char input[ MAX_INPUT ]; sigset_t sig; pid_t *suspendedChildren = NULL; int nSuspendedChildren = 0; pid_t currentChild = 0; int main( int

我正在为我的操作系统类做一个shell项目,我们正在做信号处理。作业要求我们捕获
SIGINT
SIGTSTP
,并将信号发送给子进程。这是我到目前为止得到的。如果您遇到未定义的变量或函数,我希望您能根据标识符理解其含义:

char input[ MAX_INPUT ];

sigset_t sig;
pid_t *suspendedChildren = NULL;
int nSuspendedChildren = 0;
pid_t currentChild = 0;

int main( int argc, char *argv[] )
{    
  char quit = 0;

  setup();

  do
  {
  getInput();
  quit = handleInput( input );
  } while( quit != EXIT_NUMBER );

  return 0;
}

void setup( void )
{
  // block the interrupt signal 
  sigaddset( &sig, SIGINT);
  sigprocmask( SIG_BLOCK, &sig, NULL);

  // handle the suspend signal
  signal( SIGTSTP, suspendChild );
}

void suspendChild( int signal )
{
  if (currentChild) // meaning that there is a child process currently running
  {
    // increment suspended children counter
    nSuspendedChildren++;

    // reallocate the array of suspended children
    suspendedChildren = (pid_t *)realloc( suspendedChildren, nSuspendedChildren*sizeof(pid_t));
    suspendedChildren[nSuspendedChildren-1] = currentChild;

    // send suspend signal to child
    kill( currentChild, SIGTSTP );

    printf( "\n[%d]+ Stopped\t\t", nSuspendedChildren );
    puts( input );
    putchar( '\n' );

    // set the global to 0
    currentChild = 0;

    main( 0, NULL );
  }
}

int handleInput( char *s )
{
  // string tokenizing / parsing...
  // checks for redirection / background process requests
  // (not relevant to question being asked so omitted)

  currentChild = fork();
  if (currentChild) // parent process
  {
    wait( &status );
  }
  else // child process
  {
    execvp( prgm, tokens );
  }
}
因此,为了处理
SIGINT
,我只需阻塞信号,以便子进程(已执行的命令)接收它,而父进程(shell)忽略它。这工作得非常好,但这是
SIGTSTP
和进程的暂停,我遇到了问题。对于这个信号,我选择在信号到达时调用信号处理程序。这非常有效,因为我相信进程的默认
SIGTSTP
处理行为是挂起的,但是由于我的shell正在等待(请参见
wait(&status)
)子进程返回(当前已挂起),所以我的整个终端都处于僵死状态。我不能按ctrl+D键退出,我只需要关闭窗口并重新登录

因此,为了重申这篇文章的标题,有没有办法从信号处理程序
wait(int*)
提前返回?我查阅了文档,发现了以下声明:

如果接收到信号且未被忽略,wait也会返回


不过,这就是它所说的,并没有提供进一步的洞察力。

而不是<代码>等待>代码>考虑是否真的是代码> WaistPix<代码>(有一个选项),你真的想使用。鸭子

稍微含蓄的暗示,因为它是学校作业:而不是<代码>等待>代码>考虑是否真的是代码> WaistPID < /Cuff>(有一个选项),你真的想使用。为什么你要从<代码> SigTSTP中调用<代码>主代码(?)>代码>信号处理程序?!呵呵,这是我在暂停后迅速得到提示的肮脏解决方案…@鸭子非常感谢你的提示!我真是太傻了,没有研究其他wait()系统调用。。。