Re: use of math.h / libmath discouraged?

2018-07-30 Thread Edward Welbourne
On Wed, 2018-07-25 at 14:25 -0600, Brian Vandenberg wrote:
>> # note: the space before the word TEXT is helpful for readability but causes 
>> a problem
>> $(info $(call F1, TEXT))

Paul Smith (28 July 2018 14:48) replied:
> To me this seems like a bug.  In GNU make generally the rule is
> (intended to be?) that leading whitespace is always ignored and
> trailing whitespace is always preserved.
>
> However if leading whitespace is currently preserved in call functions,
> even unintentionally, I'll need to consider whether that can be fixed
> or not due to backward-compatibility issues.

I'm fairly confident this is how call functions have been since at least
2006.  I would be in favour of applying the rule you just described
instead - I tripped over this repeatedly, back when I spent more time
maintaining make-files, and working round it felt unnatural and made
code less readable,

Eddy.

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: [PATCH 2/2] job.c: implementing child_execute_job() using posix_spawn(), and use it if present

2018-07-30 Thread Paul Smith
On Mon, 2018-07-23 at 07:10 +0200, Barath Aron wrote:
> On 07/22/2018 09:58 PM, Paul Smith wrote:
> > On Mon, 2018-07-09 at 09:05 +0200, Aron Barath wrote:
> > > ---
> > 
> > Thanks for the work you put into this!
> 
> You're welcome! :)
> > Unfortunately this change reveals some deeper problems that I will
> > need to address.  Basically, the old code never really expected
> > fork() to fail: if it did we intended to just give up completely. 
> > Thus, it expected child_execute_job() to always succeed except in
> > exceptional situations, where make itself was not able to continue.
> 
> That's good news and bad news.

This weekend I reworked the handling of failures in child_execute_job()
so that it behaves properly even when the child failure happens in the
current process (e.g., the fork() or posix_spawn()).

It needs a bit of cleanup--in particular writing a test is complicated
by the fact that errors currently have different formats when built
with fork() vs. posix_spawn().  I need to decide if I want to align
them or fix the test to understand the difference.

I also added a configure --disable-posix-spawn option for those who
want to continue to use fork()/vfork() even when posix_spawn() is
available.  Since there's one missing bit of functionality in the
posix_spawn() case (resetting the stack size in the child) and I don't
think that using posix_spawn() buys you much if anything over vfork()
in GNU/Linux, at least.

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: [PATCH 2/2] job.c: implementing child_execute_job() using posix_spawn(), and use it if present

2018-07-30 Thread Barath Aron

On 07/30/2018 12:21 PM, Paul Smith wrote:

This weekend I reworked the handling of failures in child_execute_job()
so that it behaves properly even when the child failure happens in the
current process (e.g., the fork() or posix_spawn()).

It needs a bit of cleanup--in particular writing a test is complicated
by the fact that errors currently have different formats when built
with fork() vs. posix_spawn().  I need to decide if I want to align
them or fix the test to understand the difference.

I also added a configure --disable-posix-spawn option for those who
want to continue to use fork()/vfork() even when posix_spawn() is
available.

Perfect. I can't wait to try it. :)

  Since there's one missing bit of functionality in the
posix_spawn() case (resetting the stack size in the child) and I don't
think that using posix_spawn() buys you much if anything over vfork()
in GNU/Linux, at least.
Yeah, that stuff is missing. The specification [1] does not tell 
anything about the stack size (and limits in general), but I think I 
read in some manual that limits will not be reset.
So the only possible implementation will be reset the stack in the 
current process, spawn, and set the stack size again. Which sounds quite 
odd to me, thus I didn't implemented this.


[1] 
http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html



___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


ENOEXEC from exec*() functions...?

2018-07-30 Thread Paul Smith
While looking into cleanups around fork/exec I ran into some confusing
code in GNU make.  This code dates back to the first version checked
into source control by Roland in 1992 (so who knows how far it really
goes back).

When an exec() fails, GNU make looks at the errno code and if the code
is ENOEXEC it retries the exec but this time giving the command to the
shell to run.  So for example if the command was:

  ./foo bar baz

it will attempt to rerun the exec() with:

  /bin/sh ./foo bar baz

I can't find a way to exercise this code path.

If the command being invoked doesn't have the executable bit set (e.g.,
I use "touch ./foo" with the above) then exec() fails with errno set to
EPERM not ENOEXEC, and if I make the script executable but without a #!
line at the top then exec() runs it in a shell without returning
ENOEXEC.

The GNU/Linux man page doesn't appear to allow this (a script that
doesn't start with #!) or at least doesn't document it as valid, but it
does work.  It lists ENOEXEC errno code as meaning:

  ENOEXEC
 An  executable  is  not in a recognized format, is for the wrong
 architecture, or has some other format error that means it  can‐
 not be executed.

Which doesn't sound like something that would be helped by re-running
as a shell script.  Maybe this is a feature of GNU/Linux and other
systems use ENOEXEC when there's no #! line?

Maybe some folks out there using less common systems know the answer to
that.

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: ENOEXEC from exec*() functions...?

2018-07-30 Thread Andreas Schwab
On Jul 30 2018, Paul Smith  wrote:

> Which doesn't sound like something that would be helped by re-running
> as a shell script.  Maybe this is a feature of GNU/Linux and other
> systems use ENOEXEC when there's no #! line?

http://pubs.opengroup.org/onlinepubs/9699919799/functions/execve.html

There are two distinct ways in which the contents of the process
image file may cause the execution to fail, distinguished by the
setting of errno to either [ENOEXEC] or [EINVAL] (see the ERRORS
section). In the cases where the other members of the exec family of
functions would fail and set errno to [ENOEXEC], the execlp() and
execvp() functions shall execute a command interpreter and the
environment of the executed command shall be as if the process
invoked the sh utility using execl() as follows:

execl(, arg0, file, arg1, ..., (char *)0);

Andreas.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: ENOEXEC from exec*() functions...?

2018-07-30 Thread Paul Smith
On Mon, 2018-07-30 at 13:16 +0200, Andreas Schwab wrote:
> On Jul 30 2018, Paul Smith  wrote:
> > Which doesn't sound like something that would be helped by re-
> > running as a shell script.  Maybe this is a feature of GNU/Linux
> > and other systems use ENOEXEC when there's no #! line?
> 
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/execve.html
> 
> There are two distinct ways in which the contents of the process
> image file may cause the execution to fail, distinguished by the
> setting of errno to either [ENOEXEC] or [EINVAL] (see the ERRORS
> section). In the cases where the other members of the exec family of
> functions would fail and set errno to [ENOEXEC], the execlp() and
> execvp() functions shall execute a command interpreter and the
> environment of the executed command shall be as if the process
> invoked the sh utility using execl() as follows:
> 
> execl(, arg0, file, arg1, ..., (char *)0);

Aha.  GNU make is using execvp() so that explains that.  Maybe the
original code was using a different form of exec().

So it sounds like this code in GNU make is redundant, assuming a POSIX-
compliant implementation of execvp().

I wasn't able to find any similar text in the posix_spawn() document
although posix_spawnp() does appear to behave the same way as execvp()
on GNU/Linux (not surprising since I believe posix_spawn() is
implemented in terms of fork/exec there).

Thanks Andreas!

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: ENOEXEC from exec*() functions...?

2018-07-30 Thread Eli Zaretskii
> From: Paul Smith 
> Date: Mon, 30 Jul 2018 06:47:38 -0400
> 
> I can't find a way to exercise this code path.
> 
> If the command being invoked doesn't have the executable bit set (e.g.,
> I use "touch ./foo" with the above) then exec() fails with errno set to
> EPERM not ENOEXEC, and if I make the script executable but without a #!
> line at the top then exec() runs it in a shell without returning
> ENOEXEC.
> 
> The GNU/Linux man page doesn't appear to allow this (a script that
> doesn't start with #!) or at least doesn't document it as valid, but it
> does work.  It lists ENOEXEC errno code as meaning:
> 
>   ENOEXEC
>  An  executable  is  not in a recognized format, is for the wrong
>  architecture, or has some other format error that means it  can‐
>  not be executed.
> 
> Which doesn't sound like something that would be helped by re-running
> as a shell script.  Maybe this is a feature of GNU/Linux and other
> systems use ENOEXEC when there's no #! line?

But in GNU Make, SHELL can be set to anything, including a command
that runs some executables which the Unix kernel and the Unix shell
don't recognize.  Maybe that code tries to cater to this situation?
AFAIU, such a situation will not be resolved by execvp's fallback to
the shell, because I presume execvp will call the standard shell,
right?

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: ENOEXEC from exec*() functions...?

2018-07-30 Thread Paul Smith
On Mon, 2018-07-30 at 17:29 +0300, Eli Zaretskii wrote:
> > Which doesn't sound like something that would be helped by re-
> > running
> > as a shell script.  Maybe this is a feature of GNU/Linux and other
> > systems use ENOEXEC when there's no #! line?
> 
> But in GNU Make, SHELL can be set to anything, including a command
> that runs some executables which the Unix kernel and the Unix shell
> don't recognize.  Maybe that code tries to cater to this situation?
> AFAIU, such a situation will not be resolved by execvp's fallback to
> the shell, because I presume execvp will call the standard shell,
> right?

Well, this code won't help with that.

It will run "/bin/sh foo bar" and the execvp() call will succeed and
the process will be replaced by the shell.  If "foo" is not a shell
script then the shell will still try to run it and fail with some sort
of syntax error or something.  That will be a very different error than
execvp() returning ENOEXEC.

The only way you'd get ENOEXEC here is if, I suppose, execvp() couldn't
find a shell at all.  Even then you probably just get ENOENT (I didn't
hide /bin/sh on my system to test this :)) which is what you'd get for
any other non-existent program.

As far as I can tell the only way execvp() can return ENOEXEC is if you
try to run a 64bit binary on a 32bit system, or a Windows binary on a
GNU/Linux system, or something like that: something where the kernel
can't even load the program.

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make