0

我真的很希望您能帮助我理解为什么在使用fork()命令后进程没有到达“子进程”。我正在尝试编写一个运行另一个程序的程序,但似乎该程序甚至没有到达子进程。我可以说,因为“子进程”没有被打印到屏幕上,我真的很想知道为什么。

这是代码的草图-我什至无法检查它是否正常,因为正如我所说,它甚至没有到达儿子进程,我总是得到“儿子退出错误”。

#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <assert.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <time.h>



#define MAXARGV 5;

int main() {
    char* cmd;

    int child_status;

    char* s;
    char** argv;
    int counter;

    cmd= (char*) calloc( 5, sizeof(char)*20);
    s=(char*) calloc(1,sizeof(char)*20);
    argv=(char**) calloc(5, sizeof(char*)*20);




    printf("Please write a command\n");

    gets(cmd);

    counter = 0;

    while (strcmp(cmd, "exit") != 0) {

        int pid = fork();


        if (pid == 0) {
            printf("son process");

            while (sscanf(cmd, "%s", s) == 1) {

                strcpy(argv[counter], s);
                counter++;
            }

            execv(argv[0], argv);

            printf("the command is not legal");
            assert(0);

        }

        else {

            if (wait(&child_status) == -1) {
                printf("error waiting for pid=%d\n", pid);
                exit(-1);
            }

              if(WIFEXITED(child_status)!=0)
                    printf("son status=%d\n", WEXITSTATUS(child_status));
                else
                    printf("son exited with error\n");

        }

        printf("Please write a command");

        gets(cmd);

    }

    free(s);
    free(cmd);
    free(argv);
    printf("here as well");
    return 1;
}
4

1 回答 1

2
  1. 程序达到了printf("son process")很好,但这只是将字符串放在进程内部的缓冲区中,并且由于您没有这样fflush()做,因此它不会出现在屏幕上,并且在exec调用中与进程的其余内存一起被丢弃. 请注意,这stdout通常是行缓冲的,因此如果您在那里有换行符,它将自动刷新。默认情况下也是stderr无缓冲的,更适合调试打印 ( fprintf(stderr, "child process"))。
  2. 您正在尝试组装从标准输入中读取的命令argv,但它只有内存用于给您的实际参数,因此您超出了此内存并出现分段错误。
  3. 如果WIFEXITED给出零,您应该使用WIFSIGNALEDandWTERMSIG来确认错误确实是 SIGSEGV。
  4. assert(0)不是在出错后终止进程的好方法。exit(1)是。断言仅适用于指示代码本身存在错误的条件,如果它们发生并且通常NDEBUG从生产代码中消除(通过定义)。
于 2012-11-27T12:07:42.040 回答