首页
学习
活动
专区
工具
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。

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

相关·内容

C++:cstdio 头文件详解

这个库使用流来操作物理设备如键盘,打印机,终端或者系统支持的任何其他类型的文件。 流是一种以统一的方式与这些交互的抽象; 所有流都具有相似的属性,与它们所关联的物理介质的各个特征无关。...在使用库的时候会自动创建三个标准流:stdin, stdout and stderr; 流属性 Streams有一些属性可以定义可以在它们上使用哪些函数以及它们如何通过它们处理数据输入或输出。...它的值可以通过ftell和fgetpos函数获得,并且可以使用rewinding,fseek和fsetpos重新定位函数来更改。...将格式化数据写入流 fscanf 从流中读取格式化数据 printf 将格式化数据打印到stdout scanf 从stdin读取格式化数据 snprintf 将格式化输出写入一定大小的缓冲区 sprintf...本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

2.2K10
  • 【Linux文件管理】重定向&&内核级缓冲区&&用户级缓冲区

    我们试试关闭输出流: 当我们关闭输出流的时候屏幕上是不会打印的,因为我们将输出流给关闭了,所以不会在屏幕上打印,又因为我们打开的文件占据了以前输出流数组下标对应的位置,所以不会打印在屏幕上,会打印在文件中...这里就引入一个概念:重定向 重定向 重定向概念 概念:操作系统中的一种机制,用于将程序的输入或输出流从默认位置(通常是终端)改变到其他位置(如文件或设备)。...\n刷新,但是这里重定向之后就是按照文件的刷新方式来进行,也就是全刷新,等文件满了才刷新,但是这里没满所以不会刷新,所以直接close时,还没有刷新到文件当中,但是如果不close,程序退出前会自动刷新...首先,我们了解了 files_struct 的作用及其如何在内核中管理文件描述符的详细实现,掌握了文件的重定向以及文件描述符的相关操作。...文件管理作为操作系统中非常核心的部分,不仅直接影响着系统资源的利用效率,也对程序的执行性能和稳定性起着至关重要的作用。

    10710

    Linux基础IO全面介绍

    ,如目标文件不存在,需要 open 创建,则第三个参数表示创建文件的默认权限, 否则,使用两个参数的 open。...只要拿着文件描述符,就可以找到对应的文件 补充: 标准输入、标准输出、标准错误在对应的文件描述符为 0,1,2,对应 C 语言层上的是 stdin、stdout、stderr 所有文件,如果要被使用时,...inode 节点 总结: 基本上,一个文件一个 inode(包括文件) inode 是一个文件的所有的属性集合(不包含文件名)(空文件也是占据空间的,所有的属性也是数据也要占据空间) 真正表示文件的不是文件名...将内核缓冲区数据缓冲到磁盘的数据区中 3.记录分配情况——文件内容按顺序存放(数据块)。内核在 inode 上的磁盘分布区记录了上述块列表。 4.添加文件名到目录——内核将入口添加到目录文件。...之后的内容,剩下的就是库的名字 生成可执行程序的方式有两种:动态链接、静态链接 注: ldd 可以列出一个程序所需要得动态链接库;file 命令用于辨识文件类型 Linux 中,默认情况下形成的可执行程序是动态链接的

    40840

    python中的subprocess

    程序通常执行序列或字符串的第一项,但可以通过使用明确的参数进行设置。 在UNIX上,shell = False(默认):在这种情况下,Popen类使用os.execvp()来执行程序的子进程。...字符串将被视为只有一个字符串的序列(程序执行)。 在UNIX上,shell= True:如果参数是一个字符串,它指定了通过shell执行命令字符串。...一个负bufsize意味着使用这个系统默认情况下,这通常意味着完全缓冲。默认值为bufsize是0(无缓冲的)。 stdin、stdout和stderr分别指定执行程序的标准输入,标准输出和标准错误。...os.popen2, os.popen3 与 os.popen4 同样可以在没有shell介入的情况下直接传递给程序 以序列形式执行命令行 这种方法可以用下面的方法替换: (child_stdin...=True) (child_stdout, child_stdin) = (p.stdout, p.stdin) 在 Unix系统中, popen2 也可以在没有shell介入的情况下直接传递给程序以序列形式执行命令行

    1.6K30

    标准 IO 库那些事儿

    对于三个预定义的标准 IO 流 (stdin/stdout/stderr) 的缓冲类型,ISO C 有以下要求: 当且仅当 stdin/stdout 不涉及交互式设备时,它们才是全缓冲的 stderr...,流的缓冲类型在确定后仍可以更改。.../stdout/stderr 缓冲的初始状态、第一次执行 IO 后的状态 为了验证 stdin 第一次执行 IO 操作后的状态,加了一个 scanf 操作 对于 stdout 因 tell_buf...可以看出: stdin/stderr 初始时是没有分配缓冲区的,执行第一次 IO 后,stdin/stdout 变为行缓冲类型,stderr 变为无缓冲,都分配了独立的缓冲区空间 (地址不同)。...最后,虽然流的缓冲区可以更改,但是不建议这样做,从上面的例子可以看出,大多数类型变更会引发缓冲区重新分配,其中的数据就会随之丢失,导致信息读取、写入不全的问题。

    1.5K20

    python模块之subprocess类与常量

    如果是序列,则args中的第一个元素是要执行的程序;如果是字符串,解释执行与平台有关,在POSIX系统args将被解释为要执行的程序的名称或路径(前提是不传递任何参数给程序)。...唯一需要指定shell=True的场景是要执行的指令是shell内置的,如dir, copy。...0:不始用缓冲 1:使用行缓冲 其他正整数:缓冲大小 负整数(默认):使用系统默认值 executable:使用shell=True的场景很少。...stdin/stdout/stderr:分别指定程序执行的标准输入,标准输出,标准错误。可选值包括PIPE,DEVNULL,已存在的文件描述符(正整数),已存在的文件对象,None。...Windows系统上kill()是terminate()的别名 属性 args:传入Popen构造器的第一个参数,list或string类型 stdin:如果传递给Popen的stdin参数是PIPE,

    2.5K10

    1(UNIX基础)

    有些信号表示硬件异常,例如除以0或者访问地址空间以外的单元,这些异常产生的后果不确定,所以不推荐 2.按系统默认方式处理。...我们需要提供自编的函数来处理它 10 系统调用与库函数 系统调用实际上就是指最底层的一个调用,在linux程序设计里面就是底层调用的意思。面向的是硬件。...实际上,由于库函数对文件的操作最终是通过系统调用实现的,因此,每打开一个文件所获得的FILE结构指针都有一个内核空间的文件描述符fd与之对应。...使用库函数也有系统调用的开销,为什么不直接使用系统调用呢?...在用户空间和内核空间,对文件操作都使用了缓冲区,例如用fwrite写文件,都是先将内容写到用户空间缓冲区,当用户空间缓冲区满或者写操作结束时,才将用户缓冲区的内容写到内核缓冲区,同样的道理,当内核缓冲区满或写结束时才将内核缓冲区内容写到文件对应的硬件媒介

    86030

    5(标准IO)

    不幸的是,标准I/O库最令人迷惑的也是他的缓冲。 标准I/O提供了三种类型的缓冲: 1、全缓冲。这种情况下,在填满标准I/O缓冲区后才进行实际I/O操作。...对于驻留在磁盘上的文件通常是由标准I/O库实施全缓冲。一个流上执行第一次I/O操作时,相关标准I/O函数通常调用malloc获得需使用的缓冲区。 术语冲洗说明I/O缓冲区的写操作。...在终端驱动程序方面flush表示丢弃已存储在缓冲区中的数据。 2、行缓冲。在这种情况下,当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。...此函数一般用于将一个指定的文件代开为一个预定义的流:stdout,stdin,stderr。...此函数一直读到下一个换行符为止,但是不超过n-1个字符,缓冲区以null字符结尾。gets不推荐,因为没有指定缓冲区大小,可能导致溢出。

    70640

    python 标准类库-并行执行之subprocess-子进程管理

    如果传递的是单一字符串,shell参数值必须为True,如果不提供其它任何参数,传递单一字符串的情况下,该字符串必须是需要执行的程序名。...类似在Unix上使用os.execvp(),Windows上使用CreateProcess()函数。 args 参数值为字符串、序列。默认的,如果args是个序列,程序会执行args中第一项。...如果sell为True,则推荐传递字符串参数给args Unix操作系统上,shell=True,shell默认为/bin/sh。如果args为字符串,则字符串指明了需要通过shell执行的命令。...任意负数 - 使用缓冲,缓冲大小等于系统自带的o.DEFAULT_BUFFER_SIZE Executable executable参数指定了用于执行的替代程序。很少用到。...stdin, stdout 和stderr 分别指定被执行程序的标准输入,标准输出,标准错误文件句柄。

    4.2K20

    很“迷”的字符与字符串

    具体的,首先保持符号位不变,将0101010- 1,得0101001,然后得到的结果按位取反得1010110,即十进制的86,将符号位不上可知其对应的数字就是 -86。...其次为了避免出现上述问题,必须要在读取输入前,清空缓冲区的残留数据,可以用以下的方法解决: (1) 使用fflush(stdin)函数。...某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,但是并非所有编译器都要支持这个功能(如linux 下的gcc),因为标准中根本没有定义 fflush(stdin),所以这种方法的移植性不是很好不建议使用...其次在程序中我们清除了输入缓冲区中的残留,否则 getchar()会先读取缓冲区残留的回车,然后在读入键盘输入的部分;fflush(stdin)在 ubuntu 下不可用,所以注释掉了。...这里有两点需要注意,首先 gets() 在 ubuntu 下事会报错的,所以在这里使用 fgets() 替代,其次由于 scanf不会清除最后的回车符号,所以这里我们还是手动清除缓冲区残留,执行后的结果如下所示

    1.2K20

    标准IO库(ISO C的标准IO库)

    全缓冲 在这种情况下,在填满标准I/O缓冲区以后,才进行I/O操作。在第一次执行I/O操作的时候,标准I/O会使用malloc来获取所需要的缓冲区。...行缓冲 行缓冲就是当输入和输出中遇到换行符时,标准I/O执行实际I/O操作。当我们使用scanf和printf的时候,实际上就是行缓冲在起作用。...那么就会强制冲洗所有行缓冲的输出流。 不缓冲 标准I/O对字符不进行缓冲。通常标准出错是不带缓冲的,这样就能使的出错信息及时打印出来。...ISO C的规则 当且仅当标准输入和标准输出不指向交互式设备的时候,它们才是全缓冲的。 标准错误一定不会是全缓冲。 规则就是如此的简单粗暴。它只说了什么时候全缓冲和不全缓冲。在Linux下。...通常是这样的。 标准错误是不带缓冲的。 标准输入和标准输出,如果指向的设备是终端,那么使用行缓冲,否则使用全缓冲。 更改缓冲方式 我们可以使用下面的库函数来更改缓冲方式。 ?

    1.2K20

    python之系统命令

    用于执行复杂的系统命令 参数: args:shell命令,可以是字符串或者序列类型(如:list,元组) bufsize:指定缓冲。...0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲 stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄 preexec_fn:只在Unix平台下有效,用于指定一个可执行对象...所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。...()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等 import subprocess ret1 = subprocess.Popen(["mkdir","t1"]) ret2 =...subprocess.Popen("mkdir t2", shell=True) 终端输入的命令分为两种: 输入即可得到输出,如:ifconfig 输入进行某环境,依赖再输入,如:python import

    1.1K40

    【Linux】————(文件描述符、重定向、文件缓冲区……)

    stdin、stdout、stderr都是FILE*结构体,里面除了封装着fd,还有语言级别的文件缓冲区。...由上可知,之所以注释掉fflush后,log.txt里面啥也没有,是因为内容在语言级别的缓冲区中,还没执行到return语句,冲刷内容到内核缓冲区中,log.txt就被关闭了。 ​...运行上面代码,发现不在显示器上打印,而是在log.txt里打印。 缓冲区 缓冲区就是一段内存空间。 缓冲区由C语言维护就叫语言级缓冲区,由OS维护就叫内核缓冲区。...>是标准输出重定向,只更改1号fd里面的内容,所以重定向后,1号的打印到了log,txt,而2号还是没变,依旧打印在显示器上。 直接运行代码,会全部打印在显示器上。...5.你开始炫耀自己,往往都是灾难的开始,就像老子在《道德经》里写到:光而不耀,静水流深。

    8410

    Linux文件IO操作

    ,那些用户和组群可以访问文件以及可以执行什么操作 查看文件权限 查看文件权限 文件类型后面紧跟着的就是文件权限 简单介绍下文件权限,如下图所示: 因为Linux是一个多用户登录的操作系统,所以文件权限跟用户相关...可读 可写 可执行 字符表示 r w x 数字表示 4 2 1 所有者的权限为rw-,对应着4+2+0,也就是最终的权限6,以此类推,用户组的权限为6,其他用户的权限为4....更改umask值,可以通过命令umask mode的方式来更改umask值,比如我要把umask值改为000,则使用命令 umask 000 即可。.../main readLen:4,data:text $ cat test.txt text 对比fwrite等标准的C库函数,write是没有缓冲的,不需要fflush或者close将缓冲数据写入到磁盘中...~咳咳,扯远了,实际上stdout是块设备,stderr不是。对于块设备,只有当下面几种情况下才会被输入:遇到回车;缓冲区满;flush被调用。而stderr因为没有缓冲所以直接输出。

    2.7K30

    关于stdin流以及缓冲区浅谈

    就是以终端(计算机)为对象;即从键盘输入数据,运行结果到显示器屏幕上(就叫标准输入输出);再来解释下流的概念(流这个概念也解释不通,各种说法都有,反正我就暂理解为数据传输的字节序列吧)实际上,在内存中为每个数据流开辟一个内存缓冲区...: 1)全缓冲     在这种情况下,当填满标准I/O缓存后才进行实际I/O操作,全缓冲的典型代表是对磁盘文件的读写。...2)行缓冲     在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键时才进行实际的I/O操作。...(这和计算机的分页机制有关,因为进程在计算机中分配内存使用的就是分页与分段机制,并且每个页的大小是4096个字节,因此通常情况下缓冲区的大小为4096个字节。)...还有rewind():这个是把文件指针恢复到文件开头的地方,用在stdin上就是清除了键盘缓冲区了,还有在当手动输入ctrl+z(就是EOF)的时候会出现问题,rewind(stdin)也是用来清除EOF

    1.4K20

    基础IO:系统文件IO

    _cnt:缓冲区中剩余的可用空间字节数。 _base:缓冲区的起始位置。 _flag:存储文件的状态标志,如文件是否处于读写模式等。 _file:该文件对应的系统级文件描述符,这是最直接的文件标识。...冯诺依曼体系中,CPU不直接与硬件交互,所以需要通过内存来交互,缓冲区在内存中形成。对文件内容做任何操作,都必须先把文件加载到内核对应的文件缓冲区内,从磁盘到内存的拷贝。...C++:C++ 通过标准库(如 STL)提供了一套跨平台的接口,使得程序能在不同操作系统上编译和运行。然而,当涉及到直接与操作系统底层交互时,C++ 仍然需要依赖平台特定的系统调用和 API。...Java 的字节码可以在任何实现了 JVM 的操作系统上运行。 Python:Python 通过封装了平台特定的调用接口,提供了跨平台的标准库,如 os、sys 等。...如果现在有一个程序,在编写的时候直接调用了某个操作系统特有的API,它在其他操作系统上就无法工作。必须将调用特有API更换为要在上面执行的操作系统的API才可以正常运行。

    3000

    python中执行DOS命令的3种方法小

    使用os.system("cmd") 特点是执行的时候程序会打出cmd在Linux上执行的信息。 import os os.system("ls")   2....使用Popen模块产生新的process 现在大部分人都喜欢使用Popen。Popen方法不会打印出cmd在linux上执行的信息。的确,Popen非常强大,支持多种参数和模式。...参数executable用于指定可执行程序。一般情况下我们通过args参数来设置所要运行的程序。如果将参数shell设为 True,executable将指定程序使用的shell。...我们不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。 如果参数shell设为true,程序将通过shell来执行。...使用commands.getstatusoutput方法 这个方法也不会打印出cmd在linux上执行的信息。这个方法唯一的优点是,它不是一个阻塞的方法。即没有Popen函数阻塞的问题。

    2.3K20

    getchar的使用

    ,以后的getchar()再执行时就会直接从缓冲区中读 取了。...实际上是 输入设备->内存缓冲区->程序getchar 你按的键是放进缓冲区了,然后供程序getchar 你有没有试过按住很多键然后等一会儿会滴滴滴滴响,就是缓冲区满了,你后头按的键没有存进缓冲区...4、缓冲区的类型   缓冲区 分为三种类型:全缓冲、行缓冲和不带缓冲。   1、全缓冲   在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。   ...2、行缓冲   在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据。   ...5、缓冲区的刷新 缓冲区会在以下三种情况下被刷新: 1、缓冲区满 2、执行flush刷新缓冲区的语句 3、程序正常结束。

    84050
    领券