FreeDOS Blog

❮ Back

November, 2018

Code review: simulate typing

This is part of the Code Review series, even though it's not strictly about FreeDOS.

When we released the FreeDOS 1.2 distribution, I recorded a short video about how to install FreeDOS. I prefer to run FreeDOS on my Linux laptop using the QEMU PC emulator, so that's what I used for my "how to" video. But the thing about QEMU is you don't launch QEMU from a GUI control panel, like you might for other PC emulators like VirtualBox. Instead, you create QEMU's virtual disk and define the QEMU virtual machine by typing commands at the command line. So for my video, I needed to type commands as I talked about what I was doing.

As I tried to record my video, I kept running into problems. I’m just not the kind of person who can type commands at a keyboard and talk about it at the same time. I quickly realized I needed a way to simulate typing at the keyboard, so I could create a “canned” demonstration that I could narrate in my video.

After some searching, I didn’t see a command on my Linux distribution that would simulate typing. I wasn’t surprised; that’s not a common thing people need to do. Instead, I wrote my own program to do it. Here's how I did that.


Writing a program to simulate typing isn’t as difficult as it may first seem. I needed my program to act like the echo command, where it displayed output given as command-line parameters. I added command-line options so I could set a delay between the program “typing” each letter, with an additional delay for spaces and newlines. The program basically did this:

For each character in a given string:
  1. Insert a delay
  2. Print the character
First, you need a way to simulate a delay in typing, such as someone typing slowly, or pausing before typing the next word or pressing Enter. The C function to create a delay is usleep(useconds_t usec). Use usleep() with the number of microseconds you want your program to pause. So if you want to wait one second, you would use usleep(1000000).

Microseconds means too many zeroes for me to type, so I wrote a simple wrapper called msleep(int millisec) that does the same thing in milliseconds:
msleep (int millisec)
useconds_t usec;
int ret;

/* wrapper to usleep() but values in milliseconds instead */

usec = (useconds_t) millisec * 1000;
ret = usleep (usec);
return (ret);
Next, you need to push characters to the screen after each delay. Normally, you can use putchar(int char) to send a single character to standard output (such as the screen). But you won’t actually see the output until you send a newline. To get around this, you need to flush the output buffer manually. The C function fflush(FILE *stream) will flush an output stream for you. If you put a delay() before each fflush(), it will appear that someone is pausing slightly between typing each character.


Here’s a simple function I wrote to simulate typing. The echodelay() function takes parameters that describe the delay before printing characters, spaces, and newlines. The last parameter is the string to print. The function loops through the string and pauses before printing each character, then flushes the output buffer. The effect is each character seems to appear one at a time, as though someone were typing at a keyboard:
echodelay (int chdelay, int spdelay, int nldelay, char *string)
int pos = 0;

/* add a delay between printing each character in the string,
depending on the character */

switch (string[pos])
case '\0': /* new line */
msleep (nldelay);
case ' ': /* space */
msleep (spdelay);
default: /* character */
msleep (chdelay);

putchar (string[pos]);
fflush (stdout);
while (string[pos++] != '\0');
With that, it’s a simple process to write a program to parse the command line, set the different delays, and call the echodelay() function to generate the output with the appropriate delays.
/* echodelay.c */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void echodelay (int chdelay, int spdelay, int nldelay, char *string);
int msleep (int millisec);
int atoipos (char *string);

main (int argc, char **argv)
int opt;
int chdelay = 0, spdelay = 0, nldelay = 0;

/* parse command line */

while ((opt = getopt (argc, argv, "c:s:n:")) != -1)
switch (opt)
case 'c': /* -c nnn */
chdelay = atoipos (optarg);
case 's': /* -s nnn */
spdelay = atoipos (optarg);
case 'n': /* -n nnn */
nldelay = atoipos (optarg);
default: /* unrecognized option */
fprintf (stderr, "Usage: echodelay [-c millisec] [-s millisec] [-n millisec] [text..]\n");
exit (1);

/* pass all remaining options as text to echodelay() */

for (opt = optind; opt < argc; opt++)
echodelay (chdelay, spdelay, nldelay, argv[opt]);
putchar (' ');

putchar ('\n');

exit (0);

echodelay (int chdelay, int spdelay, int nldelay, char *string)


msleep (int millisec)


atoipos (char *string)
int val;

/* wrapper to atoi() but always a positive return value */

val = atoi (string);

if (val < 0)
val = 0;

return (val);
And compile it like this:
gcc -Wall -o echodelay echodelay.c
In a shell script, I had commands to print a “prompt,” then simulate typing a command before executing the command. For example, this example to list the contents in your /tmp directory:
echo -n 'prompt$ '
echodelay -c 500 -s 1000 -n 2000 'ls -lh /tmp'
ls -lh /tmp
This is a fairly straightforward C program to simulate typing. I wrote it quickly to do a single job, but it does the job to simulate typing while I narrated my how-to video. In this way, I didn’t need to think about what I was typing while I was trying to describe it. If you need to simulate typing for a similar task, I hope you find this program useful.

Code review: reading an ini file

This is a continuation of the Code Review article series, where I'm discussing different coding examples you can use to create FreeDOS programs.

When a program becomes large enough or complex enough, with different options the user can set to make the program act more conveniently (such as text colors), you'll need a way to store those user preferences between sessions. And of course, you'll need a way to read those preferences back later.

Programmer Ben Hoyt tackled this problem by writing the inih library, available on Github. Inih is a simple ini file parser written in C. Ini files are Initialization files, and usually look like this:

[protocol]             ; Protocol configuration
version=6 ; IPv6

name = Bob Smith ; Spaces around '=' are stripped
email = ; And comments (like this) ignored
active = true ; Test a boolean
pi = 3.14159 ; Test a floating point number

The standard ini syntax is that ini variable sections are marked by square brackets (such as [user]) and ini variable names follow the format variable=value.

To parse an ini file with inih, you first need to define a handler function (I'll explain that in a minute) and a ini structure of type configuration. Then, you pass the handler function and configuration structure to the ini_parse() function like this:

configuration config;
ini_parse("test.ini", handler, &config);