/*
 * exec.c:: various execXX emulations. If we're in a child that has been
 * forked, then we restore our parent's data area and shrink the
 * fork information block to the minimum. If we're not in any child, then
 * we just wing it (we probably should shrink the text+data+bss block to
 * give more room, but that would be rather difficult to do properly).
 *
 * the real work is done in spawnve.c.
 */

#include <osbind.h>
#include <basepage.h>
#include <process.h>
#include <file.h>
#include <stdarg.h>
#include <unistd.h>

extern int _x_Bit_set_in_stat; /* in stat.c */

int
execve(path, argv, envp)
	char *path, **argv, **envp;
{
    int savex = _x_Bit_set_in_stat;

/* check to make sure that the file is executable. alas, this is not
   foolproof, since .g and .sh files are marked as executable even though
   they're not, really.
 */
	_x_Bit_set_in_stat = 1;
	if (access(path, X_OK)) {
	        _x_Bit_set_in_stat = savex;
		return -1;
	}
        _x_Bit_set_in_stat = savex;
/*
 * the call to spawnve shouldn't return unless there is an error
 */
	return spawnve(P_OVERLAY, path, argv, envp);
}

int
execv(path, argv)
	char *path, **argv;
{
	return execve(path, argv, (char **)0);
}

int
execvp(name, argv)
	char *name;
	char **argv;
{
    /* note: we cannot check x bit here as we dont know the full path.
     * we flag spawnvp to do this by passing it -ve mode
     */
    return spawnvp(-P_OVERLAY, name, argv);
}

#ifdef __STDC__
int execl(char *path, ...)
#else
int execl(path)
	char	*path;
#endif
{
	va_list args;

	va_start(args, path);
	return execve(path, (char **)args, (char **)0);
}
