Any simple/quick way to fork() on Windows (ANSI C) (_beginthread/_beginthreadex/CreateProcess)
c, fork, winapi
Solution
Windows doesn't support `fork()` at all. The Unix `fork()` is a system call that makes an identical copy of a process, and that's not at all easy to do in Windows.
If at all possible, I'd say using threads to simulate forks is the least bad choice. It does however change a few things - mainly that filehandles are SHARED, not duplicated, so the forked process mustn't close them in the same way as in a true forked process.
Basically, what I'm trying to say is that you are in for a world of pain if you plan on doing something more complicated than a few simple print statements in your forked process, and whilst threads can simulate fork in some cases, it's almost impossible to entirely simulate how fork works in Windows without A LOT of work.
Problem
Can somebody help me to make this C POSIX code to port it to run under Windows? (no Cygwin, MinGW just Windows native APIs and Visual Studio), tried many things without any luck. ``` #include <stdio.h> #include <string.h> #include <unistd.h> #include <time.h> #include <stdlib.h> void usage(char *s); int test_function(char *host); FILE *infile, *outfile; int numforks = 0; void usage(char *s) { printf("Usage: %s <input> <childs>\n", s); exit(EXIT_SUCCESS); } int main(int argc, char *argv[]) { char buf[1024]; time_t start; if (argc < 2) usage(argv[0]); outfile = fopen("test.txt", "a+"); infile = fopen(argv[1], "r"); printf("[*] In: %s Childs: %s\n", argv[1], argv[2]); start = time(0); while (!feof(infile)) { fgets((char *)&buf, sizeof(buf), infile); if (buf[strlen (buf) - 1] == '\n') buf[strlen (buf) - 1] = '\0'; if (!(fork())) { test_function(buf); exit(0); } else { numforks++; if (numforks > atoi(argv[2])) for (numforks; numforks > atoi(argv[2]); numforks--) wait(NULL); } } fclose(infile); fclose(outfile); printf("[*] Completed in: %lu secs\n", (time(0) - start)); exit(EXIT_SUCCESS); } int test_function(char *host) { usleep(2000000); // for debugging fprintf(outfile, "%s\n", host); printf("%s\n", host); return 1; } ``` I tried to do this: ``` #include <stdio.h> #include <string.h> #ifdef LINUX #include <unistd.h> #endif #include <time.h> #include <stdlib.h> #ifdef WIN32 #define fork _forkWin32 #define usleep Sleep #include <cstdlib> #include <cstring> #include <iostream> #include <process.h> #include <windows.h> using namespace std; #endif void usage(char *s); #ifdef WIN32 unsigned int _stdcall test_function(void *ptr); #else int test_function(char *host); #endif FILE *infile, *outfile; int numforks = 0; char proc; void usage(char *s) { printf("Usage: %s <input> <threads>\n", s); exit(EXIT_SUCCESS); } int main(int argc, char *argv[]) { char buf[1024]; time_t start; //#ifdef WIN32 //HANDLE child; //#endif if (argc < 3) usage(argv[0]); outfile = fopen("test.txt", "a+"); infile = fopen(argv[1], "r"); printf("[*] In: %s Threads: %s\n", argv[1], argv[2]); start = time(0); HANDLE child; while (!feof(infile)) { fgets((char *)&buf, sizeof(buf), infile); if (buf[strlen (buf) - 1] == '\n') buf[strlen (buf) - 1] = '\0'; #ifdef WIN32 child = (HANDLE) _beginthreadex(NULL, 0, test_function, buf, 0, NULL); if (child != 0) { #else if (!(fork())) { test_function(buf); #endif exit(0); } else { numforks++; if (numforks > atoi(argv[2])) for (numforks; numforks > atoi(argv[2]); numforks--) #ifdef WIN32 WaitForSingleObject(child, INFINITE); #else wait(NULL); #endif } } fclose(infile); fclose(outfile); printf("[*] Completed in: %lu secs\n", (time(0) - start)); exit(EXIT_SUCCESS); } #ifdef WIN32 unsigned int test_function(void *ptr) { char* host = (char*)ptr; #else int test_function(char *host) { #endif usleep(2000000); // for debugging fprintf(outfile, "%s\n", host); printf("%s\n", host); return 1; } ``` Doesn't seem to do anything. What am I doing wrong? Is it all wrong?