dpkg: trivial code shrinkage, and redo G trick correctly.

function                                             old     new   delta
run_package_script_or_die                              -      72     +72
fill_package_struct                                  303     309      +6
search_package_hashtable                             122     125      +3
get_status                                           112     111      -1
status_hashtable                                       4       -      -4
set_status                                           162     158      -4
package_hashtable                                      4       -      -4
name_hashtable                                         4       -      -4
package_satisfies_dependency                         112     106      -6
search_name_hashtable                                118     110      -8
configure_package                                    121     106     -15
remove_package                                       333     317     -16
search_status_hashtable                              133     111     -22
purge_package                                        247     217     -30
unpack_package                                       552     521     -31
run_package_script                                    62       -     -62
dpkg_main                                           3991    3867    -124
------------------------------------------------------------------------------
(add/remove: 1/4 grow/shrink: 2/10 up/down: 81/-331)         Total: -250 bytes
   text    data     bss     dec     hex filename
 807972     611    6924  815507   c7193 busybox_old
 807603     611    6908  815122   c7012 busybox_unstripped
This commit is contained in:
Denis Vlasenko 2008-06-21 23:15:43 +00:00
parent d235f58ac2
commit c87339d584

View File

@ -75,10 +75,21 @@ typedef struct status_node_s {
unsigned status:16; /* was:14 */ /* has to fit STATUS_HASH_PRIME */ unsigned status:16; /* was:14 */ /* has to fit STATUS_HASH_PRIME */
} status_node_t; } status_node_t;
/* Were statically declared here, but such a big bss is nommu-unfriendly */
static char **name_hashtable; /* [NAME_HASH_PRIME + 1] */ /* Globals */
static common_node_t **package_hashtable; /* [PACKAGE_HASH_PRIME + 1] */ struct globals {
static status_node_t **status_hashtable; /* [STATUS_HASH_PRIME + 1] */ char *name_hashtable[NAME_HASH_PRIME + 1];
common_node_t *package_hashtable[PACKAGE_HASH_PRIME + 1];
status_node_t *status_hashtable[STATUS_HASH_PRIME + 1];
};
#define G (*ptr_to_globals)
#define name_hashtable (G.name_hashtable )
#define package_hashtable (G.package_hashtable)
#define status_hashtable (G.status_hashtable )
#define INIT_G() do { \
SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
} while (0)
/* Even numbers are for 'extras', like ored dependencies or null */ /* Even numbers are for 'extras', like ored dependencies or null */
enum edge_type_e { enum edge_type_e {
@ -312,7 +323,6 @@ static int test_version(const unsigned version1, const unsigned version2, const
return FALSE; return FALSE;
} }
static int search_package_hashtable(const unsigned name, const unsigned version, const unsigned operator) static int search_package_hashtable(const unsigned name, const unsigned version, const unsigned operator)
{ {
unsigned probe_address; unsigned probe_address;
@ -731,7 +741,6 @@ static const char *describe_status(int status_num)
return "is not installed or flagged to be installed"; return "is not installed or flagged to be installed";
} }
static void index_status_file(const char *filename) static void index_status_file(const char *filename)
{ {
FILE *status_file; FILE *status_file;
@ -1203,25 +1212,25 @@ static int remove_file_array(char **remove_names, char **exclude_names)
return (remove_flag == 0); return (remove_flag == 0);
} }
static int run_package_script(const char *package_name, const char *script_type) static void run_package_script_or_die(const char *package_name, const char *script_type)
{ {
struct stat path_stat;
char *script_path; char *script_path;
int result; int result;
script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type); script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type);
/* If the file doesnt exist is isnt a fatal */ /* If the file doesnt exist is isnt fatal */
result = lstat(script_path, &path_stat) < 0 ? EXIT_SUCCESS : system(script_path); result = access(script_path, F_OK) ? EXIT_SUCCESS : system(script_path);
free(script_path); free(script_path);
return result; if (result)
bb_error_msg_and_die("%s failed, exit code %d", script_type, result);
} }
/* /*
The policy manual defines what scripts get called when and with The policy manual defines what scripts get called when and with
what arguments. I realize that busybox does not support all of what arguments. I realize that busybox does not support all of
these scenarios, but it does support some of them; it does not, these scenarios, but it does support some of them; it does not,
however, run them with any parameters in run_package_script(). however, run them with any parameters in run_package_script_or_die().
Here are the scripts: Here are the scripts:
preinst install preinst install
@ -1335,10 +1344,8 @@ static void remove_package(const unsigned package_num, int noisy)
if (noisy) if (noisy)
printf("Removing %s (%s)...\n", package_name, package_version); printf("Removing %s (%s)...\n", package_name, package_version);
/* run prerm script */ /* Run prerm script */
if (run_package_script(package_name, "prerm") != 0) { run_package_script_or_die(package_name, "prerm");
bb_error_msg_and_die("script failed, prerm failure");
}
/* Create a list of files to remove, and a separate list of those to keep */ /* Create a list of files to remove, and a separate list of those to keep */
sprintf(list_name, "/var/lib/dpkg/info/%s.%s", package_name, "list"); sprintf(list_name, "/var/lib/dpkg/info/%s.%s", package_name, "list");
@ -1348,7 +1355,8 @@ static void remove_package(const unsigned package_num, int noisy)
exclude_files = create_list(conffile_name); exclude_files = create_list(conffile_name);
/* Some directories can't be removed straight away, so do multiple passes */ /* Some directories can't be removed straight away, so do multiple passes */
while (remove_file_array(remove_files, exclude_files)) /*repeat */; while (remove_file_array(remove_files, exclude_files))
continue;
free_array(exclude_files); free_array(exclude_files);
free_array(remove_files); free_array(remove_files);
@ -1384,10 +1392,8 @@ static void purge_package(const unsigned package_num)
printf("Purging %s (%s)...\n", package_name, package_version); printf("Purging %s (%s)...\n", package_name, package_version);
/* run prerm script */ /* Run prerm script */
if (run_package_script(package_name, "prerm") != 0) { run_package_script_or_die(package_name, "prerm");
bb_error_msg_and_die("script failed, prerm failure");
}
/* Create a list of files to remove */ /* Create a list of files to remove */
sprintf(list_name, "/var/lib/dpkg/info/%s.%s", package_name, "list"); sprintf(list_name, "/var/lib/dpkg/info/%s.%s", package_name, "list");
@ -1405,10 +1411,8 @@ static void purge_package(const unsigned package_num)
free_array(remove_files); free_array(remove_files);
free(exclude_files); free(exclude_files);
/* run postrm script */ /* Run postrm script */
if (run_package_script(package_name, "postrm") != 0) { run_package_script_or_die(package_name, "postrm");
bb_error_msg_and_die("postrm failure.. set status to what?");
}
/* Change package status */ /* Change package status */
set_status(status_num, "not-installed", 3); set_status(status_num, "not-installed", 3);
@ -1532,10 +1536,7 @@ static void unpack_package(deb_file_t *deb_file)
unpack_ar_archive(archive_handle); unpack_ar_archive(archive_handle);
/* Run the preinst prior to extracting */ /* Run the preinst prior to extracting */
if (run_package_script(package_name, "preinst") != 0) { run_package_script_or_die(package_name, "preinst");
/* when preinst returns exit code != 0 then quit installation process */
bb_error_msg_and_die("subprocess pre-installation script returned error");
}
/* Extract data.tar.gz to the root directory */ /* Extract data.tar.gz to the root directory */
archive_handle = init_archive_deb_ar(deb_file->filename); archive_handle = init_archive_deb_ar(deb_file->filename);
@ -1573,10 +1574,9 @@ static void configure_package(deb_file_t *deb_file)
printf("Setting up %s (%s)...\n", package_name, package_version); printf("Setting up %s (%s)...\n", package_name, package_version);
/* Run the postinst script */ /* Run the postinst script */
if (run_package_script(package_name, "postinst") != 0) { /* TODO: handle failure gracefully */
/* TODO: handle failure gracefully */ run_package_script_or_die(package_name, "postinst");
bb_error_msg_and_die("postinst failure.. set status to what?");
}
/* Change status to reflect success */ /* Change status to reflect success */
set_status(status_num, "install", 1); set_status(status_num, "install", 1);
set_status(status_num, "installed", 3); set_status(status_num, "installed", 3);
@ -1604,6 +1604,8 @@ int dpkg_main(int argc ATTRIBUTE_UNUSED, char **argv)
OPT_unpack = 0x40, OPT_unpack = 0x40,
}; };
INIT_G();
opt = getopt32(argv, "CF:ilPru", &str_f); opt = getopt32(argv, "CF:ilPru", &str_f);
//if (opt & OPT_configure) ... // -C //if (opt & OPT_configure) ... // -C
if (opt & OPT_force_ignore_depends) { // -F (--force in official dpkg) if (opt & OPT_force_ignore_depends) { // -F (--force in official dpkg)
@ -1620,10 +1622,6 @@ int dpkg_main(int argc ATTRIBUTE_UNUSED, char **argv)
if (!opt || (!argv[0] && !(opt && OPT_list_installed))) if (!opt || (!argv[0] && !(opt && OPT_list_installed)))
bb_show_usage(); bb_show_usage();
name_hashtable = xzalloc(sizeof(name_hashtable[0]) * (NAME_HASH_PRIME + 1));
package_hashtable = xzalloc(sizeof(package_hashtable[0]) * (PACKAGE_HASH_PRIME + 1));
status_hashtable = xzalloc(sizeof(status_hashtable[0]) * (STATUS_HASH_PRIME + 1));
/* puts("(Reading database ... xxxxx files and directories installed.)"); */ /* puts("(Reading database ... xxxxx files and directories installed.)"); */
index_status_file("/var/lib/dpkg/status"); index_status_file("/var/lib/dpkg/status");