binmode: convert to macro and use it from tests

And use it from src and tests.

Syncing this functionality between platforms and build targets.

Also: Stop redefining `O_BINARY` in src, and use a local macro with
the same effect. `O_BINARY` is used in `CURL_SET_BINMODE()` to decide
if this functionality is supported, and redefining it makes this check
pass always in unity builds. The check is required for Apple OS, because
it offers a `setmode()` function, successfully detected by both CMake
and autotools, but that function has a different functionality and
signature than that expected by `CURL_SET_BINMODE()`.

Also:
- drop MetaWare High C (MS-DOS) support for set binmode.
- tests/libtest/Makefile.inc: dedupe comments.
- lib/curl_setup_once.h: tidy up feature guards for `io.h`, `fcntl.h`.

Ref: #15652
Closes #15787
This commit is contained in:
Viktor Szakats 2024-11-27 13:52:30 +01:00
parent 3428b8ad1c
commit 250d613763
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
18 changed files with 63 additions and 125 deletions

View File

@ -48,8 +48,11 @@
#include <sys/time.h>
#endif
#ifdef _WIN32
#ifdef HAVE_IO_H
#include <io.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif

View File

@ -396,7 +396,7 @@ $ if f$search("[.src]curl.exe") .eqs. ""
$ then
$ define/user gnv$libcurl 'gnv_libcurl_share'
$ link'ldebug'/exe=[.src]curl.exe/dsf=[.src]curl.dsf -
[.src]curl-tool_main.o, [.src]curl-tool_binmode.o, -
[.src]curl-tool_main.o, -
[.src]curl-tool_bname.o, [.src]curl-tool_cb_dbg.o, -
[.src]curl-tool_cb_hdr.o, [.src]curl-tool_cb_prg.o, -
[.src]curl-tool_cb_rea.o, [.src]curl-tool_cb_see.o, -

View File

@ -60,7 +60,6 @@ CURLX_HFILES = \
CURL_CFILES = \
slist_wc.c \
terminal.c \
tool_binmode.c \
tool_bname.c \
tool_cb_dbg.c \
tool_cb_hdr.c \

View File

@ -1,55 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "tool_setup.h"
#if defined(HAVE_SETMODE) || defined(HAVE__SETMODE)
#ifdef HAVE_IO_H
# include <io.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#include "tool_binmode.h"
#include "memdebug.h" /* keep this as LAST include */
void set_binmode(FILE *stream)
{
#ifdef O_BINARY
# ifdef __HIGHC__
_setmode(stream, O_BINARY);
# elif defined(HAVE__SETMODE)
(void)_setmode(fileno(stream), O_BINARY);
# else
(void)setmode(fileno(stream), O_BINARY);
# endif
#else
(void)stream;
#endif
}
#endif /* HAVE_SETMODE || HAVE__SETMODE */

View File

@ -25,14 +25,15 @@
***************************************************************************/
#include "tool_setup.h"
#if defined(HAVE_SETMODE) || defined(HAVE__SETMODE)
void set_binmode(FILE *stream);
#if (defined(HAVE_SETMODE) || defined(HAVE__SETMODE)) && defined(O_BINARY)
/* Requires io.h and/or fcntl.h when available */
#ifdef HAVE__SETMODE
# define CURL_SET_BINMODE(stream) (void)_setmode(fileno(stream), O_BINARY)
#else
#define set_binmode(x) Curl_nop_stmt
#endif /* HAVE_SETMODE || HAVE__SETMODE */
# define CURL_SET_BINMODE(stream) (void)setmode(fileno(stream), O_BINARY)
#endif
#else
# define CURL_SET_BINMODE(stream) (void)stream; Curl_nop_stmt
#endif
#endif /* HEADER_CURL_TOOL_BINMODE_H */

View File

@ -39,8 +39,10 @@
#include "memdebug.h" /* keep this as LAST include */
#ifndef O_BINARY
#define O_BINARY 0
#ifdef O_BINARY
#define CURL_O_BINARY O_BINARY
#else
#define CURL_O_BINARY 0
#endif
#ifdef _WIN32
#define OPENMODE S_IREAD | S_IWRITE
@ -69,7 +71,7 @@ bool tool_create_output_file(struct OutStruct *outs,
else {
int fd;
do {
fd = open(fname, O_CREAT | O_WRONLY | O_EXCL | O_BINARY, OPENMODE);
fd = open(fname, O_CREAT | O_WRONLY | O_EXCL | CURL_O_BINARY, OPENMODE);
/* Keep retrying in the hope that it is not interrupted sometime */
} while(fd == -1 && errno == EINTR);
if(config->file_clobber_mode == CLOBBER_NEVER && fd == -1) {
@ -96,7 +98,8 @@ bool tool_create_output_file(struct OutStruct *outs,
msnprintf(newname + len + 1, 12, "%d", next_num);
next_num++;
do {
fd = open(newname, O_CREAT | O_WRONLY | O_EXCL | O_BINARY, OPENMODE);
fd = open(newname, O_CREAT | O_WRONLY | O_EXCL | CURL_O_BINARY,
OPENMODE);
/* Keep retrying in the hope that it is not interrupted sometime */
} while(fd == -1 && errno == EINTR);
}

View File

@ -106,7 +106,7 @@ static struct tool_mime *tool_mime_new_filedata(struct tool_mime *parent,
curl_off_t origin;
struct_stat sbuf;
set_binmode(stdin);
CURL_SET_BINMODE(stdin);
origin = ftell(stdin);
/* If stdin is a regular file, do not buffer data but read it
when needed. */

View File

@ -600,7 +600,7 @@ static ParameterError data_urlencode(struct GlobalConfig *global,
/* a '@' letter, it means that a filename or - (stdin) follows */
if(!strcmp("-", p)) {
file = stdin;
set_binmode(stdin);
CURL_SET_BINMODE(stdin);
}
else {
file = fopen(p, "rb");
@ -866,7 +866,7 @@ static ParameterError set_data(cmdline_t cmd,
if(!strcmp("-", nextarg)) {
file = stdin;
if(cmd == C_DATA_BINARY) /* forced data-binary */
set_binmode(stdin);
CURL_SET_BINMODE(stdin);
}
else {
file = fopen(nextarg, "rb");

View File

@ -111,10 +111,12 @@ extern const unsigned char curl_ca_embed[];
#endif
#endif
#ifndef O_BINARY
/* since O_BINARY as used in bitmasks, setting it to zero makes it usable in
/* since O_BINARY is used in bitmasks, setting it to zero makes it usable in
source code but yet it does not ruin anything */
# define O_BINARY 0
#ifdef O_BINARY
#define CURL_O_BINARY O_BINARY
#else
#define CURL_O_BINARY 0
#endif
#ifndef SOL_IP
@ -379,16 +381,16 @@ static CURLcode pre_transfer(struct GlobalConfig *global,
case FAB$C_VAR:
case FAB$C_VFC:
case FAB$C_STMCR:
per->infd = open(per->uploadfile, O_RDONLY | O_BINARY);
per->infd = open(per->uploadfile, O_RDONLY | CURL_O_BINARY);
break;
default:
per->infd = open(per->uploadfile, O_RDONLY | O_BINARY,
per->infd = open(per->uploadfile, O_RDONLY | CURL_O_BINARY,
"rfm=stmlf", "ctx=stm");
}
}
if(per->infd == -1)
#else
per->infd = open(per->uploadfile, O_RDONLY | O_BINARY);
per->infd = open(per->uploadfile, O_RDONLY | CURL_O_BINARY);
if((per->infd == -1) || fstat(per->infd, &fileinfo))
#endif
{
@ -1993,7 +1995,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
}
else {
/* always use binary mode for protocol header output */
set_binmode(etag_save->stream);
CURL_SET_BINMODE(etag_save->stream);
}
}
@ -2038,7 +2040,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
if(!strcmp(config->headerfile, "%")) {
heads->stream = stderr;
/* use binary mode for protocol header output */
set_binmode(heads->stream);
CURL_SET_BINMODE(heads->stream);
}
else if(strcmp(config->headerfile, "-")) {
FILE *newfile;
@ -2079,7 +2081,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
}
else {
/* always use binary mode for protocol header output */
set_binmode(heads->stream);
CURL_SET_BINMODE(heads->stream);
}
}
@ -2266,7 +2268,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
DEBUGASSERT(per->infdopen == FALSE);
DEBUGASSERT(per->infd == STDIN_FILENO);
set_binmode(stdin);
CURL_SET_BINMODE(stdin);
if(!strcmp(per->uploadfile, ".")) {
if(curlx_nonblock((curl_socket_t)per->infd, TRUE) < 0)
warnf(global,
@ -2300,7 +2302,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
!config->use_ascii) {
/* We get the output to stdout and we have not got the ASCII/text
flag, then set stdout to be binary */
set_binmode(stdout);
CURL_SET_BINMODE(stdout);
}
/* explicitly passed to stdout means okaying binary gunk */

View File

@ -75,6 +75,7 @@ foreach(_target IN LISTS LIBTESTPROGS)
target_include_directories(${_target_name} PRIVATE
"${PROJECT_BINARY_DIR}/lib" # for "curl_config.h"
"${PROJECT_SOURCE_DIR}/lib" # for "curl_setup.h"
"${PROJECT_SOURCE_DIR}/src" # for "tool_binmode.h"
"${PROJECT_SOURCE_DIR}/tests/libtest" # to be able to build generated tests
)
if(NOT CURL_TEST_BUNDLES)

View File

@ -35,6 +35,7 @@ AUTOMAKE_OPTIONS = foreign nostdinc
AM_CPPFLAGS = -I$(top_srcdir)/include \
-I$(top_builddir)/lib \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/src \
-I$(top_srcdir)/tests/libtest
EXTRA_DIST = test307.pl test610.pl test613.pl test1013.pl test1022.pl \

View File

@ -23,26 +23,17 @@
###########################################################################
# files used only in some libcurl test programs
TESTUTIL = testutil.c testutil.h
# files used only in some libcurl test programs
TSTTRACE = testtrace.c testtrace.h
# files used only in some libcurl test programs
WARNLESS = ../../lib/warnless.c ../../lib/warnless.h
# files used only in some libcurl test programs
MULTIBYTE = ../../lib/curl_multibyte.c ../../lib/curl_multibyte.h
# files used only in some libcurl test programs
INET_PTON = ../../lib/inet_pton.c ../../lib/inet_pton.h
THREADS = ../../lib/curl_threads.c ../../lib/curl_threads.h
# these files are used in every single test program below
TIMEDIFF = ../../lib/timediff.c ../../lib/timediff.h
FIRSTFILES = first.c first.h
SUPPORTFILES = $(TIMEDIFF) $(FIRSTFILES) test.h
THREADS = ../../lib/curl_threads.c ../../lib/curl_threads.h
# These are all libcurl test programs
LIBTESTPROGS = libauthretry libntlmconnect libprereq \
lib500 lib501 lib502 lib503 lib504 lib505 lib506 lib507 lib508 lib509 \

View File

@ -28,14 +28,6 @@
# include <locale.h> /* for setlocale() */
#endif
#ifdef HAVE_IO_H
# include <io.h> /* for setmode() */
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h> /* for setmode() */
#endif
#ifdef CURLDEBUG
# define MEMDEBUG_NODEFINES
# include "memdebug.h"
@ -43,6 +35,8 @@
#include "timediff.h"
#include "tool_binmode.h"
int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc,
struct timeval *tv)
{
@ -141,13 +135,7 @@ int main(int argc, char **argv)
int basearg;
test_func_t test_func;
#ifdef O_BINARY
# ifdef __HIGHC__
_setmode(stdout, O_BINARY);
# else
setmode(fileno(stdout), O_BINARY);
# endif
#endif
CURL_SET_BINMODE(stdout);
memory_tracking_init();

View File

@ -35,7 +35,7 @@ foreach(_target IN LISTS noinst_PROGRAMS)
target_include_directories(${_target_name} PRIVATE
"${PROJECT_BINARY_DIR}/lib" # for "curl_config.h"
"${PROJECT_SOURCE_DIR}/lib" # for "curl_setup.h"
"${PROJECT_SOURCE_DIR}/src" # for "tool_xattr.h" in disabled_SOURCES
"${PROJECT_SOURCE_DIR}/src" # for "tool_binmod.h", "tool_xattr.h"
)
target_link_libraries(${_target_name} ${CURL_LIBS})
# Test servers simply are standalone programs that do not use libcurl

View File

@ -34,9 +34,7 @@ AUTOMAKE_OPTIONS = foreign nostdinc
AM_CPPFLAGS = -I$(top_srcdir)/include \
-I$(top_builddir)/lib \
-I$(top_srcdir)/lib
disabled_CPPFLAGS = $(AM_CPPFLAGS) \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/src
# Prevent LIBS from being used for all link targets

View File

@ -60,6 +60,8 @@
#include "server_sockaddr.h"
#include "warnless.h"
#include "tool_binmode.h"
/* include memdebug.h last */
#include "memdebug.h"
@ -1028,12 +1030,12 @@ int main(int argc, char *argv[])
#ifdef _WIN32
win32_init();
atexit(win32_cleanup);
setmode(fileno(stdin), O_BINARY);
setmode(fileno(stdout), O_BINARY);
setmode(fileno(stderr), O_BINARY);
#endif
CURL_SET_BINMODE(stdin);
CURL_SET_BINMODE(stdout);
CURL_SET_BINMODE(stderr);
install_signal_handlers(FALSE);
#ifdef USE_IPV6

View File

@ -107,6 +107,8 @@
#include "timediff.h"
#include "warnless.h"
#include "tool_binmode.h"
/* include memdebug.h last */
#include "memdebug.h"
@ -1497,12 +1499,12 @@ int main(int argc, char *argv[])
#ifdef _WIN32
win32_init();
atexit(win32_cleanup);
setmode(fileno(stdin), O_BINARY);
setmode(fileno(stdout), O_BINARY);
setmode(fileno(stderr), O_BINARY);
#endif
CURL_SET_BINMODE(stdin);
CURL_SET_BINMODE(stdout);
CURL_SET_BINMODE(stderr);
install_signal_handlers(false);
#ifdef USE_IPV6

View File

@ -78,6 +78,8 @@
#include "server_sockaddr.h"
#include "warnless.h"
#include "tool_binmode.h"
/* include memdebug.h last */
#include "memdebug.h"
@ -1098,12 +1100,12 @@ int main(int argc, char *argv[])
#ifdef _WIN32
win32_init();
atexit(win32_cleanup);
setmode(fileno(stdin), O_BINARY);
setmode(fileno(stdout), O_BINARY);
setmode(fileno(stderr), O_BINARY);
#endif
CURL_SET_BINMODE(stdin);
CURL_SET_BINMODE(stdout);
CURL_SET_BINMODE(stderr);
install_signal_handlers(false);
sock = socket(socket_domain, SOCK_STREAM, 0);