1 /* $NetBSD: lvm-exec.c,v 1.1.1.2 2009/12/02 00:26:43 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. 5 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved. 6 * 7 * This file is part of LVM2. 8 * 9 * This copyrighted material is made available to anyone wishing to use, 10 * modify, copy, or redistribute it subject to the terms and conditions 11 * of the GNU Lesser General Public License v.2.1. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software Foundation, 15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18 #include "lib.h" 19 #include "device.h" 20 #include "locking.h" 21 #include "lvm-exec.h" 22 #include "toolcontext.h" 23 24 #include <unistd.h> 25 #include <sys/wait.h> 26 27 /* 28 * Create verbose string with list of parameters 29 */ 30 static char *_verbose_args(const char *const argv[], char *buf, size_t sz) 31 { 32 int pos = 0; 33 int len; 34 unsigned i; 35 36 buf[0] = '\0'; 37 for (i = 0; argv[i]; i++) { 38 if ((len = dm_snprintf(buf + pos, sz - pos, 39 "%s ", argv[i])) < 0) 40 /* Truncated */ 41 break; 42 pos += len; 43 } 44 45 return buf; 46 } 47 48 /* 49 * Execute and wait for external command 50 */ 51 int exec_cmd(struct cmd_context *cmd, const char *const argv[]) 52 { 53 pid_t pid; 54 int status; 55 char buf[PATH_MAX * 2]; 56 57 log_verbose("Executing: %s", _verbose_args(argv, buf, sizeof(buf))); 58 59 if ((pid = fork()) == -1) { 60 log_error("fork failed: %s", strerror(errno)); 61 return 0; 62 } 63 64 if (!pid) { 65 /* Child */ 66 reset_locking(); 67 dev_close_all(); 68 /* FIXME Fix effect of reset_locking on cache then include this */ 69 /* destroy_toolcontext(cmd); */ 70 /* FIXME Use execve directly */ 71 execvp(argv[0], (char **const) argv); 72 log_sys_error("execvp", argv[0]); 73 _exit(errno); 74 } 75 76 /* Parent */ 77 if (wait4(pid, &status, 0, NULL) != pid) { 78 log_error("wait4 child process %u failed: %s", pid, 79 strerror(errno)); 80 return 0; 81 } 82 83 if (!WIFEXITED(status)) { 84 log_error("Child %u exited abnormally", pid); 85 return 0; 86 } 87 88 if (WEXITSTATUS(status)) { 89 log_error("%s failed: %u", argv[0], WEXITSTATUS(status)); 90 return 0; 91 } 92 93 return 1; 94 } 95