Porting DOS Applications to Linux
In general, the kernel automatically blocks programs, thus avoids having them use CPU time when they are waiting for I/O. A device can be opened with the extra option O_NDELAY to indicate that an error EWOULDBLOCK should be returned to indicate the lack of ready data (or for writing lack of buffer space). When a program is using I/O in this manner, it must take great care not to sit in a tight loop.
Avoid the following DOS-style constructs:
while(1)
{
if(kbhit())
do_something(getch());
if(timer_expired())
time_event();
}
Linux instead provides the very useful select() system call, which allows you to wait for multiple I/O events, a timeout, or both, in a manner that avoids polling and enables the kernel to avoid allocating processor resources to the task in question.
select() allows you to wait for a given time, or wait until one of a set of files has data ready to read or space to write, or wait until an exceptional condition occurs on that file. As the Linux system sees everything within reason as a file, this is extremely flexible.
Listing 1 shows is a “trivial” example. This is an implementation of kbhit(). For exact DOS behaviour, it assumes the terminal is already in raw mode, which we will discuss later. Otherwise, it will return 1 after ENTER is pressed, which is when data becomes available in the line-by-line cooked mode.
Sharp-eyed DOS programmers might wonder, “What happens with this kbhit() if we redirect the input of the program from a file? It's not a keyboard, but input is available.” The answer is simple enough—a disk file is always ready for reading, and at this level, there is no difference between reading a keyboard and reading a file. The program carries on and works fine. Indeed, you could redirect a program to run reading input from the mouse and select() would still behave consistently.
File I/O under Linux is somewhat simpler than DOS. DOS emulates the Unix low level (open(), close(), read(), and write()) and high level “stdio” facilities, but DOS C libraries have their own ascii/binary awareness to handle the carriage return/line feed differences. Under Linux these are gone and there is no need to worry about specifying these (although the ascii/binary specification will be accepted). All of the DOS device names are different under Linux. Linux systems keep their devices in /dev. Here is a rough conversion chart:
CON: /dev/tty
LPT1: /dev/lp0
LPT2: /dev/lp1
LPT3: /dev/lp2
COM1: /dev/ttyS0 /dev/cua0
COM2: /dev/ttyS1 /dev/cua1
COM3: /dev/ttyS2 /dev/cua2
COM4: /dev/ttyS3 /dev/cua3
NUL: /dev/null
Note that it is normal to print by queueing jobs via the printing service (lpr) rather than writing directly to ports. On typical Linux systems the /dev/lp* files are protected so that a normal user cannot access them directly.
Terminal I/O is distinctly different in Linux than it is under DOS. First, the POSIX terminal system is more modal than DOS. To switch from one-character-at-a-time mode (getch() in DOS) to a line-based editing mode requires an actual termios request, which gives the new terminal parameters to use. In addition, a program is responsible for restoring the terminal state before it runs other programs and when it exits. If you forget to do this, you may well need to switch screens and kill the process, or you may find that the shell gets confused by your terminal state and logs you out (which also fixes the problem).
Listing 2 includes some sample code for managing terminal I/O settings.
On output, Unix programs traditionally avoid using direct cursor control codes and cannot write directly to video memory. The reasons for this are obvious. The terminal in question may be a different type of machine, in a different part of the world. Handling all the different terminal types by hand is unpleasant, so a library called curses is available. A more modern library called ncurses, which has such things as colour support, is also available for Linux. Older versions of this have had many bugs, but the latest appears very good indeed. See article “ncurses: Portable Screen Handling for Linux”, Linux Journal issue 17, September, 1995, for an introduction.
ncurses provides you with simple output control, colour (if the terminal supports it), function keys, and other manipulations in a terminal-independent manner. In addition, it optimises the updates it does to minimize traffic over slow networks or serial links. It is free and comes with a nice set of examples and good documentation. As it is an implementation of System V curses, you can pick up a book on curses from a library and use that as a reference or tutorial (as appropriate).
Should you decide to use ncurses to do your output, it will also provide all the routines necessary to do DOS style character-by-character input via the functions cbreak(), nocbreak(), echo(), and noecho(). The ncurses documentation explains all four.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
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.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- Designing Electronics with Linux
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Dynamic DNS—an Object Lesson in Problem Solving
- Linux Systems Administrator
- Using Salt Stack and Vagrant for Drupal Development
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Reply to comment | Linux Journal
1 hour 9 min ago - Dynamic DNS
1 hour 43 min ago - Reply to comment | Linux Journal
2 hours 41 min ago - Reply to comment | Linux Journal
3 hours 31 min ago - Not free anymore
7 hours 33 min ago - Great
11 hours 20 min ago - Reply to comment | Linux Journal
11 hours 28 min ago - Understanding the Linux Kernel
13 hours 43 min ago - General
16 hours 13 min ago - Kernel Problem
1 day 2 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
Error in listing 2
The second call to signal in term_ctrlz should be a call to kill, i.e. kill( getpid(), SIGSTOP );