1// { dg-require-fork "" }
2// { dg-require-mkfifo "" }
3
4// 2001-05-21 Benjamin Kosnik  <bkoz@redhat.com>
5
6// Copyright (C) 2001-2015 Free Software Foundation, Inc.
7//
8// This file is part of the GNU ISO C++ Library.  This library is free
9// software; you can redistribute it and/or modify it under the
10// terms of the GNU General Public License as published by the
11// Free Software Foundation; either version 3, or (at your option)
12// any later version.
13
14// This library is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17// GNU General Public License for more details.
18
19// You should have received a copy of the GNU General Public License along
20// with this library; see the file COPYING3.  If not see
21// <http://www.gnu.org/licenses/>.
22
23// 27.8.1.4 Overridden virtual functions
24
25#include <fstream>
26#include <cstdlib>
27#include <unistd.h>
28#include <signal.h>
29#include <fcntl.h>
30#include <sys/types.h>
31#include <sys/stat.h>
32
33// No asserts, avoid leaking the semaphores if a VERIFY fails.
34#undef _GLIBCXX_ASSERT
35
36#include <testsuite_hooks.h>
37
38class UnderBuf : public std::filebuf
39{
40public:
41  int_type
42  pub_underflow()
43  { return underflow(); }
44
45  std::streamsize
46  pub_showmanyc()
47  { return showmanyc(); }
48};
49
50// libstdc++/10097
51// filebuf::underflow drops characters.
52bool test16()
53{
54  using namespace std;
55  using namespace __gnu_test;
56  bool test __attribute__((unused)) = true;
57
58  const char* name = "tmp_fifo1";
59
60  signal(SIGPIPE, SIG_IGN);
61  unlink(name);
62
63  if (0 != mkfifo(name, S_IRWXU))
64    {
65      VERIFY( false );
66    }
67
68  semaphore s1, s2;
69  int fval = fork();
70  if (fval == -1)
71    {
72      unlink(name);
73      VERIFY( false );
74    }
75  else if (fval == 0)
76    {
77      filebuf fbout;
78      fbout.open(name, ios_base::in|ios_base::out);
79      VERIFY( fbout.is_open() );
80      fbout.sputn("0123456789", 10);
81      fbout.pubsync();
82      s1.wait();
83      fbout.close();
84      s2.signal();
85      exit(0);
86    }
87
88  UnderBuf fb;
89  fb.open(name, ios_base::in);
90
91  fb.sgetc();
92  streamsize n = fb.pub_showmanyc();
93
94  while (n > 0)
95    {
96      --n;
97
98      UnderBuf::int_type c = fb.pub_underflow();
99      VERIFY( c != UnderBuf::traits_type::eof() );
100
101      fb.sbumpc();
102    }
103
104  fb.close();
105  s1.signal();
106  s2.wait();
107
108  return test;
109}
110
111int main()
112{
113  return !test16();
114}
115