S R Maiti
S R Maiti

Reputation: 307

How to use exec() on Windows with MSVC++?

I am attempting to port a Fortran-C code that was written for POSIX to Windows. From what I can see, the majority of the program can be compiled on Windows, only a few small commands have to be changed.

In the fortran part of the program, there is a line

call system("exec xmrcc >> output.log")

The problem is that, windows does not have any exec command. However, after some digging, I found that on linux the exec command uses the underlying execvp() call. On Windows, MSVC++ provides _exec() and the family of related functions. The _execlp() or _execlpe() seems to be those that I want.

So, I want to replace the fortran system call with a C function that will wrap around the execlpe() and call the program xmrcc.exe.

However, I cannot figure out how the functions work! I have read Microsoft documentation on exec, Use of execl (Arguments), and C- Using exec() in windows . After following the accepted answer of the last question linked, I wrote this C code to test _execlp()

#include <stdio.h>
#include <windows.h>
#include <process.h>

int main()
{
    printf("started running");
    _execlp("C::\\WINDOWS\\SYSTEM32\\CMD.EXE", "cmd.exe", "/c",
 "echo", "foo",">G:\\Python\\foo.txt");
}

However, on running the compiled code, I only got the output "started running" and then it returned; there was no foo.txt file in G:\Python. Then I thought maybe the output redirection is causing problems, so I removed it:

    _execlp("C::\\WINDOWS\\SYSTEM32\\CMD.EXE", "cmd.exe", "/c", "echo", "foo");

Still nothing. It only prints "started running", it does not print "foo".

I have two main questions:

  1. How do I properly run _execlp() on Windows? (to run xmrcc.exe and direct the output to log)
  2. Is it necessary to use the _execlpe() to pass the enviornment variables? (I don't understand how this works.)

I am using Microsoft Visual C++ v19 compiler.

[Please don't mention cygwin, or mingw or WSL, they are not what I am looking for. And I know that system calls in fortran are discouraged, but I didn't write the program, I am only porting it.

And I need to use _execlp() because it replaces the calling process with the child process entirely, and is the closest to linux exec command. This is necessary, because other parts of the program use PIDS, so it's necessary that the a child process with a different PID is not spawned.]

Edit: Would removing the exec shell command work? as in call system("xmrcc >> output.log) It was suggested in the comments by @ChrisDodd.

Upvotes: 1

Views: 1796

Answers (1)

Sami Sallinen
Sami Sallinen

Reputation: 3496

There are 2 things to fix:

  1. the colon ':' after 'C' should not be doubled
  2. _execlp expects a null in the parameter list to detect that there are no more parameters.

So this works:

_execlp("C:\\WINDOWS\\SYSTEM32\\cmd.EXE", "cmd.exe", "/c", "echo", "baz", ">c:\\test\\bar.txt", nullptr);

Upvotes: 1

Related Questions