When a script has a shebang with arguments, say "#!/usr/bin/perl -w" or "#!/bin/sh -" qemu-xxx tries to exec the whole line, and fails, obviously. e.g.: root@pkg:~ # cat test.pl #!/usr/bin/perl -w print "ok\n"; root@pkg:~ # ./test.pl Error loading /usr/bin/perl -w root@pkg:~ # ln -s /usr/local/bin/perl5.16.3 /usr/bin/"perl -w" root@pkg:~ # ./test.pl ok Generated with FreeBSD Port Tools 0.99_11 (mode: change, diff: SVN)
Responsible Changed From-To: freebsd-ports-bugs->nox Over to maintainer (via the GNATS Auto Assign Tool)
On Wed, Feb 05, 2014 at 05:30:10PM +0000, edwin@FreeBSD.org wrote: > Synopsis: emulators/qemu-devel: Can't run scripts with shebang args. > > Responsible-Changed-From-To: freebsd-ports-bugs->nox > Responsible-Changed-By: edwin > Responsible-Changed-When: Wed Feb 5 17:30:10 UTC 2014 > Responsible-Changed-Why: > Over to maintainer (via the GNATS Auto Assign Tool) > > http://www.freebsd.org/cgi/query-pr.cgi?pr=186490 Hm you are right, looks like a bug in sson's patches. Can you try the patch below? I'd like to commit it to the port if it works and sson doesn't have a better version... Thanx! :) Juergen --- a/bsd-user/freebsd/os-proc.c --- b/bsd-user/freebsd/os-proc.c @@ -83,7 +83,7 @@ out: } static int -is_target_shell_script(int fd, char *interp, size_t size) +is_target_shell_script(int fd, char *interp, size_t size, char **interp_args) { char buf[2], *p, *b; ssize_t n; @@ -120,7 +120,21 @@ is_target_shell_script(int fd, char *int return 0; } if ((p = memchr(b, '\n', size)) != NULL) { + int hasargs = 0; *p = 0; + + *interp_args = NULL; + p = interp; + while (*p) { + if ((*p == ' ') || (*p == '\t')) { + hasargs = 1; + *p = 0; + } else if (hasargs) { + *interp_args = p; + break; + } + ++p; + } return 1; } b += n; @@ -136,7 +150,7 @@ is_target_shell_script(int fd, char *int abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, abi_ulong guest_envp, int do_fexec) { - char **argp, **envp, **qargp, **qarg1, **qarg0; + char **argp, **envp, **qargp, **qarg1, **qarg0, **qargend; int argc, envc; abi_ulong gp; abi_ulong addr; @@ -166,7 +180,7 @@ abi_long freebsd_exec_common(abi_ulong p envc++; } - qarg0 = argp = alloca((argc + 4) * sizeof(void *)); + qarg0 = argp = alloca((argc + 5) * sizeof(void *)); /* save the first agrument for the emulator */ *argp++ = (char *)getprogname(); qargp = argp; @@ -188,7 +202,8 @@ abi_long freebsd_exec_common(abi_ulong p } total_size += strlen(*q) + 1; } - *q = NULL; + *q++ = NULL; + qargend = q; for (gp = guest_envp, q = envp; gp; gp += sizeof(abi_ulong), q++) { if (get_user_ual(addr, gp)) { @@ -217,7 +232,7 @@ abi_long freebsd_exec_common(abi_ulong p } if (do_fexec) { - char execpath[PATH_MAX]; + char execpath[PATH_MAX], *scriptargs; if (((int)path_or_fd > 0 && is_target_elf_binary((int)path_or_fd)) == 1) { @@ -238,7 +253,7 @@ abi_long freebsd_exec_common(abi_ulong p goto execve_end; } } else if (is_target_shell_script((int)path_or_fd, execpath, - sizeof(execpath)) != 0) { + sizeof(execpath), &scriptargs) != 0) { char scriptpath[PATH_MAX]; /* execve() as a target script using emulator. */ @@ -246,6 +261,10 @@ abi_long freebsd_exec_common(abi_ulong p sizeof(scriptpath)) != NULL) { *qargp = execpath; *qarg1 = scriptpath; + if (scriptargs) { + memmove(qarg1 + 1, qarg1, (qargend-qarg1) * sizeof(*qarg1)); + *qarg1 = scriptargs; + } ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); } else { ret = -TARGET_EBADF; @@ -256,7 +275,7 @@ abi_long freebsd_exec_common(abi_ulong p } } else { int fd; - char execpath[PATH_MAX]; + char execpath[PATH_MAX], *scriptargs; p = lock_user_string(path_or_fd); if (p == NULL) { @@ -275,11 +294,15 @@ abi_long freebsd_exec_common(abi_ulong p *qarg1 = (char *)p; ret = get_errno(execve(qemu_proc_pathname, qargp, envp)); } else if (is_target_shell_script(fd, execpath, - sizeof(execpath)) != 0) { + sizeof(execpath), &scriptargs) != 0) { close(fd); /* execve() as a target script using emulator. */ *qargp = execpath; *qarg1 = (char *)p; + if (scriptargs) { + memmove(qarg1 + 1, qarg1, (qargend-qarg1) * sizeof(*qarg1)); + *qarg1 = scriptargs; + } ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); } else { close(fd);
Nice... Thanks for fixing this. I have been too busy working on pmap = code for MIPS lately. :) I am going to try to refactor the patch set for qemu user-mode this = weekend, maybe, so I can get all this code finally upstreamed to the = qemu project. -stacey. On Feb 5, 2014, at 8:14 PM, Juergen Lock <nox@jelal.kn-bremen.de> wrote: > On Wed, Feb 05, 2014 at 05:30:10PM +0000, edwin@FreeBSD.org wrote: >> Synopsis: emulators/qemu-devel: Can't run scripts with shebang args. >>=20 >> Responsible-Changed-From-To: freebsd-ports-bugs->nox >> Responsible-Changed-By: edwin >> Responsible-Changed-When: Wed Feb 5 17:30:10 UTC 2014 >> Responsible-Changed-Why:=20 >> Over to maintainer (via the GNATS Auto Assign Tool) >>=20 >> http://www.freebsd.org/cgi/query-pr.cgi?pr=3D186490 >=20 > Hm you are right, looks like a bug in sson's patches. Can you try > the patch below? I'd like to commit it to the port if it works and > sson doesn't have a better version... >=20 > Thanx! :) > Juergen >=20 > --- a/bsd-user/freebsd/os-proc.c > --- b/bsd-user/freebsd/os-proc.c > @@ -83,7 +83,7 @@ out: > } >=20 > static int > -is_target_shell_script(int fd, char *interp, size_t size) > +is_target_shell_script(int fd, char *interp, size_t size, char = **interp_args) > { > char buf[2], *p, *b; > ssize_t n; > @@ -120,7 +120,21 @@ is_target_shell_script(int fd, char *int > return 0; > } > if ((p =3D memchr(b, '\n', size)) !=3D NULL) { > + int hasargs =3D 0; > *p =3D 0; > + > + *interp_args =3D NULL; > + p =3D interp; > + while (*p) { > + if ((*p =3D=3D ' ') || (*p =3D=3D '\t')) { > + hasargs =3D 1; > + *p =3D 0; > + } else if (hasargs) { > + *interp_args =3D p; > + break; > + } > + ++p; > + } > return 1; > } > b +=3D n; > @@ -136,7 +150,7 @@ is_target_shell_script(int fd, char *int > abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong = guest_argp, > abi_ulong guest_envp, int do_fexec) > { > - char **argp, **envp, **qargp, **qarg1, **qarg0; > + char **argp, **envp, **qargp, **qarg1, **qarg0, **qargend; > int argc, envc; > abi_ulong gp; > abi_ulong addr; > @@ -166,7 +180,7 @@ abi_long freebsd_exec_common(abi_ulong p > envc++; > } >=20 > - qarg0 =3D argp =3D alloca((argc + 4) * sizeof(void *)); > + qarg0 =3D argp =3D alloca((argc + 5) * sizeof(void *)); > /* save the first agrument for the emulator */ > *argp++ =3D (char *)getprogname(); > qargp =3D argp; > @@ -188,7 +202,8 @@ abi_long freebsd_exec_common(abi_ulong p > } > total_size +=3D strlen(*q) + 1; > } > - *q =3D NULL; > + *q++ =3D NULL; > + qargend =3D q; >=20 > for (gp =3D guest_envp, q =3D envp; gp; gp +=3D sizeof(abi_ulong), = q++) { > if (get_user_ual(addr, gp)) { > @@ -217,7 +232,7 @@ abi_long freebsd_exec_common(abi_ulong p > } >=20 > if (do_fexec) { > - char execpath[PATH_MAX]; > + char execpath[PATH_MAX], *scriptargs; >=20 > if (((int)path_or_fd > 0 && > is_target_elf_binary((int)path_or_fd)) =3D=3D 1) { > @@ -238,7 +253,7 @@ abi_long freebsd_exec_common(abi_ulong p > goto execve_end; > } > } else if (is_target_shell_script((int)path_or_fd, execpath, > - sizeof(execpath)) !=3D 0) { > + sizeof(execpath), &scriptargs) !=3D 0) { > char scriptpath[PATH_MAX]; >=20 > /* execve() as a target script using emulator. */ > @@ -246,6 +261,10 @@ abi_long freebsd_exec_common(abi_ulong p > sizeof(scriptpath)) !=3D NULL) { > *qargp =3D execpath; > *qarg1 =3D scriptpath; > + if (scriptargs) { > + memmove(qarg1 + 1, qarg1, (qargend-qarg1) * = sizeof(*qarg1)); > + *qarg1 =3D scriptargs; > + } > ret =3D get_errno(execve(qemu_proc_pathname, qarg0, = envp)); > } else { > ret =3D -TARGET_EBADF; > @@ -256,7 +275,7 @@ abi_long freebsd_exec_common(abi_ulong p > } > } else { > int fd; > - char execpath[PATH_MAX]; > + char execpath[PATH_MAX], *scriptargs; >=20 > p =3D lock_user_string(path_or_fd); > if (p =3D=3D NULL) { > @@ -275,11 +294,15 @@ abi_long freebsd_exec_common(abi_ulong p > *qarg1 =3D (char *)p; > ret =3D get_errno(execve(qemu_proc_pathname, qargp, = envp)); > } else if (is_target_shell_script(fd, execpath, > - sizeof(execpath)) !=3D 0) { > + sizeof(execpath), &scriptargs) !=3D 0) { > close(fd); > /* execve() as a target script using emulator. */ > *qargp =3D execpath; > *qarg1 =3D (char *)p; > + if (scriptargs) { > + memmove(qarg1 + 1, qarg1, (qargend-qarg1) * = sizeof(*qarg1)); > + *qarg1 =3D scriptargs; > + } > ret =3D get_errno(execve(qemu_proc_pathname, qarg0, = envp)); > } else { > close(fd);
Patch against the port for easier testing.
+--On 6 f=C3=A9vrier 2014 12:57:56 +0100 Juergen Lock = <nox@jelal.kn-bremen.de> wrote: | Patch against the port for easier testing. That fixes the bug many thanks \o/ this time devel/autoconf will build, and I'll have *more* packages for both mips64 and armv6 0:-) --=20 Mathieu Arnold
Author: nox Date: Thu Feb 6 17:48:25 2014 New Revision: 343128 URL: http://svnweb.freebsd.org/changeset/ports/343128 QAT: https://qat.redports.org/buildarchive/r343128/ Log: - Fix bsd-user targets running scripts with shebang args. [1] - Bump PORTREVISION as per the new ruling. (fix only affecting non-default option BSD_USER) PR: ports/186490 [1] Submitted by: mat [1] Added: head/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-proc.c (contents, props changed) Modified: head/emulators/qemu-devel/Makefile Modified: head/emulators/qemu-devel/Makefile ============================================================================== --- head/emulators/qemu-devel/Makefile Thu Feb 6 17:36:38 2014 (r343127) +++ head/emulators/qemu-devel/Makefile Thu Feb 6 17:48:25 2014 (r343128) @@ -3,7 +3,7 @@ PORTNAME= qemu PORTVERSION= 1.7.0 -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= emulators MASTER_SITES= http://wiki.qemu.org/download/:release \ LOCAL/nox:snapshot @@ -67,6 +67,7 @@ PATCHFILES= \ 0017-bsd-user-add-support-for-miscellaneous-system-calls.patch \ 0018-bsd-user-add-arm-mips-and-mips64-options-to-configur.patch PATCH_DIST_STRIP= -p1 +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-freebsd-os-proc.c .endif CONFIGURE_ARGS+= --extra-ldflags=-L${LOCALBASE}/lib Added: head/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-proc.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-proc.c Thu Feb 6 17:48:25 2014 (r343128) @@ -0,0 +1,116 @@ +--- a/bsd-user/freebsd/os-proc.c +--- b/bsd-user/freebsd/os-proc.c +@@ -83,7 +83,7 @@ out: + } + + static int +-is_target_shell_script(int fd, char *interp, size_t size) ++is_target_shell_script(int fd, char *interp, size_t size, char **interp_args) + { + char buf[2], *p, *b; + ssize_t n; +@@ -120,7 +120,21 @@ is_target_shell_script(int fd, char *int + return 0; + } + if ((p = memchr(b, '\n', size)) != NULL) { ++ int hasargs = 0; + *p = 0; ++ ++ *interp_args = NULL; ++ p = interp; ++ while (*p) { ++ if ((*p == ' ') || (*p == '\t')) { ++ hasargs = 1; ++ *p = 0; ++ } else if (hasargs) { ++ *interp_args = p; ++ break; ++ } ++ ++p; ++ } + return 1; + } + b += n; +@@ -136,7 +150,7 @@ is_target_shell_script(int fd, char *int + abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, + abi_ulong guest_envp, int do_fexec) + { +- char **argp, **envp, **qargp, **qarg1, **qarg0; ++ char **argp, **envp, **qargp, **qarg1, **qarg0, **qargend; + int argc, envc; + abi_ulong gp; + abi_ulong addr; +@@ -166,7 +180,7 @@ abi_long freebsd_exec_common(abi_ulong p + envc++; + } + +- qarg0 = argp = alloca((argc + 4) * sizeof(void *)); ++ qarg0 = argp = alloca((argc + 5) * sizeof(void *)); + /* save the first agrument for the emulator */ + *argp++ = (char *)getprogname(); + qargp = argp; +@@ -188,7 +202,8 @@ abi_long freebsd_exec_common(abi_ulong p + } + total_size += strlen(*q) + 1; + } +- *q = NULL; ++ *q++ = NULL; ++ qargend = q; + + for (gp = guest_envp, q = envp; gp; gp += sizeof(abi_ulong), q++) { + if (get_user_ual(addr, gp)) { +@@ -217,7 +232,7 @@ abi_long freebsd_exec_common(abi_ulong p + } + + if (do_fexec) { +- char execpath[PATH_MAX]; ++ char execpath[PATH_MAX], *scriptargs; + + if (((int)path_or_fd > 0 && + is_target_elf_binary((int)path_or_fd)) == 1) { +@@ -238,7 +253,7 @@ abi_long freebsd_exec_common(abi_ulong p + goto execve_end; + } + } else if (is_target_shell_script((int)path_or_fd, execpath, +- sizeof(execpath)) != 0) { ++ sizeof(execpath), &scriptargs) != 0) { + char scriptpath[PATH_MAX]; + + /* execve() as a target script using emulator. */ +@@ -246,6 +261,10 @@ abi_long freebsd_exec_common(abi_ulong p + sizeof(scriptpath)) != NULL) { + *qargp = execpath; + *qarg1 = scriptpath; ++ if (scriptargs) { ++ memmove(qarg1 + 1, qarg1, (qargend-qarg1) * sizeof(*qarg1)); ++ *qarg1 = scriptargs; ++ } + ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); + } else { + ret = -TARGET_EBADF; +@@ -256,7 +275,7 @@ abi_long freebsd_exec_common(abi_ulong p + } + } else { + int fd; +- char execpath[PATH_MAX]; ++ char execpath[PATH_MAX], *scriptargs; + + p = lock_user_string(path_or_fd); + if (p == NULL) { +@@ -275,11 +294,15 @@ abi_long freebsd_exec_common(abi_ulong p + *qarg1 = (char *)p; + ret = get_errno(execve(qemu_proc_pathname, qargp, envp)); + } else if (is_target_shell_script(fd, execpath, +- sizeof(execpath)) != 0) { ++ sizeof(execpath), &scriptargs) != 0) { + close(fd); + /* execve() as a target script using emulator. */ + *qargp = execpath; + *qarg1 = (char *)p; ++ if (scriptargs) { ++ memmove(qarg1 + 1, qarg1, (qargend-qarg1) * sizeof(*qarg1)); ++ *qarg1 = scriptargs; ++ } + ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); + } else { + close(fd); _______________________________________________ svn-ports-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-ports-all To unsubscribe, send any mail to "svn-ports-all-unsubscribe@freebsd.org"
State Changed From-To: open->closed Fix committed. Thanks!