Linux CreateProcess? - c++

I developing on the Linux platform.
I want to create a new proccess in my library without replacing the current executing image.
Because I am developing a library, I don't have a main function.
And I want to continue the new process after the invoker application closes (Just like CreateProcess Windows API).
Is it possible in Linux or not?
something like this function:
void Linux_CreateProcess(const char* app_name)
{
// Executing app_name.
// ???????? what is the code ??????
// app_name is running and never close if current application close.
return;
}
Note:
system() blocks the current process, it is not good. I want to continue the current process.
exec() family replace the current executing image, it is not good.
popen() closes the new process if the current process closed.

The fork/exec combination was already mentioned, but there is also the posix_spawn family of functions that can be used as a replacement for fork + exec and is a more direct equivalent to CreateProcess. Here is an example for both possibilities:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>
extern char **environ;
void test_fork_exec(void);
void test_posix_spawn(void);
int main(void) {
test_fork_exec();
test_posix_spawn();
return EXIT_SUCCESS;
}
void test_fork_exec(void) {
pid_t pid;
int status;
puts("Testing fork/exec");
fflush(NULL);
pid = fork();
switch (pid) {
case -1:
perror("fork");
break;
case 0:
execl("/bin/ls", "ls", (char *) 0);
perror("exec");
break;
default:
printf("Child id: %i\n", pid);
fflush(NULL);
if (waitpid(pid, &status, 0) != -1) {
printf("Child exited with status %i\n", status);
} else {
perror("waitpid");
}
break;
}
}
void test_posix_spawn(void) {
pid_t pid;
char *argv[] = {"ls", (char *) 0};
int status;
puts("Testing posix_spawn");
fflush(NULL);
status = posix_spawn(&pid, "/bin/ls", NULL, NULL, argv, environ);
if (status == 0) {
printf("Child id: %i\n", pid);
fflush(NULL);
if (waitpid(pid, &status, 0) != -1) {
printf("Child exited with status %i\n", status);
} else {
perror("waitpid");
}
} else {
printf("posix_spawn: %s\n", strerror(status));
}
}

posix_spawn is probably the preferred solution these days.
Before that fork() and then execXX() was the way to do this (where execXX is one of the exec family of functions, including execl, execlp, execle, execv, execvp, and execvpe). In the GNU C library currently, at least for Linux, posix_spawn is implemented via fork/exec anyway; Linux doesn't have a posix_spawn system call.
You would use fork() (or vfork()) to launch a separate process, which will be a clone of the parent. In both the child and parent process, execution continues, but fork returns a different value in either case allowing you to differentiate. You can then use one of the execXX() functions from within the child process.
Note, however, this problem - text borrowed from one of my blog posts (http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/):
There doesn’t seem to be any simple standards-conformant way (or even a generally portable way) to execute another process in parallel and be certain that the exec() call was successful. The problem is, once you’ve fork()d and then successfully exec()d you can’t communicate with the parent process to inform that the exec() was successful. If the exec() fails then you can communicate with the parent (via a signal for instance) but you can’t inform of success – the only way the parent can be sure of exec() success is to wait() for the child process to finish (and check that there is no failure indication) and that of course is not a parallel execution.
i.e. if execXX() succeeds, you no longer have control so can't signal success to the original (parent) process.
A potential solution to this problem, in case it is an issue in your case:
[...] use pipe() to create a pipe, set the output end to be close-on-exec, then fork() (or vfork()), exec(), and write something (perhaps errno) to the pipe if the exec() fails (before calling _exit()). The parent process can read from the pipe and will get an immediate end-of-input if the exec() succeeds, or some data if the exec() failed.
(Note that this solution through is prone to causing priority inversion if the child process runs at a lower priority than the parent, and the parent waits for output from it).
There is also posix_spawn as mentioned above and in other answers, but it doesn't resolve the issue of detecting failure to execute the child executable, since it is often implemented in terms of fork/exec anyway and can return success before the exec() stage fails.

You wrote:
I want to create a new proccess in my library without replacing the current executing image.
system() blocks the current process, it is not good. I want to continue current process.
Just add an ampersand after the command call.
Example: system("/bin/my_prog_name &");
Your process will not be blocked!

The classic way to do this is to use fork() to create a child process, and then use one of the exec() functions to replace the executing image of the child, leaving the parent untouched. Both process will then run in parallel.

I think posix_spawn does what you want. Internally it might do fork/exec, but maybe it also does some funky useful stuff.

You should be using fork() and then execvp().
fork() function creates a new child process. In the parent process you receive the process ID of the child process. In Child process the process ID returned is 0, which tells us that the process is a child process.
execvp() replaces the calling process image with a new process image. This has the effect of running a new program with the process ID of the calling process. Note that a new process is not started; the new process image simply overlays the original process image. The execvp function is most commonly used to overlay a process image that has been created by a call to the fork function.

Yes, fork() and exec..() is the correct solution. Look at this code if it can help you :
switch( fork() )
{
case -1 : // Error
// Handle the error
break;
case 0 :
// Call one of the exec -- personally I prefer execlp
execlp("path/to/binary","binary name", arg1, arg2, .., NULL);
exit(42); // May never be returned
break;
default :
// Do what you want
break;
}

I think fork is what you are looking for.

Related

In a C++ application in Mac or Windows, is there a way to determine if a given ProcessId still exists?

I have a QT application that runs on both Windows and Mac. Is there a way to provide a PID, and get back:
If the PID exists
The name of the process under that PID
For Windows I thing I can use EnumProcesses() to find out what I need, but how can this be done on Mac?
So it's a QT question. That constrains the space enough that I can provide an answer for the most reasonable case.
A good portable program probably does not monitor arbitrary processes but only its own; and for that everything is well in hand. Child processes are spawned using the QProcess class, and it provides of itself what you need in the form of the stateChanged signal. You don't ever ask if the process ID is good; you get told when it's no longer good.
If you insist on checking if the PID is good; you're in luck. If /proc/self exists but /proc/${pid} doesn't than the PID isn't good anymore. This works about as well as EnumProcesses on windows. You can get the process name from /proc/${pid}/exe (it's a symbolic link, so call readlink() on it). If /proc/self doesn't exist, you probably can't enum processes because the system is in a degenerate state.
#include <errno.h>
#include <libproc.h>
bool is_process_active_by_pid(pid_t pid , char * exe_path)
{
int ret;
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
bool is_active;
ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf));
if ( ret <= 0 ) {
fprintf(stderr, "PID %d: proc_pidpath ();\n", pid);
fprintf(stderr, " %s\n", strerror(errno));
is_active = false;
} else {
printf("proc %d: %s\n", pid, pathbuf);
is_active = true;
strcpy(exe_path , pathbuf);
}
return is_active;
}
On Windows:
If the PID exists
You can use OpenProcess() for it, giving it the desired PID. You have to do this anyway for the next step, so there is no point in wasting time using EnumProcesses() at all.
The name of the process under that PID
Once you have opened a HANDLE to the process, you can use GetModuleFileNameEx(), GetProcessImageFileName(), or QueryFullProcessImageName() to get the full path and filename to the process. If you want a more human-readable display name, you can pass that path+filename to GetFileVersionInfo() and VerQueryValue() to query its display name. Or, use the path+file with EnumServiceStatus() and QueryServiceConfig() to find a matching SCM service and get its display name.

Open a few files, wait ~30 mins, relaunch them in C++

I posted a thread about how to do this in batch but it turns out batch scripting isn't very popular and I barely even know it so now I'm asking for your help doing this in C++.
here's what I tried
#include <Windows.h>
using namespace std;
void openBat(char* path) {
system(path);
}
int main() {
for(;;) {
openBat("C:\\Users\\Ivan\\Desktop\\folder\\run.bat");
Sleep(1800000);
//kill opened process
}
return 0;
}
I'm not sure how to kill the opened process because every time I run the bat script it will have a new ID and I can't kill by name because I need to have 4 of these open. All help is appreciated.
What you're doing there isn't really C++. You're basically using windows to interprete the commands you pass it like batch would do. Here is what you want to do in C++, even if it only runs on Windows.
#include <Windows.h>
#include <string>
std::wstring GetEnvString()
{
wchar_t* env = GetEnvironmentStrings();
std::wstring result{ env };
FreeEnvironmentStrings(env);
result.push_back('\0');
return result;
}
int main()
{
//Setup needed structures
STARTUPINFO si{ sizeof si };
PROCESS_INFORMATION pi;
//Command line (read- and writeable)
wchar_t cmd[] = L"cmd.exe /C C:\\Users\\Ivan\\Desktop\\folder\\run.bat";
//Create process
CreateProcess(nullptr, cmd, nullptr, nullptr, false, CREATE_UNICODE_ENVIRONMENT,
const_cast<wchar_t*>(GetEnvString().c_str()), nullptr, &si, &pi);
Sleep(1800000);
//Process Termination
TerminateProcess(pi.hProcess, 0);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
I'd recommend you read up on the CreateProcess function, as well as the Terminate Process one. There is also an example from Microsoft about how to use the former of the two. I hope this information can help you.
edit: Fixed stuff. Should work now. Credits to user4581301, his links were really useful.
I think the solution can be killing the self process tree without killing process itself.
Terminate a process tree (C for Windows)
When you create a process, hold onto the process handle and use the handle to terminate the when you are done. With the handle you know exactly which of possibly thousands of instances of the same process you want dead.
Note: Terminating a process may have undesirable results. You are almost always better off writing the processes in such a way that you can message them and request that they terminate themselves politely. How you would do this with a batch file... Smurfed if I know. Someone else may have a waaaaay better answer to this problem, and I'm fine with that. One day I might need that better solution.
On Windows you likely want CreateProcess and TerminateProcess.
Running a batchfile with CreateProcess is covered here: Use CreateProcess to Run a Batch File
Terminating a process launched with Create process is covered here:
how to terminate a process created by CreateProcess()?

CPP running external program, wait until it finishes and return the retcode

Okay, as a part of my Lib i need a 'Worker' application to run an external program.
Normally i would do it with a call to:
system("");
But this time what is needed is:
Return code of that program
Application to work while the executed program is running
So a pseudocode would look like this in perfect implementation:
CTask::Run()
{
m_iReturnCode = -1;
ExecuteTask(m_strBinaryName);
while(Task_Executing)
{
HeartBeat();
}
return m_iReturnCode;
}
Just to clarify, i am running this on Unix platforms.
What are my options here, popen / fork ?
Anyone having a good solution already running and can shed a bit of light on this please?
Thanks for any input into this.
I am using a linux system, boost for threading and a pipe to execute the command and get its result (if you do not know boost you certainly should have a look at it).
I found the hint to use a pipe here on stackoverflow but I am sorry I do not know the exact question any more.
I do not add the outside thread code. Just start the method execute within its own thread.
std::string execute()
{
std::string result;
// DO NOT INTERRUPT THREAD WHILE READING FROM PIPE
boost::this_thread::disable_interruption di;
// add echo of exit code to command to get the exit code
std::string command = mp_command + "; echo $?";
// open pipe, execute command and read input from pipe
FILE* pipe = popen(command.c_str(), "r");
if (pipe)
{
char buffer[128];
while (!feof(pipe))
{
if (fgets(buffer, 128, pipe) != NULL)
{
std::string currBuffer(buffer);
result += currBuffer;
}
}
}
else
{
mp_isValid = false;
}
// sleeping busy wait for the pipe to close
while (pclose(pipe) == -1)
{
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
}
return result;
}
You can create a fork with fork() (or clone() if you want threads), and then run the program using execve() or system() in one process, and continue running the original program in the other.
For the return code, you can get the return code even from system() call as :
ret = system("<your_command>");
printf("%d\n", WEXITSTATUS(ret));
There must be some sort of interprocess or interthread communication. In case you don't want to fork it or use threads, you can try using a shared file. Open the file for writing in the child task (called by system()) and when you are done, write some value (e.g. "finished") and close the file. In the parent task, heartbeat until you read "finished" from the shared file.
You can do this also by writing a global variable instead of shared file.
However, I would fort or thread it, using a shared file or global variable is error-prone and I am not entirely sure it would work that way.

How to handle "End Task" from Windows Task Manager on a background process?

I wrote a simple test program (TestProgram.exe) to learn how to handle the CTRL_CLOSE_EVENT and here are my observations and my question:
1) When I double click TestProgram.exe to launch it, and if I now go to Task Manager, TestProgram.exe is listed under "Apps". When I do "End Task" on TestProgram.exe, my handler for CTRL_CLOSE_EVENT is getting called.
BUT
2) When I open a command prompt and launch TestProgram.exe, it is listed under "Background Processes" under Task Manager and doing an "End Task" on the same doesn't result in a CTRL_CLOSE_EVENT.
My real application is used as described in case 2) above. I want to do some cleanup when users do an End Task on my app (which is listed under Background processes in Task Manager).
Thanks,
Krishna
In general, when a process is listed as an "Application", it means Task Manger has detected the process has a GUI, and an "End Task" on a GUI will first attempt to graceful close the GUI via standard WM_CLOSE and/or WM_QUIT messages before then resorting to a brute-force termination of the GUI's process via TerminateProcess(). On the other hand, doing an "End Task" on a "Background Process" will perform a brute-force termination immediately.
So in your situation, double-clicking on the .exe file results in a new dedicated console process that is running just your app by itself, so the console's GUI gets flagged as an "Application", but when you open a console window first and execute your .exe via the command-line, your app is running within the existing console and is sharing the console's original GUI, so your app does not have its own GUI and thus gets flagged as a "Background Process" instead.
When a process is terminated (not closed) nothing realy can be done unless you start do some hooking, either by hooking TerminateProcess or NtTerminateProcess in the Task Manger process, example of how it works:
#include <windows.h>
#include <assert.h>
BOOL WINAPI MyTerminateProcess(HANDLE hProcess, UINT uExitCode ) {
MessageBox(NULL, TEXT("Do some cleanup"), NULL, MB_OK);
ExitProcess(0);
return TRUE;
}
#pragma pack(1)
typedef struct __PATCHDATA {
BYTE push;
DWORD address;
BYTE ret;
} PATCHDATA;
#pragma pack()
int main(int argc, char **argv) {
HMODULE hModule;
DWORD written;
// This struct contains assembly instruction that do:
// push address ; 0x68 MyTerminateProcess
// ret ; 0xc3
// so the execution will return to our hook
PATCHDATA patch = {0x68, (DWORD) MyTerminateProcess, 0xc3};
// remove this code, the program will terminate itself.
// TODO: check the memory protection and modify it.
WriteProcessMemory(GetCurrentProcess(),
TerminateProcess,
&patch,
sizeof(PATCHDATA),
&written);
TerminateProcess(NULL, 0);
return 0;
}
This hooks TerminateProcess in the same process, you need to ship it in a DLL and inject it in the Task Maneger process, didn't test it. But this method is overwork and not safe, some AV products may detect it as harmful program.
A simple solution is to clean up on the program start-up as #Martin James suggested. On your program start-up create a file or use the registry to store some value like 0, if the program was closed, received WM_CLOSE if it's GUI or CTRL_CLOSE_EVENT if you closed the command prompt, you do the clean-up and store 1.
On the next start-up you you check back that value if it stills 0, this mean do the program was not closed properly, do do the clean up, if it's 1 no need to the clean-up, store 0 and move on.
Many programs use this method to detect if the program was closed properly.

Linux C++ run and communicate with new process

I need to make a program that runs a process (my another programm) and can communicate with this process (sending stdin and recieving stdout).
I have read about functions like popen() and CreateProcess() but I don't really understand how to work with them.
Would be great, if you show me some sample code (how to start process, send stdin, recieve stdout).
C++ functions would be preferred (if there are any).
Thank you in advice.
The interface for POSIX functions C language only. But you can use them in C++.
Basically:
#include <unistd.h>
// Include some other things I forgot. See manpages.
int main()
{
// Open two pipes for communication
// The descriptors will be available to both
// parent and child.
int in_fd[2];
int out_fd[2];
pipe(in_fd); // For child's stdin
pipe(out_fd); // For child's stdout
// Fork
pid_t pid = fork();
if (pid == 0)
{
// We're in the child
close(out_fd[0]);
dup2(out_fd[1], STDOUT_FILENO);
close(out_fd[1]);
close(in_fd[1]);
dup2(in_fd[0], STDIN_FILENO);
close(in_fd[0]);
// Now, launch your child whichever way you want
// see eg. man 2 exec for this.
_exit(0); // If you must exit manually, use _exit, not exit.
// If you use exec, I think you don't have to. Check manpages.
}
else if (pid == -1)
; // Handle the error with fork
else
{
// You're in the parent
close(out_fd[1]);
close(in_fd[0]);
// Now you can read child's stdout with out_fd[0]
// and write to its stdin with in_fd[1].
// See man 2 read and man 2 write.
// ...
// Wait for the child to terminate (or it becomes a zombie)
int status
waitpid(pid, &status, 0);
// see man waitpid for what to do with status
}
}
Don't forget to check error codes (which I did not), and refer to man pages for details. But you see the point: when you open file descriptors (eg. via pipe), they will be available to parent and child. The parent closes one end, the child closes one other end (and redirects the first end).
Be smart and not afraid of google and man pages.