Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tool: improve --stderr handling #10673

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Makefile.inc
Expand Up @@ -82,6 +82,7 @@ CURL_CFILES = \
tool_paramhlp.c \
tool_parsecfg.c \
tool_progress.c \
tool_stderr.c \
tool_strdup.c \
tool_setopt.c \
tool_sleep.c \
Expand Down Expand Up @@ -126,6 +127,7 @@ CURL_HFILES = \
tool_setopt.h \
tool_setup.h \
tool_sleep.h \
tool_stderr.h \
tool_strdup.h \
tool_urlglob.h \
tool_util.h \
Expand Down
4 changes: 2 additions & 2 deletions src/tool_cb_dbg.c
Expand Up @@ -48,7 +48,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type,
{
struct OperationConfig *operation = userdata;
struct GlobalConfig *config = operation->global;
FILE *output = config->errors;
FILE *output = stderr;
const char *text;
struct timeval tv;
char timebuf[20];
Expand Down Expand Up @@ -80,7 +80,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type,
config->trace_stream = stdout;
else if(!strcmp("%", config->trace_dump))
/* Ok, this is somewhat hackish but we do it undocumented for now */
config->trace_stream = config->errors; /* aka stderr */
config->trace_stream = stderr;
else {
config->trace_stream = fopen(config->trace_dump, FOPEN_WRITETEXT);
config->trace_fopened = TRUE;
Expand Down
2 changes: 1 addition & 1 deletion src/tool_cb_prg.c
Expand Up @@ -274,7 +274,7 @@ void progressbarinit(struct ProgressData *bar,
else if(bar->width > MAX_BARLENGTH)
bar->width = MAX_BARLENGTH;

bar->out = config->global->errors;
bar->out = stderr;
bar->tick = 150;
bar->barmove = 1;
}
2 changes: 0 additions & 2 deletions src/tool_cfgable.h
Expand Up @@ -302,8 +302,6 @@ struct GlobalConfig {
bool silent; /* don't show messages, --silent given */
bool noprogress; /* don't show progress bar */
bool isatty; /* Updated internally if output is a tty */
FILE *errors; /* Error stream, defaults to stderr */
bool errors_fopened; /* Whether error stream isn't stderr */
char *trace_dump; /* file to dump the network trace to */
FILE *trace_stream;
bool trace_fopened;
Expand Down
9 changes: 4 additions & 5 deletions src/tool_formparse.c
Expand Up @@ -417,8 +417,7 @@ static int read_field_headers(struct OperationConfig *config,
if(hdrlen) {
hdrbuf[hdrlen] = '\0';
if(slist_append(pheaders, hdrbuf)) {
fprintf(config->global->errors,
"Out of memory for field headers!\n");
fprintf(stderr, "Out of memory for field headers!\n");
return -1;
}
hdrlen = 0;
Expand All @@ -428,8 +427,8 @@ static int read_field_headers(struct OperationConfig *config,
switch(c) {
case EOF:
if(ferror(fp)) {
fprintf(config->global->errors,
"Header file %s read error: %s\n", filename, strerror(errno));
fprintf(stderr, "Header file %s read error: %s\n", filename,
strerror(errno));
return -1;
}
return 0; /* Done. */
Expand Down Expand Up @@ -585,7 +584,7 @@ static int get_param_part(struct OperationConfig *config, char endchar,
sep = *p;
*endpos = '\0';
if(slist_append(&headers, hdr)) {
fprintf(config->global->errors, "Out of memory for field header!\n");
fprintf(stderr, "Out of memory for field header!\n");
curl_slist_free_all(headers);
return -1;
}
Expand Down
19 changes: 4 additions & 15 deletions src/tool_getparam.c
Expand Up @@ -42,6 +42,7 @@
#include "tool_parsecfg.h"
#include "tool_main.h"
#include "dynbuf.h"
#include "tool_stderr.h"

#include "memdebug.h" /* keep this as LAST include */

Expand Down Expand Up @@ -1036,19 +1037,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
break;

case 'v': /* --stderr */
if(strcmp(nextarg, "-")) {
FILE *newfile = fopen(nextarg, FOPEN_WRITETEXT);
if(!newfile)
warnf(global, "Failed to open %s!\n", nextarg);
else {
if(global->errors_fopened)
fclose(global->errors);
global->errors = newfile;
global->errors_fopened = TRUE;
}
}
else
global->errors = stdout;
tool_set_stderr_file(nextarg);
Dismissed Show dismissed Hide dismissed
break;
case 'w': /* --interface */
/* interface */
Expand Down Expand Up @@ -2567,9 +2556,9 @@ ParameterError parse_args(struct GlobalConfig *global, int argc,
const char *reason = param2text(result);

if(orig_opt && strcmp(":", orig_opt))
helpf(global->errors, "option %s: %s\n", orig_opt, reason);
helpf(stderr, "option %s: %s\n", orig_opt, reason);
else
helpf(global->errors, "%s\n", reason);
helpf(stderr, "%s\n", reason);
}

curlx_unicodefree(orig_opt);
Expand Down
8 changes: 3 additions & 5 deletions src/tool_main.c
Expand Up @@ -53,6 +53,7 @@
#include "tool_vms.h"
#include "tool_main.h"
#include "tool_libinfo.h"
#include "tool_stderr.h"

/*
* This is low-level hard-hacking memory leak tracking and similar. Using
Expand Down Expand Up @@ -156,7 +157,6 @@ static CURLcode main_init(struct GlobalConfig *config)

/* Initialise the global config */
config->showerror = FALSE; /* show errors when silent */
config->errors = stderr; /* Default errors to stderr */
config->styled_output = TRUE; /* enable detection */
config->parallel_max = PARALLEL_DEFAULT;

Expand Down Expand Up @@ -196,10 +196,6 @@ static void free_globalconfig(struct GlobalConfig *config)
{
Curl_safefree(config->trace_dump);

if(config->errors_fopened && config->errors)
fclose(config->errors);
config->errors = NULL;

if(config->trace_fopened && config->trace_stream)
fclose(config->trace_stream);
config->trace_stream = NULL;
Expand Down Expand Up @@ -245,6 +241,8 @@ int main(int argc, char *argv[])
struct GlobalConfig global;
memset(&global, 0, sizeof(global));

tool_init_stderr();

#ifdef WIN32
/* Undocumented diagnostic option to list the full paths of all loaded
modules. This is purposely pre-init. */
Expand Down
8 changes: 4 additions & 4 deletions src/tool_msgs.c
Expand Up @@ -54,7 +54,7 @@ static void voutf(struct GlobalConfig *config,

ptr = print_buffer;
while(len > 0) {
fputs(prefix, config->errors);
fputs(prefix, stderr);

if(len > width) {
size_t cut = width-1;
Expand All @@ -67,13 +67,13 @@ static void voutf(struct GlobalConfig *config,
max text width then! */
cut = width-1;

(void)fwrite(ptr, cut + 1, 1, config->errors);
fputs("\n", config->errors);
(void)fwrite(ptr, cut + 1, 1, stderr);
fputs("\n", stderr);
ptr += cut + 1; /* skip the space too */
len -= cut + 1;
}
else {
fputs(ptr, config->errors);
fputs(ptr, stderr);
len = 0;
}
}
Expand Down
39 changes: 16 additions & 23 deletions src/tool_operate.c
Expand Up @@ -306,7 +306,7 @@ static CURLcode pre_transfer(struct GlobalConfig *global,
if((per->infd == -1) || fstat(per->infd, &fileinfo))
#endif
{
helpf(global->errors, "Can't open '%s'!\n", per->uploadfile);
helpf(stderr, "Can't open '%s'!\n", per->uploadfile);
if(per->infd != -1) {
close(per->infd);
per->infd = STDIN_FILENO;
Expand Down Expand Up @@ -404,18 +404,18 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
if(!config->synthetic_error && result &&
(!global->silent || global->showerror)) {
const char *msg = per->errorbuffer;
fprintf(global->errors, "curl: (%d) %s\n", result,
fprintf(stderr, "curl: (%d) %s\n", result,
(msg && msg[0]) ? msg : curl_easy_strerror(result));
if(result == CURLE_PEER_FAILED_VERIFICATION)
fputs(CURL_CA_CERT_ERRORMSG, global->errors);
fputs(CURL_CA_CERT_ERRORMSG, stderr);
}
else if(config->failwithbody) {
/* if HTTP response >= 400, return error */
long code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
if(code >= 400) {
if(!global->silent || global->showerror)
fprintf(global->errors,
fprintf(stderr,
"curl: (%d) The requested URL returned error: %ld\n",
CURLE_HTTP_RETURNED_ERROR, code);
result = CURLE_HTTP_RETURNED_ERROR;
Expand Down Expand Up @@ -448,7 +448,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
/* something went wrong in the writing process */
result = CURLE_WRITE_ERROR;
if(!global->silent || global->showerror)
fprintf(global->errors, "curl: (%d) Failed writing body\n", result);
fprintf(stderr, "curl: (%d) Failed writing body\n", result);
}
}

Expand Down Expand Up @@ -589,8 +589,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
/* We have written data to an output file, we truncate file
*/
if(!global->silent)
fprintf(global->errors, "Throwing away %"
CURL_FORMAT_CURL_OFF_T " bytes\n",
fprintf(stderr, "Throwing away %" CURL_FORMAT_CURL_OFF_T " bytes\n",
outs->bytes);
fflush(outs->stream);
/* truncate file at the position where we started appending */
Expand All @@ -599,8 +598,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
/* when truncate fails, we can't just append as then we'll
create something strange, bail out */
if(!global->silent || global->showerror)
fprintf(global->errors,
"curl: (23) Failed to truncate file\n");
fprintf(stderr, "curl: (23) Failed to truncate file\n");
return CURLE_WRITE_ERROR;
}
/* now seek to the end of the file, the position where we
Expand All @@ -615,8 +613,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
#endif
if(rc) {
if(!global->silent || global->showerror)
fprintf(global->errors,
"curl: (23) Failed seeking to end of file\n");
fprintf(stderr, "curl: (23) Failed seeking to end of file\n");
return CURLE_WRITE_ERROR;
}
outs->bytes = 0; /* clear for next round */
Expand All @@ -641,7 +638,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
/* something went wrong in the writing process */
result = CURLE_WRITE_ERROR;
if(!global->silent || global->showerror)
fprintf(global->errors, "curl: (%d) Failed writing body\n", result);
fprintf(stderr, "curl: (%d) Failed writing body\n", result);
}
if(result && config->rm_partial) {
notef(global, "Removing output file: %s\n", outs->filename);
Expand Down Expand Up @@ -801,7 +798,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
/* Unless explicitly shut off */
result = glob_url(&inglob, infiles, &state->infilenum,
(!global->silent || global->showerror)?
global->errors:NULL);
stderr:NULL);
if(result)
break;
config->state.inglob = inglob;
Expand Down Expand Up @@ -837,7 +834,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
expressions and return total number of URLs in pattern set */
result = glob_url(&state->urls, urlnode->url, &state->urlnum,
(!global->silent || global->showerror)?
global->errors:NULL);
stderr:NULL);
if(result)
break;
urlnum = state->urlnum;
Expand Down Expand Up @@ -1096,7 +1093,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
file output call */

if(config->create_dirs) {
result = create_dir_hierarchy(per->outfile, global->errors);
result = create_dir_hierarchy(per->outfile, stderr);
/* create_dir_hierarchy shows error upon CURLE_WRITE_ERROR */
if(result)
break;
Expand Down Expand Up @@ -1240,9 +1237,6 @@ static CURLcode single_transfer(struct GlobalConfig *global,
}
}

if(!global->errors)
global->errors = stderr;

if((!per->outfile || !strcmp(per->outfile, "-")) &&
!config->use_ascii) {
/* We get the output to stdout and we have not got the ASCII/text
Expand Down Expand Up @@ -1851,7 +1845,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
my_setopt(curl, CURLOPT_TIMEVALUE_LARGE, config->condtime);
my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
customrequest_helper(config, config->httpreq, config->customrequest);
my_setopt(curl, CURLOPT_STDERR, global->errors);
my_setopt(curl, CURLOPT_STDERR, stderr);

/* three new ones in libcurl 7.3: */
my_setopt_str(curl, CURLOPT_INTERFACE, config->iface);
Expand Down Expand Up @@ -2517,8 +2511,7 @@ static CURLcode transfer_per_config(struct GlobalConfig *global,

/* Check we have a url */
if(!config->url_list || !config->url_list->url) {
helpf(global->errors, "(%d) no URL specified!\n",
CURLE_FAILED_INIT);
helpf(stderr, "(%d) no URL specified!\n", CURLE_FAILED_INIT);
return CURLE_FAILED_INIT;
}

Expand Down Expand Up @@ -2576,7 +2569,7 @@ static CURLcode transfer_per_config(struct GlobalConfig *global,
if(!config->capath) {
curl_free(env);
curl_easy_cleanup(curltls);
helpf(global->errors, "out of memory\n");
helpf(stderr, "out of memory\n");
return CURLE_OUT_OF_MEMORY;
}
capath_from_env = true;
Expand Down Expand Up @@ -2694,7 +2687,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[])

/* If we had no arguments then make sure a url was specified in .curlrc */
if((argc < 2) && (!global->first->url_list)) {
helpf(global->errors, NULL);
helpf(stderr, NULL);
result = CURLE_FAILED_INIT;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/tool_progress.c
Expand Up @@ -173,7 +173,7 @@ bool progress_meter(struct GlobalConfig *global,
header = TRUE;
fputs("DL% UL% Dled Uled Xfers Live "
"Total Current Left Speed\n",
global->errors);
stderr);
}
if(final || (diff > 500)) {
char time_left[10];
Expand Down Expand Up @@ -275,7 +275,7 @@ bool progress_meter(struct GlobalConfig *global,
}
time2str(time_spent, spent);

fprintf(global->errors,
fprintf(stderr,
"\r"
"%-3s " /* percent downloaded */
"%-3s " /* percent uploaded */
Expand Down
9 changes: 9 additions & 0 deletions src/tool_setup.h
Expand Up @@ -37,6 +37,15 @@

#include "curl_setup.h" /* from the lib directory */

extern FILE *tool_stderr;

#if !defined(CURL_DO_NOT_OVERRIDE_STDERR) && !defined(UNITTESTS)
#ifdef stderr
#undef stderr
#endif
#define stderr tool_stderr
#endif

/*
* curl tool certainly uses libcurl's external interface.
*/
Expand Down