C ++,是否有可能(以及如何)通过exec()运行多动作,单线程卷曲命令?

时间:2015-10-23 02:28:12

标签: c++ macos curl exec

我有一个curl命令:

curl -c cookies.txt -b cookies.txt -k https://www.example.com/ajaxauth/login -d 'identity=email@example.com&password=pa$$w0rd&query=https://example.com/data/format/json' > ~/Documents/.../myProject/bin/data/myData.json"

  1. 登录API,
  2. 管理cookies,
  3. 获取数据集并保存到本地文件。
  4. 我在char数组中发送它并发送到system()命令,但由于将vars(电子邮件和密码)传递给system()的危险,我必须使用exec()代替。我不熟悉这个命令,文档令我困惑。所以我的问题:

    • 这是否可行,或者我 回去将我的命令分解为单个呼叫甚至多个exec呼叫?

    • 我假设我应该使用exec v 版本,因为我传入一个完整的字符数组,这是正确的吗?

    • 许多不同的消息来源说exec()命令的第一个参数必须是可执行文件。 For example,“按照惯例,第一个参数应指向与正在执行的文件关联的文件名。” curl命令如何计算?

    • 为什么this person传递(char *) 0作为最后一个参数?

    这是我到目前为止所做的:

    int pid = fork();
    
    switch(pid){
        case -1:{            
            perror("fork"); // via https://stackoverflow.com/q/2329640/1757149
            _exit(EXIT_FAILURE);
            break;
        }
        case 0:{ // child process
            //execv(cmd, ???);
            break;
        }
        default:{ // parent process                
            break;
        }
    }
    

    请注意,我不能使用libcurl。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:2)

您可以使用execlp这样的分割参数执行命令(添加NULL以指示参数结束):

execlp("curl","curl","-c","cookies.txt","-b","cookies.txt","-k","https://www.example.com/ajaxauth/login","-d","identity=email@example.com&password=pa$$w0rd&query=https://example.com/data/format/json",NULL);

第一个参数是将从PATH搜索的可执行文件,第二个参数在manpage中被引用为“第一个参数,按照惯例,应该指向与之关联的文件名正在执行的文件。

为了将exec的输出重定向到文件,您应该用输出文件替换标准输出:

int out = creat("myData.json", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
dup2(out,STDOUT_FILENO); 

全部放在一起:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>

int main()
{   
    int pid = fork();
    switch(pid){
        case -1:{            
            perror("fork"); 
            _exit(EXIT_FAILURE);
            break;
        }
        case 0:{ // child process
            // create output file
            int out = creat("myData.json", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
            if (out == -1){
                perror("creat"); 
                _exit(EXIT_FAILURE);
            } else {
                // redirect stdout to output file
                dup2(out,STDOUT_FILENO); 
                // exec the command
                execlp("curl","curl","-c","cookies.txt","-b","cookies.txt","-k","https://www.example.com/ajaxauth/login","-d","identity=email@example.com&password=pa$$w0rd&query=https://example.com/data/format/json",NULL);
                // close output file
                close(out);
            }
            break;
        }
        default:{ // parent process                
            // wait for child process
            int status = 0;
            wait(&status);  
            printf("child status:%d\n",status);
            break;
        }
    }       
    return 0;
}