Is This Unix?

In the beginning, Ken Thompson, Dennis Ritchie, and others created Unix. And it was good. Then came the varieties and variants: BSD, System V, and eventually Linux. These are all similar operating systems, not identical, but with a common root and familiar features. You can’t call them all “Unix,” so over time various standards and terms have been developed.

A term that frequently pops up when ruminating over the various Unixes and Linux distros, is POSIX.

Not an operating system, the Portable Operating System Interface (POSIX) family of standards helps define what makes a Unix-like OS. POSIX provides consistency. This effect extends to the C language, where a POSIX test can be made in your code to determine whether the program is running in a Unix/Linux environment or something more perverse, such as Windows.

In the unistd.h header file, the defined constant _POSIX_VERSION is declared. For a Unix, Linux, or other POSIX-obedient operating system, this value is assigned an integer value representing the POSIX version. In Windows, however, which also has the unistd.h header file available for its C compilers, the _POSIX_VERSION constant is undefined. Therefore, a test can be made in the code to determine whether the system has POSIX functions and features available.

2020_10_10-Lesson.c

#include <stdio.h>
#include <unistd.h>

int main()
{
#ifndef _POSIX_VERSION
    puts("This system is most likely not POSIX (Unix/Linux)");
#else
    printf("This system is POSIX standard %ld\n",_POSIX_VERSION);
#endif

    return(0);
}

This code uses the #ifndef preprocessor directive to determine whether _POSIX_VERSION is defined. If not, Line 7 is executed, informing the user that the system isn’t POSIX-compatible, e.g., most likely Windows. Otherwise, the #else condition takes over, and the output shows the current POSIX version, as shown here:

This system is POSIX standard 200112

And for Windows:

This system is most likely not POSIX (Unix/Linux)

Such a decision tree is useful in a code, such as last week’s Lesson, where a POSIX function ttyname() is used. On a Windows computer, the code could be compiled, but the function would be part of an #ifndef/#else/#endif decision so that it compiles and presents a proper answer for the user.

Way, way back in time, when I would code for the original IBM PC under DOS, I wrote decisions like this in my code after determining whether the system could generate color output. Back then, color monitors were expensive and rare. So a test was made and the program changed its output routines based on whether color was available. This is yet another practical example of using defined constants to alter the course of your program, and ensure that it’s compatible across a broad platform of systems.

Leave a Reply