Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any simple/quick way to fork() on Windows (ANSI C) (_beginthread/_beginthreadex/CreateProcess)

Tags:

c

fork

winapi

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?

like image 732
bsteo Avatar asked Oct 19 '25 12:10

bsteo


1 Answers

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.

like image 71
Mats Petersson Avatar answered Oct 22 '25 03:10

Mats Petersson