You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现C命令行解释器时,执行含quit命令后无法退出的问题求助

Hey there, let's break down what's going on here and fix your issue step by step.

The Core Problem

Your main issue boils down to address space isolation after fork(): once you create a child process, it gets a copy of the parent's memory—any changes to variables like flag in the child don't affect the parent at all. That's why setting flag = 1 in the child doesn't trigger the parent's exit condition. As for the SIGTERM signal, it likely didn't work because either the parent wasn't listening for it, or sending it would terminate the parent immediately (which skips executing all remaining commands, defeating your goal).

Solution 1: Use Exit Codes to Signal the Parent

The simplest way to communicate "quit was executed" from child to parent is to use a custom exit status code. Here's how to implement it:

First, define a custom exit code for the "quit" case:

#define EXIT_QUIT 2  // Pick a value not used by standard commands

Then modify your child process logic to track if quit was encountered, and exit with that code after running all commands:

else if (pid == 0) {
    int encountered_quit = 0;
    char *cmd = strtok(line, ";");  // Split commands by semicolons (fix your original strtok call!)
    
    while (cmd != NULL) {
        // Trim whitespace from the command (optional but helpful)
        while (*cmd == ' ') cmd++;
        char *end = cmd + strlen(cmd) - 1;
        while (end > cmd && *end == ' ') end--;
        *(end + 1) = '\0';

        if (strcmp(cmd, "quit") == 0) {
            encountered_quit = 1;
        }

        // Execute the command (replace this with your actual exec logic)
        if (execlp(cmd, cmd, (char *)NULL) == -1) {
            perror("Failed to execute command");
        }

        cmd = strtok(NULL, ";");
    }

    // Exit with our custom code if quit was found, else normal success
    exit(encountered_quit ? EXIT_QUIT : EXIT_SUCCESS);
}

Finally, update the parent process to check the child's exit code and set its own flag accordingly:

else {
    int wpid, stat;
    int should_quit = 0;

    // Wait for all child processes to finish
    while ((wpid = wait(&stat)) > 0) {
        if (WIFEXITED(stat)) {
            int exit_code = WEXITSTATUS(stat);
            if (exit_code == EXIT_QUIT) {
                should_quit = 1;
            }
        }
    }

    // Update the parent's flag to trigger exit if needed
    if (should_quit) {
        flag = 1;
    }
}

Solution 2: Use a Pipe for IPC (Alternative)

If you need more complex communication later, a pipe works well. Here's a quick outline:

  1. Before calling fork(), create a pipe with pipe().
  2. In the child, after executing all commands, write a byte (like 'q') to the pipe if quit was encountered.
  3. In the parent, after waiting for all children, read from the pipe. If the byte is present, set flag = 1.

This is more flexible but overkill for your current use case—exit codes are simpler here.

Quick Fixes to Your Original Code

Don't forget these small but critical issues:

  • Your strcmp(line_1, "quit") is missing == 0 (it's a syntax error right now).
  • strtok(line, NULL) should be strtok(line, ";") to split commands by semicolons.

内容的提问来源于stack exchange,提问作者user6420403

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:01:36