diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/.gitignore | 1 | ||||
-rw-r--r-- | src/coreutils-arch.c | 32 | ||||
-rw-r--r-- | src/coreutils-dir.c | 32 | ||||
-rw-r--r-- | src/coreutils-vdir.c | 32 | ||||
-rw-r--r-- | src/coreutils.c | 205 | ||||
-rw-r--r-- | src/kill.c | 6 | ||||
-rw-r--r-- | src/local.mk | 61 | ||||
-rw-r--r-- | src/readlink.c | 2 | ||||
-rw-r--r-- | src/shuf.c | 2 | ||||
-rw-r--r-- | src/timeout.c | 8 | ||||
-rw-r--r-- | src/truncate.c | 2 |
11 files changed, 373 insertions, 10 deletions
diff --git a/src/.gitignore b/src/.gitignore index e273bb867..e8bccbae5 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -12,6 +12,7 @@ chown chroot cksum comm +coreutils cp csplit cut diff --git a/src/coreutils-arch.c b/src/coreutils-arch.c new file mode 100644 index 000000000..899cc937b --- /dev/null +++ b/src/coreutils-arch.c @@ -0,0 +1,32 @@ +/* arch -- wrapper to uname with the right uname_mode. + Copyright (C) 2014 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Alex Deymo <deymo@chromium.org>. */ + +#include <config.h> +#include "system.h" + +#include "uname.h" +/* Ensure that the main for uname is declared even if the tool is not being + built in this single-binary. */ +int _single_binary_main_uname (int argc, char** argv) ATTRIBUTE_NORETURN; +int _single_binary_main_arch (int argc, char** argv) ATTRIBUTE_NORETURN; + +int _single_binary_main_arch (int argc, char** argv) +{ + uname_mode = UNAME_ARCH; + _single_binary_main_uname (argc, argv); +} diff --git a/src/coreutils-dir.c b/src/coreutils-dir.c new file mode 100644 index 000000000..4b488f415 --- /dev/null +++ b/src/coreutils-dir.c @@ -0,0 +1,32 @@ +/* dir -- wrapper to ls with the right ls_mode. + Copyright (C) 2014 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Alex Deymo <deymo@chromium.org>. */ + +#include <config.h> +#include "system.h" + +#include "ls.h" +/* Ensure that the main for ls is declared even if the tool is not being built + in this single-binary. */ +int _single_binary_main_ls (int argc, char** argv) ATTRIBUTE_NORETURN; +int _single_binary_main_dir (int argc, char** argv) ATTRIBUTE_NORETURN; + +int _single_binary_main_dir (int argc, char** argv) +{ + ls_mode = LS_MULTI_COL; + _single_binary_main_ls (argc, argv); +} diff --git a/src/coreutils-vdir.c b/src/coreutils-vdir.c new file mode 100644 index 000000000..036367f6d --- /dev/null +++ b/src/coreutils-vdir.c @@ -0,0 +1,32 @@ +/* vdir -- wrapper to ls with the right ls_mode. + Copyright (C) 2014 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Alex Deymo <deymo@chromium.org>. */ + +#include <config.h> +#include "system.h" + +#include "ls.h" +/* Ensure that the main for ls is declared even if the tool is not being built + in this single-binary. */ +int _single_binary_main_ls (int argc, char** argv) ATTRIBUTE_NORETURN; +int _single_binary_main_vdir (int argc, char** argv) ATTRIBUTE_NORETURN; + +int _single_binary_main_vdir (int argc, char** argv) +{ + ls_mode = LS_LONG_FORMAT; + _single_binary_main_ls (argc, argv); +} diff --git a/src/coreutils.c b/src/coreutils.c new file mode 100644 index 000000000..c459b1d62 --- /dev/null +++ b/src/coreutils.c @@ -0,0 +1,205 @@ +/* Copyright (C) 2014 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* coreutils.c aggregates the functionality of every other tool into a single + binary multiplexed by the value of argv[0]. This is enabled by passing + --enable-single-binary to configure. + + Written by Alex Deymo <deymo@chromium.org>. */ + +#include <config.h> +#include <getopt.h> +#include <stdio.h> +#if HAVE_PRCTL +# include <sys/prctl.h> +#endif + +#include "system.h" +#include "error.h" +#include "quote.h" + +#ifdef SINGLE_BINARY +/* Declare the main function on each one of the selected tools. This name + needs to match the one passed as CFLAGS on single-binary.mk (generated + by gen-single-binary.sh). */ +# define SINGLE_BINARY_PROGRAM(prog_name_str, main_name) \ + int _single_binary_main_##main_name (int, char**) ATTRIBUTE_NORETURN; +# include "coreutils.h" +# undef SINGLE_BINARY_PROGRAM +#endif + +/* The official name of this program (e.g., no 'g' prefix). */ +#define PROGRAM_NAME "coreutils" + +#define AUTHORS \ + proper_name ("Alex Deymo") + +void +launch_program (const char *prog_name, int prog_argc, char **prog_argv); + +static struct option const long_options[] = +{ + {GETOPT_HELP_OPTION_DECL}, + {GETOPT_VERSION_OPTION_DECL}, + {NULL, 0, NULL, 0} +}; + + +void +usage (int status) +{ + if (status != EXIT_SUCCESS) + emit_try_help (); + else + { + printf (_("\ +Usage: %s --coreutils-prog=PROGRAM_NAME [PARAMETERS]... \n"), + program_name); + fputs (_("\ +Execute the PROGRAM_NAME built-in program with the given PARAMETERS.\n\ +\n"), stdout); + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); + + printf ("\n\ +Built-in programs:\n" +#ifdef SINGLE_BINARY +/* XXX: Ideally we#d like to present "install" here, not "ginstall". */ +# define SINGLE_BINARY_PROGRAM(prog_name_str, main_name) " " prog_name_str +# include "coreutils.h" +# undef SINGLE_BINARY_PROGRAM +#endif + "\n"); + + printf (_("\ +\n\ +Use: '%s --coreutils-prog=PROGRAM_NAME --help' for individual program help.\n"), + program_name); + emit_ancillary_info (); + } + exit (status); +} + +void +launch_program (const char *prog_name, int prog_argc, char **prog_argv) +{ + int (*prog_main)(int, char **) = NULL; + + /* Ensure that at least one parameter was passed. */ + if (!prog_argc || !prog_argv || !prog_argv[0] || !prog_name) + return; + +#ifdef SINGLE_BINARY + if (false); + /* Lookup the right main program. */ +# define SINGLE_BINARY_PROGRAM(prog_name_str, main_name) \ + else if (STREQ (prog_name_str, prog_name)) \ + prog_main = _single_binary_main_##main_name; +# include "coreutils.h" +# undef SINGLE_BINARY_PROGRAM +#endif + + if (! prog_main) + return; + +#if HAVE_PRCTL && defined PR_SET_NAME + /* Not being able to set the program name is not a fatal error. */ + prctl (PR_SET_NAME, prog_argv[0]); +#endif +#if HAVE_PRCTL && defined PR_SET_MM_ARG_START + /* Shift the beginning of the command line to prog_argv[0] (if set) so + /proc/pid/cmdline reflects the right value. */ + prctl (PR_SET_MM_ARG_START, prog_argv[0]); +#endif + + exit ((*prog_main) (prog_argc, prog_argv)); +} + +int +main (int argc, char **argv) +{ + char *prog_name = last_component (argv[0]); + int optc; + + /* Map external name to internal name. */ + char ginstall[] = "ginstall"; + if (STREQ (prog_name, "install")) + prog_name = ginstall; + + /* If this program is called directly as "coreutils" or if the value of + argv[0] is an unknown tool (which "coreutils" is), we proceed and parse + the options. */ + launch_program (prog_name, argc, argv); + + /* No known program was selected via argv[0]. Try parsing the first + argument as --coreutils-prog=PROGRAM to determine the program. The + invocation for this case should be: + path/to/coreutils --coreutils-prog=someprog someprog ... + The third argument is what the program will see as argv[0]. */ + + if (argc >= 2) + { + size_t nskip = 0; + char *arg_name = NULL; + + /* If calling coreutils directly, the "script" name isn't passed. + Distinguish the two cases with a -shebang suffix. */ + if (STRPREFIX (argv[1], "--coreutils-prog=")) + { + nskip = 1; + arg_name = prog_name = argv[1] + strlen ("--coreutils-prog="); + } + else if (STRPREFIX (argv[1], "--coreutils-prog-shebang=")) + { + nskip = 2; + prog_name = argv[1] + strlen ("--coreutils-prog-shebang="); + if (argc >= 3) + arg_name = last_component (argv[2]); + else + arg_name = prog_name; + } + + if (nskip) + { + argv[nskip] = arg_name; /* XXX: Discards any specified path. */ + launch_program (prog_name, argc - nskip, argv + nskip); + error (EXIT_FAILURE, 0, _("unknown program %s"), quote (prog_name)); + } + } + + /* No known program was selected. From here on, we behave like any other + coreutils program. */ + initialize_main (&argc, &argv); + set_program_name (argv[0]); + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + atexit (close_stdout); + + if ((optc = getopt_long (argc, argv, "", long_options, NULL)) != -1) + switch (optc) + { + case_GETOPT_HELP_CHAR; + + case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + } + + /* Only print the error message when no options have been passed + to coreutils. */ + if (optind == 1 && prog_name && !STREQ (prog_name, "coreutils")) + error (0, 0, _("unknown program %s"), quote (prog_name)); + + usage (EXIT_FAILURE); +} diff --git a/src/kill.c b/src/kill.c index 4ab86a48f..724667e0e 100644 --- a/src/kill.c +++ b/src/kill.c @@ -306,7 +306,7 @@ main (int argc, char **argv) usage (EXIT_FAILURE); } - return (list - ? list_signals (table, optind < argc ? argv + optind : NULL) - : send_signals (signum, argv + optind)); + exit (list + ? list_signals (table, optind < argc ? argv + optind : NULL) + : send_signals (signum, argv + optind)); } diff --git a/src/local.mk b/src/local.mk index 865dd7452..e35d28688 100644 --- a/src/local.mk +++ b/src/local.mk @@ -42,6 +42,7 @@ noinst_PROGRAMS = \ noinst_HEADERS = \ src/chown-core.h \ src/copy.h \ + src/coreutils.h \ src/cp-hash.h \ src/dircolors.h \ src/fiemap.h \ @@ -105,6 +106,9 @@ src_cksum_LDADD = $(LDADD) src_comm_LDADD = $(LDADD) src_nproc_LDADD = $(LDADD) src_cp_LDADD = $(LDADD) +if !SINGLE_BINARY +src_coreutils_LDADD = $(LDADD) +endif src_csplit_LDADD = $(LDADD) src_cut_LDADD = $(LDADD) src_date_LDADD = $(LDADD) @@ -150,6 +154,7 @@ src_mv_LDADD = $(LDADD) src_nice_LDADD = $(LDADD) src_nl_LDADD = $(LDADD) src_nohup_LDADD = $(LDADD) +src_numfmt_LDADD = $(LDADD) src_od_LDADD = $(LDADD) src_paste_LDADD = $(LDADD) src_pathchk_LDADD = $(LDADD) @@ -395,6 +400,46 @@ src_libstdbuf_so_LDADD = $(LIBINTL) src_libstdbuf_so_LDFLAGS = -shared src_libstdbuf_so_CFLAGS = -fPIC $(AM_CFLAGS) +BUILT_SOURCES += src/coreutils.h +if SINGLE_BINARY +# Single binary dependencies +src_coreutils_CFLAGS = -DSINGLE_BINARY $(AM_CFLAGS) +#src_coreutils_LDFLAGS = $(AM_LDFLAGS) +src_coreutils_LDADD = $(single_binary_deps) $(LDADD) $(single_binary_libs) +src_coreutils_DEPENDENCIES = $(LDADD) $(single_binary_deps) + +include $(top_srcdir)/src/single-binary.mk + +# Creates symlinks or shebangs to the installed programs when building +# coreutils single binary. +EXTRA_src_coreutils_DEPENDENCIES = src/coreutils_$(single_binary_install_type) +endif SINGLE_BINARY + +CLEANFILES += src/coreutils_symlinks +src/coreutils_symlinks: Makefile + $(AM_V_GEN)touch $@ + $(AM_V_at)for i in $(single_binary_progs); do \ + rm -f src/$$i$(EXEEXT) || exit $$?; \ + $(LN_S) -s coreutils$(EXEEXT) src/$$i$(EXEEXT) || exit $$?; \ + done + +CLEANFILES += src/coreutils_shebangs +src/coreutils_shebangs: Makefile + $(AM_V_GEN)touch $@ + $(AM_V_at)for i in $(single_binary_progs); do \ + rm -f src/$$i$(EXEEXT) || exit $$?; \ + printf '#!%s --coreutils-prog-shebang=%s\n' \ + $(abs_top_builddir)/src/coreutils$(EXEEXT) $$i \ + >src/$$i$(EXEEXT) || exit $$?; \ + chmod a+x,a-w src/$$i$(EXEEXT) || exit $$?; \ + done + +clean-local: + $(AM_V_at)for i in $(single_binary_progs); do \ + rm -f src/$$i$(EXEEXT) || exit $$?; \ + done + + BUILT_SOURCES += src/dircolors.h src/dircolors.h: src/dcgen src/dircolors.hin $(AM_V_GEN)rm -f $@ $@-t @@ -515,6 +560,22 @@ src/version.h: Makefile $(AM_V_at)chmod a-w $@t $(AM_V_at)mv $@t $@ +# Generates a list of macro invocations like: +# SINGLE_BINARY_PROGRAM(program_name_str, main_name) +# once for each program list on $(single_binary_progs). Note that +# for [ the macro invocation is: +# SINGLE_BINARY_PROGRAM("[", _) +CLEANFILES += src/coreutils.h +src/coreutils.h: Makefile + $(AM_V_GEN)rm -f $@ + $(AM_V_at)for prog in $(single_binary_progs); do \ + prog=`basename $$prog`; \ + main=`echo $$prog | tr '[' '_'`; \ + echo "SINGLE_BINARY_PROGRAM(\"$$prog\", $$main)"; \ + done | sort > $@t + $(AM_V_at)chmod a-w $@t + $(AM_V_at)mv $@t $@ + DISTCLEANFILES += src/version.c src/version.h MAINTAINERCLEANFILES += $(BUILT_SOURCES) diff --git a/src/readlink.c b/src/readlink.c index d63f07b40..f46d948e1 100644 --- a/src/readlink.c +++ b/src/readlink.c @@ -174,5 +174,5 @@ main (int argc, char **argv) } } - return status; + exit (status); } diff --git a/src/shuf.c b/src/shuf.c index 915f7b7a5..2505be6f1 100644 --- a/src/shuf.c +++ b/src/shuf.c @@ -622,5 +622,5 @@ main (int argc, char **argv) } #endif - return EXIT_SUCCESS; + exit (EXIT_SUCCESS); } diff --git a/src/timeout.c b/src/timeout.c index 23d894159..68baa23ce 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -440,7 +440,7 @@ main (int argc, char **argv) if (monitored_pid == -1) { error (0, errno, _("fork system call failed")); - return EXIT_CANCELED; + exit (EXIT_CANCELED); } else if (monitored_pid == 0) { /* child */ @@ -455,7 +455,7 @@ main (int argc, char **argv) /* exit like sh, env, nohup, ... */ exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); error (0, errno, _("failed to run command %s"), quote (argv[0])); - return exit_status; + exit (exit_status); } else { @@ -500,8 +500,8 @@ main (int argc, char **argv) } if (timed_out && !preserve_status) - return EXIT_TIMEDOUT; + exit (EXIT_TIMEDOUT); else - return status; + exit (status); } } diff --git a/src/truncate.c b/src/truncate.c index 44d0b9670..f31250920 100644 --- a/src/truncate.c +++ b/src/truncate.c @@ -420,5 +420,5 @@ main (int argc, char **argv) } } - return errors ? EXIT_FAILURE : EXIT_SUCCESS; + exit (errors ? EXIT_FAILURE : EXIT_SUCCESS); } |