Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Aug 2012 00:29:44 +0200
From:      Jilles Tjoelker <jilles@stack.nl>
To:        "Simon J. Gerraty" <sjg@juniper.net>
Cc:        svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org, Ruslan Ermilov <ru@FreeBSD.org>, "David E. O'Brien" <obrien@FreeBSD.org>
Subject:   Re: svn commit: r238563 - head/gnu/usr.bin/groff/tmac
Message-ID:  <20120821222943.GA27203@stack.nl>
In-Reply-To: <20120821053519.BD5A158085@chaos.jnpr.net>
References:  <201207180557.q6I5vheM034018@svn.freebsd.org> <20120726084903.GA48240@lo0.su> <20120821053519.BD5A158085@chaos.jnpr.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Aug 20, 2012 at 10:35:19PM -0700, Simon J. Gerraty wrote:
> Hi, sorry about the slow response.

> On Thu, 26 Jul 2012 12:49:03 +0400, Ruslan Ermilov writes:
> >On Wed, Jul 18, 2012 at 05:57:43AM +0000, David E. O'Brien wrote:
> >> Author: obrien
> >> Date: Wed Jul 18 05:57:42 2012
> >> New Revision: 238563
> >> URL: http://svn.freebsd.org/changeset/base/238563

> >> Log:
> >>   a ";" tells make we want the shell to be used

> >>   Submitted by:	Simon Gerraty <sjg@juniper.net>

> >> Modified:
> >>   head/gnu/usr.bin/groff/tmac/Makefile

> >I don't quite understand what this change does, could you elaborate?

> Sure.  This is a consequence of bmake trying to be clever.

> >Without -jN (in backwards compatibility mode), the "cd" is a no-op
> >(whether it's terminated by `;' or not) because make will execute a
> >single shell per command, with cwd set to ${.OBJDIR}.

> Except on very weird systems, bmake is built in what NetBSD call
> "native" mode, and even in compat mode will attempt to avoid the
> overhead of all those shells.
> Thus, unless it spots a shell meta char, it will try and skip the shell.

> Shell builtins like 'cd' or 'chdir' cannot be directly invoked, but make
> doesn't know that.  Simply adding the ';' convinces it to use a shell.
> It is still a no-op.

On FreeBSD, the first two statements are partially false. All sh(1)
builtins that correspond to utilities specified by POSIX (but not
special builtins) have versions accessible to execve() (on 8.x and
older, hash, type and ulimit are missing). This includes cd but not
chdir, since chdir is not specified by POSIX. Also, FreeBSD make
includes a somewhat arbitrary list of shell builtins, including cd, that
cause it to invoke the shell even if there are no metacharacters.

This list of shell builtins should probably be replaced with the list of
POSIX special builtins, which are
  break continue eval exec exit export readonly return set shift times
  trap unset . :

There is a portability issue in that a few systems refuse to comply to
the part of POSIX (XCU 1.6 Built-In Utilities) that says that all
specified utilities (except special builtins) shall be accessible via
exec functions, env, find, nice, nohup, time, xargs. Working around this
requires knowing which utilities are "generally" only provided as
builtins.

> >With -jN, "cd" becomes necessary because all commands are executed as
> >a script by one shell (the reason it was added in the first place),
> >but adding `;' is a no-op because commands are on separate lines.

> A better way to construct targets like this is to put any excursion out
> of .OBJDIR inside ():

> 	(cd ${.CURDIR} && \
> 	${INSTALL} -o ${TMACOWN} -g ${TMACGRP} -m ${TMACMODE} \
> 	koi8-r.tmac hyphen.ru ${DESTDIR}${TMACDIR})

> then the cd ${.OBJDIR} isn't needed at all.
> note use of && rather than ; which can be very dangerous

This method makes more sense and should hardly cost any performance.

-- 
Jilles Tjoelker



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120821222943.GA27203>