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

--stderr does not direct all stderr writes to file #10491

Closed
u20221022 opened this issue Feb 13, 2023 · 3 comments
Closed

--stderr does not direct all stderr writes to file #10491

u20221022 opened this issue Feb 13, 2023 · 3 comments

Comments

@u20221022
Copy link

u20221022 commented Feb 13, 2023

I did this

curl.exe -I --stderr err.txt --write-out "%{stderr}%{json}" "https://curl.se/" > Nul
{"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":null,"ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"2","local_ip":"?.?.?.?","local_port":?,"method":"HEAD","num_connects":1,"num_headers":21,"num_redirects":0,"proxy_ssl_verify_result":0,"redirect_url":null,"referer":null,"remote_ip":"151.101.65.91","remote_port":443,"response_code":200,"scheme":"HTTPS","size_download":0,"size_header":845,"size_request":70,"size_upload":0,"speed_download":0,"speed_upload":0,"ssl_verify_result":0,"time_appconnect":1.604500,"time_connect":0.221004,"time_namelookup":0.019257,"time_pretransfer":1.384094,"time_redirect":0.000000,"time_starttransfer":1.469586,"time_total":1.470412,"url":"https://curl.se/","url_effective":"https://curl.se/","urlnum":0,"curl_version":"libcurl/7.87.0 OpenSSL/3.0.8 (Schannel) zlib/1.2.13 brotli/1.0.9 zstd/1.5.4 WinIDN libssh2/1.10.0 nghttp2/1.51.0 ngtcp2/0.13.1 nghttp3/0.8.0 libgsasl/2.2.0"}
dir err.txt
Том в устройстве ? имеет метку ?
Серийный номер тома: ?

Содержимое папки ?:?\curl-7.87.0_7-win64-mingw\bin

13.02.2023 05:00 0 err.txt
1 файлов 0 байт
0 папок ? байт свободно
curl.exe -I --stderr err.txt --write-out "%{stderr}%{json}" "htps://curl.se/" > Nul
{"content_type":null,"errormsg":"Protocol "htps" not supported or disabled in libcurl","exitcode":1,"filename_effective":null,"ftp_entry_path":null,"http_code":0,"http_connect":0,"http_version":"0","local_ip":"","local_port":0,"method":"HEAD","num_connects":0,"num_headers":0,"num_redirects":0,"proxy_ssl_verify_result":0,"redirect_url":null,"referer":null,"remote_ip":"","remote_port":0,"response_code":0,"scheme":null,"size_download":0,"size_header":0,"size_request":0,"size_upload":0,"speed_download":0,"speed_upload":0,"ssl_verify_result":0,"time_appconnect":0.000000,"time_connect":0.000000,"time_namelookup":0.000000,"time_pretransfer":0.000000,"time_redirect":0.000000,"time_starttransfer":0.000000,"time_total":0.000000,"url":"htps://curl.se/","url_effective":"htps://curl.se/","urlnum":0,"curl_version":"libcurl/7.87.0 OpenSSL/3.0.8 (Schannel) zlib/1.2.13 brotli/1.0.9 zstd/1.5.4 WinIDN libssh2/1.10.0 nghttp2/1.51.0 ngtcp2/0.13.1 nghttp3/0.8.0 libgsasl/2.2.0"}
type err.txt
curl: (1) Protocol "htps" not supported or disabled in libcurl

I expected the following

Какой-нибудь глюк типа «not-a-bug» (#10459 и другие). Иначе не стал бы время тратить на такую примитивную проверку.
«Верной дорогой идёте, товарищи!»©

curl/libcurl version

7.87.0
[curl -V output]
curl 7.87.0 (x86_64-w64-mingw32) libcurl/7.87.0 OpenSSL/3.0.8 (Schannel) zlib/1.2.13 brotli/1.0.9 zstd/1.5.4 WinIDN libssh2/1.10.0 nghttp2/1.51.0 ngtcp2/0.13.1 nghttp3/0.8.0 libgsasl/2.2.0
Release-Date: 2022-12-21
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli gsasl HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL SSPI threadsafe TLS-SRP UnixSockets zstd

operating system

MS Windows

@u20221022 u20221022 changed the title %{stderr} --stderr Feb 13, 2023
@u20221022 u20221022 changed the title --stderr --stderr and %{stderr} Feb 13, 2023
@u20221022
Copy link
Author

u20221022 commented Feb 13, 2023

Я не понимаю, что происходит, поэтому не могу быть уверен в том, что подобрал подходящий заголовок; извините.


I don't understand what's going on, so I can't be sure I've picked the right title; Sorry.

@jay jay changed the title --stderr and %{stderr} --stderr does not direct all stderr writes to file Feb 13, 2023
@jay
Copy link
Member

jay commented Feb 13, 2023

Please tell us in English. It looks like you are reporting that --write-out %{stderr} does not direct its output to the --stderr file. That is true, it goes directly to stderr. I'm not sure if that was intended or not. The --stderr documentation does say "Redirect all writes to stderr to the specified file instead." hm.

curl/src/tool_writeout.c

Lines 425 to 427 in 7ce140b

case VAR_STDERR:
stream = stderr;
break;

The code could be changed to use the stream opened by --stderr (see below) but I wonder if we are just covering up a larger problem here, like maybe it would be better to freopen stderr when --stderr?

diff --git a/src/tool_operate.c b/src/tool_operate.c
index c9583b8..ca361bd 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -660,7 +660,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
 
   /* Write the --write-out data before cleanup but after result is final */
   if(config->writeout)
-    ourWriteOut(config->writeout, per, result);
+    ourWriteOut(config, per, result);
 
   /* Close function-local opened file descriptors */
   if(per->heads.fopened && per->heads.stream)
diff --git a/src/tool_writeout.c b/src/tool_writeout.c
index 5246db2..d93de82 100644
--- a/src/tool_writeout.c
+++ b/src/tool_writeout.c
@@ -376,15 +376,19 @@ static int writeOffset(FILE *stream, const struct writeoutvar *wovar,
   return 1; /* return 1 if anything was written */
 }
 
-void ourWriteOut(const char *writeinfo, struct per_transfer *per,
+void ourWriteOut(struct OperationConfig *config, struct per_transfer *per,
                  CURLcode per_result)
 {
   FILE *stream = stdout;
+  const char *writeinfo = config->writeout;
   const char *ptr = writeinfo;
   bool done = FALSE;
   struct curl_certinfo *certinfo;
   CURLcode res = curl_easy_getinfo(per->curl, CURLINFO_CERTINFO, &certinfo);
 
+  if(!writeinfo)
+    return;
+
   if(!res && certinfo)
     per->certinfo = certinfo;
 
@@ -423,7 +427,7 @@ void ourWriteOut(const char *writeinfo, struct per_transfer *per,
                 stream = stdout;
                 break;
               case VAR_STDERR:
-                stream = stderr;
+                stream = config->global->errors;
                 break;
               case VAR_JSON:
                 ourWriteOutJSON(stream, variables, per, per_result);
diff --git a/src/tool_writeout.h b/src/tool_writeout.h
index 0c07f22..fac7bdd 100644
--- a/src/tool_writeout.h
+++ b/src/tool_writeout.h
@@ -84,7 +84,7 @@ struct writeoutvar {
                    bool use_json);
 };
 
-void ourWriteOut(const char *writeinfo, struct per_transfer *per,
+void ourWriteOut(struct OperationConfig *config, struct per_transfer *per,
                  CURLcode per_result);
 
 #endif /* HEADER_CURL_TOOL_WRITEOUT_H */

@bagder
Copy link
Member

bagder commented Feb 13, 2023

I'm not sure if that was intended or not

I don't think it was intended but an oversight. I think you can do a proper PR with your change.

We never defined exactly what --stderr should redirect, but I consider it an alternative for systems that cannot redirect stderr with 2>file so basically everything stderr should go there.

bagder pushed a commit that referenced this issue Feb 20, 2023
@bagder bagder closed this as completed in d9b7f6e Feb 23, 2023
jay added a commit to jay/curl that referenced this issue Mar 4, 2023
- freopen stderr with the user-specified file (--stderr file) instead of
  using a separate 'errors' stream.

- Override stderr macro in tool_setup as global variable tool_stderr.

Both freopen and overriding the stderr macro are necessary because if
the user-specified filename is "-" then stdout is assigned to
tool_stderr and no freopen takes place.

Note --stderr maps to libcurl's CURLOPT_STDERR but they are documented
differently:

--stderr :
"Redirect all writes to stderr"

CURLOPT_STDERR :
"when showing the progress meter and displaying CURLOPT_VERBOSE data"

If the curl tool has freopened stderr as a file (--stderr file) then
libcurl stderr output will also go to the file. OTOH if stdout was
specified (--stderr -) then libcurl writes to stderr go to actual
stderr and just the criteria above is written to stdout. IMO the
distinction is moot since in libcurl we only write to stderr for
developer debug output.

Ref: curl#10491

Closes #xxxx
jay added a commit to jay/curl that referenced this issue Mar 5, 2023
- freopen stderr with the user-specified file (--stderr file) instead of
  using a separate 'errors' stream.

- Override stderr macro in tool_setup as global variable tool_stderr.

Both freopen and overriding the stderr macro are necessary because if
the user-specified filename is "-" then stdout is assigned to
tool_stderr and no freopen takes place. See the PR for more information.

Ref: curl#10491

Closes #xxxx
jay added a commit to jay/curl that referenced this issue Mar 6, 2023
- freopen stderr with the user-specified file (--stderr file) instead of
  using a separate 'errors' stream.

- Override stderr macro in tool_setup as global variable tool_stderr.

Both freopen and overriding the stderr macro are necessary because if
the user-specified filename is "-" then stdout is assigned to
tool_stderr and no freopen takes place. See the PR for more information.

Ref: curl#10491

Closes #xxxx
jay added a commit to jay/curl that referenced this issue Mar 8, 2023
- freopen stderr with the user-specified file (--stderr file) instead of
  using a separate 'errors' stream.

- Override stderr macro in tool_setup as global variable tool_stderr.

Both freopen and overriding the stderr macro are necessary because if
the user-specified filename is "-" then stdout is assigned to
tool_stderr and no freopen takes place. See the PR for more information.

Ref: curl#10491

Closes #xxxx
jay added a commit that referenced this issue Mar 12, 2023
- freopen stderr with the user-specified file (--stderr file) instead of
  using a separate 'errors' stream.

- In tool_setup.h override stdio.h's stderr macro as global variable
  tool_stderr.

Both freopen and overriding the stderr macro are necessary because if
the user-specified filename is "-" then stdout is assigned to
tool_stderr and no freopen takes place. See the PR for more information.

Ref: #10491

Closes #10673
GerHobbelt added a commit to GerHobbelt/thirdparty-curl that referenced this issue Mar 15, 2023
* tool: improve --stderr handling

- freopen stderr with the user-specified file (--stderr file) instead of
  using a separate 'errors' stream.

- In tool_setup.h override stdio.h's stderr macro as global variable
  tool_stderr.

Both freopen and overriding the stderr macro are necessary because if
the user-specified filename is "-" then stdout is assigned to
tool_stderr and no freopen takes place. See the PR for more information.

Ref: curl/curl#10491

Closes curl/curl#10673
bch pushed a commit to bch/curl that referenced this issue Jul 19, 2023
bch pushed a commit to bch/curl that referenced this issue Jul 19, 2023
- freopen stderr with the user-specified file (--stderr file) instead of
  using a separate 'errors' stream.

- In tool_setup.h override stdio.h's stderr macro as global variable
  tool_stderr.

Both freopen and overriding the stderr macro are necessary because if
the user-specified filename is "-" then stdout is assigned to
tool_stderr and no freopen takes place. See the PR for more information.

Ref: curl#10491

Closes curl#10673
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

3 participants