Skip to content

Commit

Permalink
PR libstdc++/60555 std::system_category() should recognise POSIX errn…
Browse files Browse the repository at this point in the history
…o values

	PR libstdc++/60555
	* src/c++11/system_error.cc
	(system_error_category::default_error_condition): New override to
	check for POSIX errno values.
	* testsuite/19_diagnostics/error_category/generic_category.cc: New
	* testsuite/19_diagnostics/error_category/system_category.cc: New
	test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@263210 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
redi committed Aug 1, 2018
1 parent 40632ac commit 42e4d3a
Show file tree
Hide file tree
Showing 4 changed files with 411 additions and 0 deletions.
10 changes: 10 additions & 0 deletions libstdc++-v3/ChangeLog
@@ -1,3 +1,13 @@
2018-08-01 Jonathan Wakely <jwakely@redhat.com>

PR libstdc++/60555
* src/c++11/system_error.cc
(system_error_category::default_error_condition): New override to
check for POSIX errno values.
* testsuite/19_diagnostics/error_category/generic_category.cc: New
* testsuite/19_diagnostics/error_category/system_category.cc: New
test.

2018-07-31 Jonathan Wakely <jwakely@redhat.com>

PR libstdc++/86751
Expand Down
255 changes: 255 additions & 0 deletions libstdc++-v3/src/c++11/system_error.cc
Expand Up @@ -29,6 +29,7 @@
#include <system_error>
#include <bits/functexcept.h>
#include <limits>
#include <errno.h>
#undef __sso_string

namespace
Expand Down Expand Up @@ -65,6 +66,260 @@ namespace
// _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc)
return string(strerror(i));
}

virtual std::error_condition
default_error_condition(int ev) const noexcept
{
switch (ev)
{
// List of errno macros from [cerrno.syn].
// C11 only defines EDOM, EILSEQ and ERANGE, the rest are from POSIX.
// They expand to integer constant expressions with type int,
// and distinct positive values, suitable for use in #if directives.
// POSIX adds more macros (but they're not defined on all targets,
// see config/os/*/error_constants.h), and POSIX allows
// EAGAIN == EWOULDBLOCK and ENOTSUP == EOPNOTSUPP.

#ifdef E2BIG
case E2BIG:
#endif
#ifdef EACCES
case EACCES:
#endif
#ifdef EADDRINUSE
case EADDRINUSE:
#endif
#ifdef EADDRNOTAVAIL
case EADDRNOTAVAIL:
#endif
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT:
#endif
#ifdef EAGAIN
case EAGAIN:
#endif
#ifdef EALREADY
case EALREADY:
#endif
#ifdef EBADF
case EBADF:
#endif
#ifdef EBADMSG
case EBADMSG:
#endif
#ifdef EBUSY
case EBUSY:
#endif
#ifdef ECANCELED
case ECANCELED:
#endif
#ifdef ECHILD
case ECHILD:
#endif
#ifdef ECONNABORTED
case ECONNABORTED:
#endif
#ifdef ECONNREFUSED
case ECONNREFUSED:
#endif
#ifdef ECONNRESET
case ECONNRESET:
#endif
#ifdef EDEADLK
case EDEADLK:
#endif
#ifdef EDESTADDRREQ
case EDESTADDRREQ:
#endif
case EDOM:
#ifdef EEXIST
case EEXIST:
#endif
#ifdef EFAULT
case EFAULT:
#endif
#ifdef EFBIG
case EFBIG:
#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH:
#endif
#ifdef EIDRM
case EIDRM:
#endif
case EILSEQ:
#ifdef EINPROGRESS
case EINPROGRESS:
#endif
#ifdef EINTR
case EINTR:
#endif
#ifdef EINVAL
case EINVAL:
#endif
#ifdef EIO
case EIO:
#endif
#ifdef EISCONN
case EISCONN:
#endif
#ifdef EISDIR
case EISDIR:
#endif
#ifdef ELOOP
case ELOOP:
#endif
#ifdef EMFILE
case EMFILE:
#endif
#ifdef EMLINK
case EMLINK:
#endif
#ifdef EMSGSIZE
case EMSGSIZE:
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG:
#endif
#ifdef ENETDOWN
case ENETDOWN:
#endif
#ifdef ENETRESET
case ENETRESET:
#endif
#ifdef ENETUNREACH
case ENETUNREACH:
#endif
#ifdef ENFILE
case ENFILE:
#endif
#ifdef ENOBUFS
case ENOBUFS:
#endif
#ifdef ENODATA
case ENODATA:
#endif
#ifdef ENODEV
case ENODEV:
#endif
#ifdef ENOENT
case ENOENT:
#endif
#ifdef ENOEXEC
case ENOEXEC:
#endif
#ifdef ENOLCK
case ENOLCK:
#endif
#ifdef ENOLINK
case ENOLINK:
#endif
#ifdef ENOMEM
case ENOMEM:
#endif
#ifdef ENOMSG
case ENOMSG:
#endif
#ifdef ENOPROTOOPT
case ENOPROTOOPT:
#endif
#ifdef ENOSPC
case ENOSPC:
#endif
#ifdef ENOSR
case ENOSR:
#endif
#ifdef ENOSTR
case ENOSTR:
#endif
#ifdef ENOSYS
case ENOSYS:
#endif
#ifdef ENOTCONN
case ENOTCONN:
#endif
#ifdef ENOTDIR
case ENOTDIR:
#endif
#ifdef ENOTEMPTY
case ENOTEMPTY:
#endif
#ifdef ENOTRECOVERABLE
case ENOTRECOVERABLE:
#endif
#ifdef ENOTSOCK
case ENOTSOCK:
#endif
#ifdef ENOTSUP
case ENOTSUP:
#endif
#ifdef ENOTTY
case ENOTTY:
#endif
#ifdef ENXIO
case ENXIO:
#endif
#if defined EOPNOTSUPP && (!defined ENOTSUP || EOPNOTSUPP != ENOTSUP)
case EOPNOTSUPP:
#endif
#ifdef EOVERFLOW
case EOVERFLOW:
#endif
#ifdef EOWNERDEAD
case EOWNERDEAD:
#endif
#ifdef EPERM
case EPERM:
#endif
#ifdef EPIPE
case EPIPE:
#endif
#ifdef EPROTO
case EPROTO:
#endif
#ifdef EPROTONOSUPPORT
case EPROTONOSUPPORT:
#endif
#ifdef EPROTOTYPE
case EPROTOTYPE:
#endif
case ERANGE:
#ifdef EROFS
case EROFS:
#endif
#ifdef ESPIPE
case ESPIPE:
#endif
#ifdef ESRCH
case ESRCH:
#endif
#ifdef ETIME
case ETIME:
#endif
#ifdef ETIMEDOUT
case ETIMEDOUT:
#endif
#ifdef ETXTBSY
case ETXTBSY:
#endif
#if defined EWOULDBLOCK && (!defined EAGAIN || EWOULDBLOCK != EAGAIN)
case EWOULDBLOCK:
#endif
#ifdef EXDEV
case EXDEV:
#endif
return std::error_condition(ev, std::generic_category());

/* Additional system-dependent mappings from non-standard error codes
* to one of the POSIX values above would go here, e.g.
case EBLAH:
return std::error_condition(EINVAL, std::generic_category());
*/

default:
return std::error_condition(ev, std::system_category());
}
}
};

const generic_error_category generic_category_instance{};
Expand Down
@@ -0,0 +1,69 @@
// Copyright (C) 2018 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.

// { dg-do run { target c++11 } }

#include <system_error>
#include <locale>
#include <testsuite_hooks.h>

void
test01()
{
const char* name = std::generic_category().name();
VERIFY( name == std::string("generic") );
}

void
test02()
{
const std::error_category& cat = std::generic_category();
std::error_condition cond;

cond = cat.default_error_condition(EBADF);
VERIFY( cond.value() == EBADF );
VERIFY( cond == std::errc::bad_file_descriptor );
VERIFY( cond.category() == std::generic_category() );
cond = cat.default_error_condition(EACCES);
VERIFY( cond.value() == EACCES );
VERIFY( cond == std::errc::permission_denied );
VERIFY( cond.category() == std::generic_category() );

// PR libstdc++/60555
VERIFY( std::error_code(EBADF, cat) == std::errc::bad_file_descriptor );
VERIFY( std::error_code(EACCES, cat) == std::errc::permission_denied );
}

void
test03()
{
// set "C" locale to get expected message
auto loc = std::locale::global(std::locale::classic());

std::string msg = std::generic_category().message(EBADF);
VERIFY( msg.find("file") != std::string::npos );

std::locale::global(loc);
}

int
main()
{
test01();
test02();
test03();
}

0 comments on commit 42e4d3a

Please sign in to comment.