Programming Tips...

 in
In this initial column, I'll explore porting programs from other Un*x versions to Linux. Porting Un*x applications to Linux is best done, as a general rule, by porting the application to some standard which Linux follows. This way, not only will Linux users benefit from your port, but so will users of other operating systems which follow the same standards. As always, there are some exceptions.
Broad Hints

When you write a new application, trying to make as much of the application as possible follow the POSIX standard will generally provide the highest level of portability. If an application “tracks,” or follows the rules of, POSIX, it will compile without changes on almost every known version and clone of Un*x, and on Windows NT, OS/2 2.x, and recent versions of VMS, as well. If some system-dependent code must be written, it can be isolated and clearly marked, making it possible for the next person who ports the application to a new platform to port it much more easily. And programmers on non-POSIX-compliant platforms will probably know their platforms limitations, and know what to do to port your application to their platform.

Unfortunately, the current version of the POSIX standard is showing its age a little. To make a sufficiently powerful application, you generally need to use a more powerful standard, on which defines facilities missing in POSIX. In general, if your program compiles under System V (often referred to as SYSV) or BSD systems, it will probably compile without change under Linux. System V compatibility is enabled default in Linux, and I will show later in this article how to enable BSD compatibility. In general, the Linux libraries, combined with GCC, provide one of the easiest platforms available to port to. In fact, the greatest challenge in writing applications on Linux is to not use all the facilities available on Linux. To do so would make it difficult to port the application to other platforms, even though it would make the application easier to write originally for Linux, because many of these rich facilities are not available on other platforms. Some say that Linux is a better platform to port to than to port from.

For the future, a specification called “Spec 1170” is being written, and all operating systems will have to follow it to be called “UNIXtm”. It is more powerful that most previous un*x specifications—powerful enough that common applications will not have to violate it to get real work done and will be widely followed, as most Un*x vendors have already pledged to support it. Spec1170 is being developed by X/Open, developers of the current XPG3 specification. Linux will eventually comply with most, if not all, of Spec 1170, but the developers will not commit to it without seeing the final standard.

Specific Issues

There are essentially three areas in Linux which cause problems porting, two of which are not avoidable, and the other of which it would be undesirable to avoid.

Conflicting standards

In most cases, it has been possible to make library functions compatible with both SYSV and BSD, but in some cases, standards simply conflict. When this happens, the POSIX behavior is chosen, if POSIX defines it. (If POSIX does not define it, the most reasonable behavior is chosen, or some other standard behavior is used.) For instance, the behavior of signals has changed from one version of unix to another.

Signals in early versions of un*x were unreliable. Whenever a signal was called, the signal handler was uninstalled, and so the first thing that most signal handlers did was reinstall themselves, leading to code like:

void sigfoo_handler(int foo) {
    signal(SIGFOO, sigfoo_handler); /* Rest of signal handler */
}

However, if another SIGFOO signal was received after the signal handler had been scheduled to run, and before signal() had been called, the default behavior for the signal would happen (perhaps it was just ignored, or perhaps the program was terminated, depending on the signal), or if the new signal was received before the signal handler has returned, the signal could be lost completely. Later, reliable signals were introduced to solve these problems, but SYSV and BSD took different routes.

BSD introduced a sigaction() function to replace the old signal() function, and then re-implemented signal() in terms of sigaction(), but changed the semantics of signal() so that a signal handler installed with the signal() function stays installed. SYSV kept the old version of signal() which uninstalls itself, and introduced a whole mess of different functions for dealing with reliable signals. POSIX uses sigaction(). Linux follows POSIX, but can provide BSD signals if the BSD environment is selected, as described below.

Terminal handling also varies, and BSD terminal handling is significantly different from SYSV and POSIX, although SYSV and POSIX terminal handling are similar enough that both interfaces are easily provided by Linux by using the same mechanism in the kernel. The SYSV scheme is known as termio, and the POSIX scheme is known as termio. The older BSD scheme is known as sgtty. When porting a BSD application, you may notice compiler warnings and errors referring to sgtty.h, TIOCGETP, TIOCSETP, TIOCFLUSH, RAW, and other similar things.

To compile applications written specifically for the BSD platform, simply compile with the -I/usr/include/bsd flag, and link the application with the -lbsd flag. This makes BSD terminal handling ioctl()'s work, and makes signal() install the reliable signals that “recent” BSD code expects.

______________________

White Paper
Fabric-Based Computing Enables Optimized Hyperscale Data Centers

Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.

Learn More

Sponsored by AMD

White Paper
Red Hat White Paper: Using an Open Source Framework to Catch the Bad Guy

Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6

Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.

Learn more about catching the bad guy in this free white paper.

Learn More

Sponsored by DLT Solutions