operate() - mapleeit/curl_SourceAnalysis GitHub Wiki

operate()函数在Tool_operate.c文件的1778行。我们从这里开始:

注意: config参数非常之重要,它指示最后程序应该怎么工作,是copy网页,还是ftp,是使用ipv4还是ipv6。


因此这个过程可以表达为:

用户输入->argv[]接收参数->通过parse_args()函数解析参数->传入config中->后续函数根据config来控制程序通信


CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[])
{
  CURLcode result = CURLE_OK;
  if((argc == 1) || (!curlx_strequal(argv[1], "-q"))) {
    parseconfig(NULL, config); /* NULL表示使用默认配置文件$HOME/.curlrc */

注意: argv[0]curl 如果第一个参数不为是-q,或者没有参数。那么自动读取$HOME/.curlrc的配置文件。

    if((argc < 2) && (!config->first->url_list)) {
      helpf(config->errors, NULL);
      result = CURLE_FAILED_INIT;
    }
  }

如果没有参数传入并且初始的config文件中没有指定url,出错

  if(!result) {
    ParameterError res = parse_args(config, argc, argv);
    if(res) {
      result = CURLE_OK;

[parse_args()][1]将在下一节讲。其功能为:分析参数并将这些解析出的参数含义传到config中,与初始config进行合并(新替换旧,无新则旧不变)

      /* Check if we were asked for the help */
      if(res == PARAM_HELP_REQUESTED)
        tool_help();
      /* Check if we were asked for the manual */
      else if(res == PARAM_MANUAL_REQUESTED)
        hugehelp();
      /* Check if we were asked for the version information */
      else if(res == PARAM_VERSION_INFO_REQUESTED)
        tool_version_info();
      /* Check if we were asked to list the SSL engines */
      else if(res == PARAM_ENGINES_REQUESTED)
        tool_list_engines(config->easy);
      else
        result = CURLE_FAILED_INIT;
    }

根据返回值判断出错类型,并且执行相应响应

    else {
      /* Perform the main operations */
      if(!result) {
        size_t count = 0;
        struct OperationConfig *operation = config->first;

        /* Get the required aguments for each operation */
        while(!result && operation) {
          result = get_args(operation, count++);

          operation = operation->next;
        }

        /* Set the current operation pointer */
        config->current = config->first;

        /* Perform each operation */
        while(!result && config->current) {
          result = operate_do(config, config->current);

          config->current = config->current->next;
        }
      }
      else
        helpf(config->errors, "out of memory\n");
    }
  }

  return result;
}

[operate_do()][2]是真正执行命令的函数 [1]: https://github.com/mapleeit/curl_SourceAnalysis/wiki/parse_args() [2]: https://github.com/mapleeit/curl_SourceAnalysis/wiki/operate_do()