精华内容
下载资源
问答
  • shell中posix_spawn的功能。 概述 这是一个命令行实用程序,包装了posix_spawn函数,将额外的进程生成功能暴露给您的shell。 它甚至支持Apple的所有私有API,例如在禁用ASLR的情况下生成进程。 用法 Usage: ...
  • posix_spawn的异步和更通用的替换 介绍 aspawn器具从主意 ,使用户做posix_spawn通过使系统调用直接通过以异步方式pure_syscall在我的库,完全不使用任何全局/线程局部变量来实现。 我的aspawn有签名: struct ...
  • posix_spawn函数

    2021-11-14 20:14:50
    posix_spawn函数可用于替代fork/vfork+exec用于执行程序,同时提供比system函数更多的控制权 引入这个函数的原因主要有以下几点: 调用fork绝大多数情况下是用于exec的,少数用于低效的并发进程创建(但并不适用...

     posix_spawn函数可用于替代fork/vfork+exec用于执行程序,同时提供比system函数更多的控制权

    引入这个函数的原因主要有以下几点:

    • 调用fork绝大多数情况下是用于exec的,少数用于低效的并发进程创建(但并不适用于多线程程序,因为子进程只会fork当前线程,但会fork整个虚拟地址空间,其它线程的栈和资源都会复制过来,会导致资源泄露),以及daemon进程脱离父进程控制(使自己变为孤儿进程)等用途,调用vfork几乎一定是用于exec的(因为栈是和父进程共享的,只能进行一些操作以后exec或exit,不能从函数中返回)
    • fork/vfork+exec手写起来比较复杂,特别是vfork写起来有很多坑,比如共享stack和signal handler有损坏父进程执行上下文的可能性(所以提供一个模板用于调用)
    • 有些设备没有MMU,根本实现不了写时复制

    当前Linux上是通过“分配stack+屏蔽所有信号+clone(CLONE_VM|CLONE_VFORK,stack)+exec”实现的,在FreeBSD上是用vfork+exec实现的,而在macOS上这个函数是一个系统调用

    #include <spawn.h>
    
    int posix_spawn(pid_t *restrict pid, const char *restrict path,
                    const posix_spawn_file_actions_t *restrict file_actions,
                    const posix_spawnattr_t *restrict attrp,
                    char *const argv[restrict],
                    char *const envp[restrict]);
    int posix_spawnp(pid_t *restrict pid, const char *restrict file,
                    const posix_spawn_file_actions_t *restrict file_actions,
                    const posix_spawnattr_t *restrict attrp,
                    char *const argv[restrict],
                    char *const envp[restrict]);
    

    posix_spawn函数包括posix_spawn和posix_spawnp两个函数,都包括6个参数

    第一个参数pid是一个输出参数,可以传入一个pid_t变量的地址,返回创建的pid,也可以是NULL表示不需要返回pid 

    第二个参数path/file,对于posix_spawn,直接执行path路径指向的程序,对于posix_spawnp,如果file不包含/,则认为是一个命令,会搜索PATH环境变量

    第三个参数file_actions,指向一个posix_spawn_file_actions_t对象,也可以是NULL表示继承所有没有设置fcntl(fd, SETFD, 1)的文件描述符,这个对象使用posix_spawn_file_actions_init初始化,使用*_destroy销毁,使用*_addopen添加打开文件操作,使用*_addclose添加关闭文件操作,使用*_adddup2添加复制文件描述符操作

    第四个参数attrp,指向一个posix_spawnattr_t对象,也可以是NULL表示使用默认值,这个对象使用posix_spawnattr_init初始化,使用*_destroy销毁,使用*_setflags、*_setpgroup、*_setsigdefault、*_setsigmask等设置参数,其中*_setflags可以设置POSIX_SPAWN_RESETIDS、*_SETPGROUP、*_SETSIGMASK、*_SETSIGDEFAULT等(Linux、FreeBSD、macOS分别还有其它支持的参数,这里只列出了公共部分)

    第五个参数argv,就是main函数的第二个参数char *argv[],其中argv[0]是命令名称,必须提供,数组最后一个元素一定要是NULL

    第六个参数envp,就是main函数的第三个参数char *envp[]或全局变量extern char **environ;,数组最后一个元素一定要是NULL,这个参数也可以是NULL,表示没有环境变量

    函数成功返回0,失败返回非0的errno错误码

    参考:

    posix_spawn(3) - Linux manual page (man7.org)

    Mac OS X Manual Page For posix_spawn(2) (apple.com)

    posix_spawn(3) [freebsd man page] (unix.com)

    展开全文
  • 更好的解决办法是不使用system调用方法,而是使用posix_spawn调用,简单的示例如下: #include #include #include #include #include #include int main(int argc, char* argv[]) { pid_t pid; int err; char *...

    linux下一切设备皆文件,对于一些驱动函数的操作,无外乎open、read、write、ioctl、close;日常熟悉linux内核驱动模型,调用驱动函数接口,可以避免编程中多数情况下直接调用shell命令;

    对于一些想实现的功能与现有linux shell命令功能相同的情况下,编程调用shell命令无外乎是最简便快速的方法了;

    下面附上Linux的system()和popen()差异_liuxingen的专栏-CSDN博客_popen和system区别

    总结:

    1、在linux中我们可以通过system()来执行一个shell命令,popen()也是执行shell命令并且通过管道和shell命令进行通信。

    2、system()、popen()给我们处理了fork、exec、waitpid等一系列的处理流程,让我们只需要关注最后的返回结果(函数的返回值)即可;

    3、system()是串行执行的,popen()是并行执行的;

    4、在特权(setuid、setgid)进程中千万注意不要使用system和popen。

    为什么建议使用posix_spawn?

    工作中发现system调用某些shell指令会失败,拿udhcpc为例;

    这个问题的表面现象是用system调用的方式执行udhcpc会失败。

    解释:由于system是通过fork实现的,而子进程会复制父进程的VM空间,当父进程占用较多VM空间,很容易导致system调用失败。其本质是子进程分配VM空间失败导致的。

    解决方法:执行:echo 1 > /proc/sys/vm/overcommit_memory即可。

    更好的解决办法是不使用system调用方法,而是使用posix_spawn调用,简单的示例如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <spawn.h>
    #include <sys/wait.h>
    
    int main(int argc, char* argv[])
    {
    
        pid_t pid;
        int err;
    
        char *spawnedArgs[] = {"/bin/ls","-l","/home ",NULL};/* posix_spawn需要指定子进程的命令的全路径(绝对路径) */
    
        char *spawnedEnv[] = {NULL};
        printf("Parent process id=%ld\n", getpid());
    
        if( (err=posix_spawn(&pid, spawnedArgs[0], NULL, NULL,  spawnedArgs, spawnedEnv)) !=0 )
        {
            fprintf(stderr,"posix_spawn() error=%d\n",err), exit(-1);
        }
    
        printf("Child process  id=%ld\n", pid);
    
        /* Wait for the spawned process to exit */
        (void)wait(NULL);
    
        return 0;
    }


    posix_spawn的更多用法,请自行上网搜索。

    展开全文
  • 我已成功使用popen()从我的C程序中运行命令.据我了解,它在幕后使用了fork()...现在,我正在尝试使用posix_spawn()实现相同的功能,我理解这可能对资源更友好,尤其是如果我们不打算与新的子进程进行通信时,尤其如此:/...

    我已成功使用popen()从我的C程序中运行命令.据我了解,它在幕后使用了fork()和exec()(或它们的变体).效果很好:

    FILE *fd = popen("xterm", "r");

    pclose(fd);

    …将如预期的那样打开一个新的xterm窗口.

    现在,我正在尝试使用posix_spawn()实现相同的功能,我理解这可能对资源更友好,尤其是如果我们不打算与新的子进程进行通信时,尤其如此:

    /* p.we_wordv contains the argv, index 0 holds the actual command */

    pid_t pid;

    posix_spawnp(&pid, p.we_wordv[0], NULL, NULL, p.we_wordv, NULL);

    …但这对于xterm作为命令,在父项的输出中产生以下内容:

    xterm: Xt error: Can't open display:

    xterm: DISPLAY is not set

    尝试启动其他进程将产生其他错误消息,无提示地失败,或者在某些情况下(如ls)按预期工作.这使我很难真正看到一种模式.

    您能否指出是什么导致第二种方法的行为不同于第一种?

    解决方法:

    消息未设置DISPLAY告诉您xterm找不到DISPLAY环境变量.所有图形输出程序均使用此环境变量连接到屏幕.

    由于环境为空,因此未找到变量(这是posix_spawnp函数调用中的最后一个NULL).看来popen重用了当前进程的环境,所以它没有这个问题.

    您可能想要传递仅包含所需内容的手动创建的环境,或者仅传递过程所具有的任何环境.后者更灵活(xterm将从您的进程继承各种配置设置,而这些配置设置则从您的shell继承它们),但可能存在安全风险.

    要访问您的流程环境,请使用environ全局变量或更改您的main函数以接收其他参数:

    int main(int argc, char *argv[], char *envp[])

    {

    ...

    posix_spawnp(&pid, p.we_wordv[0], NULL, NULL, p.we_wordv, envp);

    }

    标签:popen,spawn,c-3,linux

    来源: https://codeday.me/bug/20191109/2012814.html

    展开全文
  • posix_spawnThe posix_spawn() and posix_spawnp() functions create a new child process from the specified process image constructed from a regular executable file. It can be used to replace the relative...

    posix_spawn

    The posix_spawn() and posix_spawnp() functions create a new child process from the specified process image constructed from a regular executable file. It can be used to replace the relative complex “fork-exec-wait” methods with fork() and exec(). However, compared to fork() and exec(), posix_spawn() is less introduced if you search on the Web. The posix_spawn() manual provides details. However, it is still not sufficient especially for beginners. Here, I give an example of C program using posix_spawn() to create child processes.

    posix_spawn()posix_spawnp()函数根据由常规可执行文件构造的指定过程映像创建新的子过程。 它可以用来用fork()exec()代替相对复杂的“ fork-exec-wait”方法。 但是,与fork()exec() ,如果在Web上搜索,则不会引入posix_spawn()posix_spawn()手册提供了详细信息。 但是,对于初学者来说,这仍然是不够的。 在这里,我举一个使用posix_spawn()创建子进程的C程序示例。

    The program is to run the command by /bin/sh -c that you pass as the first argument to the program. The run.c source code is as follows.

    该程序将通过/bin/sh -c运行命令,并将其作为第一个参数传递给该程序。 run.c源代码如下。

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #include <unistd.h>
    #include <spawn.h>
    #include <sys/wait.h>
    
    extern char **environ;
    
    void run_cmd(char *cmd)
    {
        pid_t pid;
        char *argv[] = {"sh", "-c", cmd, NULL};
        int status;
        printf("Run command: %s\n", cmd);
        status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
        if (status == 0) {
            printf("Child pid: %i\n", pid);
            if (waitpid(pid, &status, 0) != -1) {
                printf("Child exited with status %i\n", status);
            } else {
                perror("waitpid");
            }
        } else {
            printf("posix_spawn: %s\n", strerror(status));
        }
    }
    
    int main(int argc, char* argv[])
    {
        run_cmd(argv[1]);
        return 0;
    }

    From the example, you can find the posix_spawn() has its advantages and flexibility over other similar ones although it is a little tedious with 6 arguments.

    从该示例中,您可以发现posix_spawn()具有优于其他类似优点和灵活性的优点,尽管它有6个参数有点乏味。

    • system()system()exec(), it returns the new child process’ pid which you can wait by exec() ,它返回新的子进程的pid,您可以通过waitpid(). Of course, waitpid()等待。 当然, system()system ()
    • Difference from fork()/vfork(), the logic you implement is within the same process and you do not need to think about which piece of code is executed by the child process and which is executed by the parent process. It also avoid problems from vfork().

      fork() / vfork()不同之处在于,您实现的逻辑在同一进程内,因此您无需考虑子进程执行哪段代码以及父进程执行哪段代码。 它还避免了来自vfork()问题。

    翻译自: https://www.systutorials.com/a-posix_spawn-example-in-c-to-create-child-process-on-linux/

    posix_spawn

    展开全文
  • windows 10 ssh proxycommand 报错: “posix_spawn: No such file or directory”问题解决方案Long Story 问题 ssh使用ProxyCommand通过跳板机连接目标机,报错: CreateProcessW failed error:2 posix_spawn: No ...
  •  This macro is not speci‐ fied in POSIX.1-2001 and is not available on some UNIX implementations (e.g., AIX, SunOS). Only use this enclosed in #ifdef WCOREDUMP ... #endif. ...
  • 关于在Mac中装Django出现了posix_spawn: /Library/Frameworks/Python.framework/Versions/3.7/bin/python3.72.7: No such file or directory解决方法。时间:2019-12-17本文章向大家介绍关于在Mac中装Django出现了...
  • 将创建进程的API封装成一个进程类,用该类生成一个对象,则创建了一个进程;posix_spawn()来创建一个进程;
  • 多进程编程函数posix_spawn实例

    万次阅读 2015-12-14 15:10:24
    posix_spawn将可执行文件直接吊起,生成一个进程;该示例二中其实有三个进程在运行;main, ls , cat
  • linux posix_spawn

    千次阅读 2014-03-26 16:27:02
     posix_spawn_file_actions_t *file_actions,    const  posix_spawnattr_t *restrict attrp,    char  * const  argv[restrict],  char  * const  envp[restrict]);      int  ...
  • 多进程函数系列fork(), wait(), exec()系列,system(), posix_spawn()实例详解
  • fork vs. posix_spawn Sun

    千次阅读 2014-06-09 21:28:43
     posix_spawn_file_actions_adddup2(&action, out[0], 0);  posix_spawn_file_actions_addclose(&action, out[1]);  posix_spawn_file_actions_adddup2(&action, in[1], 1);  posix_spawn_file_actions...
  • posix-spawn 由于需要复制页表,因此父进程使用更多内存,因此fork(2)调用速度变慢。 在fork()的许多常见用法中,其后是exec函数家族之一以生成子进程( Kernel#system , IO::popen , Process::spawn等),可以...
  • ssh_askpass: posix_spawnp: Unknown error xxx@192.198.0.xx: Permission denie 分析:就是权限拒绝呗,常规讲pycharm不应该弹个窗啥的吗?如下: 但我的pycharm直接报错,连上面的弹窗都没有,我去,搞了好久,...
  • constposix_spawn_file_actions_t *file_actions, constposix_spawnattr_t *attrp, char *const argv[], char *const envp[]); 函数成功返回 0,失败返回-1 并设置错误码。函数参数如表21函数参数对比: 表...
  • SylixOS 的system使用

    2019-09-12 03:41:47
    posix_spawn函数创建子进程并继承父系的文件描述符,所以可以通过posix_spawn替换system实现。如程序清单 3‑3所示,只需修改A进程,B进程不用修改。 程序清单 3‑3 A进程修改后源码 #include #include ...
  • SSH连接出错

    2020-08-21 15:45:59
    问题: ...ssh_askpass: posix_spawn: No such file or directory Host key verification failed. 解决方法: 这是一个bug。要去电脑的环境变量里,把Display: 0.0的变量名改名字,我改的是Display123。
  • oc之脚本

    2019-02-21 15:16:00
     There is an problem launching using posix_spawn (error code: 8).错误:解决的办法,shell脚本中必须带#!/bin/sh   20150116173522546.jpeg   3、'/Users/user/lcg/code/ShellDemo/Shell...
  • During the past years, I have installed many Python libraries with various Python versions. To make them ready to work immediately, I installed them blindly without control. Currently they're causing ...
  • Linux下使用cp,mv,rm等命令时经常会碰到“Argument list too long”错误,这主要是因为这些命令的参数太长,即文件个数过多 解决方法1: find ./test -name "gen*.log" |xargs -i rm {} 解决方法2: ...
  • GIT 传输协议实现

    2016-07-19 14:06:00
    posix_spawn_file_actions_adddup2(&fa, p[1-op], 1-op)) { if (!(e = posix_spawn(&pid, "/bin/sh", &fa, 0, (char *[]){ "sh", "-c", (char *)cmd, 0 }, __environ))) { posix_spawn_file_actions_...
  • const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]); 函数成功返回 0,失败返回-1 并设置错误码。函数参数如表2-1函数参数对比: ...
  • 先来看这样一个例子,利用fork调用execlp()函数来在Linux下实现ps或ls命令: #include sys/types.h #include unistd.h #include stdio.h #include stdlib.h int main() { pid_t result;... if((result=e
  • system 函数被废除的替代方法

    千次阅读 2018-12-31 20:48:09
    做越狱应用和插件开发,经常会...'system' is deprecated: first deprecated in iOS 8.0 - Use posix_spawn APIs installd 只是警告,还是可以正常编译和使用,但是升级到 Xcode 9,system 函数就从 SDK 中移除了,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,418
精华内容 1,367
关键字:

posix_spawn