Free Download Windows XP Command Line Hacks Guide:
Windows XP Command Line Hacks (5.3 MB)
A preprocessor #line directive has the form:
>>-#--line--+-decimal_constant--+-----------------+-+----------><
| '-"--file_name--"-' |
'-characters----------------------------'
In order for the compiler to produce meaningful references to line numbers in preprocessed source, the preprocessor inserts #line directives where necessary (for example, at the beginning and after the end of included text).
A file name specification enclosed in double quotation marks can follow the line number. If you specify a file name, the compiler views the next line as part of the specified file. If you do not specify a file name, the compiler views the next line as part of the current source file.
In all C and C++ implementations, the token sequence on a #line directive is subject to macro replacement. After macro replacement, the resulting character sequence must consist of a decimal constant, optionally followed by a file name enclosed in double quotation marks.
Example of the #line Directive
You can use #line control directives to make the compiler provide more meaningful error messages. The following program uses #line control directives to give each function an easily recognizable line number:
/**
** This example illustrates #line directives.
**/
#include
#define LINE200 200
int main(void)
{
func_1();
func_2();
getch();
return 0;
}
#line 100
func_1()
{
printf("Func_1 - the current line number is %d\n",__LINE__);
}
#line LINE200
func_2()
{
printf("Func_2 - the current line number is %d\n",__LINE__);
}
This program produces the following output:
Func_1 - the current line number is 102
Func_2 - the current line number is 202
The history of UNIX® dates back to 1969. Through the years, it has developed and evolved through a number of different versions and environments. Most modern UNIX variants known today are licensed versions of one of the original UNIX editions. Sun's Solaris, Hewlett-Packard's HP-UX, and IBM's AIX® are all flavors of UNIX that have their own unique elements and foundations. For example, Sun's Solaris is UNIX, but incorporates many tools and extensions designed to get the best out of Sun's own workstation and server hardware.
Linux® was born out of the desire to create a free software alternative to the commercial UNIX environments. Its history dates back to 1991, or further back to 1983, when the GNU project, whose original aims where to provide a free alternative to UNIX, was introduced. Linux runs on a much wider range of platforms than most UNIX environments, such as the Intel®/AMD led x86 platform. Most UNIX variants run on just one architecture.
Because of this history and the heritage of the two products, Linux and UNIX have a common foundation, but are also very different. Many of the tools, utilities, and free software products that are standard under Linux were originally developed as free alternatives to the versions available on UNIX. Linux often provides support for many different options and applications, picking the best (or most popular) functionality from the UNIX and free software environment.
An administrator or developer who supports Linux systems might find it uncomfortable to move to a commercial UNIX system. On the whole, the foundations of any UNIX-like operating system (tools, filesystem layout, programming APIs) are fairly standardized. However, some details of the systems show significant differences. The remainder of this article covers the details of these differences.
The developers of commercial editions of UNIX have a specific target audience and platform for their operating system. They also have a pretty good idea of what applications they want to support and optimize. Commercial UNIX vendors do everything they can to maintain consistency between different versions. They have published standards that they follow for their customers.
The development of GNU/Linux, on the other hand, is more diverse. Developers come from many different backgrounds, and therefore have different experiences and opinions. There has not been as strict of a standard set of tools, environments, and functionality within the Linux community. The Linux Standards Base (LSB) project was formed in an attempt to alleviate this problem, but it has not provided as much help as hoped.
This lack of standards results in noticeable inconsistencies within Linux. It might seem a benefit to some for developers to have the freedom to emulate the best parts of other operating systems, but it can be very confusing when certain elements of Linux emulate different UNIX variants. For example, device names within Linux might emulate AIX, while the filesystem tools seem more like the tools supplied with HP-UX. These sorts of inconsistencies even exist between different Linux distributions. For example, Gentoo and RedHat have different methods for keeping their systems current with the latest patches and software releases.
By comparison, each new release of an operating system comes with a well-documented range of new features and changes within the UNIX space. Commands, tools, and other elements are rarely changed, and often the same command line arguments and interfaces remain over many editions of the software. Where there are significant changes, a commercial UNIX vendor often provides a compatibility layer, or the ability to run the older version of the tool.
This consistency means that tools and applications can be used on new editions of the operating system without a large body of testing. It is much easier for a UNIX user or administrator to update their skills on what is otherwise an unchanged UNIX operating system than the migration or adaptation of skills that might be required between Linux distributions.
Most commercial versions of UNIX are coded for a single, or possibly a small handful, of hardware architectures. HP-UX is available on PA-RISC and Itanium machines. Solaris is available on SPARC and x86. AIX is only for power processors, and so forth.
Because of these limitations, the UNIX vendors can optimize their code for these architectures. They can take advantage of every feature. Since they know their supported devices, their drivers can be better optimized as well. They are also not restricted by the weak BIOS limitations of most PCs.
Linux, on the other hand, has historically been designed to be as compatible as possible. Not only is Linux available for dozens of architectures, but the number of I/O and other external devices that might be used are almost limitless. The developers cannot assume that a specific hardware feature will be installed and, so often, cannot optimize as well. One example is the memory management on Linux. Since it was originally developed on x86 hardware, it used the segmented memory model. It adapted to use paged mode memory over time, but still retains some segmented memory requirements. This has caused problems for architectures that do not support segmented memory. This is not an issue for UNIX vendors. They know exactly which hardware features they have available.
The kernel is the core of any operating system. The source code is not freely available for any of the commercial versions of UNIX. Quite the opposite exists for Linux. As such, procedures for compiling and patching kernels and drivers are vastly different. With Linux and other open source operating systems, a patch can be released in source code form and end users can install it, or even verify and modify it if desired. These patches tend to be far less tested than patches from UNIX vendors. Since there is not a complete list of applications and environments that need to be tested on Linux, the Linux developers have to depend on the many eyes of end users and other developers to catch bugs.
Commercial UNIX vendors only release their kernels in binary form. Some release the kernel as a single monolithic package, while others are able to dismantle the kernel and upgrade just a single module. Either way, it is still in binary form. If an update is required, the administrator has to wait for the vendor to release the patch in binary form, but they can be more secure knowing that the vendor has performed sufficient regression testing.
All commercial versions of UNIX have evolved to support some sort of module-based kernel. Drivers and certain features are available as separate components and can be loaded or unloaded from the kernel as needed. None is quite as open and flexible as the module architecture in Linux. However, with the flexibility and adaptability of Linux comes constant change. The Linux code base is constantly changing and the API can change at the whim of a developer. When a module or driver is written for a commercial version of UNIX, that code works far longer than the same driver written for Linux.
One of the reasons Linux has become such a powerful tool is its immense compatibility with other operating systems. One of the most obvious features is the plethora of filesystems that are available. Most commercial version of UNIX supports two, or possibly three, different local filesystem types. Linux, however, supports almost all of the filesystems that are currently available on any operating system. Table 1 shows which filesystems are supported under which version of UNIX. You can mount each of these filesystems under Linux, although not all of them allow full read-write support.
AIX | jfs, gpfs |
HP-UX | hfs, vxfs |
Solaris | ufs, zfs |
Irix | xfs |
Most commercial UNIX versions have at least some sort of journaling filesystem available. For instance, HP-UX uses hfs as its standard filesystem, but it also supports the journaling vxfs filesystems. Solaris is similar with ufs and zfs. Journaling filesystems are a critical component of any enterprise server environment. Linux was relatively late to support journaling filesystems, but now there are several options ranging from ports of commercial filesystems (xfs, jfs) to native Linux-only filesystems (ext3, reiserfs).
Other filesystem features include quota support, file access control lists, mirroring, snapshots, and resizing. These are are supported in some form or another on some of the Linux filesystems. Most of these features are not standardized on Linux. They might work one way on one filesystem, but another method is required on another filesystem. Some of these features are just not available on some Linux filesystems, and some require additional tools to be installed, such as a certain version of LVM or software raid package. Linux historically had difficulty reaching consensus on programming interfaces and standard tools, since there are so many filesystems that present these features so differently.
Since commercial versions of UNIX have a limited number of filesystems to support, their tools and methods are more standardized. For instance, since there is only one main filesystem on Irix, there is only one method used to set access control lists. This makes it much simpler for the end user as well as for vendor support.
Most of the core applications are the same between UNIX and Linux. For instance, cp
, ls
, vi
, and cc
are commands that are available in both UNIX and Linux, and are very similar, if not apparently identical. The Linux versions tend to be based on the GNU version of these tools, whereas the current UNIX versions are based on the original UNIX tools. The tools on UNIX have had a very stable history and rarely change anymore.
This is not to say that commercial versions of UNIX cannot use the GNU tools. In fact, many commercial UNIX vendors include many of the GNU tools in their installations, or as free options. They are just not the standard tools in the customary locations. Certain free programs, such as emacs or Perl, do not have non-free counterparts. Most vendors offer these as pre-compiled packages that are either automatically installed or available as an optional component.
Free and open source applications are almost always assumed to be available and function on all Linux distributions. There are huge amounts of free software available for Linux. Many of these applications have been ported and are available in some form on commercial versions of UNIX.
When it comes to non-free and/or closed-source applications (CAD, financial, graphics design), however, Linux comes up short. While some software vendors have released versions of their programs for Linux, the majority seem to be delaying their releases until Linux adoption reaches a critical mass.
On the other hand, commercial versions of UNIX have historically had large amounts of support for enterprise-level applications, such as Oracle or SAP. Linux lacks in this regard, because of the difficulty of larger applications to be certified, whereas commercial versions of UNIX do not change very much from release to release. Linux can change wildly not only between different distributions, but sometimes between releases of the same distribution. This makes it very difficult for application vendors to understand the exact environment in which their tool will be used.
Although some Linux distributions come with a standard system management tool, such as SUSE's YaST, there is not a Linux-wide standard on tools for system management. Text files and command-line tools are available, but these can be cumbersome and sometimes difficult to remember. Each commercial version of UNIX has its own separate management interface. From this interface, aspects of the entire system can be manipulated and altered. One example of this is the System Administration Manager (SAM) on HP-UX.
From within SAM, there are modules where:
This tool is well-written and incorporates well with the back-end text files. There is no such tool for Linux. Even SUSE's YaST is not nearly as complete, or compatible.
One aspect of UNIX and Linux that appears to be different for almost every version of UNIX and Linux is the location of system initialization scripts. Luckily /sbin/init and /etc/inittab are in standard locations. But beyond that, all the startup scripts are in different locations. Table 2 lists the location of system initialization scripts for various UNIX and Linux distributions.
HP-UX | /sbin/init.d |
AIX | /etc/rc.d/init.d |
Irix | /etc/init.d |
Solaris | /etc/init.d |
Redhat | /etc/rc.d/init.d |
SUSE | /etc/rc.d/init.d |
Debian | /etc/init.d |
Slackware | /etc/rc.d |
Because of the many different distributions of Linux and the almost infinite number of application and version differences, package management on Linux has always been a little tricky. There are a range of different package management tools available. The correct tool depends on which Linux distribution you are using. Further confusion results from different distributions using the Redhat Package Manager (RPM) file format, but their packages remain incompatible. This fragmentation has led to a myriad of different options, and it is not always obvious which system is in use within a particular environment
On the other hand, UNIX vendors use standard package managers. Even though there are different applications and formats among the different commercial UNIX variants within a specific version, the application environment is consistent and stable. For instance, Solaris has used the same package management tools since its inception. It has been, and will most likely always be, the same tools to identify, add, or remove packages on Solaris.
Recalling that commercial UNIX vendors supply the hardware that accompanies their operating systems, they are able to introduce hardware features that are much harder for Linux to include. For instance, recent Linux versions have attempted to support hot-swap components in hardware (with varied success). Commercial UNIX versions have had these features for many years. There is also more advanced hardware monitoring on commercial UNIX versions. The vendors can write drivers and hooks into their operating system that can monitor hardware health, such as ECC memory failures or power supply parameters, or any other hardware component. This sort of support on Linux is very premature.
Commercial UNIX hardware also has far more advanced initial boot options. Before the operating system boots, there are many options to decide how to boot, check system health, or set hardware parameters. The BIOS that is standard in PCs has few, if any, of these features.
SupportOne of the most obvious differences between Linux and UNIX is the cost perspective. Commercial UNIX vendors charge significant amounts of money to acquire and use their versions of UNIX on their optimized hardware. Linux distributions, on the other hand, charge relatively little, if anything, for their operating system.
If a commercial version of UNIX is purchased, the vendors usually provide technical support to make sure the system works as expected. Most Linux users do not have the luxury of a company to stand behind their systems. They depend on the support of email lists, forums, and various Linux users groups. These support tools are not only restricted to Linux. Many administrator and users of commercial versions of UNIX participate in these free support groups to find and provide help. Many people even claim the free support groups are more responsive than the commercial vendor's support systems.
Overall, the general environment between UNIX and Linux is very similar. Moving as a user or administrator from Linux to UNIX, or vice versa, brings some inconsistencies, but overall is fairly seamless. Even though the filesystems or kernels might differ and require specialized knowledge to optimize, the tools and APIs are consistent. In general, these differences are no more drastic than variations among different versions of UNIX. All branches of UNIX and Linux have evolved and will be slightly different, but because of the maturity of the UNIX concept, the foundation doesn't change very much.
Learn
Discuss