Obviously, fork() not implemented in the Windows API, and all that is there are options around CreateProccess , such as in cygwin.

The question is, with what keys and parameters do you need to run CreateProccess that you can safely exit the first process and release the console?

And I understand that forcing the code to run from the same place where CreateProccess called from, there really is no way? and it is necessary to invent crutches with the detection of whether the first fork was or was not already. What are the solutions to this?

Desired behavior: 1. The parent process starts the child and finishes itself. 2. Only the former child process works. 3. The task to release the console and run in the "background".

As in the case of a separated child process, the situation with the input / output in Win, taking into account the closure of the parent ..

  • I looked, but I didn’t find the answer there; more interested in the second part of the question, about the place where the code starts, so to speak. General reasoning on this topic is known. The threads in the task to free the console do not fit. - NewView
  • specify the expected behavior of the program. 1. parent process creates a child process. 2. The parent process stops. 3. The child process runs to the end. 4. The parent process resumes and continues execution. Such an order? And is it necessary to run the child process in a separate console window? - acade
  • Added to the question. - NewView
  • one
    "Freeing the console" (more precisely, the change of control tty) does not occur in the usual fork . For such behavior in the new process, setsid - avp is called

2 answers 2

I am not very familiar with Unix in general and the fork function in particular, but if I remember correctly, the fibers support in Windows was just introduced for porting Unix applications using fork . The point is that in the understanding of Windows, a fork program is single-threaded, and its implementation through a multithreading mechanism is very inconvenient. Therefore, in Windows NT and fiber appeared. They are rarely used (because the streams are better) and few people remember about them, but they fit your task perfectly - that's what they came up with.

The fiber documentation is here . They are also described in Jeffrey Richter’s classic book “Windows for Professionals,” Appendix A.

    In general, in the draft version, the multiplatform fork turned out to be as follows: Capturing the state in the Win version occurs using the command line keys.

    One thing is not clear what to do in this case with cleaning handles from CreateProccess, typical cleaning / closing like this:

      CloseHandle(pi.hProcess); CloseHandle(pi.hThread); 

    but I strongly fear that it will kill / ruin the instance that CreateProccess creates.

    code:

     int my_fork(int argc, char *argv[]) { # if defined(OS_WIN) int i, ret = 0; size_t sz = 0; char *cmd = NULL; char *p; for (i = 0; i < argc; i++) { size_t ssz; if (!argv[i]) break; ssz = strlen(argv[i]); if ( ( (ssz == 2U) && (!memcmp(argv[i], (void*)&"-k", 2U)) ) || ( (ssz == 9U) && (!memcmp(argv[i], (void*)&"--nonloop", 9U)) ) ) continue; if (!(p = realloc(cmd, (size_t)(sz + ssz + 2U)))) { if (cmd) free(cmd); return -1; } cmd = p; memcpy((void*)(p + sz), argv[i], ssz); sz += ssz; p[sz] = 0x20; p[++sz] = 0x0; } sz = ((sz) ? (sz - 1) : 0); if ((!cmd) || (!sz)) { errno = EINVAL; return -1; } /* remove last blank 0x20 */ cmd[sz] = 0x0; do { STARTUPINFO si; PROCESS_INFORMATION pi; memset(&si, 0, sizeof(si)); memset(&pi, 0, sizeof(pi)); si.cb = sizeof(si); si.dwFlags |= DETACHED_PROCESS; if (!CreateProcess( NULL, cmd, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS, NULL, NULL, &si, &pi ) ) { ret = -((int)GetLastError()); } } while (0); free(cmd); return ret; # elif defined(__GNUC__) (void) argc; (void) argv; switch(fork()) { case 0: { int cfd; (void) signal(SIGHUP, SIG_IGN); if ((cfd = open("/dev/null", O_RDWR, 0)) >= 0) { dup2(cfd, STDIN_FILENO); dup2(cfd, STDOUT_FILENO); dup2(cfd, STDERR_FILENO); if (cfd > 2) { close(cfd); } } if ((getppid() != 1) && (setsid() < 0)) { return -1; } (void) sleep(12); return (int)getpid(); } case -1: { return -1; } default: { (void) signal(SIGCHLD, SIG_IGN); errno = 0; return 0; } } # else /* default value > 0, continue run, no errors */ return 100; # endif } 

    UPD. if you later call CreateProccess , then to prevent blinking with new windows, you must specify the CREATE_NO_WINDOW flag.

    Yes, for understanding, it starts like this:

      switch(my_fork(argc, argv)) { case -1: { exit(127); } case 0: { exit(0); } default: { break; } } 
    • " but I strongly fear that it will kill / spoil the instance CreateProccess creates " - it will not kill and will not spoil. - freim
    • @freim, Yes, thanks, I already checked, it was a long time ago .. :) - NewView