0

I have some C code which uses fork()+exec(), wait() (or waitpid()) and kill() - and assumes they exist after including the relevant POSIX headers.

Now, I want to make this code as multi-platform as possible - with minimal changes. So, no introduction of third-party library dependencies, and no implementing these facilities on systems that don't have them. However, it is important for me to go beyond just Linux, Windows and Mac OS. My tool for doing so is CMake, which the project with this code uses; and the C preprocessor. Maybe a smidgen bit of glue code in C proper.

My question: What should I check for, what should I put in a generated include file, and how should I modify my code calling these functions to effect the same behavior on both POSIX and various non-POSIX platforms?

PS - I realize many platforms don't have Unix-style signals. Let's assume for the sake of discussion I'm only terminating processes, not sending other signals.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 1
    *"no introduction of third-party library dependencies, and no reinventing of wheels"* -- It seems to me that those are two directly conflicting requirements. – Jonathon Reinhart Feb 10 '19 at 21:59
  • @JonathonReinhart: Edited to clarify what I mean. – einpoklum Feb 10 '19 at 22:01
  • 1
    Well, I'm not sure what you're looking for then, aside from the obvious `#ifdef HAVE_FORK` solution. – Jonathon Reinhart Feb 10 '19 at 22:02
  • 2
    If you need `fork()`, then going *beyond* Linux, Windows, and Mac is getting a bit ahead, as you'll first have to get around the fact that Windows doesn't have `fork()`. – John Bollinger Feb 10 '19 at 22:03
  • @JonathonReinhart: Oh, well, exactly that, except that I want an "if you have fork+exec, use that; if you have spawn, use that; if you have something else that's similar but with different parameter order, use that" etc. etc. – einpoklum Feb 10 '19 at 22:03
  • "It is important for me to go beyond just Linux, Windows and Mac OS" -- OK, so, where do you plan on going? There isn't a lot else out there. –  Feb 10 '19 at 22:04
  • The main problem is Windows does not have a direct equivalent of fork function (at least when last I used Win32 API), because its process model is different from UNIX systems. Although there are equivalents of waitpid and kill. Maybe you can simulate a fork function with creating the same process with CreateProcess, than load all memory of first process to second process and jump second process to current location of first process. I am not sure if last steps are possible/stable. Also inclusion of Windows may change how you manage your processes in your platform-independent API. – unlut Feb 10 '19 at 22:05
  • @einpoklum I'm still not sure exactly what you're looking for then. It seems that you're aware of the fact that creating and terminating processes are different on different operating systems, and therefore you'll need to write code for each OS. I'm fairly confident you're not just asking Stack Overflow to write it for you, so I'm trying to figure out exactly what you're looking for in an answer. Most of the complexity probably lies in the `#ifdef` specifics and/or the build system behavior. – Jonathon Reinhart Feb 10 '19 at 22:09
  • @JonathonReinhart: I was kind of hoping there were CMake modules which help you with this and/or existing projects/libraries which need to do the same thing from which I could lift a few lines of code. – einpoklum Feb 10 '19 at 22:17

1 Answers1

2

Windows

Well fork() (create a new process) and exec() (run a new program in this process) don't exist on Windows, plain and simple. Instead, you have CreateProcess which combines the two.

You can then use TerminateProcess to, well, terminate a process.

You could then implement two separate .c files: one for Windows, and one for systems that have fork()/exec().

POSIX

If you only care about portability across POSIX environments (Linux, BSD, Mac OS), then posix_spawn() is definitely the way to go. It handles all the intricacies of error handling in the child process.

See also: capability of `posix_spawn`

Cross-platform Libraries

There are a number of cross-platform frameworks that solve this problem for you:

They of course solve a number of other portability problems also, so it's best to really "buy in" and use the framework for everything you do that interacts with the system.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328