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:
parent
6ae95945aa
commit
3048e4b9f5
1 changed files with 19 additions and 18 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue