如何编写一个程序来告诉我的其他程序什么时候结束?
在没有自己生成的程序上执行waitpid()或waitid()的唯一方法是通过ptrace来成为它的父级.
下面是一个如何在posix操作系统上使用ptrace临时成为另一个进程父进程的示例,然后等待该程序退出.作为副作用,您还可以获得退出代码以及导致该程序退出的信号:
#include#include #include #include #include #include int main(int argc, char** argv) { int pid = atoi(argv[1]); int status; siginfo_t si; switch (ptrace(PTRACE_ATTACH, pid, NULL)) { case 0: break; case -ESRCH: case -EPERM: return 0; default: fprintf(stderr, "Failed to attach child\n"); return 1; } if (pid != wait(&status)) { fprintf(stderr, "wrong wait signal\n"); return 1; } if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) { /* The pid might not be running */ if (!kill(pid, 0)) { fprintf(stderr, "SIGSTOP didn't stop child\n"); return 1; } else { return 0; } } if (ptrace(PTRACE_CONT, pid, 0, 0)) { fprintf(stderr, "Failed to restart child\n"); return 1; } while (1) { if (waitid(P_PID, pid, &si, WSTOPPED | WEXITED)) { // an error occurred. if (errno == ECHILD) return 0; return 1; } errno = 0; if (si.si_code & (CLD_STOPPED | CLD_TRAPPED)) { /* If the child gets stopped, we have to PTRACE_CONT it * this will happen when the child has a child that exits. **/ if (ptrace(PTRACE_CONT, pid, 1, si.si_status)) { if (errno == ENOSYS) { /* Wow, we're stuffed. Stop and return */ return 0; } } continue; } if (si.si_code & (CLD_EXITED | CLD_KILLED | CLD_DUMPED)) { return si.si_status; } // Fall through to exiting. return 1; } }