首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在不更改stdin上的缓冲的情况下执行fork-then-execve?

在不更改stdin上的缓冲的情况下执行fork-then-execve的方法是使用文件描述符重定向。具体步骤如下:

  1. 首先,使用pipe()函数创建一个管道,得到两个文件描述符,一个用于读取,一个用于写入。
  2. 然后,使用fork()函数创建一个子进程。
  3. 在子进程中,关闭写入端的文件描述符,并将读取端的文件描述符复制到stdin(文件描述符0)。
  4. 在子进程中,使用execve()函数执行需要的命令。
  5. 在父进程中,关闭读取端的文件描述符,并将需要执行的命令写入写入端的文件描述符。

下面是一个示例代码:

代码语言:txt
复制
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    int pipefd[2];
    pid_t pid;

    // 创建管道
    if (pipe(pipefd) == -1) {
        perror("pipe");
        return 1;
    }

    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork");
        return 1;
    }

    if (pid == 0) {
        // 子进程中
        close(pipefd[1]);  // 关闭写入端的文件描述符
        dup2(pipefd[0], 0);  // 将读取端的文件描述符复制到stdin
        close(pipefd[0]);  // 关闭读取端的文件描述符

        // 执行命令
        char *args[] = {"/bin/sh", "-c", "command", NULL};
        execve(args[0], args, NULL);
        perror("execve");
        return 1;
    } else {
        // 父进程中
        close(pipefd[0]);  // 关闭读取端的文件描述符

        // 写入命令
        char *command = "command\n";
        write(pipefd[1], command, strlen(command));
        close(pipefd[1]);  // 关闭写入端的文件描述符

        // 等待子进程结束
        wait(NULL);
    }

    return 0;
}

这样,就可以在不更改stdin上的缓冲的情况下执行fork-then-execve。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

ICS lab9 TinyShell 的10条建议

0.仔细看pdf,尤其是hint部分。 1.先抄书上的代码,然后再添加书上没有的功能。做到一定程度后,测试已有的功能,要不然不好改正。注意规范输出格式。 2.WNOHANG,这个不用说了。 3.调用deletejob和更改state都应改放进sigchld_handler中,sigint和sigtstp的handler应该仅仅捕获信号并传给前台的进程组。 4.waitpid也应该只在sigchld_handler中出现,而且必须仅仅出现一次。waitfg中不应该调用waitpid,否则会和sigchld_handler产生回收竞争。 5.发送sigint,sigtstp,以及sigcont信号时要注意,传进-pid而不是pid,以便发送给整个进程组。否则trace11,12,13会有麻烦。子进程fork之后execve之前,注意要setgpid(0, 0)。 6.由于你的sigchld_handler要处理stop的进程,所以要加上WUNTRACED。然后循环里要分情况判断WIFEXITED,WIFSIGNALED,WIFSTOPPED。这三个函数会特别有用。 7.fg进程最多只有一个,所以一旦产生就必须调用waitfg,do_bgfg函数里也是。 8.一定要注意使用sigprocmask,pdf中也写了。由于addjob在eval中调用,deletejob在sigchld_handler中调用,很可能出现add之前就delete的情况。所以要在fork之前调用sigprocmask,屏蔽掉sigchld信号,然后add之后再解除。由于子进程也屏蔽掉了这个信号,所以要在fork之后execve之前解除掉。 9.waitfg的循环里注意调用sleep。

011

[Linux][seccomp]seccomp引起的SIGSYS问题 ​

前言 作者习惯使用Libvrit,多数情况下,会直接使用libvirt进行虚拟机操作。 如果要用qemu启动的情况,一般会比较习惯ps -ef | grep qemu得到qemu的启动参数,进行修改,然后启动。 在一次启动中,qemu发生了错误:qemu-system-x86_64: network script /etc/qemu-ifup failed with status 159 问题的原因是因为seccomp的配置导致的,那么我们就来看一下这个问题的具体表现。 分析 实例代码 构造一段实例代码,在父进程中初始化了seccomp,禁用了execve这个syscall,在子进程中尝试调用execve运行其他的程序。 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <seccomp.h> char *cmd = "/bin/ls"; int main() { int pid, status, ret; char *args[4]; char **parg; scmp_filter_ctx ctx; ctx = seccomp_init(SCMP_ACT_ALLOW); if (ctx == NULL) { printf("seccomp_init fail\n"); return 0; } ret = seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0); if (ret < 0) { printf("seccomp_rule_add fail\n"); return 0; } ret = seccomp_load(ctx); if (ret < 0) { printf("seccomp_load fail\n"); return 0; } seccomp_release(ctx); pid = fork(); if (pid == 0) { parg = args; *parg++ = cmd; *parg++ = "-al"; *parg++ = "/proc/self/fd"; *parg = NULL; execv(cmd, args); } else { while (waitpid(pid, &status, 0) != pid); printf("status %d\n", status); } return 0; } 需要先安装libseccomp-dev(apt-get install libseccomp-dev),编译的时候: gcc execv.c -g -o execv -lseccomp 运行可以发现,子进程并不是正常退出的。 打开coredump 调整/proc/sys/kernel/core_pattern,配置coredump文件生成的规则。 ulimit -c unlimited调整但前shell的coredump文件大小限制,在当前的shell下运行,文件大小生效。

01
领券