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; } }
fork. For such behavior in the new process, setsid - avp is called