Calling an executable file within the C++ code and display files

I am trying to execute a program called "testWeb", it is a linux executable file. And I wanted to check the output file "output.txt" is ready before I display it onto the web. Please Help me

Especially how to call an executable command in Linux environment which I have no idea how to do this. Since I do not need to pass any arguement or variables to the executable files.

Than you for the help.

Here is my code (part of it)


#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstdlib>
#include <time.h> //time stamp

//execute a file
execve("testWeb", argv, envp); // this line I am not sure how to write it


cout << "<Table><tbody><tr><th colspan=2 bgcolor=#99CCFF>Loop1: </th></tr>" << endl;
cout << "</tbody></table>";

//check file exist

bool fexist = false;
while ( fexist == false ){
ifstream inp;
string targetFile;
cout << "<Table><tbody><tr><th colspan=2 bgcolor=#99CCFF>Loop2: </th></tr>" << endl;
cout << "</tbody></table>";

targetFile = "output.txt";
inp.open(targetFile.c_str(), ifstream::in);
inp.close();
if(inp.fail())
{
cout << "<Table><tbody><tr><th colspan=2 bgcolor=#99CCFF>Loop3: </th></tr>" << endl;
cout << "</tbody></table>";
inp.clear(ios::failbit);
fexist = false;
}
else
{
cout << "<Table><tbody><tr><th colspan=2 bgcolor=#99CCFF>Loop4: </th></tr>" << endl;
cout << "</tbody></table>";
fexist = true;
}
}

cout << "Test Error" << endl;

// Display output files
ifstream feedback ("output.txt"); // the output file is called output.txt
cout << endl;
cout << "<Table><tbody><tr><th colspan=2 bgcolor=#99CCFF>FeedBack File: </th></tr>" << endl;
if (feedback.is_open())
{
while (! feedback.eof() )
{
getline (feedback,line);
cout << "<tr><td>" <<line << "</td></tr>" << endl;
}
feedback.close();
}


You probably want to be using one of the spawnx() functions instead of execx().

For Linux:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <process.h>

...

char *spawn_args[2] = {NULL};

// execute the other process and wait for it to terminate
spawn_args[0] = "./testWeb";
spawnv(
  P_WAIT,
  "./testWeb",
  spawn_args
  );

...
// play with file here 

The return value for spawnv() is either a non-negative value (which is the exit code of the executed program -- 0 is 'terminated successfully') or a negative value indicating that the program could not be executed (it couldn't be found or missing permissions or etc).


If you want to continue running and just occasionally check to see if the child has terminated, or if your compiler doesn't support spawnv(), you'll have to use the fork()/exec()/wait() idiom (which is POSIX standard):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#if defined(__cplusplus) || defined(_cplusplus)
#include <exception>  // terminate()
#else
#include <cstdlib>    // abort()
#endif

#include <unistd.h>     // execv(), fork()
#include <sys/types.h>  // pid_t
#include <sys/wait.h>   // waitpid()

...

pid_t child_pid;
char* child_args[2] = {NULL};
int   child_status;
pid_t wait_result;

...

// Execute the child process and get its PID

child_pid = fork();

switch (child_pid)
  {
  case -1:  // I am the parent. Failure to execute child process.
    break;

  case 0:   // I am the child. Turn myself into the desired process.
    child_args[0] = "./testWeb";
    execv( "./testWeb", child_args );
    #if defined(__cplusplus) || defined(_cplusplus)
      terminate();
    #else
      abort();
    #endif

  default:  // I am the parent.
    // If I want to wait for the child before continuing:
    wait_result = waitpid( child_pid, &child_status, 0 );

    if (wait_result != child_pid)
      ...  // Something went wrong with the wait function. Try again later.
           // Otherwise the child terminated successfully.
  }

...

// Check to see if the child has terminated or not
wait_result = waitpid( child_pid, &child_status, WUNTRACED | WCONTINUED );

if (wait_result != child_pid)
  ... // same as above

if (WIFEXITED(child_status))
  child's exit code = WEXITSTATUS(child_status);

... 

The following links may be useful for you:
http://www.cprogramming.com/faq/cgi-bin/smartfaq.cgi?answer=1044654269&id=1043284392
http://linux.about.com/library/cmd/blcmdl3_execv.htm
http://man.he.net/man2/waitpid

Phew. Hope this helps.
i have tried

// initial a program
char* argv[] = {"/bin/sh", "-c", NULL, NULL};
char* envp[] = {NULL};

//execute a file
execve("testWeb", argv, envp);


the code will excute the testWeb but will not execute the rest of the code.

please point out my problem
Sigh. This is going to sound harsh, but...

The problem is you didn't use the code I gave you nor did you read any of the links I listed for you.

The execx() functions replace your program with the one you execute. That's why you need to fork() first. Or use spawnve().

I know it's an obnoxious pain.

Alas.
One question, about process.h

I don't seem to able to get process.h files in my linux server to compile it

342: error: P_WAIT was not declared in this scope
345: error: spawn_args was not declared in this scope

thanks for the help
Hmm. Let me see your code.

Or

Compile and run this program and tell me exactly what error messages you get:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <process.h>
#include <stdio.h>

int main()
  {
  const char *spawn_args[ 3 ] = { "/usr/bin/echo", "Success!", NULL };
  int result = spawnv(
    #ifdef P_WAIT
    P_WAIT,
    #elif defined( _P_WAIT )
    _P_WAIT,
    #else
    0,
    #endif
    spawn_args[ 0 ],
    spawn_args
    );
  printf( "Exit code = %d\n", result );
  puts(
    #if defined( P_WAIT )
    "P_WAIT"
    #elif defined( _P_WAIT )
    "_P_WAIT"
    #else
    "neither is defined"
    #endif
    );
  return 0;
  }
Last edited on
Yeah thanks, I will email my code because it is rather long

email me

my email: sniperxking@hotmail.com
OK. Check your mail.

It will help a lot if you try that code I posted and tell me the output also.
Can someone tell me,

does process.h exist in Linux? because when I try to compile it in Linux server, it gives the following errors:

process.h:23:2: error: #error ERROR: Only Win32 target supported!
process.h:77: error: redeclaration of C++ built-in type âwchar_tâ

??? Please let me know.

Thanks
Hi Duoas

here is the error of the code you told me to compile:

testM.cpp:1:21: error: process.h: No such file or directory
testM.cpp:29:4: warning: no newline at end of file
testM.cpp: In function âint main()â:
testM.cpp:17: error: âspawnvâ was not declared in this scope

Alrighty then...

I thought that might happen. <process.h> is non-standard on *nix.

Anyway, I wanted to play with this, so here's a little module to do the dirty work for you.

execprocess.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// execprocess.hpp
// Copyright (c) 2008 Michael Thomas Greer.
//
// Boost Software License - Version 1.0 - August 17th, 2003
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

#ifndef EXECPROCESS_HPP
#define EXECPROCESS_HPP

#include <string>
#include <sys/types.h>  // pid_t

class ExecProcess
  {
  private:
    pid_t f_pid;
    bool  f_is_ok;
    int   f_status;

  public:
    enum mode_t {mWait, mNoWait};

    explicit ExecProcess( const std::string& command, mode_t mode = mWait, const char* environment = NULL );
    explicit ExecProcess( const std::string& command, const char* environment, mode_t mode = mWait )
      {
      ExecProcess( command, mode, environment );
      }

    bool coredump_ok() const;

    void wait();

    bool terminated();
    bool signaled();
    bool coredumped();
    bool stopped();
    bool continued();

    int  exitcode() const;
    int  exitsignal() const;
    int  stopsignal() const;

    bool ok() const { return f_is_ok; }
    const void* operator * () const { return f_is_ok ? NULL : this; }
    bool operator ! () const { return !f_is_ok; }
    bool operator () () const { return f_is_ok; }

    int  signal( int signal ) const;
    int  terminate() const;
    int  kill() const;
    int  core() const;
    int  stop() const;
    int  scontinue() const;
  };

#endif

// end execprocess.hpp 


Remainder follows.
Last edited on
execprocess.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
// execprocess.cpp
// Copyright (c) 2008 Michael Thomas Greer.
//
// Boost Software License - Version 1.0 - August 17th, 2003
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

#include <algorithm>    // for_each()
#include <cctype>       // isspace()
#include <cstring>
#include <exception>    // terminate()
#include <signal.h>     // kill()
#include <sstream>
#include <sys/wait.h>   // waitpid()
#include <unistd.h>     // execvp(), fork()
#include <vector>

#include "execprocess.hpp"

//----------------------------------------------------------------------------
const char* olds[] = { "\\b", "\\\"", "\\'", "\\\\", "\\a", "\\?" };
const char* news[] = { "\b",  "\"",   "\'",  "\\",   "\a",  "\?"  }; //"

//----------------------------------------------------------------------------
struct convert_specials
  {
  std::string operator () ( const std::string& s )
    {
    std::string result( s );
    std::string::size_type i;
    for (int counter = 0; counter < 6; counter++)
      while ((i = result.find( olds[ counter ] )) != std::string::npos)
        result.replace( i, std::strlen( olds[ counter ] ), news[ counter ] );
    return result;
    }
  };

//----------------------------------------------------------------------------
ExecProcess::ExecProcess( const std::string& command, mode_t mode, const char* environment )
  {
  const char whitespace[] = " \f\n\r\t\v";

  std::vector<const char*> argp;
  std::vector<std::string> args;
  char**                   envp;

  // Initialize
  f_status = 0;

  // Parse out the command into individual arguments
  for (unsigned int i = 0, j = 0; (j != std::string::npos) and (i < command.length()); i++)
    if (command[ i ] == '\"')
      {
      j = i;
      do j = command.find( '\"', ++j );
      while ((j != std::string::npos) and (command[ j -1 ] == '\\'));
      args.push_back( command.substr( i, j-i ) );
      i = j;
      }
    else if (std::isspace( command[ i ] ))
      {
      j = command.find_first_not_of( whitespace, i );
      i = j -1;
      }
    else
      {
      j = i;
      do j = command.find_first_of( whitespace, ++j );
      while ((j != std::string::npos) and (command[ j -1 ] == '\\'));
      args.push_back( command.substr( i, j-i ) );
      i = j -1;
      }
  // Get rid of special characters
  for_each( args.begin(), args.end(), convert_specials() );

  // Make an argument list that execvp() can use.
  for (unsigned int i = 0; i < args.size(); i++)
    argp.push_back( args[ i ].c_str() );

  // Give the new process an environment block
  envp = environ;
  if (environment != NULL) environ = const_cast<char**>( &environment );

  // Alright. Create our new process
  f_pid = fork();

  if (f_pid != 0)
    {
    // I am the parent
    f_is_ok = (f_pid > 0);
    if ((f_is_ok) and (mode == mWait))
      wait();
    }
  else
    {
    // I am the child
    // Replace myself with the desired process
    execv( argp[ 0 ], const_cast<char**>( &argp[ 0 ] ) );
    std::terminate();
    }

  // Restore our environemt block
  environ = envp;
  }

//----------------------------------------------------------------------------
bool ExecProcess::coredump_ok() const
  {
  #ifdef WCOREDUMP
  return true;
  #else
  return false;
  #endif
  }

//----------------------------------------------------------------------------
void ExecProcess::wait()
  {
  f_is_ok = waitpid( f_pid, &f_status, 0 ) == f_pid;
  }

//----------------------------------------------------------------------------
bool ExecProcess::terminated()
  {
  if (!f_is_ok) throw 0;

  f_is_ok = (waitpid( f_pid, &f_status, WNOHANG | WUNTRACED | WCONTINUED ) == f_pid);
  if (!f_is_ok) throw 0;

  return WIFEXITED( f_status );
  }

//----------------------------------------------------------------------------
bool ExecProcess::signaled()
  {
  if (!f_is_ok) throw 0;

  f_is_ok = (waitpid( f_pid, &f_status, WNOHANG | WUNTRACED | WCONTINUED ) == f_pid);
  if (!f_is_ok) throw 0;

  return WIFSIGNALED( f_status );
  }

//----------------------------------------------------------------------------
bool ExecProcess::coredumped()
  {
  #ifndef WCOREDUMP
  throw 0;
  #else
  if (!f_is_ok) throw 0;

  if (!signaled()) return false;

  return WCOREDUMP( f_status );
  #endif
  }

//----------------------------------------------------------------------------
bool ExecProcess::stopped()
  {
  if (!f_is_ok) throw 0;

  f_is_ok = (waitpid( f_pid, &f_status, WNOHANG | WUNTRACED | WCONTINUED ) == f_pid);
  if (!f_is_ok) throw 0;

  return WIFSTOPPED( f_status );
  }

//----------------------------------------------------------------------------
bool ExecProcess::continued()
  {
  if (!f_is_ok) throw 0;

  f_is_ok = (waitpid( f_pid, &f_status, WNOHANG | WUNTRACED | WCONTINUED ) == f_pid);
  if (!f_is_ok) throw 0;

  return WIFCONTINUED( f_status );
  }

//----------------------------------------------------------------------------
int ExecProcess::exitcode() const
  {
  if (WIFEXITED( f_status )) return WEXITSTATUS( f_status );
  throw 0;
  }

//----------------------------------------------------------------------------
int ExecProcess::exitsignal() const
  {
  if (WIFSIGNALED( f_status )) return WTERMSIG( f_status );
  throw 0;
  }

//----------------------------------------------------------------------------
int ExecProcess::stopsignal() const
  {
  if (WIFSTOPPED( f_status )) return WSTOPSIG( f_status );
  throw 0;
  }

//----------------------------------------------------------------------------
int ExecProcess::signal( int signal ) const
  {
  if (!f_is_ok) throw 0;
  return ::kill( f_pid, signal );
  }

//----------------------------------------------------------------------------
int ExecProcess::terminate() const
  {
  return signal( SIGTERM );
  }

//----------------------------------------------------------------------------
int ExecProcess::kill() const
  {
  return signal( SIGKILL );
  }

//----------------------------------------------------------------------------
int ExecProcess::core() const
  {
  return signal( SIGTRAP );
  }

//----------------------------------------------------------------------------
int ExecProcess::stop() const
  {
  return signal( SIGSTOP );
  }

//----------------------------------------------------------------------------
int ExecProcess::scontinue() const
  {
  return signal( SIGCONT );
  }

// end execprocess.cpp

Last edited on
Alas, post size...

Finally, here's a simple example of how to use it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include "execprocess.hpp"

using namespace std;

int main( int argc, char *argv[] )
  {
  if (argc > 1)
    {
    cout << "child: Hello world!" << endl;
    return 42;
    }
  else
    {
    cout << "parent: executing child" << endl;
    ExecProcess p( string( argv[ 0 ] ) +" child" );
    if (!p)
      cout << "fooey!" << endl;
    else
      cout << "parent: child exited with code " << p.exitcode() << endl;
    }
  return EXIT_SUCCESS;
  }


I have only moderately tested the code (with the above example), but it does all the heavy work...

If you try to do something you aren't allowed to do (for example, if you try anything when the child process failed to execute, or if you try to get the exit code before the child process terminates) you'll get an integer exception.

Don't kill() children unless they won't terminate().

Enjoy!

[edit] Oh yeah...
The argument to the constructor is very much the same as for system().
You can put double-quotes around things to preserve spaces, and you can use all the standard C++ \ escape sequences except for octal and hexadecimal numbers.
Last edited on
Thanks so much

I will try to get them working now.. will reply here asap when i get the result
FWIW: lurking it, answered all my questions.

Thank you for the effort D.

s
Here is a MUCH MORE SIMPLER method

char child1[] = "TARGET.exe";
char child2[4];
system (child1);
system ("./TARGET.exe"); // Make sure you type "./"

I had tested a lot of ways already but I think if you know there programming u are calling does not has problem and guarantee to work. My best suggestion is use this. I was going around in circle. But here is the best and simplest method for me.

And once again thank you to Duoas
Just be aware that if you want to do any control or monitoring of the child process, including making sure it started OK, for example handling SIGCHLD, you cannot use system(). The bourne shell system() uses messes all that up. In fact using system() to start a process, while appearing simple can cause lots of very difficult to pin down problems.
Yes, and also the module I provided above is standard POSIX, so it is guaranteed to work on any standard POSIX platform...
Topic archived. No new replies allowed.