diff --git a/ChangeLog b/ChangeLog
index 6c9172b77..0a83ee93f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-06-15 Peter Stephenson
+
+ * 43008: Src/otpions.c: combine suggestion from Sebastain to
+ silence warnings for double setgid/setuid with suggestion
+ from Eitan to put setgid first.
+
2018-06-13 dana
* 42992: Completion/Unix/Command/_bash: Fix minor escaping bug
diff --git a/Src/options.c b/Src/options.c
index 590652ea9..600b649e4 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -769,15 +769,32 @@ dosetopt(int optno, int value, int force, char *new_opts)
} else if(optno == PRIVILEGED && !value) {
/* unsetting PRIVILEGED causes the shell to make itself unprivileged */
#ifdef HAVE_SETUID
- setuid(getuid());
- setgid(getgid());
- if (setuid(getuid())) {
- zwarn("failed to change user ID: %e", errno);
- return -1;
- } else if (setgid(getgid())) {
+ int ignore_err;
+ errno = 0;
+ /*
+ * Set the GID first as if we set the UID to non-privileged it
+ * might be impossible to restore the GID.
+ *
+ * Some OSes (possibly no longer around) have been known to
+ * fail silently the first time, so we attempt the change twice.
+ * If it fails we are guaranteed to pick this up the second
+ * time, so ignore the first time.
+ *
+ * Some versions of gcc make it hard to ignore the results the
+ * first time, hence the following. (These are probably not
+ * systems that require the doubled calls.)
+ */
+ ignore_err = setgid(getgid());
+ (void)ignore_err;
+ ignore_err = setuid(getuid());
+ (void)ignore_err;
+ if (setgid(getgid())) {
zwarn("failed to change group ID: %e", errno);
return -1;
- }
+ } else if (setuid(getuid())) {
+ zwarn("failed to change user ID: %e", errno);
+ return -1;
+ }
#else
zwarn("setuid not available");
return -1;