summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exec/hashexec.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/exec/hashexec.c b/exec/hashexec.c
index 6eff8015..c554ac16 100644
--- a/exec/hashexec.c
+++ b/exec/hashexec.c
@@ -22,6 +22,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "priv.h"
#include <hurd/sigpreempt.h>
#include <unistd.h>
+#include <envz.h>
/* This is called to check E for a #! interpreter specification. E has
already been prepared (successfully) and checked (unsuccessfully). If
@@ -164,6 +165,7 @@ check_hashbang (struct execdata *e,
if (! e->error)
{
+ int free_file_name = 0; /* True if we should free FILE_NAME. */
jmp_buf args_faulted;
void fault_handler (int signo)
{ longjmp (args_faulted, 1); }
@@ -183,6 +185,7 @@ check_hashbang (struct execdata *e,
error_t error;
char *name;
+ int free_name = 0; /* True if we should free NAME. */
file_t name_file;
struct stat st;
int file_fstype;
@@ -195,20 +198,14 @@ check_hashbang (struct execdata *e,
error_t search_path (struct hurd_signal_preempter *preempter)
{
error_t error;
- const char envar[] = "\0PATH=";
- char *path, *p;
- if (envplen >= sizeof (envar) &&
- !memcmp (&envar[1], envp, sizeof (envar) - 2))
- p = envp - 1;
- else
- p = memmem (envp, envplen, envar, sizeof (envar) - 1);
- if (p != NULL)
+ char *path;
+ char *env_path = envz_get (envp, envplen, "PATH");
+
+ if (env_path)
{
- size_t len;
- p += sizeof (envar) - 1;
- len = strlen (p) + 1;
+ size_t len = strlen (env_path) + 1;
path = alloca (len);
- bcopy (p, path, len);
+ bcopy (env_path, path, len);
}
else
{
@@ -240,11 +237,13 @@ check_hashbang (struct execdata *e,
{
size_t dirlen = strlen (p);
size_t namelen = strlen (name);
- char *new = alloca (dirlen + 1 + namelen + 1);
+ char *new = malloc (dirlen + 1 + namelen + 1);
+
memcpy (new, p, dirlen);
new[dirlen] = '/';
memcpy (&new[dirlen + 1], name, namelen + 1);
name = new;
+ free_name = 1;
}
break;
}
@@ -283,7 +282,12 @@ check_hashbang (struct execdata *e,
st.st_fstype == file_fstype &&
st.st_fsid == file_fsid &&
st.st_ino == file_fileno)
- file_name = name;
+ {
+ file_name = name;
+ free_file_name = free_name;
+ }
+ else if (free_name)
+ free (name);
mach_port_deallocate (mach_task_self (), name_file);
}
}
@@ -354,6 +358,9 @@ check_hashbang (struct execdata *e,
memcpy (memcpy (n, arg, len) + len, file_name, namelen);
}
+ if (free_file_name)
+ free (file_name);
+
return 0;
}