C getppid等价于获取子pid
getppid()返回父进程的进程ID 因为任何给定的进程在任何时候都只能有一个父进程。 从getppid返回是有意义的 是否存在对getChildPid的等效系统调用 我知道一个进程可以有很多子进程,但就我而言,我确信我的进程在任何时候都只有一个子进程。因此,在我的例子中,使用上面这样的系统调用是有意义的C getppid等价于获取子pid,c,unix,C,Unix,getppid()返回父进程的进程ID 因为任何给定的进程在任何时候都只能有一个父进程。 从getppid返回是有意义的 是否存在对getChildPid的等效系统调用 我知道一个进程可以有很多子进程,但就我而言,我确信我的进程在任何时候都只有一个子进程。因此,在我的例子中,使用上面这样的系统调用是有意义的 编辑:子进程是由外部库生成的,该库不公开由fork()返回的pid。一个进程可以有多个子进程,而调用只返回其中一个子进程是没有意义的。最广泛使用的机制是保存从fork返回的pid。您可以维护
编辑:子进程是由外部库生成的,该库不公开由
fork()
返回的pid。一个进程可以有多个子进程,而调用只返回其中一个子进程是没有意义的。最广泛使用的机制是保存从fork
返回的pid。您可以维护以下结构。现在,在执行fork()时,检查返回值(PID)。如果它不是零(大于零),则它是父进程。现在,将该进程id复制到数组中
typedef struct
{
char process[128];
pid_t current_pid;
pid_t child_pid[127];
unsigned int child_pid_index;
}my_pid_record;
my_pid_record sample;
if( ( p = fork()) > 0 )
{
printf("I am a parent process\r\n");
sample.current_pid = getpid();
strcpy(sample.process,argv[0]);
sample.child_pid[child_pid_index] = p;
child_pid_index++;
/** basically write this information on the disk **/
/** This is your lookup table **/
fwrite(file, sample....)
flush();
}
else
{
printf("I am child process..\r\n");
/** whenever you do fork ..do this routine **/
}
执行get()和set()以读取文件。您将能够检索它。从设计的角度来看,这是一个很好的问题,也许我会为叉子做一个包装。不要调用fork,而是调用我的函数 某些API已损坏,并且不公开子API的pid-在MacOS上,
AuthorizationExecuteWithPrivileges
就是一个例子。API不给您子pid是完全错误的,因为您必须能够waitpid
来清理僵尸
对于这些破碎的API,这里有一个解决方法(例如Chrome)。在伪代码中:
pid_t sneakyFork(std::vector<const char*> args) {
std::vector<const char*> newArgs = makeVect(
"/usr/bin/perl","-w", "-e",
"printf \"%s,%s\\n\", $$, getppid();"
"$ENV{PATH} = '/usr/bin:/bin';"
"delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};"
"if ($#ARGV >= 0 and $ARGV[0] =~ /^(\\/.*)$/)"
"{ $ARGV[0] = $1;"
" for ($i=1; $i <= $#ARGV; $i++)"
" { $ARGV[$i] =~ /^(.*)$/; $ARGV[$i] = $1; }"
" die unless exec { $ARGV[0] } @ARGV; }",
(char*)0
);
newArgs.insert(newArgs.end(), args.begin(), args.end());
newArgs.push_back(0);
int pipe = nasty_library_call_with_stdout_inherited(newArgs);
char buf[1024];
read(pipe, &buf); // error checking...
pid_t pid, ppid;
parseBuf(buf, &pid, &ppid); // strchr for ',' and strtoul
if (ppid == getpid())
return pid; // we're the parent, the trick worked
else
return -1;
}
pid\u t偷偷工作(std::vector args){
std::vector newArgs=makeVect(
“/usr/bin/perl”、“-w”、“-e”,
“printf\%s,%s\\n\,$$,getppid();”
“$ENV{PATH}='/usr/bin:/bin'
删除@ENV{'IFS','CDPATH','ENV','BASH_ENV'}
“如果($#ARGV>=0和$ARGV[0]=~/^(\\/.*)$/)”
“{$ARGV[0]=$1;”
“因为($i=1;$i为什么不保存从派生新子进程中获得的Pid?是的,我知道。但是我需要这个子Pid的地方与我保存它的地方无关。@Ram:如果你没有派生它,它就不能是子进程。如果外部库函数创建了新进程,你可能需要阅读libr的文档我想看看是否有可能得到子进程的pid。否则就不可能了(特别是如果你有自己的子进程,你怎么知道哪个进程来自你自己的fork,哪个进程来自库fork?)
在hook函数中,调用original和log并存储返回的值。这正是我在上一句话中提到的。写入磁盘是丑陋的,没有必要的。但这个想法是正确的——他只需要存储他的子PID。我不能在RAM上写入。因为这将在另一个进程中。另一个进程无法访问它我想最好的办法是在一个公共的地方写。而且,没有人会时不时地做叉子。箱子一启动就会做。你可以-家长可以在自己的记忆中随时跟踪自己的孩子。家长创建了一个childA,然后childA创建了另一个childB,n此childB创建了另一个childC。childC现在将如何通知父进程?在子进程中,P的值应为0。因此,对于P==0,需要有单独的大小写。