How to test POSIX compatibility? - c

I am writing a C program with POSIX API and using Linux.
I compiled and ran it on a friend's Mac OSX PC and there was a small error, but I did not use Linux specific features.
I will use some specific features that Linux adds to the API. I will also use specific POSIX extensions for Mac Os X and FreeBSD.
I will use conditional compilation to choose the code. If the OS is none of those, I will use generic POSIX code.
I do not own Darwin/Mac OSX and FreeBSD, Linux is the only OS that I have in my PC. I cannot download and install FreeBSD, because it is more than 500 MB.
I want to know a way to test if the program will compile and behave as expected on other POSIX systems.
I wonder if there is a POSIX simulator and compiler to do tests.
The tests are simple, they do not use GUI and drivers, they are only command line.
I will need to do 3 tests: FreeBSD, Mac OSX/Darwin and Generic POSIX, but I do not have the tools.
EDIT
Is there a minimal version of FreeBSD and Darwin without GUI, but with GCC/G++ and ssh/scp? Darwin is free, is not it?
My PC is old, but I think I can install them in a virtual machine, create a virtual network and use ssh/scp to transfer and test the programs.

One simple way is to compile your program with the proper feature test macros. For example if you define _POSIX_C_SOURCE to the target version of POSIX (currently 200809L), you will request the system headers expose to your program nothing except what's needed/allowed by POSIX base. This can be done via the command line CFLAGS with -D_POSIX_C_SOURCE=200809L. If you want the XSI option (full Single Unix Standard functionality, which is a superset of POSIX base) then use -D_XOPEN_SOURCE=700 instead.
This will not help you detect problems that come from either certain systems lacking POSIX functionality (for example, OSX is broken and lacks a working sem_init last I checked, even though it's mandatory in POSIX), or from writing code that depends on non-standard behavior in the POSIX-standard interfaces (for example, using GNU regex extensions in the expressions you pass to regcomp) but it will help you catch any accidental usage of interfaces not in the standard.

If you want to compile for other system, you usually don't need to have the other system, you just need an appropriate cross compiler.

Related

Why can I access unistd.h in windows?

I'm running Codeblocks on Windows platform. When studying about POSIX superset standard in C I came across some incompatibilities. I do understand that POSIX standard is designed to work on unix like systems whereas on windows I should search for the equivalents.
The problem I encounter is that for example (from wikipedia)
In the C and C++ programming languages, unistd.h is the name of the header file that provides access to the POSIX operating system API. It is defined by the POSIX.1 standard, the base of the Single Unix Specification, and should therefore be available in any POSIX-compliant operating system and compile
But when I include unistd.h in my IDE, I get no errors. Of course, I miss some of the defines but surprisingly for me it works. I was expecting an error when including the library. For example, on ubuntu running the same IDE with the same compiler I got error when including Windows.h header which makes sense. Why doesn't it works both ways?
Also, why do I have on windows access to functions for unix like systems (found in POSIX standard)?
Is there any conversions my compiler does? It automatically converts POSIX standard to windows compatible?
Mingw (the default Codeblocks compiler) provides some of those headers inside the include directory of the installation. It has some manner of POSIX support, but I don't think it is 100% compliant. If you want to be certain to run *nix/POSIX compliant libraries under Windows, you should probably use Cygwin instead.

The C language and Mac OSX

I was wondering whether anybody here could help me better understand the relationship between OSX and C. There's some developer information related to C++ in xcode but nothing for C.
I believe one fundamental difference is that osx uses libc as opposed to glibc. Can anybody point me to libc documentation? I can't seem to find any.
I've seen the usr/includes folder but all that does is make me wonder where I can get a reference that elucidates all the options available to me. For instance, I just discovered <tree.h>. That's all well and good but is there any documentation? Or do I need to trawl the includes folder?
It seems that you're asking whether the functionality that OSX provides to you as a programmer is partially different from other *nix systems; focusing on the functionality that OSX's implementation of the C Standard Library provides you with.
Now keep in mind that while the C Standard Library is a very common way to take advantage of the functionality the operating system kernel exposes, it's not the only way. You can use other low-level libraries, or write low-level functions yourself.
Having said that, consider the following:
OSX, like many other *nix systems, is "mostly POSIX-compliant". Meaning that its particular C Standard Library implementation will likely expose headers defined by the POSIX standard. This is the stuff you can rely on regardless of whether you use libc, glibc, or some other implementation of the C Standard Library.
Depending on the particular C Standard Library you're using, it might come with additional functionality, like BSD libc - we say "superset of the POSIX Standard Library" to that. While it can contain implementations of things specific to BSD (and therefore OSX), it mostly seems to contain things that can be implemented regardless of the operating system flavour. For example, the sys/tree.h header that you mention is "an implementation of Red-black tree and Splay tree" - by no means something that couldn't have been implemented on a Linux system!
To sum up:
OSX comes with an implementation of the C Standard Library called BSD libc that provides some additional headers on top of what the POSIX Standard defines.
The difference in functionality between the XNU kernel used by OSX and other *nix kernels will not necessarily be captured in the difference between the C Standard Library implementations. If you want to know what the XNU kernel can do for you that the Linux kernel can't, the place to start is with the kernels themselves.
So your question can be split into:
What is the difference between glibc and BSD libc?
and
What is the difference between the XNU kernel and the Linux kernel?
It's a bit unclear what you're asking.
OS X is based on top of FreeBSD, a POSIX-compliant UNIX operating system. The relationship between OS X and C is that C is one of many programming languages that you can code in to develop for the platform (C is the core of Objective-C, an otherwise unused language that Apple champions).
OS X doesn't use libc. clang, the compiler that ships as part of Apple's developer tools package for OS X, uses libc. There's a difference. If you want to use glib, grab GCC from Homebrew or Macports and use it to compile your programs instead of clang.
Lastly, you can't find documentation for libc, as all C libraries, like libc, glibc, etc, all provide the same set of functions if they are standards-compliant. There tend to be few differences end-user-wise between the different C libraries; so, if you want to find out about a header file, use man, like this: man clang to read clang documentation, for example.
Hope this helps.

Programming in C - Differences between Linux and OSX

Hello I'm looking into C Programming.
I'm wondering if there are differences between Linux and OSX in C? I know there are some between Windows and Linux/Unix (like getting a system timestamp). Are there any specific commands or techniques which won't work one of the two? Should "basic" programs run on both?
I'm aware that C isn't a cross compiling language but OSX and Linux are both Unix - aren't they?
What changes is not the language itself, but the libraries (and related API calls). There is no difference between Mac OSX and Linux under this aspect, as long as you stick with standard POSIX calls. Both Linux and Mac OSX are POSIX-compliant systems.
Of course, when talking about proprietary Apple libraries, you can't expect to find them under Linux. But this is another problem. Same for Linux internals.
Note that we are talking about source compatibility, not binary compatibility. You won't have to modify your source code at all, but you will have to compile it for each platform separately.
Linux includes quite a few extensions over the basic POSIX standard that both Linux and Darwin follow (Linux is "standard" in that it is exactly like Linux). As Stefano notes, in many cases this is fine, but if you have a program that was written for Linux without concern for portability ("runs on both Ubuntu and SuSE" is not "portability"), you should expect to see some different behaviors and missing extensions. For instance, mremap() and pipe2() are Linux-specific functions. SOCK_NONBLOCK is a Linux-specific flag to socket(), etc. The man pages will typically indicate when something is Linux-specific in the "Conforming To" section.

dos.h for Linux?

I have a C program which contains #include <dos.h> header. It shows a compile time error. I know that the dos.h header file is not valid in Linux.
Is there any other equivalent header for dos.h in Linux?
Linux is a Posix/Unix like system, so you should learn the system calls and facilities that you can use. Read the advanced unix programming book (or some equivalent; AUP is considered a very good book). You can also read advanced linux programming (even online, a copy is here). So Linux don't have a dos.h header.
You could also type man 2 intro to get an intro to syscalls, and their list in in syscalls(2) man page. From an application's point of view syscalls are elementary operations provided by the Linux kernel.
The GNU libc provides a big lot of functionality (e.g. standard C functions like malloc and fprintf, and system functions like fgetpwent to query user database, etc etc...) above the system calls. Almost every Linux program uses it.
If you care about coding stuff which should be portably runnable (after recompilation) on other similar systems (e.g. MacOSX or FreeBSD) consider following the Posix standard.
If you want to code a terminal screen application, consider using ncurses.
If you care about graphical interfaces, use a graphical toolkit like Qt or Gtk; they usually interact with an X11 server (and both Qt and Gtk are able to run on some other non Posix systems, e.g. Windows, by providing a common graphical abstraction layer.). Both Gtk and Qt are adding an abstraction layer (Glib and QCore respectively) above system functions and facilities (in particular above the pthreads standard thread library).
At last, Linux is free software; so you might find interesting to look inside the source code (of a library or utility) that you are using. You could even improve it and contribute to it.
In all these aspects, Linux programming is very different from Windows or DOS.
Don't try to mimic every Windows or Dos function into Linux (e.g. don't ask the equivalent of every dos.h function); learn the Posix/Unix way of thinking and coding.
The time(7) man page tells you a lot about time (various meanings and functions about it) on Linux.
Don't forget to ask warnings from the compiler with gcc -Wall -Wextra; as a general rule, improve your source code till you get no warnings.
There cannot be an exact Linux equivalent of dos.h because Linux (i.e. Unix or Posix spec) and Windows are systems with different features and concepts. However several free libraries (I mentioned Glib and QCore) are providing common abstractions to fit into Linux and into Windows, so if you want to develop software portable to Windows and to Linux I suggest using these libraries instead (use them both on Windows and on Linux).
(I also suspect that Microsoft would use legal threats -patent or copyright based- to avoid that free clone of their proprietary dos.h, given their monopolistic reputation and their aversion to standards and to free software; I admit I have strong opinions against Microsoft..)
dos.h header file is interface to the DOS operating system. They are not portable to operating systems other than DOS (means not works in Linux). Which functionality in dos.h you are going to use?
#include<dos.h> is not available for Linux
but if you want to use dos.h for displaying the time you can use the system function and do it like this
prototype -> system(command);
system("date +%H:%M:%S");
if you want your program to sleep for a specific seconds
try this
system("sleep 3") //sleep for a 3 seconds
or use this
std::this_thread::sleep_for(std::chrono::milliseconds(100));
but you have to include the thread header file #include<thread>

fork(), sleep(), and pipe(int *fd) in Mac OS X

I am taking a class called 'Operating Systems' and we are learning about these functions. I have a Mac and i want to know if these function work on Mac, or do I have to install linux. If I can't do this on Mac, what linux distribution should I install? (There's so many, I don't know which one to get).
Your prototype for pipe() is wrong, but all three functions are part of POSIX. Since OS X is a POSIX operating system, it supports all three. Note that you will need to install Apple's developer tools in order to have access to a compiler and the appropriate headers and such in order to build software that uses them.
I just took Operating Systems, and since the course revolves around UNIX, if you were on Windows, I'd recommend installing Linux just for the sake of the course. Since you are on a mac, it shouldn't be too different. By the way, most distros have live versions, so you can just boot up Linux for an assignment or something, if you want. Any popular distro would do just fine.

Resources