1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 08:07:44 +00:00

LibC: Make sure we always return the intended errno from execvpe().

This commit is contained in:
Andreas Kling 2019-07-25 15:21:50 +02:00
parent 6ae95945aa
commit 3048e4b9f5

View file

@ -1,4 +1,5 @@
#include <AK/AKString.h> #include <AK/AKString.h>
#include <AK/ScopedValueRollback.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <Kernel/Syscall.h> #include <Kernel/Syscall.h>
#include <assert.h> #include <assert.h>
@ -53,28 +54,28 @@ int execve(const char* filename, char* const argv[], char* const envp[])
int execvpe(const char* filename, char* const argv[], char* const envp[]) int execvpe(const char* filename, char* const argv[], char* const envp[])
{ {
// NOTE: We scope everything here to make sure that setting errno on exit is sticky. ScopedValueRollback errno_rollback(errno);
{ int rc = execve(filename, argv, envp);
int rc = execve(filename, argv, envp); if (rc < 0 && errno != ENOENT) {
errno_rollback.set_override_rollback_value(errno);
dbg() << "execvpe() failed on first with" << strerror(errno);
return rc;
}
String path = getenv("PATH");
if (path.is_empty())
path = "/bin:/usr/bin";
auto parts = path.split(':');
for (auto& part : parts) {
auto candidate = String::format("%s/%s", part.characters(), filename);
int rc = execve(candidate.characters(), argv, envp);
if (rc < 0 && errno != ENOENT) { if (rc < 0 && errno != ENOENT) {
dbg() << "execvpe() failed on first with" << strerror(errno); errno_rollback.set_override_rollback_value(errno);
dbg() << "execvpe() failed on attempt (" << candidate << ") with " << strerror(errno);
return rc; return rc;
} }
String path = getenv("PATH");
if (path.is_empty())
path = "/bin:/usr/bin";
auto parts = path.split(':');
for (auto& part : parts) {
auto candidate = String::format("%s/%s", part.characters(), filename);
int rc = execve(candidate.characters(), argv, envp);
if (rc < 0 && errno != ENOENT) {
dbg() << "execvpe() failed on attempt (" << candidate << ") with " << strerror(errno);
return rc;
}
}
dbg() << "execvpe() leaving :(";
} }
errno = ENOENT; errno_rollback.set_override_rollback_value(ENOENT);
dbg() << "execvpe() leaving :(";
return -1; return -1;
} }