Open-Source Wikis

/

curl

/

Apps

/

curl

curl/curl

curl

Active contributors: Daniel Stenberg, Viktor Szakats, Jay Satiro

Purpose

curl is the command-line tool. It parses command-line options into libcurl easy-handle configurations, drives one or many transfers via the multi interface, and writes the response bodies and metadata to disk or stdout. It is the most visible product of the project, but the heavy lifting lives in libcurl.

Directory layout

src/
├── tool_main.c              # Entry point: argc/argv → main_call → curl_easy
├── tool_operate.c           # Per-URL transfer orchestration & multi loop
├── tool_getparam.c          # ~100KB option parser (273 long options)
├── tool_listhelp.c          # Auto-generated --help table
├── tool_help.[ch]           # --help and --manual implementations
├── tool_cfgable.[ch]        # struct OperationConfig — the in-memory option set
├── tool_paramhlp.c          # Per-option validation/parse helpers
├── tool_parsecfg.c          # Reads ~/.curlrc and -K config files
├── tool_setopt.[ch]         # libcurl setopt with --libcurl source emission
├── config2setopts.c         # Bridges OperationConfig → curl_easy_setopt calls
├── tool_cb_*.c              # libcurl callbacks (write, header, read, debug, progress, seek, sockopt)
├── tool_progress.[ch]       # Progress bar / progress meter
├── tool_writeout*           # --write-out templating
├── tool_urlglob.c           # {a,b,c} and [1-10] URL globbing
├── tool_findfile.c          # Locate ~/.curlrc, .netrc
├── tool_filetime.c          # Local-file timestamping
├── tool_xattr.c             # Extended attributes (--xattr) on POSIX/Windows
├── tool_doswin.c            # Windows/DOS console & filesystem quirks
├── tool_ipfs.c              # IPFS gateway translation
├── tool_formparse.c         # -F multipart and stdin parsing
├── tool_easysrc.[ch]        # --libcurl: emit C source for the equivalent program
├── tool_libinfo.c           # Reads curl_version_info() at startup
├── tool_msgs.c              # Logger
├── var.c                    # --variable (project variable substitution)
├── terminal.c               # Detect TTY for color and progress
├── slist_wc.c               # Wildcard-matching slist
├── curlinfo.c               # curl-tool side of feature detection
├── curl.rc                  # Windows resource (icon, version, manifest)
└── toolx/                   # Source shared between tools

CLI tooling shared with libcurl lives under lib/curlx/ (curlx).

Key abstractions

Symbol File Role
struct GlobalConfig src/tool_cfgable.h Process-wide options: stderr file, parallelism, color, progress format, --libcurl path
struct OperationConfig src/tool_cfgable.h Per-operation options: URL, method, headers, body, auth — one per --next invocation
getparameter() src/tool_getparam.c Long/short option parser; produces OperationConfig mutations
single_transfer() src/tool_operate.c Sets up one easy handle for one URL
parallel_transfers() src/tool_operate.c Drives curl_multi_socket_action for -Z/--parallel mode
tool_setopt() src/tool_setopt.c Wrapper around curl_easy_setopt that also emits source for --libcurl
tool_progress_* src/tool_progress.c Progress callbacks for both single and parallel transfers
tool_help_arg src/tool_help.c Implements --help [option] and the categorised long help

How it works

graph TD
    A[main argv] --> B[parse_args via tool_getparam.c]
    B --> C{multiple URLs<br/>or --next?}
    C -- yes --> D[N OperationConfigs in linked list]
    C -- no --> E[single OperationConfig]
    D --> F{--parallel ?}
    E --> G[per-URL loop<br/>tool_operate.c::single_transfer]
    F -- yes --> H[multi loop<br/>parallel_transfers]
    F -- no --> G
    G --> I[curl_easy_setopt × many]
    H --> I
    I --> J[curl_easy_perform / curl_multi_*]
    J --> K[tool_cb_* callbacks → stdout/file]
    K --> L[tool_writeout — --write-out templates]
    L --> M[exit code = mapped CURLcode]

Option parsing

src/tool_getparam.c is the largest CLI source file (~103 KB) for a reason: every command-line flag is a row in a table with type info, short-form mapping, and category, and the parser walks both POSIX-style and curl's slightly extended syntax. The auto-generated table src/tool_listhelp.c mirrors docs/cmdline-opts/*.md so that --help output and the man page never drift; the helper scripts/managen regenerates both during build.

Configuration files

-K <file> and ~/.curlrc are parsed by src/tool_parsecfg.c. They use the same option syntax as the command line, with = and quoting. ~/.netrc is parsed by lib/netrc.c (so libcurl can use it programmatically too).

Variables and templating

--variable name=value and --variable name@file populate a small interpreter implemented in src/var.c. Variables can be referenced from request bodies, headers, query strings, and --write-out templates with the {{var}} syntax. --write-out itself is a separate mini-template language implemented in src/tool_writeout.c and src/tool_writeout_json.c.

URL globbing

curl accepts a small URL grammar for batch downloads:

curl https://example.com/file[1-100].txt
curl https://example.com/{red,green,blue}.html

The parser is src/tool_urlglob.c. Globs expand to a sequence of full URLs which the operate loop drives sequentially or in parallel.

--libcurl C source emission

When invoked with --libcurl program.c, every curl_easy_setopt the tool would do is also emitted as readable C source via src/tool_setopt.c and src/tool_easysrc.c. The result is a self-contained C program equivalent to the command line — extremely useful for porting a working command line into an application.

Parallel transfers

-Z / --parallel flips on the multi-socket loop in src/tool_operate.c::parallel_transfers. By default the parallelism is capped (CURLOPT_MAXCONNECTS × CURLMOPT_MAX_TOTAL_CONNECTIONS), but --parallel-max lets you raise or lower it. The progress meter is also reorganised in this mode (src/tool_progress.c) since the per-transfer line layout no longer makes sense.

Integration points

  • libcurl: every transfer-touching feature ultimately calls into curl_easy_* and curl_multi_* via src/tool_setopt.c and src/config2setopts.c. The CLI does not implement protocol logic itself.
  • docs/cmdline-opts/: the canonical source for option semantics and --help output. Adding an option requires both a curldown file there and a matching entry in src/tool_getparam.c.
  • scripts/managen: generates src/tool_listhelp.c and docs/curl.1 from the markdown sources.
  • tests/data/test* drive the binary directly — every option has at least one test.

Entry points for modification

  • Adding a new command-line option → add a curldown file under docs/cmdline-opts/<name>.md, add a row to the option table in src/tool_getparam.c, plumb it into OperationConfig (src/tool_cfgable.h), and connect it to curl_easy_setopt in src/config2setopts.c. Run make to regenerate src/tool_listhelp.c and the man page.
  • Changing exit-code mapping → src/tool_operate.c is where libcurl CURLcode values are translated.
  • Changing the progress meter → src/tool_progress.c (single) and parallel_transfers (multi).

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

curl – curl wiki | Factory