使用fork()进行拆分过程 - 程序出了什么问题

时间:2012-11-27 11:49:14

标签: c linux fork

我非常乐意帮助您理解为什么在使用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;
}

1 个答案:

答案 0 :(得分:2)

  1. 程序到达printf("son process")就好了,但只是将字符串放在进程内的缓冲区中,因为你没有fflush()它,它不会进入屏幕,被exec调用中的剩余进程内存丢弃。注意,stdout通常是行缓冲的,所以如果你在那里有换行符,它会自动刷新。此外,stderr默认情况下是无缓冲的,更适合于调试打印(fprintf(stderr, "child process"))。
  2. 您正在尝试组装从argv中的标准输入读取的命令,但它只有内存用于给您的实际参数,因此您会超出此内存并导致分段错误。
  3. 如果WIFEXITED为零,则应使用WIFSIGNALEDWTERMSIG确认错误确实是SIGSEGV。
  4. assert(0)不是错误后终止进程的好方法。 exit(1)是。断言仅适用于表明代码本身存在错误的条件,并且通常会从生产代码中消除(通过定义NDEBUG)。