You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2008/02/13 03:08:47 UTC

svn commit: r627221 - /stdcxx/trunk/tests/regress/27.filebuf.members.stdcxx-308.cpp

Author: sebor
Date: Tue Feb 12 18:08:45 2008
New Revision: 627221

URL: http://svn.apache.org/viewvc?rev=627221&view=rev
Log:
2008-02-12  Martin Sebor  <se...@roguewave.com>

	* tests/regress/27.filebuf.members.stdcxx-308.cpp: Regression
	test exercising STDCXX-308.

Added:
    stdcxx/trunk/tests/regress/27.filebuf.members.stdcxx-308.cpp   (with props)

Added: stdcxx/trunk/tests/regress/27.filebuf.members.stdcxx-308.cpp
URL: http://svn.apache.org/viewvc/stdcxx/trunk/tests/regress/27.filebuf.members.stdcxx-308.cpp?rev=627221&view=auto
==============================================================================
--- stdcxx/trunk/tests/regress/27.filebuf.members.stdcxx-308.cpp (added)
+++ stdcxx/trunk/tests/regress/27.filebuf.members.stdcxx-308.cpp Tue Feb 12 18:08:45 2008
@@ -0,0 +1,173 @@
+/***********************************************************************
+ *
+ * 27.filebuf.members.stdcxx-308.cpp - regression test for STDCXX-308
+ *   http://issues.apache.org/jira/browse/STDCXX-308
+ *
+ * $Id$
+ *
+ ***********************************************************************
+ *
+ * Licensed to the Apache Software  Foundation (ASF) under one or more
+ * contributor  license agreements.  See  the NOTICE  file distributed
+ * with  this  work  for  additional information  regarding  copyright
+ * ownership.   The ASF  licenses this  file to  you under  the Apache
+ * License, Version  2.0 (the  "License"); you may  not use  this file
+ * except in  compliance with the License.   You may obtain  a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the  License is distributed on an  "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
+ * implied.   See  the License  for  the  specific language  governing
+ * permissions and limitations under the License.
+ *
+ * Copyright 2008 Rogue Wave Software, Inc.
+ * 
+ ***********************************************************************
+ *
+ * Test description:
+ *  Sets a maxinum file size limit, forces filebuf to exceed the limit,
+ *  causing the class dtor to fail to flush the excess data. Verifies
+ *  that the dtor closes the associated file descriptor regardless of
+ *  the failure as required by the resolution of LWG issue 622:
+ *  http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#622
+ *
+ ***********************************************************************/
+
+#include <cassert>   // for assert()
+#include <cstdio>    // for remove(), size_t
+#include <fstream>   // for filebuf
+
+#if !defined (_WIN32) || defined (__CYGWIN__)
+#  include <sys/resource.h>   // for getrlimit(), rlim_t
+#  include <unistd.h>         // for close(), write(), ssize_t
+#endif   // !_WIN32 || __CYGWIN__
+
+
+int write_bytes (const char *fname, std::size_t nbytes)
+{
+    std::filebuf fb;
+
+    if (   0 == fb.pubsetbuf (0, nbytes + 1)
+        || 0 == fb.open (fname, std::ios::out))
+        return -1;
+
+#if defined (_RWSTD_VER) && !defined (_RWSTD_NO_EXT_FILEBUF)
+
+    // use the filebuf::fd() extension to get the filebuf's
+    // associated file descriptor
+    const int fd = fb.fd ();
+
+#else   // if defined (RWSTD_NO_EXT_FILEBUF)
+
+    // assume fd is the next available file descriptor after
+    // STDIN_FILENO, _FILENO_STDOUT, and STDERR_FILENO
+    const int fd = 3;
+
+#endif   // RWSTD_NO_EXT_FILEBUF
+
+    if (0 < fd) {
+        // fill up the filebuf's character buffer without
+        // overflowing
+        for (std::size_t i = 0; i != nbytes; ++i)
+            fb.sputc ('*');
+    }
+
+    // have filebuf dtor try to flush the object's character
+    // buffer and expect it to fail (and flush out only the
+    // number specified by RLIMIT_FSIZE)
+
+    // return the file descriptor to the caller so that it can
+    // verify that it has been closed
+    return fd;
+}
+
+
+int main ()
+{
+#if !defined (_WIN32) || defined (__CYGWIN__)
+
+    const char fname[] = "testfile.text";
+
+    std::remove (fname);
+
+    rlimit rl;
+    int status;
+
+    // retrieve the current file size limits
+    status = getrlimit (RLIMIT_FSIZE, &rl);
+
+    if (status) {
+        std::perror ("getrlimit(RLIMIT_FSIZE, ...)");
+        return 1;
+    }
+
+    // uncomment for debugging
+    // std::printf ("file size limits = %ld, %ld\n",
+    //              long (rl.rlim_cur), long (rl.rlim_max));
+
+    const rlim_t rlim_cur_saved = rl.rlim_cur;
+    rl.rlim_cur = 32;
+
+    // set a new file size limit
+    status = setrlimit (RLIMIT_FSIZE, &rl);
+    if (status) {
+        std::perror ("setrlimit(RLIMIT_FSIZE, ...)");
+        return 1;
+    }
+
+    // uncomment for debugging
+    // status = getrlimit (RLIMIT_FSIZE, &rl);
+
+    // if (status) {
+    //     std::perror ("getrlimit(RLIMIT_FSIZE, ...)");
+    //     return 1;
+    // }
+    // std::printf ("file size limits = %ld, %ld\n",
+    //              long (rl.rlim_cur), long (rl.rlim_max));
+
+    // try to write more bytes than the current soft limit using
+    // filebuf, expecting the class dtor to fail but close the
+    // associated file descriptor
+    const int fd = write_bytes (fname, std::size_t (rl.rlim_cur + 1));
+    if (fd < 0) {
+        std::perror ("filebuf::~filebuf()");
+        std::remove (fname);
+        return 1;
+    }
+
+    // restore the previous soft limit
+    rl.rlim_cur = rlim_cur_saved;
+
+    status = setrlimit (RLIMIT_FSIZE, &rl);
+    if (status) {
+        std::perror ("setrlimit(RLIMIT_FSIZE, ...)");
+
+        close (fd);
+
+        std::remove (fname);
+        return 1;
+    }
+
+    // try to write to the filebuf's file descriptor, expecting
+    // the write() to fail
+    const ssize_t nwrote = write (fd, "<", 1);
+
+    assert (-1 == nwrote);
+
+    // close file descriptor before removing the file (it's okay
+    // if the call fails because the fd has already been closed)
+    close (fd);
+    std::remove (fname);
+
+#else   // Windows
+
+    // See about implementing using SetFileValidData():
+    // http://msdn.microsoft.com/en-us/library/aa365544(VS.85).aspx
+
+#endif   // !_WIN32 || __CYGWIN__
+
+    return 0;
+}

Propchange: stdcxx/trunk/tests/regress/27.filebuf.members.stdcxx-308.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: stdcxx/trunk/tests/regress/27.filebuf.members.stdcxx-308.cpp
------------------------------------------------------------------------------
    svn:keywords = Id