c - 用C解释代码

标签 c linux shell code-analysis

<分区>

我想理解这段代码,特别是 parse_args。这段代码就像运行 pwd cat 等基本 linux 命令的简单 shell。我想了解 parse_args 的工作原理。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#define BUFFER_SIZE 1<<16
#define ARR_SIZE 1<<16

void parse_args(char *buffer, char** args, 
                size_t args_size, size_t *nargs)
{
    char *buf_args[args_size]; /* You need C99 */
    char **cp;
    char *wbuf;
    size_t i, j;

    wbuf=buffer;
    buf_args[0]=buffer; 
    args[0] =buffer;

    for(cp=buf_args; (*cp=strsep(&wbuf, " \n\t")) != NULL ;){
        if ((*cp != '\0') && (++cp >= &buf_args[args_size]))
            break;
    }

    for (j=i=0; buf_args[i]!=NULL; i++){
        if(strlen(buf_args[i])>0)
            args[j++]=buf_args[i];
    }

    *nargs=j;
    args[j]=NULL;
}


int main(int argc, char *argv[], char *envp[]){
    char buffer[BUFFER_SIZE];
    char *args[ARR_SIZE];

    int *ret_status;
    size_t nargs;
    pid_t pid;

    while(1){
        printf("$ ");
        fgets(buffer, BUFFER_SIZE, stdin);
        parse_args(buffer, args, ARR_SIZE, &nargs); 

        if (nargs==0) continue;
        if (!strcmp(args[0], "exit" )) exit(0);       
        pid = fork();
        if (pid){
            printf("Waiting for child (%d)\n", pid);
            pid = wait(ret_status);
            printf("Child (%d) finished\n", pid);
        } else {
            if( execvp(args[0], args)) {
                puts(strerror(errno));
                exit(127);
            }
        }
    }    
    return 0;
}

最佳答案

这很有趣。该函数将缓冲区分隔为一个字符串数组,并在其中命中一个空白分隔符。

void parse_args(char *buffer, char** args, 
                size_t args_size, size_t *nargs)
{
    char *buf_args[args_size]; /* You need C99 */
    char **cp;
    char *wbuf;
    size_t i, j;

初始化代码...

    wbuf=buffer;
    buf_args[0]=buffer; 
    args[0] =buffer;

将所有指针指向缓冲区的开头

    for(cp=buf_args; (*cp=strsep(&wbuf, " \n\t")) != NULL ;){
  1. 设置写指针cp指向buf_args数组的第一个元素。
  2. 将*cp设置为缓冲区中非空白标记的下一个实例,并将wbuf推进到它的结束位置

        if ((*cp != '\0') && (++cp >= &buf_args[args_size]))
            break;
    

strsep 返回 NULL 时,或者当它指向缓冲区的末尾时,或者当它指向超出 buf_args[] 的末尾时停止

    }

    for (j=i=0; buf_args[i]!=NULL; i++){
        if(strlen(buf_args[i])>0)
            args[j++]=buf_args[i];
    }

此循环创建 buf_args[] 数组的精简副本:它仅复制非空字符串的参数。我想如果您的源缓冲区有一系列连续的空白字符,就会发生这种情况。

    *nargs=j;
    args[j]=NULL;
}

在输出数组末尾放置一个 NULL 并设置 nargs 输出参数。

关于c - 用C解释代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13507614/

相关文章:

c - 主/从设备出现段错误

linux - 授予特定用户对文件的访问权限

shell - xargs 执行字符串 - 我做错了什么?

c - c编程中的strcat函数原型(prototype)

objective-c - 计算垂直于另一条线的中点的线

c - wmain 与主 C 运行时

c++ - 如何使用 C++ 在 Linux 中获取文件的所有者名称?

linux - 我如何知道 bash 中的进程是否超时?

c - 用于非内置命令的简单 shell 程序 unix 文件重定向

linux - 存储被另一个脚本调用的脚本的PID