First impressions of the "getopt.h forrest"

Mats Erik Andersson mats.andersson64 at comhem.se
Tue Mar 27 11:54:09 UTC 2007


Hi all busy Boxers,

encouraged by answers of Bernard Fischer and Denis Vlasenko
I began auditing the methodology with which Busybox finds
access to the getopt library code. There are indeed sevaral
points of departure in there, hence "getopt.h forrest".

This message is a kind of "proof of concept" on my behalf,
and it is me fishing for comments from people more proficient
with the code in Busybox than I am myself. I will be quite
lengthy, so stop reading now if you do not feel concerned.

My provisional goal is this:

	Find and remove unnecessary references to GNU-getopt
	in order that getopt-susv3 be a viable choice for
	at least minimal configurations of Busybox.

In particular, this means identifying places where getopt_long
ought to be avoided or forced to be explicitly invoked in a 
configuration by the system builder. For this posting I must
disregard anything that depends on getopt32, a speciality of
Busybox, to get starting at all.

Let me remark on the header file include/getopt.h to motivate
my later statements. Our library uClibc makes include/getopt.h
contain nothing but an inclusion of include/bits/getopt.h. This
file, in its turn, has two major modes of invokation:

  1)	#define __need_getopt
	#include <bits/getopt.h>

	This is effectuated by unistd.h.

	This essentially declares  getopt(argc,argv,optstring)
	and four external variables. Nothing more. Two important
	points are that this is compatible with getopt-susv3,
	and that this inclusion is performed by the Busybox header
	chain

		busybox.h -> libbb.h -> unistd.h

  2)	#undefine __need_getopt    /* or no mention of __need_getopt */
	#include <getopt.h>
		or
	#include <bits/getopt.h>

	This performs case 1) and additionally declares 
	getopt_long(...) and getopt_long_only(...), thus
	forcing upon us the full power of GNU-getopt and
	preventing any hope of using uClibc with only
        getopt-susv3 compiled into the library.

That being said, my provisional goal must address measures to
eliminate case 2) whenever possible. Whenever the analysis
admits it, it is a matter of doing

   /* Replacing #include <getopt.h> by */
   #include <unistd.h>   /* for getopt-susv3 compatibility! */

Using 'grep' I constructed a list of all source files in
Busybox 1.4.0 which call upon getopt.h without using getopt32,
and I did a quick crosscheck against busybox-20070327 to be safe.
This test is done against 1.4.0 since I run two minimal, but different,
systems based on that Busybox edition, and thus can test quickly. The
hits are as follows. I comment individually on them afterwards.

coreutils/od.c
debianutils/run_parts.c
e2fsprogs/old_e2fsprogs/blkid/dev.c
e2fsprogs/old_e2fsprogs/blkid/tag.c
e2fsprogs/old_e2fsprogs/e2fsck.h
e2fsprogs/old_e2fsprogs/mke2fs.c
e2fsprogs/old_e2fsprogs/tune2fs.c
networking/udhcp/dumpleases.c
shell/hush.c
util-linux/getopt.c
util-linux/hexdump.c

a) od.c and hexdump.c are very similar. They do not use
   long options only standard getopt(argc,argv,opts). 
   Therefore I tested an alteration to hexdump.c:

#include "busybox.h"
/* #include <getopt.h>  Declaration is already in  
      busybox.h->libbb.h->unistd.h */
#include "dump.h"

   Of course I gained nothing except a functional busybox 
   binary of the same size, but it compiles without errors
   and I know (believe?) that getopt-susv3 suffices for od/hexdump.

b) run_parts.c is an odd fellow. There is a configuration option
   CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS that is never used in the
   C code, which in its turn is written using getopt_long, but is
   almost trivially converted to using only short options and
   thus getopt-susv3.

c) dumpleases.c is constructed using getopt_long, but can easily
   be altered for conditional compilation to use getopt() and only
   short options.

d) hush.c is clearly coded with short options, yet uses the full
   include/getopt.h. I se no reason it should not respond well to
   an alteration

   /* #include <getopt.h> */
   #include <unistd.h>
   
e) The applet getopt.c is intentionally built to be GNU-getopt
   conformant, but is discretional as all applets are. Disregarded!

f) I disregards those files in e2fsprogs/old_e2fsprogs, since of the
   three applets for busybox, chattr and fsck do their own parsing on
   short options, and lsattr relies on getopt32, but uses only short
   options. There is a TODO inside fsck.c that expresses a desire to
   convert to getopt32, but as of now a better option would be to strive
   towards susv3 compatibility at the sametime.

Feel free to comment on my errors, presumptions, predjudice, or the
futility of this undertaking. Just do not hold me for completely
ignorant, even though I do lack most of your intimate knowledge of
Busybox' overall structure.

With all best intentions, I apologise for my lengthy discussion,
and offer my regards to the thus far diligent reader

	Mats Erik Andersson



More information about the busybox mailing list