【问题标题】:Shell implementation: signal handling: Any way to return early from wait()?Shell 实现:信号处理:有什么方法可以从 wait() 中提前返回?
【发布时间】:2013-12-19 15:26:24
【问题描述】:

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

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 也会返回。

然而,这就是它所说的一切,并没有提供进一步的见解。

【问题讨论】:

  • 有点神秘的提示,因为它是学校作业:而不是 wait 考虑它是否真的是您真正想要使用的 waitpid(带有特定选项)。
  • 你为什么要从SIGTSTP-信号处理程序中调用main()?!
  • @alk heh,这是我在暂停后恢复提示的快速而肮脏的解决方案......
  • @Duck 非常感谢您的提示!我不去探索替代的 wait() 系统调用是愚蠢的......

标签: c linux shell unix signals


【解决方案1】:

而不是wait,请考虑您真正想要使用的是否真的是waitpid(带有某个选项)。 – 鸭子

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 2022-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多