Re: [PATCH 2/3] Revert Eliminated global exerrno.

2010-11-28 Thread Herbert Xu
On Wed, Oct 06, 2010 at 10:35:18PM -0500, Jonathan Nieder wrote:

 Maybe the following would make sense on top?
 
 -- 8 --
 Subject: [EXCEPTIONS] Use EXEXIT in place of EXEXEC

Patch applied.  Thanks a lot!
-- 
Email: Herbert Xu herb...@gondor.apana.org.au
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line unsubscribe dash in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] Revert Eliminated global exerrno.

2010-10-07 Thread Jonathan Nieder
Herbert Xu wrote:

   sh -c 'trap exec nosuchfile EXIT; exit 3'; echo $?
 
 This makes dash exit with 127 instead of 3 as it does now.
 
 AFAIK the wording of POSIX is such that we should return 3, however,
 it does seem that every other shell exits with 127.

On 'exec':

 If exec is specified with command, it shall replace the shell with
 command without creating a new process.   (1)

 If command is specified, exec shall not return to the shell; rather,
 the exit status of the process shall be the exit status of the program
 implementing command, which overlaid the shell. If command is not
 found, the exit status shall be 127. If command is found, but it is
 not an executable utility, the exit status shall be 126. If a
 redirection error occurs (see Consequences of Shell Errors ), the
 shell shall exit with a value in the range 1-125. Otherwise, exec
 shall return a zero exit status.  (2)

On 'exit':

 ...
 A trap on EXIT shall be executed before the shell terminates, except
 when the exit utility is invoked in that trap itself, in which case
 the shell shall exit immediately. (3)

 The exit status [of the exit utility -jrn] shall be n, if specified.
 Otherwise, the value shall be the exit value of the last command
 executed, or zero if no command was executed. When exit is executed in
 a trap action, the last command is considered to be the command that
 executed immediately preceding the trap action.   (4)

The passage (3) seems to mean that exit triggers an EXIT trap
(except, to avoid having to deal with recursion, when the exit
occurs within an EXIT trap).  Then the exec builtin is invoked,
resulting (according to (2)) in an exit(127) without returning to the
shell.

So I think the proposed behavior fits the spec.

Regards,
Jonathan
--
To unsubscribe from this list: send the line unsubscribe dash in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] Revert Eliminated global exerrno.

2010-10-06 Thread Jonathan Nieder
This reverts commit c0e07c010e5abdea1a7d1357edb1d08adac529cb.

Yes, it is nicer to pass the exit status through the exitstatus
global, but look at the consequences:

 $ sh -c 'exec nonexistent'; echo $?
 exec: 1: nonexistent: not found
 2
 $ sh -c 'exec .'; echo $?
 exec: 1: .: Permission denied
 2

According to POSIX:
If command is not found, the exit status shall be 127. If command is
found, but it is not an executable utility, the exit status shall
be 126.

Make it so again.

Reported-by: Eric Blake ebl...@redhat.com
Signed-off-by: Jonathan Nieder jrnie...@gmail.com
---
 src/error.h |1 +
 src/exec.c  |3 +--
 src/main.c  |2 ++
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/error.h b/src/error.h
index 15ccbe3..1bb6a82 100644
--- a/src/error.h
+++ b/src/error.h
@@ -62,6 +62,7 @@ struct jmploc {
 
 extern struct jmploc *handler;
 extern int exception;
+extern int exerrno;/* error for EXEXEC */
 
 /* exceptions */
 #define EXINT 0/* SIGINT received */
diff --git a/src/exec.c b/src/exec.c
index 42299ea..9525a16 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -86,6 +86,7 @@ struct tblentry {
 
 STATIC struct tblentry *cmdtable[CMDTABLESIZE];
 STATIC int builtinloc = -1;/* index in path of %builtin, or -1 */
+int exerrno;   /* Last exec error */
 
 
 STATIC void tryexec(char *, char **, char **);
@@ -108,7 +109,6 @@ shellexec(char **argv, const char *path, int idx)
char *cmdname;
int e;
char **envp;
-   int exerrno;
 
envp = environment();
if (strchr(argv[0], '/') != NULL) {
@@ -138,7 +138,6 @@ shellexec(char **argv, const char *path, int idx)
exerrno = 2;
break;
}
-   exitstatus = exerrno;
TRACE((shellexec failed for %s, errno %d, suppressint %d\n,
argv[0], e, suppressint ));
exerror(EXEXEC, %s: %s, argv[0], errmsg(e, E_EXEC));
diff --git a/src/main.c b/src/main.c
index 2bff956..5bc1a99 100644
--- a/src/main.c
+++ b/src/main.c
@@ -115,6 +115,8 @@ main(int argc, char **argv)
e = exception;
if (e == EXERROR)
exitstatus = 2;
+   else if (e == EXEXEC)
+   exitstatus = exerrno;
 
s = state;
if (e == EXEXIT || s == 0 || iflag == 0 || shlvl)
-- 
1.7.2.3

--
To unsubscribe from this list: send the line unsubscribe dash in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] Revert Eliminated global exerrno.

2010-10-06 Thread Herbert Xu
On Wed, Oct 06, 2010 at 08:04:58PM -0500, Jonathan Nieder wrote:
 This reverts commit c0e07c010e5abdea1a7d1357edb1d08adac529cb.
 
 Yes, it is nicer to pass the exit status through the exitstatus
 global, but look at the consequences:
 
  $ sh -c 'exec nonexistent'; echo $?
  exec: 1: nonexistent: not found
  2
  $ sh -c 'exec .'; echo $?
  exec: 1: .: Permission denied
  2
 
 According to POSIX:
 If command is not found, the exit status shall be 127. If command is
 found, but it is not an executable utility, the exit status shall
 be 126.
 
 Make it so again.
 
 Reported-by: Eric Blake ebl...@redhat.com
 Signed-off-by: Jonathan Nieder jrnie...@gmail.com

Actually the bug is elsewhere.  This patch works for me.

commit 7f684260a2426ac61c06d2e4822429b00437ae24
Author: Herbert Xu herb...@gondor.apana.org.au
Date:   Thu Oct 7 10:55:15 2010 +0800

[BUILTIN] Fix EXEXEC status clobbering

evalcommand always clobbers the exit status in case of an EXEXEC
which means that exec always fails with exit status 2 regardless
of what it actually returns.

This patch adds the missing check for EXEXEC so that the correct
exit status is preserved.

Signed-off-by: Herbert Xu herb...@gondor.apana.org.au

diff --git a/ChangeLog b/ChangeLog
index 1dfe241..2faaedd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-10-07  Herbert Xu herb...@gondor.apana.org.au
+
+   * Fix EXEXEC status clobbering.
+
 2010-09-08  Herbert Xu herb...@gondor.apana.org.au
 
* Fix ifsfirst/ifslastp leak.
diff --git a/src/eval.c b/src/eval.c
index 5b8d36b..b966749 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -854,7 +854,7 @@ bail:
int i;
 
i = exception;
-   if (i == EXEXIT)
+   if (i == EXEXIT || i == EXEXEC)
goto raise;
 
status = (i == EXINT) ? SIGINT + 128 : 2;

Thanks,
-- 
Email: Herbert Xu herb...@gondor.apana.org.au
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line unsubscribe dash in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] Revert Eliminated global exerrno.

2010-10-06 Thread Jonathan Nieder
Herbert Xu wrote:

 Actually the bug is elsewhere.

It does bisect to there. :)  But you're right, it would have been
simpler to send one patch.

 --- a/src/eval.c
 +++ b/src/eval.c
 @@ -854,7 +854,7 @@ bail:
   int i;
  
   i = exception;
 - if (i == EXEXIT)
 + if (i == EXEXIT || i == EXEXEC)
   goto raise;

Good call.  This is better than my patch because it exits like it
ought to for

command exec nonexistent

(as POSIX says:

If command is specified, exec shall not return to the shell

).

Maybe the following would make sense on top?

-- 8 --
Subject: [EXCEPTIONS] Use EXEXIT in place of EXEXEC

The intended semantics of EXEXEC are identical to EXEXIT, so
simplify by using EXEXIT directly.

Functional change: in edge cases (exec within a trap handler),
this causes the exit status from exec not to be clobbered.
For example, without this patch:

 $ sh -c 'trap exec nonexistent EXIT'; echo $?
 exec: 1: nonexistent: not found
 0

And with it:

 $ sh -c 'trap exec nonexistent EXIT'; echo $?
 exec: 1: nonexistent: not found
 127

Signed-off-by: Jonathan Nieder jrnie...@gmail.com
---
 src/error.h |1 -
 src/eval.c  |2 +-
 src/exec.c  |2 +-
 3 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/error.h b/src/error.h
index be0eec9..f236d9f 100644
--- a/src/error.h
+++ b/src/error.h
@@ -66,7 +66,6 @@ extern int exception;
 /* exceptions */
 #define EXINT 0/* SIGINT received */
 #define EXERROR 1  /* a generic error */
-#define EXEXEC 3   /* command execution failed */
 #define EXEXIT 4   /* exit the shell */
 
 
diff --git a/src/eval.c b/src/eval.c
index b966749..5b8d36b 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -854,7 +854,7 @@ bail:
int i;
 
i = exception;
-   if (i == EXEXIT || i == EXEXEC)
+   if (i == EXEXIT)
goto raise;
 
status = (i == EXINT) ? SIGINT + 128 : 2;
diff --git a/src/exec.c b/src/exec.c
index 42299ea..b273420 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -141,7 +141,7 @@ shellexec(char **argv, const char *path, int idx)
exitstatus = exerrno;
TRACE((shellexec failed for %s, errno %d, suppressint %d\n,
argv[0], e, suppressint ));
-   exerror(EXEXEC, %s: %s, argv[0], errmsg(e, E_EXEC));
+   exerror(EXEXIT, %s: %s, argv[0], errmsg(e, E_EXEC));
/* NOTREACHED */
 }
 
-- 
1.7.2.3

--
To unsubscribe from this list: send the line unsubscribe dash in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] Revert Eliminated global exerrno.

2010-10-06 Thread Herbert Xu
On Wed, Oct 06, 2010 at 10:35:18PM -0500, Jonathan Nieder wrote:
 Herbert Xu wrote:
 
  Actually the bug is elsewhere.
 
 It does bisect to there. :)  But you're right, it would have been
 simpler to send one patch.
 
  --- a/src/eval.c
  +++ b/src/eval.c
  @@ -854,7 +854,7 @@ bail:
  int i;
   
  i = exception;
  -   if (i == EXEXIT)
  +   if (i == EXEXIT || i == EXEXEC)
  goto raise;
 
 Good call.  This is better than my patch because it exits like it
 ought to for
 
   command exec nonexistent
 
 (as POSIX says:
 
   If command is specified, exec shall not return to the shell
 
 ).
 
 Maybe the following would make sense on top?

Nice! I like where you are going with this :)

Let me run it through the tests and apply it.

Thanks,
-- 
Email: Herbert Xu herb...@gondor.apana.org.au
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line unsubscribe dash in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] Revert Eliminated global exerrno.

2010-10-06 Thread Herbert Xu
On Thu, Oct 07, 2010 at 12:14:06PM +0800, Herbert Xu wrote:

 Let me run it through the tests and apply it.

There is one problem with this and that is changing the exit
status in a trap:

sh -c 'trap exec nosuchfile EXIT; exit 3'; echo $?

This makes dash exit with 127 instead of 3 as it does now.

AFAIK the wording of POSIX is such that we should return 3, however,
it does seem that every other shell exits with 127.

So unless anyone objects, I will apply your patch and adopt this
new behaviour.

Thanks,
-- 
Email: Herbert Xu herb...@gondor.apana.org.au
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line unsubscribe dash in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html