|
NCBI C++ ToolKit
|
00001 /* $Id: exec.cpp 16579 2008-04-02 13:20:08Z dicuccio $ 00002 * =========================================================================== 00003 * 00004 * PUBLIC DOMAIN NOTICE 00005 * National Center for Biotechnology Information 00006 * 00007 * This software/database is a "United States Government Work" under the 00008 * terms of the United States Copyright Act. It was written as part of 00009 * the author's official duties as a United States Government employee and 00010 * thus cannot be copyrighted. This software/database is freely available 00011 * to the public for use. The National Library of Medicine and the U.S. 00012 * Government have not placed any restriction on its use or reproduction. 00013 * 00014 * Although all reasonable efforts have been taken to ensure the accuracy 00015 * and reliability of the software and data, the NLM and the U.S. 00016 * Government do not and cannot warrant the performance or results that 00017 * may be obtained by using this software or data. The NLM and the U.S. 00018 * Government disclaim all warranties, express or implied, including 00019 * warranties of performance, merchantability or fitness for any particular 00020 * purpose. 00021 * 00022 * Please cite the author in any work or product based on this material. 00023 * 00024 * =========================================================================== 00025 * 00026 * Authors: Josh Cherry 00027 * 00028 * File Description: execute another program, capturing output in strings 00029 * 00030 */ 00031 00032 00033 #include <ncbi_pch.hpp> 00034 #include <gui/utils/exec.hpp> 00035 00036 #include <corelib/ncbitime.hpp> 00037 #include <connect/ncbi_pipe.hpp> 00038 00039 BEGIN_NCBI_SCOPE 00040 00041 // run an executable using strings for std* 00042 int CExecute::Exec(const string& cmd, 00043 const vector<string>& args, 00044 const string& std_in, 00045 string& std_out, 00046 string& std_err, 00047 STimeout *timeout) 00048 { 00049 // open a pipe, with text mode for std_in, std_out, and std_err 00050 CPipe pipe; 00051 00052 // set up timeout, if requested 00053 CStopWatch sw; 00054 double max_time = 0; // initialize to avoid compiler warning 00055 if (timeout) { 00056 pipe.SetTimeout(eIO_Open, timeout); 00057 pipe.SetTimeout(eIO_Close, timeout); 00058 max_time = timeout->sec + timeout->usec / 1000000.0; 00059 } 00060 sw.Start(); 00061 00062 pipe.Open(cmd.c_str(), args, CPipe::fStdErr_Open); 00063 00064 STimeout short_time = {0, 1}; 00065 pipe.SetTimeout(eIO_Read, &short_time); 00066 pipe.SetTimeout(eIO_Write, &short_time); 00067 00068 size_t bytes_written; 00069 size_t total_bytes_written = 0; 00070 bool out_done = false; 00071 bool err_done = false; 00072 00073 const size_t buf_size = 4096; 00074 char buf[buf_size]; 00075 00076 while (!out_done || !err_done) { 00077 00078 // write stdin 00079 if (total_bytes_written < std_in.size()) { 00080 pipe.Write(std_in.c_str() + total_bytes_written, 00081 std_in.size() - total_bytes_written, 00082 &bytes_written); 00083 total_bytes_written += bytes_written; 00084 if (total_bytes_written == std_in.size()) { 00085 pipe.CloseHandle(CPipe::eStdIn); 00086 } 00087 } 00088 00089 EIO_Status rstatus; 00090 size_t bytes_read; 00091 00092 // read stdout 00093 if (!out_done) { 00094 rstatus = pipe.Read(buf, buf_size, &bytes_read); 00095 std_out.append(buf, bytes_read); 00096 if (rstatus != eIO_Success && rstatus != eIO_Timeout) { 00097 out_done = true; 00098 } 00099 } 00100 00101 // read stderr 00102 if (!err_done) { 00103 rstatus = pipe.Read(buf, buf_size, &bytes_read, CPipe::eStdErr); 00104 std_err.append(buf, bytes_read); 00105 if (rstatus != eIO_Success && rstatus != eIO_Timeout) { 00106 err_done = true; 00107 } 00108 } 00109 00110 // check whether total time (timeout paramater) exceeded 00111 if (timeout) { 00112 if (sw.Elapsed() > max_time) { 00113 pipe.SetTimeout(eIO_Close, &short_time); 00114 break; 00115 } 00116 } 00117 } 00118 00119 int exit_value; 00120 pipe.Close(&exit_value); 00121 00122 // return the value with which the process exited 00123 return exit_value; 00124 } 00125 00126 00127 END_NCBI_SCOPE
1.7.5.1
Modified on Wed May 23 13:14:26 2012 by modify_doxy.py rev. 337098