From 40346de6d31051c8a626d531b03e82a83b516836 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 19 Oct 2013 02:56:40 +0200 Subject: [PATCH] * grub-core/osdep/unix/getroot.c: Move exec functions to ... * osdep/unix/exec.c: ... here. Add few additional exec_* variants. --- ChangeLog | 5 + Makefile.util.def | 1 + grub-core/Makefile.core.def | 2 + grub-core/osdep/exec.c | 3 + grub-core/osdep/linux/getroot.c | 25 ++-- grub-core/osdep/unix/exec.c | 195 ++++++++++++++++++++++++++++++++ grub-core/osdep/unix/getroot.c | 72 +++--------- include/grub/emu/exec.h | 39 +++++++ include/grub/emu/getroot.h | 6 - 9 files changed, 269 insertions(+), 79 deletions(-) create mode 100644 grub-core/osdep/exec.c create mode 100644 grub-core/osdep/unix/exec.c create mode 100644 include/grub/emu/exec.h diff --git a/ChangeLog b/ChangeLog index 57a54d99d..a585a1310 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-10-19 Vladimir Serbinenko + + * grub-core/osdep/unix/getroot.c: Move exec functions to ... + * osdep/unix/exec.c: ... here. Add few additional exec_* variants. + 2013-10-19 Vladimir Serbinenko * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Define size_t to diff --git a/Makefile.util.def b/Makefile.util.def index d7538c28d..225b82d13 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -17,6 +17,7 @@ library = { common = grub-core/osdep/devmapper/hostdisk.c; common = grub-core/osdep/hostdisk.c; common = grub-core/osdep/unix/hostdisk.c; + common = grub-core/osdep/exec.c; common = grub-core/osdep/sleep.c; common = grub-core/osdep/password.c; common = grub-core/kern/emu/misc.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index e736e08b9..c8ce7c951 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -241,6 +241,8 @@ kernel = { emu = kern/emu/cache_s.S; emu = kern/emu/hostdisk.c; emu = osdep/unix/hostdisk.c; + emu = osdep/exec.c; + extra_dist = osdep/unix/exec.c; emu = osdep/devmapper/hostdisk.c; emu = osdep/hostdisk.c; emu = kern/emu/hostfs.c; diff --git a/grub-core/osdep/exec.c b/grub-core/osdep/exec.c new file mode 100644 index 000000000..b5f532a3e --- /dev/null +++ b/grub-core/osdep/exec.c @@ -0,0 +1,3 @@ +#if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__AROS__) +#include "unix/exec.c" +#endif diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c index 689436855..ee57eb643 100644 --- a/grub-core/osdep/linux/getroot.c +++ b/grub-core/osdep/linux/getroot.c @@ -54,6 +54,7 @@ #include #include #include +#include #define LVM_DEV_MAPPER_STRING "/dev/mapper/" @@ -397,7 +398,7 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) static char * get_mdadm_uuid (const char *os_dev) { - char *argv[5]; + const char *argv[5]; int fd; pid_t pid; FILE *mdadm; @@ -405,12 +406,10 @@ get_mdadm_uuid (const char *os_dev) size_t len = 0; char *name = NULL; - /* execvp has inconvenient types, hence the casts. None of these - strings will actually be modified. */ - argv[0] = (char *) "mdadm"; - argv[1] = (char *) "--detail"; - argv[2] = (char *) "--export"; - argv[3] = (char *) os_dev; + argv[0] = "mdadm"; + argv[1] = "--detail"; + argv[2] = "--export"; + argv[3] = os_dev; argv[4] = NULL; pid = grub_util_exec_pipe (argv, &fd); @@ -464,7 +463,7 @@ grub_util_is_imsm (const char *os_dev) do { - char *argv[5]; + const char *argv[5]; int fd; pid_t pid; FILE *mdadm; @@ -473,12 +472,10 @@ grub_util_is_imsm (const char *os_dev) retry = 0; /* We'll do one more pass if device is part of container */ - /* execvp has inconvenient types, hence the casts. None of these - strings will actually be modified. */ - argv[0] = (char *) "mdadm"; - argv[1] = (char *) "--detail"; - argv[2] = (char *) "--export"; - argv[3] = (char *) dev; + argv[0] = "mdadm"; + argv[1] = "--detail"; + argv[2] = "--export"; + argv[3] = dev; argv[4] = NULL; pid = grub_util_exec_pipe (argv, &fd); diff --git a/grub-core/osdep/unix/exec.c b/grub-core/osdep/unix/exec.c new file mode 100644 index 000000000..575377fe7 --- /dev/null +++ b/grub-core/osdep/unix/exec.c @@ -0,0 +1,195 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +grub_util_exec (const char *const *argv) +{ + pid_t pid; + int status = -1; + + pid = fork (); + if (pid < 0) + grub_util_error (_("Unable to fork: %s"), strerror (errno)); + else if (pid == 0) + { + /* Child. */ + + /* Close fd's. */ + grub_util_devmapper_cleanup (); + grub_diskfilter_fini (); + + /* Ensure child is not localised. */ + setenv ("LC_ALL", "C", 1); + + execvp ((char *) argv[0], (char **) argv); + exit (127); + } + + waitpid (pid, &status, 0); + if (!WIFEXITED (status)) + return -1; + return WEXITSTATUS (status); +} + +int +grub_util_exec_redirect (const char *const *argv, const char *stdin_file, + const char *stdout_file) +{ + pid_t mdadm_pid; + int status = -1; + + mdadm_pid = fork (); + if (mdadm_pid < 0) + grub_util_error (_("Unable to fork: %s"), strerror (errno)); + else if (mdadm_pid == 0) + { + int in, out; + /* Child. */ + + /* Close fd's. */ + grub_util_devmapper_cleanup (); + grub_diskfilter_fini (); + + in = open (stdin_file, O_RDONLY); + dup2 (in, STDIN_FILENO); + close (in); + + out = open (stdout_file, O_WRONLY | O_CREAT, 0700); + dup2 (out, STDOUT_FILENO); + close (out); + + /* Ensure child is not localised. */ + setenv ("LC_ALL", "C", 1); + + execvp ((char *) argv[0], (char **) argv); + exit (127); + } + waitpid (mdadm_pid, &status, 0); + if (!WIFEXITED (status)) + return -1; + return WEXITSTATUS (status); +} + +int +grub_util_exec_redirect_null (const char *const *argv) +{ + return grub_util_exec_redirect (argv, "/dev/null", "/dev/null"); +} + +pid_t +grub_util_exec_pipe (const char *const *argv, int *fd) +{ + int mdadm_pipe[2]; + pid_t mdadm_pid; + + *fd = 0; + + if (pipe (mdadm_pipe) < 0) + { + grub_util_warn (_("Unable to create pipe: %s"), + strerror (errno)); + return 0; + } + mdadm_pid = fork (); + if (mdadm_pid < 0) + grub_util_error (_("Unable to fork: %s"), strerror (errno)); + else if (mdadm_pid == 0) + { + /* Child. */ + + /* Close fd's. */ + grub_util_devmapper_cleanup (); + grub_diskfilter_fini (); + + /* Ensure child is not localised. */ + setenv ("LC_ALL", "C", 1); + + close (mdadm_pipe[0]); + dup2 (mdadm_pipe[1], STDOUT_FILENO); + close (mdadm_pipe[1]); + + execvp ((char *) argv[0], (char **) argv); + exit (127); + } + else + { + close (mdadm_pipe[1]); + *fd = mdadm_pipe[0]; + return mdadm_pid; + } +} + +pid_t +grub_util_exec_pipe_stderr (const char *const *argv, int *fd) +{ + int mdadm_pipe[2]; + pid_t mdadm_pid; + + *fd = 0; + + if (pipe (mdadm_pipe) < 0) + { + grub_util_warn (_("Unable to create pipe: %s"), + strerror (errno)); + return 0; + } + mdadm_pid = fork (); + if (mdadm_pid < 0) + grub_util_error (_("Unable to fork: %s"), strerror (errno)); + else if (mdadm_pid == 0) + { + /* Child. */ + + /* Close fd's. */ + grub_util_devmapper_cleanup (); + grub_diskfilter_fini (); + + /* Ensure child is not localised. */ + setenv ("LC_ALL", "C", 1); + + close (mdadm_pipe[0]); + dup2 (mdadm_pipe[1], STDOUT_FILENO); + dup2 (mdadm_pipe[1], STDERR_FILENO); + close (mdadm_pipe[1]); + + execvp ((char *) argv[0], (char **) argv); + exit (127); + } + else + { + close (mdadm_pipe[1]); + *fd = mdadm_pipe[0]; + return mdadm_pid; + } +} diff --git a/grub-core/osdep/unix/getroot.c b/grub-core/osdep/unix/getroot.c index f1ff596a9..2552e536e 100644 --- a/grub-core/osdep/unix/getroot.c +++ b/grub-core/osdep/unix/getroot.c @@ -35,6 +35,7 @@ #include #endif #include +#include #include #include @@ -149,49 +150,6 @@ xgetcwd (void) return path; } -pid_t -grub_util_exec_pipe (char **argv, int *fd) -{ - int mdadm_pipe[2]; - pid_t mdadm_pid; - - *fd = 0; - - if (pipe (mdadm_pipe) < 0) - { - grub_util_warn (_("Unable to create pipe: %s"), - strerror (errno)); - return 0; - } - mdadm_pid = fork (); - if (mdadm_pid < 0) - grub_util_error (_("Unable to fork: %s"), strerror (errno)); - else if (mdadm_pid == 0) - { - /* Child. */ - - /* Close fd's. */ - grub_util_devmapper_cleanup (); - grub_diskfilter_fini (); - - /* Ensure child is not localised. */ - setenv ("LC_ALL", "C", 1); - - close (mdadm_pipe[0]); - dup2 (mdadm_pipe[1], STDOUT_FILENO); - close (mdadm_pipe[1]); - - execvp (argv[0], argv); - exit (127); - } - else - { - close (mdadm_pipe[1]); - *fd = mdadm_pipe[0]; - return mdadm_pid; - } -} - #if !defined (__GNU__) char ** grub_util_find_root_devices_from_poolname (char *poolname) @@ -271,15 +229,13 @@ grub_util_find_root_devices_from_poolname (char *poolname) char name[PATH_MAX + 1], state[257], readlen[257], writelen[257]; char cksum[257], notes[257]; unsigned int dummy; - char *argv[4]; + const char *argv[4]; pid_t pid; int fd; - /* execvp has inconvenient types, hence the casts. None of these - strings will actually be modified. */ - argv[0] = (char *) "zpool"; - argv[1] = (char *) "status"; - argv[2] = (char *) poolname; + argv[0] = "zpool"; + argv[1] = "status"; + argv[2] = poolname; argv[3] = NULL; pid = grub_util_exec_pipe (argv, &fd); @@ -603,7 +559,7 @@ grub_guess_root_devices (const char *dir_in) void grub_util_pull_lvm_by_command (const char *os_dev) { - char *argv[8]; + const char *argv[8]; int fd; pid_t pid; FILE *mdadm; @@ -640,20 +596,18 @@ grub_util_pull_lvm_by_command (const char *os_dev) *optr = '\0'; } - /* execvp has inconvenient types, hence the casts. None of these - strings will actually be modified. */ /* by default PV name is left aligned in 10 character field, meaning that we do not know where name ends. Using dummy --separator disables alignment. We have a single field, so separator itself is not output */ - argv[0] = (char *) "vgs"; - argv[1] = (char *) "--options"; + argv[0] = "vgs"; + argv[1] = "--options"; if (vgid) - argv[2] = (char *) "vg_uuid,pv_name"; + argv[2] = "vg_uuid,pv_name"; else - argv[2] = (char *) "pv_name"; - argv[3] = (char *) "--noheadings"; - argv[4] = (char *) "--separator"; - argv[5] = (char *) ":"; + argv[2] = "pv_name"; + argv[3] = "--noheadings"; + argv[4] = "--separator"; + argv[5] = ":"; argv[6] = vgname; argv[7] = NULL; diff --git a/include/grub/emu/exec.h b/include/grub/emu/exec.h new file mode 100644 index 000000000..ecc3adc30 --- /dev/null +++ b/include/grub/emu/exec.h @@ -0,0 +1,39 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_EMU_EXEC_H +#define GRUB_EMU_EXEC_H 1 + +#include +#include + +#include +pid_t +grub_util_exec_pipe (const char *const *argv, int *fd); +pid_t +grub_util_exec_pipe_stderr (const char *const *argv, int *fd); + +int +grub_util_exec (const char *const *argv); +int +grub_util_exec_redirect (const char *const *argv, const char *stdin_file, + const char *stdout_file); +int +grub_util_exec_redirect_null (const char *const *argv); + +#endif diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h index 061b94f26..6684e372a 100644 --- a/include/grub/emu/getroot.h +++ b/include/grub/emu/getroot.h @@ -65,12 +65,6 @@ grub_util_devmapper_part_to_disk (struct stat *st, char * grub_util_get_devmapper_grub_dev (const char *os_dev); -/* Functions provided by getroot.c. */ -#if !defined (__MINGW32__) && !defined (__CYGWIN__) -#include -pid_t -grub_util_exec_pipe (char **argv, int *fd); -#endif void grub_util_pull_lvm_by_command (const char *os_dev); char **