mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Add PATH variable.
This commit is contained in:
parent
f29abd73ec
commit
15c48f4efc
2 changed files with 76 additions and 19 deletions
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
|
||||
|
||||
This file is part of the Sortix C Library.
|
||||
|
||||
|
@ -22,31 +22,79 @@
|
|||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(PLATFORM_X86)
|
||||
#define CPUTYPE_STR "i486-sortix"
|
||||
#elif defined(PLATFORM_X64)
|
||||
#define CPUTYPE_STR "x86_64-sortix"
|
||||
#else
|
||||
#error No cputype environmental variable provided here.
|
||||
#endif
|
||||
// TODO: Move this to some generic environment interface!
|
||||
static const char* LookupEnvironment(const char* name, char* const* envp)
|
||||
{
|
||||
size_t equalpos = strcspn(name, "=");
|
||||
if ( name[equalpos] == '=' )
|
||||
return NULL;
|
||||
size_t namelen = equalpos;
|
||||
for ( size_t i = 0; envp[i]; i++ )
|
||||
{
|
||||
if ( strncmp(name, envp[i], namelen) )
|
||||
continue;
|
||||
if ( envp[i][namelen] != '=' )
|
||||
continue;
|
||||
return envp[i] + namelen + 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Note that the only PATH variable in Sortix is the one used here.
|
||||
// TODO: Provide an interface that allows user-space to find out which command
|
||||
// would have been executed (according to PATH) had execvpe been called now.
|
||||
// This is of value to programs such as which(1), instead of repeating much of
|
||||
// this logic there.
|
||||
extern "C" int execvpe(const char* filename, char* const* argv,
|
||||
char* const* envp)
|
||||
{
|
||||
if ( strchr(filename, '/') )
|
||||
const char* path = LookupEnvironment("PATH", envp);
|
||||
// TODO: Should there be a default PATH value?
|
||||
if ( strchr(filename, '/') || !path )
|
||||
return execve(filename, argv, envp);
|
||||
size_t filenamelen = strlen(filename);
|
||||
const char* PATH = "/" CPUTYPE_STR "/bin";
|
||||
size_t pathlen = strlen(PATH);
|
||||
char* pathname = (char*) malloc(filenamelen + 1 + pathlen + 1);
|
||||
if ( !pathname ) { return -1; }
|
||||
stpcpy(stpcpy(stpcpy(pathname, PATH), "/"), filename);
|
||||
int result = execve(pathname, argv, envp);
|
||||
free(pathname);
|
||||
return result;
|
||||
|
||||
// Search each directory in the PATH variable for a suitable file.
|
||||
size_t filename_len = strlen(filename);
|
||||
while ( *path )
|
||||
{
|
||||
size_t len = strcspn(path, ":");
|
||||
if ( !len )
|
||||
{
|
||||
// Sortix doesn't support that the empty string means current
|
||||
// directory. While it does inductively make sense, the common
|
||||
// kernel interfaces such as openat doesn't accept it and software
|
||||
// often just prefix their directories and a colon to PATH without
|
||||
// regard to whether it's already empty. S
|
||||
path++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine the full path to the file if it is in the directory.
|
||||
size_t fullpath_len = len + 1 + filename_len + 1;
|
||||
char* fullpath = (char*) malloc(fullpath_len * sizeof(char));
|
||||
if ( !fullpath )
|
||||
return -1;
|
||||
stpcpy(stpcpy(stpncpy(fullpath, path, len), "/"), filename);
|
||||
if ( (path += len + 1)[0] == ':' )
|
||||
path++;
|
||||
|
||||
execve(fullpath, argv, envp);
|
||||
free(fullpath);
|
||||
|
||||
// TODO: There may be some security concerns here as to whether to
|
||||
// continue or abort execution. For instance, if a directory in the
|
||||
// start of the PATH has permissions set up too restrictively, then
|
||||
// it would never look in the later directories (and you can't execute
|
||||
// anything without absolute paths). And other situations.
|
||||
if ( errno == EACCES )
|
||||
return -1;
|
||||
if ( errno == ENOENT )
|
||||
continue;
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -79,6 +79,15 @@ int main(int /*argc*/, char* /*argv*/[])
|
|||
// we are running.
|
||||
setenv("objtype", getenv("cputype"), 0);
|
||||
|
||||
// Set up the PATH variable.
|
||||
const char* prefix = "/";
|
||||
const char* cputype = getenv("cputype");
|
||||
const char* suffix = "/bin";
|
||||
char* path = new char[strlen(prefix) + strlen(cputype) + strlen(suffix) + 1];
|
||||
stpcpy(stpcpy(stpcpy(path, prefix), cputype), suffix);
|
||||
setenv("PATH", path, 0);
|
||||
delete[] path;
|
||||
|
||||
// Make sure that we have a /tmp directory.
|
||||
mkdir("/tmp", 01777);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue