File: syncwithstdio.m4

package info (click to toggle)
monotone 1.1-4%2Bdeb8u2
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 20,664 kB
  • ctags: 8,113
  • sloc: cpp: 86,443; sh: 6,906; perl: 924; makefile: 838; python: 517; lisp: 379; sql: 118; exp: 91; ansic: 52
file content (133 lines) | stat: -rw-r--r-- 3,957 bytes parent folder | download | duplicates (5)
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
])