1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
# Copyright (C) 2006 Zack Weinberg <zackw@panix.com>
#
# This program is made available under the GNU GPL version 2.0 or
# greater. See the accompanying file COPYING for details.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE.
# Check whether sync_with_stdio(false) run on C++ streams works correctly.
# It causes strange problems (EOF returned too early) on some versions of
# MinGW and OS X. The first test is for the MinGW issue, the second for
# the OS X issue.
#
# In order to check for this issue, we first generate a large input file
# (over 128KB) and then try to read it (using a buffer size over 512
# bytes). If the amount of bytes read does not match the generated input,
# the implementation is broken.
AC_DEFUN([AC_CXX_SYNC_WITH_STDIO_WORKS],
[AC_CACHE_CHECK([whether C++ streams support sync_with_stdio],
ac_cv_cxx_sync_with_stdio_works, [
if test x$cross_compiling = xyes; then
AC_MSG_FAILURE([cannot run test program while cross compiling])
fi
# Note that we can't use AC_RUN_IFELSE for these because we have to
# redirect standard input. Instead, we use AC_LINK_IFELSE to
# generate the binaries and then run them by hand. Hence the manual
# failure-if-cross-compiling above.
AC_RUN_IFELSE([AC_LANG_SOURCE([
/*
* Generates the input file.
*/
#include <cstdlib>
#include <fstream>
int
main(void)
{
std::ofstream ofs("_conftest.dat");
for (int i = 0; i < 50000; i++)
ofs << "0123456789\r\n";
ofs.close();
return EXIT_SUCCESS;
}
])], [], [AC_MSG_FAILURE([could not generate input for test 1])])
AC_LINK_IFELSE([AC_LANG_SOURCE([[
/*
* Reads the input file.
*/
#include <cstdlib>
#include <fstream>
#include <iostream>
int
main(void)
{
std::cin.sync_with_stdio(false);
int length = 0;
while (std::cin.good())
{
char buffer[1024];
(void)std::cin.read(buffer, sizeof(buffer));
length += std::cin.gcount();
}
return length == 600000 ? EXIT_SUCCESS : EXIT_FAILURE;
}
]])],
[if ./conftest$ac_exeext <_conftest.dat; then
:
else
ac_cv_sync_with_stdio_works=no
fi],
[AC_MSG_FAILURE([could not link test program for test 1])])
rm -f _conftest.dat
if test "x$ac_cv_sync_with_stdio_works" != xno; then
# To check for issue 2, we have a writer with a short delay between
# writes, and a reader who has set sync_with_stdio(false).
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <cstdlib>
#include <iostream>
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define sleep(x) Sleep((x) * 1000)
#else
#include <unistd.h>
#endif
int
main(int argc, char * argv[])
{
if (argc != 2)
return EXIT_FAILURE;
if (argv[1][0] == 'R')
{
std::cin.sync_with_stdio(false);
int length = 0;
while (std::cin.good())
{
char buffer@<:@1024@:>@;
(void)std::cin.read(buffer, sizeof(buffer));
length += std::cin.gcount();
}
return length == 82 ? EXIT_SUCCESS : EXIT_FAILURE;
}
else
{
std::cout << "1234567890123456789012345678901234567890" << std::endl;
sleep(1);
std::cout << "1234567890123456789012345678901234567890" << std::endl;
}
return EXIT_SUCCESS;
}
]])],
[if ./conftest$ac_exeext W | ./conftest$ac_exeext R; then
ac_cv_cxx_sync_with_stdio_works=yes
else
ac_cv_cxx_sync_with_stdio_works=no
fi],
[AC_MSG_FAILURE([could not link test program for test 2])])
fi # skip test 2
])
if test $ac_cv_cxx_sync_with_stdio_works = yes; then
AC_DEFINE(SYNC_WITH_STDIO_WORKS, 1,
[Define to 1 if ios::sync_with_stdio(false) works])
fi
])
|