OSDN Git Service

2002-01-28 Paolo Carlini <pcarlini@unitus.it>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / testsuite / 27_io / filebuf_members.cc
1 // Copyright (C) 2001, 2002 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library.  This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 2, or (at your option)
7 // any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING.  If not, write to the Free
16 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 // USA.
18
19 // 27.8.1.3 filebuf member functions
20 // @require@ %-*.tst %-*.txt
21 // @diff@ %-*.tst %-*.txt
22
23 // various tests for filebuf::open() and filebuf::close() including
24 // the non-portable functionality in the libstdc++-v3 IO library
25
26 #include <iostream>
27 #include <fstream>
28 #include <unistd.h>
29 #include <signal.h>
30 #include <fcntl.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <testsuite_hooks.h>
34
35 const char name_01[] = "filebuf_members-1.tst";
36 const char name_02[] = "filebuf_members-1.txt";
37
38 // Test member functions.
39 void test_01() 
40 {
41   bool                  test = true;
42   const char* name_03 = "filebuf_members-3"; // empty file, need to create
43
44   std::filebuf fb_01; // in 
45   std::filebuf fb_02; // out
46   std::filebuf fb_03; // in | out
47
48   // bool is_open()
49   VERIFY( !fb_01.is_open() );
50   VERIFY( !fb_02.is_open() );
51   VERIFY( !fb_03.is_open() );
52
53   // filebuf_type* open(const char* __s, ios_base::openmode __mode)
54   fb_01.open(name_01, std::ios_base::in | std::ios_base::ate);
55   fb_02.open(name_02, std::ios_base::in | std::ios_base::out 
56              | std::ios_base::trunc);
57   // Try to open two different files without closing the first:
58   // Should keep the old file attached, and disregard attempt to overthrow.
59   fb_02.open(name_03, std::ios_base::in | std::ios_base::out);
60   fb_03.open(name_03, std::ios_base::out | std::ios_base::trunc);
61   VERIFY( fb_01.is_open() );
62   VERIFY( fb_02.is_open() );
63   VERIFY( fb_03.is_open() );
64
65   // filebuf_type* close()
66   fb_01.close();
67   fb_02.close();
68   fb_03.close();
69   VERIFY( !fb_01.is_open() );
70   VERIFY( !fb_02.is_open() );
71   VERIFY( !fb_03.is_open() );
72 }
73
74 // Verify that std::filebuf doesn't close files that it didn't open
75 // when using the following std::filebuf ctor:
76 //
77 //      std::filebuf(__c_file_type*  __f,
78 //                   ios_base::openmode __mode,
79 //                   int_type  __s);
80 //
81 // Thanks to "George T. Talbot" <george@moberg.com> for uncovering
82 // this bug/situation. 
83 void test_02()
84 {
85   bool test = true;
86   int close_num;
87
88   // read (ext)
89   FILE* f2 = fopen(name_01, "r");
90   VERIFY( f2 != NULL );
91   {
92     std::filebuf fb(f2, std::ios_base::in, 512);
93   }
94   close_num = fclose(f2);
95   VERIFY( close_num == 0 );
96
97
98   // read (standard)
99   FILE* f = fopen(name_01, "r");
100   VERIFY( f != NULL );
101   {
102     std::ifstream ifstream1(name_01);
103     VERIFY( ifstream1.is_open() );
104     std::ios_base::iostate st01 = ifstream1.rdstate();
105     VERIFY( st01 == std::ios_base::goodbit );
106   }
107   close_num = fclose(f);
108   VERIFY( close_num == 0 );
109 }
110
111 void test_03()
112 {
113   bool test = true;
114   int first_fd = ::open(name_01, O_RDONLY);
115   VERIFY( first_fd != -1 );
116   FILE* first_file = ::fdopen(first_fd, "r");
117   VERIFY( first_file != NULL );
118   std::filebuf fb (first_file, std::ios_base::in);
119
120   int second_fd = fb.fd();
121
122   VERIFY( first_fd == second_fd );
123 }
124
125 // libstdc++/2913, libstdc++/4879
126 // John Fardo  <jfardo@laurelnetworks.com>, Brad Garcia <garsh@attbi.com>
127 void
128 test_04()
129 {
130   signal(SIGPIPE, SIG_IGN);
131   
132   if (0 != mkfifo("xxx", S_IRWXU))
133     {
134       std::cerr << "failed to creat fifo" << std::endl;
135       exit(-1);
136     }
137   
138   int fval = fork();
139   if (fval == -1)
140     {
141       std::cerr << "failed to fork" << std::endl;
142       unlink("xxx");
143       exit(-1);
144     }
145   else if (fval == 0)
146     {
147       std::ifstream ifs("xxx");
148       sleep(1);
149       ifs.close();
150       exit(0);
151     }
152
153   std::ofstream ofs("xxx");
154   sleep(2);
155   ofs.put('t');
156
157   /*
158    * ISO/IED 14882:1998(E) 27.8.1.10.4
159    *
160    * void close();
161    *
162    * Effects:  Calls rdbuf()->close() and, if that function fails
163    * (returns a null pointer), calls setstate(failbit)...
164    */
165   ofs.close();
166   if (!(ofs.rdstate() & std::ios::failbit))
167     {
168       std::cerr << "fail bit was not set!" << std::endl;
169       unlink("xxx");
170       exit(-1);
171     }
172
173   unlink("xxx");
174   exit(0);
175 }
176
177 // Charles Leggett <CGLeggett@lbl.gov>
178 void test_05()
179 {
180   bool test = true;
181
182   std::fstream scratch_file;
183
184   scratch_file.open("SCRATCH", std::ios::out);
185   scratch_file.close();
186
187   scratch_file.open("SCRATCH", std::ios::in);
188   scratch_file.close();
189
190   VERIFY(scratch_file);
191 }
192
193 int
194 main()
195 {
196   test_01();
197   test_02();
198   test_03();
199   test_04();
200   test_05();
201   return 0;
202 }
203
204