From b1aaba1fc8176ac0b7c202a664d2554aa0967116 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 20 Jan 2008 17:25:44 -0600 Subject: [PATCH] Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS() macros in each C file, and making generated/globals.h from that. Rename "toy" to "this" along the way to avoid toy/toys confusion. --- Makefile | 2 +- lib/args.c | 2 +- main.c | 2 +- scripts/install.c | 2 +- scripts/make.sh | 28 ++++++++++++- toys.h | 20 ++++++++- toys/df.c | 24 +++++++---- toys/dmesg.c | 7 +++- toys/mke2fs.c | 104 +++++++++++++++++++++++++++++------------------ toys/mkfifo.c | 10 ++++- toys/netcat.c | 12 +++++- toys/oneit.c | 7 +++- toys/patch.c | 12 +++++- toys/sed.c | 8 +++- toys/sleep.c | 4 ++ toys/touch.c | 16 ++++++-- toys/toylist.h | 118 ------------------------------------------------------ toys/toysh.c | 6 ++- 18 files changed, 201 insertions(+), 183 deletions(-) delete mode 100644 toys/toylist.h diff --git a/Makefile b/Makefile index cdb6c9c..f712788 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ install_flat: instlist clean:: rm -f toybox toybox_unstripped generated/config.h generated/Config.in \ - generated/newtoys.h instlist + generated/newtoys.h generated/globals.h instlist distclean: clean rm -f toybox_old .config* generated/help.h diff --git a/lib/args.c b/lib/args.c index 09939fb..96e1e6d 100644 --- a/lib/args.c +++ b/lib/args.c @@ -130,7 +130,7 @@ void get_optflags(void) char *str; int len; } *longopts = NULL; - long *nextarg = (long *)&toy; + long *nextarg = (long *)&this; char *options = toys.which->options; if (CFG_HELP) toys.exithelp++; diff --git a/main.c b/main.c index b7adeda..d9408f3 100644 --- a/main.c +++ b/main.c @@ -22,7 +22,7 @@ struct toy_list toy_list[] = { // global context for this applet. struct toy_context toys; -union toy_union toy; +union global_union this; char toybuf[4096]; struct toy_list *toy_find(char *name) diff --git a/scripts/install.c b/scripts/install.c index 5564fa5..317b180 100644 --- a/scripts/install.c +++ b/scripts/install.c @@ -14,7 +14,7 @@ // Populate toy_list[]. struct toy_list toy_list[] = { -#include "toys/toylist.h" +#include "generated/newtoys.h" }; #define TOY_LIST_LEN (sizeof(toy_list)/sizeof(struct toy_list)) diff --git a/scripts/make.sh b/scripts/make.sh index b5300d3..0833395 100755 --- a/scripts/make.sh +++ b/scripts/make.sh @@ -4,9 +4,11 @@ source ./configure -echo "Extract configuration information from toys/*.c files." +echo "Extract configuration information from toys/*.c files..." scripts/genconfig.sh +echo "Generate headers from toys/*.h..." + # Create a list of all the applets toybox can provide. Note that the first # entry is out of order on purpose (the toybox multiplexer applet must be the # first element of the array). The rest must be sorted in alphabetical order @@ -22,6 +24,30 @@ function newtoys() echo "NEWTOY(toybox, NULL, 0)" > generated/newtoys.h newtoys | sort >> generated/newtoys.h +# Extract global structure definitions from toys/*.c + +function getglobals() +{ + for i in toys/*.c + do + NAME="$(echo $i | sed 's@toys/\(.*\)\.c@\1@')" + + echo -e "// $i\n" + sed -n -e '/^DEFINE_GLOBALS(/,/^)/b got;b;:got' \ + -e 's/^DEFINE_GLOBALS(/struct '"$NAME"'_data {/' \ + -e 's/^)/};/' -e 'p' $i + done +} + +GLOBSTRUCT="$(getglobals)" +( + echo "$GLOBSTRUCT" + echo + echo "extern union global_union {" + echo "$GLOBSTRUCT" | sed -n 's/struct \(.*\)_data {/ struct \1_data \1;/p' + echo "} this;" +) > generated/globals.h + # Only recreate generated/help.h if python is installed if [ ! -z "$(which python)" ] && [ ! -z "$(grep 'CONFIG_HELP=y' .config)" ] then diff --git a/toys.h b/toys.h index 686d752..3c48fb8 100644 --- a/toys.h +++ b/toys.h @@ -39,13 +39,13 @@ #include "lib/lib.h" #include "toys/e2fs.h" -#include "toys/toylist.h" // Get list of function prototypes for all enabled command_main() functions. #define NEWTOY(name, opts, flags) void name##_main(void); #define OLDTOY(name, oldname, opts, flags) #include "generated/newtoys.h" +#include "generated/globals.h" // These live in main.c @@ -53,6 +53,22 @@ struct toy_list *toy_find(char *name); void toy_init(struct toy_list *which, char *argv[]); void toy_exec(char *argv[]); +// List of available applets + +#define TOYFLAG_USR (1<<0) +#define TOYFLAG_BIN (1<<1) +#define TOYFLAG_SBIN (1<<2) +#define TOYMASK_LOCATION ((1<<4)-1) + +#define TOYFLAG_NOFORK (1<<4) + +extern struct toy_list { + char *name; + void (*toy_main)(void); + char *options; + int flags; +} toy_list[]; + // Global context for any applet. extern struct toy_context { @@ -67,3 +83,5 @@ extern struct toy_context { // One big temporary buffer, for use by applets (not library functions). extern char toybuf[4096]; + +#define DEFINE_GLOBALS(...) diff --git a/toys/df.c b/toys/df.c index 6cc9e27..f5d2710 100644 --- a/toys/df.c +++ b/toys/df.c @@ -39,6 +39,14 @@ config DF_PEDANTIC #include "toys.h" +DEFINE_GLOBALS( + struct arg_list *fstype; + + long units; +) + +#define TT this.df + static void show_mt(struct mtab_list *mt) { int len; @@ -49,10 +57,10 @@ static void show_mt(struct mtab_list *mt) if (!mt) return; // If we have -t, skip other filesystem types - if (toy.df.fstype) { + if (TT.fstype) { struct arg_list *al; - for (al = toy.df.fstype; al; al = al->next) { + for (al = TT.fstype; al; al = al->next) { if (!strcmp(mt->type, al->arg)) break; } if (!al) return; @@ -64,12 +72,12 @@ static void show_mt(struct mtab_list *mt) // Figure out how much total/used/free space this filesystem has, // forcing 64-bit math because filesystems are big now. block = mt->statvfs.f_bsize ? : 1; - size = (long)((block * mt->statvfs.f_blocks) / toy.df.units); + size = (long)((block * mt->statvfs.f_blocks) / TT.units); used = (long)((block * (mt->statvfs.f_blocks-mt->statvfs.f_bfree)) - / toy.df.units); + / TT.units); avail = (long)((block * (getuid() ? mt->statvfs.f_bavail : mt->statvfs.f_bfree)) - / toy.df.units); + / TT.units); percent = size ? 100-(long)((100*(uint64_t)avail)/size) : 0; // Figure out appropriate spacing @@ -89,12 +97,12 @@ void df_main(void) struct mtab_list *mt, *mt2, *mtlist; // Handle -P and -k - toy.df.units = 1024; + TT.units = 1024; if (CFG_DF_PEDANTIC && (toys.optflags & 8)) { // Units are 512 bytes if you select "pedantic" without "kilobytes". - if ((toys.optflags&3) == 1) toy.df.units = 512; + if ((toys.optflags&3) == 1) TT.units = 512; printf("Filesystem %ld-blocks Used Available Capacity Mounted on\n", - toy.df.units); + TT.units); } else puts("Filesystem\t1K-blocks\tUsed Available Use% Mounted on"); mtlist = getmountlist(1); diff --git a/toys/dmesg.c b/toys/dmesg.c index a02de5a..95b023d 100644 --- a/toys/dmesg.c +++ b/toys/dmesg.c @@ -24,7 +24,12 @@ config DMESG #include "toys.h" #include -#define TT toy.dmesg +DEFINE_GLOBALS( + long level; + long size; +) + +#define TT this.dmesg void dmesg_main(void) { diff --git a/toys/mke2fs.c b/toys/mke2fs.c index e54cb85..cf31342 100644 --- a/toys/mke2fs.c +++ b/toys/mke2fs.c @@ -77,8 +77,35 @@ config MKE2FS_EXTENDED #include "toys.h" +DEFINE_GLOBALS( + // Command line arguments. + long blocksize; + long bytes_per_inode; + long inodes; // Total inodes in filesystem. + long reserved_percent; // Integer precent of space to reserve for root. + char *gendir; // Where to read dirtree from. + + // Internal data. + struct dirtree *dt; // Tree of files to copy into the new filesystem. + unsigned treeblocks; // Blocks used by dt + unsigned treeinodes; // Inodes used by dt + + unsigned blocks; // Total blocks in the filesystem. + unsigned freeblocks; // Free blocks in the filesystem. + unsigned inodespg; // Inodes per group + unsigned groups; // Total number of block groups. + unsigned blockbits; // Bits per block. (Also blocks per group.) + + // For gene2fs + unsigned nextblock; // Next data block to allocate + unsigned nextgroup; // Next group we'll be allocating from + int fsfd; // File descriptor of filesystem (to output to). + + struct ext2_superblock sb; +) + // Shortcut to our global data structure, since we use it so much. -#define TT toy.mke2fs +#define TT this.mke2fs #define INODES_RESERVED 10 @@ -140,20 +167,20 @@ static struct dirtree *treenext(struct dirtree *this) // Returns blocks used by this directory, assigns bytes used to *size. // Writes total block count to TT.treeblocks and inode count to TT.treeinodes. -static long check_treesize(struct dirtree *this, off_t *size) +static long check_treesize(struct dirtree *that, off_t *size) { long blocks; - while (this) { - *size += sizeof(struct ext2_dentry) + strlen(this->name); + while (that) { + *size += sizeof(struct ext2_dentry) + strlen(that->name); - if (this->child) - this->st.st_blocks = check_treesize(this->child, &this->st.st_size); - else if (S_ISREG(this->st.st_mode)) { - this->st.st_blocks = file_blocks_used(this->st.st_size, 0); - TT.treeblocks += this->st.st_blocks; + if (that->child) + that->st.st_blocks = check_treesize(that->child, &that->st.st_size); + else if (S_ISREG(that->st.st_mode)) { + that->st.st_blocks = file_blocks_used(that->st.st_size, 0); + TT.treeblocks += that->st.st_blocks; } - this = this->next; + that = that->next; } TT.treeblocks += blocks = file_blocks_used(*size, 0); TT.treeinodes++; @@ -170,30 +197,31 @@ static long check_treesize(struct dirtree *this, off_t *size) static void check_treelinks(struct dirtree *tree) { - struct dirtree *this=tree, *that; + struct dirtree *current=tree, *that; long inode = INODES_RESERVED; - while (this) { + while (current) { ++inode; // Since we can't hardlink to directories, we know their link count. - if (S_ISDIR(this->st.st_mode)) this->st.st_nlink = 2; + if (S_ISDIR(current->st.st_mode)) current->st.st_nlink = 2; else { - dev_t new = this->st.st_dev; + dev_t new = current->st.st_dev; if (!new) continue; - this->st.st_nlink = 0; + // Look for other copies of current node + current->st.st_nlink = 0; for (that = tree; that; that = treenext(that)) { - if (this->st.st_ino == that->st.st_ino && - this->st.st_dev == that->st.st_dev) + if (current->st.st_ino == that->st.st_ino && + current->st.st_dev == that->st.st_dev) { - this->st.st_nlink++; - this->st.st_ino = inode; + current->st.st_nlink++; + current->st.st_ino = inode; } } } - this->st.st_ino = inode; - this = treenext(this); + current->st.st_ino = inode; + current = treenext(current); } } @@ -363,15 +391,15 @@ static void put_zeroes(int len) } // Fill out an inode structure from struct stat info in dirtree. -static void fill_inode(struct ext2_inode *in, struct dirtree *this) +static void fill_inode(struct ext2_inode *in, struct dirtree *that) { uint32_t fbu[15]; int temp; - file_blocks_used(this->st.st_size, fbu); + file_blocks_used(that->st.st_size, fbu); - // If this inode needs data blocks allocated to it. - if (this->st.st_size) { + // If that inode needs data blocks allocated to it. + if (that->st.st_size) { int i, group = TT.nextblock/TT.blockbits; // TODO: teach this about indirect blocks. @@ -382,26 +410,26 @@ static void fill_inode(struct ext2_inode *in, struct dirtree *this) } } // TODO : S_ISREG/DIR/CHR/BLK/FIFO/LNK/SOCK(m) - in->mode = SWAP_LE32(this->st.st_mode); + in->mode = SWAP_LE32(that->st.st_mode); - in->uid = SWAP_LE16(this->st.st_uid & 0xFFFF); - in->uid_high = SWAP_LE16(this->st.st_uid >> 16); - in->gid = SWAP_LE16(this->st.st_gid & 0xFFFF); - in->gid_high = SWAP_LE16(this->st.st_gid >> 16); - in->size = SWAP_LE32(this->st.st_size & 0xFFFFFFFF); + in->uid = SWAP_LE16(that->st.st_uid & 0xFFFF); + in->uid_high = SWAP_LE16(that->st.st_uid >> 16); + in->gid = SWAP_LE16(that->st.st_gid & 0xFFFF); + in->gid_high = SWAP_LE16(that->st.st_gid >> 16); + in->size = SWAP_LE32(that->st.st_size & 0xFFFFFFFF); // Contortions to make the compiler not generate a warning for x>>32 // when x is 32 bits. The optimizer should clean this up. - if (sizeof(this->st.st_size) > 4) temp = 32; + if (sizeof(that->st.st_size) > 4) temp = 32; else temp = 0; - if (temp) in->dir_acl = SWAP_LE32(this->st.st_size >> temp); + if (temp) in->dir_acl = SWAP_LE32(that->st.st_size >> temp); - in->atime = SWAP_LE32(this->st.st_atime); - in->ctime = SWAP_LE32(this->st.st_ctime); - in->mtime = SWAP_LE32(this->st.st_mtime); + in->atime = SWAP_LE32(that->st.st_atime); + in->ctime = SWAP_LE32(that->st.st_ctime); + in->mtime = SWAP_LE32(that->st.st_mtime); - in->links_count = SWAP_LE16(this->st.st_nlink); - in->blocks = SWAP_LE32(this->st.st_blocks); + in->links_count = SWAP_LE16(that->st.st_nlink); + in->blocks = SWAP_LE32(that->st.st_blocks); // in->faddr } diff --git a/toys/mkfifo.c b/toys/mkfifo.c index 5ddfa6c..0f57ca5 100644 --- a/toys/mkfifo.c +++ b/toys/mkfifo.c @@ -21,6 +21,12 @@ config MKFIFO #include "toys.h" +DEFINE_GLOBALS( + char *mode; +) + +#define TT this.mkfifo + void mkfifo_main(void) { char *arg; @@ -29,8 +35,8 @@ void mkfifo_main(void) if (toys.optflags) { char *end; - mode = (mode_t)strtol(toy.mkfifo.mode, &end, 8); - if (end<=toy.mkfifo.mode || *end || mode<0 || mode>0777) + mode = (mode_t)strtol(TT.mode, &end, 8); + if (end<=TT.mode || *end || mode<0 || mode>0777) error_exit("Invalid mode"); } else mode = 0644; diff --git a/toys/netcat.c b/toys/netcat.c index ed7a887..f5024c9 100644 --- a/toys/netcat.c +++ b/toys/netcat.c @@ -33,7 +33,17 @@ config NETCAT #include "toys.h" #include "toynet.h" -#define TT toy.netcat +DEFINE_GLOBALS( + char *filename; // -f read from filename instead of network + long quit_delay; // -q Exit after EOF from stdin after # seconds. + char *source_address; // -s Bind to a specific source address. + long port; // -p Bind to a specific source port. + long listen; // -l Listen for connection instead of dialing out. + long wait; // -w Wait # seconds for a connection. + long delay; // -i delay between lines sent +) + +#define TT this.netcat static void timeout(int signum) { diff --git a/toys/oneit.c b/toys/oneit.c index 991eba1..4c36491 100644 --- a/toys/oneit.c +++ b/toys/oneit.c @@ -29,6 +29,12 @@ config ONEIT #include "toys.h" #include +DEFINE_GLOBALS( + char *console; +) + +#define TT this.oneit + // The minimum amount of work necessary to get ctrl-c and such to work is: // // - Fork a child (PID 1 is special: can't exit, has various signals blocked). @@ -39,7 +45,6 @@ config ONEIT // PID 1 then reaps zombies until the child process it spawned exits, at which // point it calls sync() and reboot(). I could stick a kill -1 in there. -#define TT toy.oneit void oneit_main(void) { diff --git a/toys/patch.c b/toys/patch.c index 9ec748e..34d33c7 100644 --- a/toys/patch.c +++ b/toys/patch.c @@ -45,7 +45,17 @@ config PATCH #include "toys.h" -#define TT toy.patch +DEFINE_GLOBALS( + char *infile; + long prefix; + + struct double_list *plines, *flines; + long oldline, oldlen, newline, newlen, linenum; + int context, state, filein, fileout, filepatch; + char *tempname, *oldname; +) + +#define TT this.patch #define FLAG_REVERSE 1 #define FLAG_PATHLEN 4 diff --git a/toys/sed.c b/toys/sed.c index b3800d8..c4eb1a4 100644 --- a/toys/sed.c +++ b/toys/sed.c @@ -21,6 +21,12 @@ config SED #include "toys.h" #include "lib/xregcomp.h" +DEFINE_GLOBALS( + struct arg_list *commands; +) + +#define TT this.sed + struct sed_command { // Doubly linked list of commands. struct sed_command *next, *prev; @@ -46,8 +52,6 @@ struct sed_command { char command; }; -#define TT toy.sed - void sed_main(void) { struct arg_list *test; diff --git a/toys/sleep.c b/toys/sleep.c index 55a6b97..7052eca 100644 --- a/toys/sleep.c +++ b/toys/sleep.c @@ -19,6 +19,10 @@ config SLEEP #include "toys.h" +DEFINE_GLOBALS( + long seconds; +) + void sleep_main(void) { toys.exitval = sleep(atol(*toys.optargs)); diff --git a/toys/touch.c b/toys/touch.c index 65afe58..c8cba76 100644 --- a/toys/touch.c +++ b/toys/touch.c @@ -26,6 +26,14 @@ config TOUCH #include "toys.h" +DEFINE_GLOBALS( + char *ref_file; + char *time; + long length; +) + +#define TT this.touch + #define OPT_MTIME 0x01 #define OPT_NOCREATE 0x02 #define OPT_ATIME 0x04 @@ -48,7 +56,7 @@ void touch_main(void) if (toys.optflags & OPT_TIME) error_exit("Redundant time source"); - xstat(toy.touch.ref_file, &sb); + xstat(TT.ref_file, &sb); curr_m = sb.st_mtime; curr_a = sb.st_atime; @@ -60,10 +68,10 @@ void touch_main(void) curr = time(NULL); if (localtime_r(&curr, &t) - || !(c = strptime(toy.touch.time, "%m%d%H%M", &t)) + || !(c = strptime(TT.time, "%m%d%H%M", &t)) || *c || -1==(curr_a = curr_m = mktime(&t))) { - error_exit("Unknown time %s", toy.touch.time); + error_exit("Unknown time %s", TT.time); } // use current time @@ -93,7 +101,7 @@ void touch_main(void) } if (toys.optflags & OPT_LENGTH) - if (truncate(arg, toy.touch.length)) + if (truncate(arg, TT.length)) goto error; if (utime(arg, &buf)) error: diff --git a/toys/toylist.h b/toys/toylist.h deleted file mode 100644 index 135310a..0000000 --- a/toys/toylist.h +++ /dev/null @@ -1,118 +0,0 @@ -/* vi: set ts=4 :*/ -/* Toybox infrastructure. - * - * Copyright 2006 Rob Landley - */ - - -struct df_data { - struct arg_list *fstype; - - long units; -}; - -struct dmesg_data { - long level; - long size; -}; - -struct mke2fs_data { - // Command line arguments. - long blocksize; - long bytes_per_inode; - long inodes; // Total inodes in filesystem. - long reserved_percent; // Integer precent of space to reserve for root. - char *gendir; // Where to read dirtree from. - - // Internal data. - struct dirtree *dt; // Tree of files to copy into the new filesystem. - unsigned treeblocks; // Blocks used by dt - unsigned treeinodes; // Inodes used by dt - - unsigned blocks; // Total blocks in the filesystem. - unsigned freeblocks; // Free blocks in the filesystem. - unsigned inodespg; // Inodes per group - unsigned groups; // Total number of block groups. - unsigned blockbits; // Bits per block. (Also blocks per group.) - - // For gene2fs - unsigned nextblock; // Next data block to allocate - unsigned nextgroup; // Next group we'll be allocating from - int fsfd; // File descriptor of filesystem (to output to). - - struct ext2_superblock sb; -}; - -struct mkfifo_data { - char *mode; -}; - -struct netcat_data { - char *filename; // -f read from filename instead of network - long quit_delay; // -q Exit after EOF from stdin after # seconds. - char *source_address; // -s Bind to a specific source address. - long port; // -p Bind to a specific source port. - long listen; // -l Listen for connection instead of dialing out. - long wait; // -w Wait # seconds for a connection. - long delay; // -i delay between lines sent -}; - -struct oneit_data { - char *console; -}; - -struct patch_data { - char *infile; - long prefix; - - struct double_list *plines, *flines; - long oldline, oldlen, newline, newlen, linenum; - int context, state, filein, fileout, filepatch; - char *tempname, *oldname; -}; - -struct sed_data { - struct arg_list *commands; -}; - -struct sleep_data { - long seconds; -}; - -struct touch_data { - char *ref_file; - char *time; - long length; -}; - -struct toysh_data { - char *command; -}; - -extern union toy_union { - struct dmesg_data dmesg; - struct df_data df; - struct mke2fs_data mke2fs; - struct mkfifo_data mkfifo; - struct netcat_data netcat; - struct oneit_data oneit; - struct patch_data patch; - struct sed_data sed; - struct sleep_data sleep; - struct touch_data touch; - struct toysh_data toysh; -} toy; - -#define TOYFLAG_USR (1<<0) -#define TOYFLAG_BIN (1<<1) -#define TOYFLAG_SBIN (1<<2) -#define TOYMASK_LOCATION ((1<<4)-1) - -#define TOYFLAG_NOFORK (1<<4) - -extern struct toy_list { - char *name; - void (*toy_main)(void); - char *options; - int flags; -} toy_list[]; diff --git a/toys/toysh.c b/toys/toysh.c index 15c7811..e280068 100644 --- a/toys/toysh.c +++ b/toys/toysh.c @@ -170,7 +170,11 @@ config CD_P #include "toys.h" -#define TT toy.toysh +DEFINE_GLOBALS( + char *command; +) + +#define TT this.toysh // A single executable, its arguments, and other information we know about it. #define TOYSH_FLAG_EXIT 1 -- 2.7.4