Subject: lib/630: usr.bin/rdist doesn't link due to multiply defined ``warn''
To: None <gnats-admin@sun-lamp.cs.berkeley.edu>
From: None <jonathan@DSG.Stanford.EDU>
List: netbsd-bugs
Date: 12/11/1994 08:35:33
>Number:         630
>Category:       lib
>Synopsis:       libc/gen/getnetgrent.c calling ``warnx()'' breaks rdist and lpd
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    lib-bug-people (Library Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Dec 11 08:35:32 1994
>Originator:     Jonathan Stone
>Organization:
Stanford Distributed Systems Group
>Release:        NetBSD-current at December 10, 1994
>Environment:
System: NetBSD Reno.Stanford.EDU 1.0A NetBSD 1.0A (RENO) #62: Fri Dec 9 00:42:34 PST 1994 jonathan@Reno.Stanford.EDU:/greyhawk/n1/src/NetBSD/src/sys/arch/pmax/compile/RENO pmax


>Description:

The problem is this: A reference to innetgr is causing the linker to pull
in getnetgrent.o.  getnetgrent.o is, in turn, references warnx().  To
resolve that reference. the linker is pulling in err.o from libc.a. Then,
err.o provides its own definition of ``warn()'', the one documented
in the manpage for warn(3).

src/usr.bin/rdist/main.c defines its own function ``warn()''.
This results in a ``multiple definition of _warn' message from the
linker.

	This is essentially a namespace intrusion problem, coupled
	with the fact that _all_ the functions described in ''man 3 err''
	reside in a single source file; causing an intrusion of any
	one of them (e.g., due to a reference from libc.a) to cause
	_all_ those functions to intrude into a program's namespace.

>How-To-Repeat:
	Making and installing libc.a from current at Dec 10 1994,
	then ``cd /src/usr.bin/rdist; make -k''
	should suffice.  I don't believe this is specific to the pmax.

>Fix:
	Introduce a new function, __warnx(), that does what warnx() does
	now.  Change warnx() to simply call __warnx(). Change all
	occurences of ``warnx()'' under src/lib/libc to call ``__warnx()''
	instead.   Place all functions documented in the manpage for
	err(3) into their own source files, so that any one of them
	can be redefined by an application that defines its own function
	``warn()'', ``err()'', etc., but still wishes to call the  functions
	defined in the manpage for err(3).

	Alternatively, use weak references.  However the calls to
	`warnx()'', and other functions described in ``man 3 err'',
	from within libc would still need to be fixed.

	A complete list of offending object files in libc.a can be found
	from the following command:
	nm -p /usr/lib/libc.a | egrep '.o:$|U _warn| _err| _vwarn| _verr'
	| grep -v '_errno$' | more
	which shows the follwoing offenders:
		initgroups.o
		getnetgret.o
		getbsize.o
		devname.o
	Yet a third alternative is to rewrite rdist and lpr to use
	the 4.4bsd version of warn().  I don't like this, because
	I don't see how rdist could then cleanly provide the line
	numbers of unparseable lines in its error messages, as it
	does now.
>Audit-Trail:
>Unformatted: