Programming Tips...

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
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState