Subject: Possible solution to toolchain/16963 - NBUILDJOBS/METALOG conflict
To: None <tech-userlevel@netbsd.org>
From: Mason Loring Bliss <mason@acheron.middleboro.ma.us>
List: tech-userlevel
Date: 06/06/2002 06:16:52
--mFM6r0jQWo48NPCK
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hi, all. I'd appreciate feedback on this.

The lack of the capability to build NetBSD with -j foo where foo > 1 has
been annoying me, and I've been thinking of a couple possible solutions.
There are as follows:

1) Have Makefile in share/man and share/zoneinfo (and possibly elsewhere -
I haven't performed an exhaustive search) write out temporary METALOG.$$
files, and, sometime afterwards, nebulously, when the coast is clear, take
all of these and append them to the real METALOG file.

The problems here:

 *) It's potentially hard to figure out when exactly nothing else is going
    to be mucking with METALOG, since we're letting make(1) schedule things.

 *) It seems unclean. There is no mktemp(1) on many systems, so we'd be
    forced to use the process ID. While this is probably safe, it doesn't
    seem as nice as the next potential solution.

2) Have an append(1) command as the last item in the pipe when writing to
METALOG. This command would take its stdin and dump it to a target file
given on its command line, but (and here's the critical bit!) would set
and obey exclusive advisory locks while doing so.

Possible problem:

 *) flock(2) doesn't necessarily exist everywhere.

The obvious benefit is that it's doing locking. Also, install(1) uses
advisory locks, so the two would cooperate quite nicely WRT METALOG.

As luck would have it, I've just spend some time writing and boiling down
an append(1) command. I personally think it'd be pretty useful in its own
right, as there's really nothing out there of which I'm aware which does
exactly what it does.

Here it is. Please comment. I'm going to sleep a bit and then try a -j 4
build using this as a proof of concept. In any event, I'd like to know what
folks think of this solution.

Thanks in advance for your input.


/*
 * $Id: append.c,v 1.6 2002/06/06 10:12:42 mason Exp $
 *
 * Copyright (c) 2002 Mason Loring Bliss.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define BLOCKSIZE 1024

int main(int, char *[]);
void bail(void);

int
main(int argc, char *argv[])
{
	int i, file;
	unsigned char *buffer;

	if (argc !=3D 2) {
		fprintf(stderr, "usage: %s <file>\n", getprogname());
		exit(1);
	}

	buffer =3D (unsigned char *) malloc(BLOCKSIZE);
	if (! buffer)
		bail();

	file =3D open(argv[1], O_APPEND | O_CREAT | O_EXLOCK | O_WRONLY,
	    S_IRWXU | S_IRWXG | S_IRWXO);
	if (file =3D=3D -1)
		bail();

	for (i =3D 1; i; ) {
		i =3D read(0, buffer, BLOCKSIZE);
		if (i)
			if (write(file, buffer, i) =3D=3D -1)
				bail();
	}

	flock(file, LOCK_UN);
	close(file);

	return(0);
}

void
bail(void)
{
	fprintf(stderr, "%s: %s\n", getprogname(), strerror(errno));
	exit(1);
}

--=20
Mason Loring Bliss   mason@acheron.middleboro.ma.us   Ewige Blumenkraft!
https://www.deadsexy.org/  awake ? sleep : random() & 2 ? dream : sleep;

--mFM6r0jQWo48NPCK
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (NetBSD)
Comment: For info see http://www.gnupg.org

iD8DBQE8/zaUykMMY715wXIRAjRKAJ9iQiiEmqtF6FCVtmtytsoVGo9UEACg9ASS
LnBQUug/VavlakjTABOv4NM=
=mDjn
-----END PGP SIGNATURE-----

--mFM6r0jQWo48NPCK--