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