tst_run_cmd.c revision e63337a09474e594900efab91d1a3fc7fa332f2e
14bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev/* 24bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. 34bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * 44bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * This program is free software; you can redistribute it and/or 54bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * modify it under the terms of the GNU General Public License as 64bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * published by the Free Software Foundation; either version 2 of 74bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * the License, or (at your option) any later version. 84bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * 94bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * This program is distributed in the hope that it would be useful, 104bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * but WITHOUT ANY WARRANTY; without even the implied warranty of 114bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 124bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * GNU General Public License for more details. 134bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * 144bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * You should have received a copy of the GNU General Public License 154bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * along with this program; if not, write the Free Software Foundation, 164bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 174bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * 184bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * Author: Alexey Kodanev <alexey.kodanev@oracle.com> 194bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev * 204bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev */ 214bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev 22bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh#include <errno.h> 234bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev#include <sys/types.h> 24bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh#include <sys/stat.h> 254bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev#include <sys/wait.h> 26bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh#include <fcntl.h> 274bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev#include <unistd.h> 284bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev#include "test.h" 294bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev 30bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh#define OPEN_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) 31bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh#define OPEN_FLAGS (O_WRONLY | O_APPEND | O_CREAT) 32bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 33bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikhvoid tst_run_cmd_fds(void (cleanup_fn)(void), 34e63337a09474e594900efab91d1a3fc7fa332f2eStanislav Kholmanskikh const char *const argv[], 35bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh int stdout_fd, 36bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh int stderr_fd) 374bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev{ 384bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev if (argv == NULL || argv[0] == NULL) { 394bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev tst_brkm(TBROK, cleanup_fn, 404bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev "argument list is empty at %s:%d", __FILE__, __LINE__); 414bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev } 424bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev 434bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev pid_t pid = vfork(); 444bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev if (pid == -1) { 454bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev tst_brkm(TBROK | TERRNO, cleanup_fn, "vfork failed at %s:%d", 464bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev __FILE__, __LINE__); 474bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev } 48bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh if (!pid) { 49bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh /* redirecting stdout and stderr if needed */ 50bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh if (stdout_fd != -1) { 51bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh close(STDOUT_FILENO); 52bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh dup2(stdout_fd, STDOUT_FILENO); 53bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh } 54bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 55bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh if (stderr_fd != -1) { 56bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh close(STDERR_FILENO); 57bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh dup2(stderr_fd, STDERR_FILENO); 58bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh } 59bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 60e63337a09474e594900efab91d1a3fc7fa332f2eStanislav Kholmanskikh _exit(execvp(argv[0], (char *const *)argv)); 61bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh } 624bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev 634bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev int ret = -1; 644bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev if (waitpid(pid, &ret, 0) != pid) { 654bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev tst_brkm(TBROK, cleanup_fn, "waitpid failed at %s:%d", 664bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev __FILE__, __LINE__); 674bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev } 684bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev 694bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { 704bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev tst_brkm(TBROK, cleanup_fn, "failed to exec cmd '%s' at %s:%d", 714bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev argv[0], __FILE__, __LINE__); 724bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev } 734bc55ecaa76244f3ba28a91f4fb8b3dac9c744acAlexey Kodanev} 74bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 75bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikhvoid tst_run_cmd(void (cleanup_fn)(void), 76e63337a09474e594900efab91d1a3fc7fa332f2eStanislav Kholmanskikh const char *const argv[], 77bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh const char *stdout_path, 78bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh const char *stderr_path) 79bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh{ 80bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh int stdout_fd = -1; 81bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh int stderr_fd = -1; 82bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 83bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh if (stdout_path != NULL) { 84bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh stdout_fd = open(stdout_path, 85bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh OPEN_FLAGS, OPEN_MODE); 86bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 87bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh if (stdout_fd == -1) 88bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh tst_resm(TWARN | TERRNO, 89bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh "open() on %s failed at %s:%d", 90bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh stdout_path, __FILE__, __LINE__); 91bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh } 92bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 93bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh if (stderr_path != NULL) { 94bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh stderr_fd = open(stderr_path, 95bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh OPEN_FLAGS, OPEN_MODE); 96bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 97bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh if (stderr_fd == -1) 98bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh tst_resm(TWARN | TERRNO, 99bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh "open() on %s failed at %s:%d", 100bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh stderr_path, __FILE__, __LINE__); 101bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh } 102bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 103bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh tst_run_cmd_fds(cleanup_fn, argv, stdout_fd, stderr_fd); 104bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 105bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh if ((stdout_fd != -1) && (close(stdout_fd) == -1)) 106bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh tst_resm(TWARN | TERRNO, 107bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh "close() on %s failed at %s:%d", 108bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh stdout_path, __FILE__, __LINE__); 109bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh 110bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh if ((stderr_fd != -1) && (close(stderr_fd) == -1)) 111bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh tst_resm(TWARN | TERRNO, 112bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh "close() on %s failed at %s:%d", 113bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh stderr_path, __FILE__, __LINE__); 114bee0a9469641d3cc8d29853abb4ba10883b30ba6Stanislav kholmanskikh} 115