1

I'm a Winapi/C++ beginner, and I've been stuck for a while on a simple college task.

I have already written a similar program using fork() from POSIX. My question is, how can Windows separate/identify which process is considered a parent/child using a single .exe file?

To simplify the problem, I decided to make sure the parent always launches first, waits for all children to finish, and then closes.

Print command line arguments in child processes in a way that each process prints only one arguments and parent waits for them to finish and closes. In short parent only spawns processes, children do the task.

For example, the command-line call would look like this:

untitled.exe a b c

Expected output would be in random order:

Child process #1: a
Child process #2: b
Child process #3: c
Parent finishes...

I've tried passing a single argument to each child process by command-line arguments, so each gets: untitled.exe argv[index], where index stands for argument range [a, b, c]. This solution is faulty because the parent might get one argument and the child wouldn't spawn.

if (argc <= 2){...}

I though about using a separate .exe file, but I would like to avoid this solution.

I though about using shared memory, but how do I differentiate the parent from each child in that case?

EDIT:

Minimal referral example:

int _tmain(int argc, TCHAR *argv[]) {

    for (int i = 1; i < argc; ++i) {

        if (argc <= 2){
            //print if only has two arguments and finish
        }

        STARTUPINFO si;
        PROCESS_INFORMATION pi;

        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));

        CHAR *temp;
        sprintf(temp,"%s%s%s",argv[0]," ",argv[i]);//create new command line call to pass to createProcess

        if (!CreateProcess(nullptr,   // No module name (use command line)
                           temp,        // exe with one argument
                           nullptr,           // Process handle not inheritable
                           nullptr,           // Thread handle not inheritable
                           FALSE,          // Set handle inheritance to FALSE
                           0,              // No creation flags
                           nullptr,           // Use parent's environment block
                           nullptr,           // Use parent's starting directory
                           &si,            // Pointer toa STARTUPINFO structure
                           &pi)           // Pointer to PROCESS_INFORMATION structure
                ) {
            printf("CreateProcess failed (%d).\n", GetLastError());
            return 0;
        }
        else {
            std::cout << "Child created" << std::endl;
        }
        // Wait until child process exits.
        WaitForSingleObject(pi.hProcess, INFINITE);

        // Close process and thread handles.
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Blemm
  • 11
  • 2
  • 1
    Although you could change the format of the command-line in such a way that you can distinguish a parent from a child, the cleanest solution seems to be to use two different .EXE files, one for the parent and one for the child. On UNIX, the cleanest solution would be to use a single executable which call [`fork`](https://man7.org/linux/man-pages/man3/fork.3p.html), but Windows does not offer this functionality. – Andreas Wenzel Dec 28 '21 at 21:33
  • 2
    The modus operandi for launching the child process in Windows is important, and your code to do so should be included as part of a proper [mcve] in your question. – WhozCraig Dec 28 '21 at 21:35
  • Questions asking for homework help must include a summary of the work you've done so far to solve the problem, and a description of the difficulty you are having solving it. Please read [How to ask homework questions](//meta.stackoverflow.com/q/334822) and [edit] your post. You'll find your experiences here will be much better if you spend some time taking the [tour] and reading the [help] pages to learn how the site works before you begin posting. – Ken White Dec 29 '21 at 01:10
  • 1
    I suggest you could refer to the Doc: https://learn.microsoft.com/en-us/windows/win32/procthread/creating-a-child-process-with-redirected-input-and-output – Jeaninez - MSFT Dec 29 '21 at 06:04
  • @WhozCraig Hi, I've updated the question with minimal example although the code is preety minimalistic too. – Blemm Dec 29 '21 at 08:21
  • @KenWhite Thank you for linking the homework question guide. I've added minimalistic referral code and made my question more specified. I do not wish for anyone to answer this question with prepared solution. All i want is to hear from someone experienced what is a viable solution so i can learn in the right path – Blemm Dec 29 '21 at 08:32
  • Hi @AndreasWenzel thank you for answering. I've alerdy done this task using posix fork, but its tough nut with winapi. If you consider creating two exe files the cleanest solution I might just do it this way :) Still i really want to find out whether it is possible with a single exe file :) – Blemm Dec 29 '21 at 08:54
  • 1
    The code is roughly correct, modulo one bug: `CHAR *temp;` declares a pointer that remains uninitialized. The following call to `sprintf` then attempts to write through that uninitialized pointer, failing with an access violation at best, or corrupting memory. You have to provide a sufficiently sized buffer instead. `std::vector` allows you to construct one when the size is only known at run time (as in this case). – IInspectable Dec 29 '21 at 09:47
  • @Blemm: `"Still i really want to find out whether it is possible with a single exe file"` -- If you want a UNIX-style solution, then you may want to read this question: [What is the closest thing Windows has to fork()?](https://stackoverflow.com/questions/985281/what-is-the-closest-thing-windows-has-to-fork) – Andreas Wenzel Dec 30 '21 at 01:38
  • 1
    @and You don't need to `fork()` to determine the number of command line arguments passed to a process. The code already works, as-is, with a single PE image. Other than porting ancient code, there is literally no reason to ever want to drop down to POSIX when writing code on Windows. – IInspectable Dec 30 '21 at 09:25

1 Answers1

0

"My question is, how can Windows separate/identify which process is considered a parent/child using a single .exe file?"

The fork() function create a new process. The new process (child process) shall be an exact copy of the calling process (parent process). CreateProcess creates a new process and load a program from disk.

In Windows, you could read the InheritedFromUniqueProcessId value, but this does not tell you which process started your process. It only tells you where handles and other attributes were inherited from.

For more details about the difference between fork() and CreateProcess(), I suggest you could refer to the thread: forking() and CreateProcess()

Jeaninez - MSFT
  • 3,210
  • 1
  • 5
  • 20