Req*_*iem 4 c unix background-process
我目前潜入创建一个backgrounding工作C用&.我需要实现非阻塞waitpid才能使其正常工作.我知道.此外,如果&在命令行末尾输入,我已经抓住了这个条件.我只是不确定如何准确地将进程作为后台作业发送,并将其实现为执行,而另一个提示是提示下一个命令.
任何事情都会有所帮助,谢谢.
struct bgprocess{
int pid;
struct bgprocess * next;
struct bgprocess * prev;
};
struct bgprocess * bgprocess1;
bgprocess1 = malloc(sizeof(struct bgprocess));
bgprocess1->prev = NULL;
bgprocess1->next = NULL;
bgprocess1->pid = NULL;
struct bgprocess * current;
current = bgprocess1;
do{
int bgreturn = 0;
while (current != NULL){
if (waitpid(current->pid, &bgreturn, WNOHANG)){
printf("Child exited");
current->prev->next = current->next;
current->next->prev = current->prev;
current->prev = NULL;
current->next = NULL;
free(current);
}
current = current->next;
}
if (end){
int pid = fork();
if (pid < 0){
exit(1);
}
if (pid) {
execvp(args[0], args);
exit(0);
}
struct bgprocess * newNode;
newNode = malloc(sizeof(struct bgprocess));
newNode->pid = pid;
newNode->next = NULL;
if (current->next == NULL){
current->next = newNode;
}
while (1){
if (current->next == NULL){
current->next = newNode;
}
current = current->next;
}
}
}
while (current != NULL);
int bgreturn = 0;
while (current != NULL){
if (waitpid(current->pid, &bgreturn,0)){
printf("Child exited");
current->prev->next = current->next;
current->next->prev = current->prev;
current->prev = NULL;
current->next = NULL;
free(current);
}
current = current->next;
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,所以我一直在研究这个问题,我想我可能已经开始明白了.我仍然有一些语法错误,我不知道如何修复所以我可能会使用gdb或其他东西,除非别人可以指出它们.我是以正确的方式去做还是我完全错了?
Fra*_*Man 11
听起来你正在实现一个shell.
只需使用fork来创建一个子进程 - 它将是并发的.从那里,你可以使用的EXEC*系列执行任何你喜欢的可执行文件,或者干脆运行在孩子的C代码而父返回并提示更多的信息(下一个命令等)使用等待在顶部的WNOHANG选项循环检查已终止的孩子,并在最后为这些孩子的其余部分再次(这次没有WNOHANG).
我必须鼓励你不要让它变得比实际更复杂.用简单的英语(或你的母语,或伪代码)写出你想要的东西,然后用最少的聪明才能把它翻译成C.
(伪)代码:
struct child {
int pid;
struct child * next;
struct child * prev;
}
struct child * children = null;
do {
int return = 0;
struct child * curr = children;
while(curr != null){
if(waitpid(curr->pid, &return, WNOHANG)){
//Report child exited with return status 'return'
//Remove child (linked list style)
}
curr = curr->next;
}
/* PROMPT, ETC */
if ( doInBackground ){
int pid = fork();
if(pid <0 )exit(); //error
if(pid){
//Child
execvp(processName, arrayOfArgs);
//This should never get executed
exit();
}
//Add pid (linked list style, again)
}
}while(!exitCondition)
int return = 0;
struct child * curr = children;
while(curr != null){
if(waitpid(curr->pid, &return, 0)){
//Report child exited with return status 'return'
//Remove child (linked list style)
}
curr = curr->next;
}
Run Code Online (Sandbox Code Playgroud)