if (!getcwd(cwd, MAXPGPATH))
{
+ int save_errno = errno;
+
log_error(_("could not identify current directory: %s"),
- strerror(errno));
+ strerror(save_errno));
return -1;
}
*/
if (!getcwd(orig_wd, MAXPGPATH))
{
+ int save_errno = errno;
+
log_error(_("could not identify current directory: %s"),
- strerror(errno));
+ strerror(save_errno));
return -1;
}
*lsep = '\0';
if (chdir(path) == -1)
{
- log_error4(_("could not change directory to \"%s\": %s"), path, strerror(errno));
+ int save_errno = errno;
+
+ log_error4(_("could not change directory to \"%s\": %s"),
+ path, strerror(save_errno));
return -1;
}
fname = lsep + 1;
if (!getcwd(path, MAXPGPATH))
{
+ int save_errno = errno;
+
log_error(_("could not identify current directory: %s"),
- strerror(errno));
+ strerror(save_errno));
return -1;
}
join_path_components(path, path, link_buf);
if (chdir(orig_wd) == -1)
{
- log_error4(_("could not change directory to \"%s\": %s"), orig_wd, strerror(errno));
+ int save_errno = errno;
+
+ log_error4(_("could not change directory to \"%s\": %s"),
+ orig_wd, strerror(save_errno));
return -1;
}
#endif /* HAVE_READLINK */
if (exitstatus == -1)
{
/* pclose() itself failed, and hopefully set errno */
- log_error(_("pclose failed: %s"), strerror(errno));
+ int save_errno = errno;
+
+ log_error(_("pclose failed: %s"),
+ strerror(save_errno));
}
else
{
/* SQLSTATE codes for errors are defined in a separate file */
#include "utils/errcodes.h"
+/*
+ * Provide a way to prevent "errno" from being accidentally used inside an
+ * elog() or ereport() invocation. Since we know that some operating systems
+ * define errno as something involving a function call, we'll put a local
+ * variable of the same name as that function in the local scope to force a
+ * compile error. On platforms that don't define errno in that way, nothing
+ * happens, so we get no warning ... but we can live with that as long as it
+ * happens on some popular platforms.
+ */
+#if defined(errno) && defined(__linux__)
+#define pg_prevent_errno_in_scope() int __errno_location pg_attribute_unused()
+#elif defined(errno) && (defined(__darwin__) || defined(__freebsd__))
+#define pg_prevent_errno_in_scope() int __error pg_attribute_unused()
+#else
+#define pg_prevent_errno_in_scope()
+#endif
+
/*----------
* New-style error reporting API: to be used in this way:
#ifdef HAVE__BUILTIN_CONSTANT_P
#define ereport_domain(elevel, domain, rest) \
do { \
+ pg_prevent_errno_in_scope(); \
if (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \
errfinish rest; \
if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \
#define ereport_domain(elevel, domain, rest) \
do { \
const int elevel_ = (elevel); \
+ pg_prevent_errno_in_scope(); \
if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \
errfinish rest; \
if (elevel_ >= ERROR) \
#ifdef HAVE__BUILTIN_CONSTANT_P
#define elog(elevel, ...) \
do { \
+ pg_prevent_errno_in_scope(); \
elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \
elog_finish(elevel, __VA_ARGS__); \
if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \
#else /* !HAVE__BUILTIN_CONSTANT_P */
#define elog(elevel, ...) \
do { \
+ pg_prevent_errno_in_scope(); \
elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \
{ \
const int elevel_ = (elevel); \