1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

- execve() now actually works!

git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@15118 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
Olaf Barthel
2006-08-02 11:07:57 +00:00
parent cdfe0dad6f
commit 5828c6cdab

View File

@ -1,5 +1,5 @@
/*
* $Id: unistd_execve.c,v 1.4 2006-08-02 08:00:27 obarthel Exp $
* $Id: unistd_execve.c,v 1.5 2006-08-02 11:07:57 obarthel Exp $
*
* :ts=4
*
@ -77,7 +77,10 @@ find_resident_command(const char * command_name)
a more sophisticated arbitration method for this yet... */
Forbid();
seg = FindSegment((STRPTR)command_name,NULL,0);
seg = FindSegment((STRPTR)command_name,NULL,FALSE);
if(seg == NULL)
seg = FindSegment((STRPTR)command_name,NULL,TRUE);
if(seg != NULL)
{
/* Check if that's a disable command or something else. */
@ -167,11 +170,12 @@ get_first_script_line(const char * path,char ** line_ptr)
line feed and carriage return characters. */
while(script_line_length > 0 && isspace(script_line[script_line_length-1]))
script_line_length--;
script_line[script_line_length] = '\0';
}
script_line[script_line_length] = '\0';
(*line_ptr) = script_line;
script_line = NULL;
result = 0;
@ -271,6 +275,13 @@ find_command(const char * path,struct program_info ** result_ptr)
__set_errno(ENOENT);
goto out;
}
pi->program_name = strdup(path);
if(pi->program_name == NULL)
{
__set_errno(ENOMEM);
goto out;
}
}
else
{
@ -396,38 +407,37 @@ find_command(const char * path,struct program_info ** result_ptr)
free(script_line);
script_line = NULL;
}
}
/* If that still didn't work, check if the file has
the script bit set */
if(error == 0 && !done)
/* If that still didn't work, check if the file has
the "script" protection bit set. */
if(error == 0 && !done)
{
BPTR file_lock;
file_lock = Lock(relative_path,SHARED_LOCK);
if(file_lock != ZERO)
{
BPTR file_lock;
D_S(struct FileInfoBlock,fib);
file_lock = Lock(relative_path,SHARED_LOCK);
if(file_lock != ZERO)
if(Examine(file_lock,fib))
{
D_S(struct FileInfoBlock,fib);
if(Examine(file_lock,fib))
if(fib->fib_Protection & FIBF_SCRIPT)
{
if(fib->fib_Protection & FIBF_SCRIPT)
{
/* If it's an AmigaDOS script, remember
to run it through the Execute command */
pi->interpreter_name = strdup("Execute");
if(pi->interpreter_name != NULL)
done = TRUE;
else
error = ENOMEM;
}
/* That's an AmigaDOS script */
pi->interpreter_name = strdup("Execute");
if(pi->interpreter_name != NULL)
done = TRUE;
else
error = ENOMEM;
}
else
{
error = __translate_io_error_to_errno(IoErr());
}
UnLock(file_lock);
}
else
{
error = __translate_io_error_to_errno(IoErr());
}
UnLock(file_lock);
}
}
@ -438,6 +448,9 @@ find_command(const char * path,struct program_info ** result_ptr)
SetFileSysTask(file_system);
if(error == 0 && !done)
error = ENOENT;
if(error != 0)
{
__set_errno(error);
@ -446,6 +459,9 @@ find_command(const char * path,struct program_info ** result_ptr)
}
(*result_ptr) = pi;
pi = NULL;
result = 0;
out:
@ -551,7 +567,7 @@ get_arg_string_length(char *const argv[])
static void
build_arg_string(char *const argv[],char * arg_string)
{
BOOL first_char = FALSE;
BOOL first_char = TRUE;
size_t i,j,len;
char * s;
@ -573,10 +589,20 @@ build_arg_string(char *const argv[],char * arg_string)
for(j = 0 ; j < len ; j++)
{
if(s[j] == '\"' || s[j] == '*' || s[j] == '\n')
if(s[j] == '\"' || s[j] == '*')
{
(*arg_string++) = '*';
(*arg_string++) = s[j];
(*arg_string++) = s[j];
}
else if(s[j] == '\n')
{
(*arg_string++) = '*';
(*arg_string++) = 'N';
}
else
{
(*arg_string++) = s[j];
}
}
(*arg_string++) = '\"';
@ -607,7 +633,6 @@ build_arg_string(char *const argv[],char * arg_string)
int
execve(const char *path, char *const argv[], char *const envp[])
{
struct Process * this_process = (struct Process *)FindTask(NULL);
char old_program_name[256];
int result = -1;
struct program_info * pi;
@ -617,7 +642,6 @@ execve(const char *path, char *const argv[], char *const envp[])
BOOL success = FALSE;
BOOL clean_up_env = FALSE;
BPTR old_dir;
LONG rc;
/* We begin by trying to find the command to execute */
if(find_command((char *)path,&pi) != 0)
@ -631,6 +655,7 @@ execve(const char *path, char *const argv[], char *const envp[])
if(pi->interpreter_name != NULL)
{
struct program_info * pi_interpreter;
size_t path_len = strlen(path);
/* Now try to find the command corresponding to the
interpreter given */
@ -658,35 +683,45 @@ execve(const char *path, char *const argv[], char *const envp[])
arguments */
if(pi->interpreter_args != NULL)
{
arg_string_len = strlen(pi->interpreter_args);
size_t interpreter_args_len = strlen(pi->interpreter_args);
arg_string = malloc(arg_string_len + 1 + parameter_string_len + 1 + 1);
arg_string = malloc(interpreter_args_len + 1 + path_len + 1 + parameter_string_len + 1 + 1);
if(arg_string == NULL)
{
__set_errno(ENOMEM);
goto out;
}
memcpy(arg_string,pi->interpreter_args,arg_string_len);
memcpy(arg_string,pi->interpreter_args,interpreter_args_len);
arg_string_len = interpreter_args_len;
arg_string[arg_string_len++] = ' ';
if(parameter_string_len > 0)
arg_string[arg_string_len++] = ' ';
memcpy(&arg_string[arg_string_len],path,path_len);
arg_string_len += path_len;
arg_string[arg_string_len++] = ' ';
}
else
{
arg_string = malloc(parameter_string_len + 1 + 1);
arg_string = malloc(path_len + 1 + parameter_string_len + 1 + 1);
if(arg_string == NULL)
{
__set_errno(ENOMEM);
goto out;
}
memcpy(arg_string,path,path_len);
arg_string_len = path_len;
arg_string[arg_string_len++] = ' ';
}
}
else
{
arg_string = malloc(parameter_string_len + 1 + 1);
}
/* If that didn't work, we quit here */
if(arg_string == NULL)
{
__set_errno(ENOMEM);
goto out;
if(arg_string == NULL)
{
__set_errno(ENOMEM);
goto out;
}
}
/* Any command parameters to take care of? */
@ -717,23 +752,22 @@ execve(const char *path, char *const argv[], char *const envp[])
/* Change the command's home directory, so that "PROGDIR:"
can be used */
old_dir = this_process->pr_HomeDir;
this_process->pr_HomeDir = pi->home_dir;
old_dir = SetProgramDir(pi->home_dir);
/* Reset the break signal before the program starts */
SetSignal(0,SIGBREAKF_CTRL_C);
/* Now try to run the program with the accumulated parameters */
rc = RunCommand((pi->resident_command != NULL) ? pi->resident_command->seg_Seg : pi->segment_list,Cli()->cli_DefaultStack * sizeof(LONG),arg_string,arg_string_len);
result = RunCommand((pi->resident_command != NULL) ? pi->resident_command->seg_Seg : pi->segment_list,Cli()->cli_DefaultStack * sizeof(LONG),arg_string,arg_string_len);
/* Restore the home directory */
this_process->pr_HomeDir = old_dir;
SetProgramDir(old_dir);
/* Restore the program name */
SetProgramName(old_program_name);
/* Did we launch the program? */
if(rc == -1)
if(result == -1)
{
__set_errno(__translate_io_error_to_errno(IoErr()));
goto out;
@ -748,13 +782,13 @@ execve(const char *path, char *const argv[], char *const envp[])
if(clean_up_env)
__execve_environ_exit(envp);
if(pi != NULL)
free_program_info(pi);
/* If things went well, we can actually quit now. */
if(success)
exit(result);
if(pi != NULL)
free_program_info(pi);
if(arg_string != NULL)
free(arg_string);