Function Pointer

Table of Contents
1.What are function pointers?
2.What advantages does this give me?
3.Example – Iterating through a list
-Example 1 – Code
-Example 2 – Code
-Example 3 – Code
4.Some useful tips for programmers
-Short hand notation
-Module abstraction and indepenence

What are function pointers?

Function pointers are means to add another level of indirection. Remember pointers to variables? Function pointers are no different.

Let’s say that there are two identical functions a and b (by identical we mean that the functions have the same return type and the same parameter type). We also declare a function pointer p. The function pointer is defined such that it shares the same return type and parameter types as a and b. By assigning the address of a to p, p = a;, calls to p will in effect yield calls to a. Likewise, p can be assigned b, where calls to p yield calls to b. Getting dizzy yet?

Here’s a very simple example which works with C and C++.

#include &ltstdio.h>

void a(void)
{
printf(“a was called.\n”);
}

void b(void)
{
printf(“b was called.\n”);
}

int main(void)
{
void (*p)(void); /* This is a function pointer declaration */

p = a;
(*p)(); /* Using function pointer p */
p = b;
(*p)(); /* Using function pointer p (again) */
return 0; /* Standard exit procedure in UNIX */
}

As you can see, the function pointer declaration looks somewhat complicated. The “standard remedy” for this is to create a new function pointer type by using the typedef operator.

Same example again using the typedef operator.

#include &ltstdio.h>

typedef void (*FuncType)(void); /* FuncType is a function pointer type */

void a(void)
{
printf(“a was called.\n”);
}

void b(void)
{
printf(“b was called.\n”);
}

int main(void)
{
FuncType p; /* This is a function pointer declaration */

p = a;
(*p)(); /* Using function pointer p */
p = b;
(*p)(); /* Using function pointer p (again) */
return 0; /* Standard exit procedure in UNIX */
}

What advantage does this give me?

As you probably learned in your first programming courses, pointers to variables allows you to modify variable contents from a non-local environment. This gives the flexibility of writing generic functions which do not alter “known” global variables, but references to “unknown” variables. Such functions can be reused. Function pointers gives you the same flexibility, but at a higher level. Instead of calling a “known” function, one can call any arbitrary “unknown” function. This is the main advantage of function pointers: greater flexibility and better code reuse.

Example – Iterating through a list

In this example I’ll show a very common (and naive) solution for iterating through a list, then a somewhat “better” solution and last I’ll show a general and resuable solution.

The list is a list of strings and we want to iterate it for printing to screen. As a twist, we also want to print out the a list of the string lengths rather than the strings.

Example 1 – Code:
This is a very naive implementation.

#include &ltstdio.h>

typedef struct ListRecord List;

struct ListRecord {
char* text;
List* next;
};

List* listInsert(List* list, const char* text)
{
ListRecord* rec;

rec = (ListRecord*)malloc(sizeof(ListRecord));
rec->text = strdup(text); /* Make a copy of string */
rec->next = list; /* Link in old list */
return list;
}

int main(void)
{
List* list;
ListRecord* i;

list = NULL;
list = listInsert(list, “World!”);
list = listInsert(list, “Hello”);

printf(“List begins\n”);
for(i = list; i != NULL; i = i->next)
printf(“Text: %s\n”, i->text);
printf(“List ends\n”);

printf(“List begins (lengths)\n”);
for(i = list; i != NULL; i = i->next)
printf(“Text Length: %d\n”, strlen(i->text));
printf(“List ends\n”);

return 0;
}

Example 2 – Code:
This is a better implementation. Functionality has been moved out into separate functions. printList and printListStrLen are new functions.

#include &ltstdio.h>

typedef struct ListRecord List;

struct ListRecord {
char* text;
List* next;
};

void printList(List* list)
{
ListRecord* i;

printf(“List begins\n”);
for(i = list; i != NULL; i = i->next)
printf(“Text: %s\n”, i->text);
printf(“List ends\n”);
}

void printListStrLen(List* list)
{
ListRecord* i;

printf(“List begins (reversed)\n”);
for(i = list; i != NULL; i = i->next)
printf(“Text Length: %s\n”, strlen(i->text));
printf(“List ends\n”);
}

List* listInsert(List* list, const char* text)
{
ListRecord* rec;

rec = (ListRecord*)malloc(sizeof(ListRecord));
rec->text = strdup(text); /* Make a copy of string */
rec->next = list; /* Link in old list */
return list;
}

int main(void)
{
List* list;

list = NULL;
list = listInsert(list, “World!”);
list = listInsert(list, “Hello”);

printList(list);
printListStrLen(list);

return 0;
}

Example 3 – Code:
This solution is the best of the three since it allows for high code reuse. It makes use of function pointers for performing the actual printing and it separates the “for-looping” into a function of its own. The three new key features in this example is ListRecordOperation, print, printStrLen and listForEach. Note that adding new features such as printing the text in reverse is now very easy. Just add a function that is compatible with the ListRecordOperation type and call listForEach with the function as argument. No more tedious moments of writing for-loops and such, now you can focus on the problem at hand instead.

#include &ltstdio.h>

typedef void (*ListRecordOperation)(const char*);

typedef struct ListRecord List;

struct ListRecord {
char* text;
List* next;
};

/* function compatible with ListRecordOperation */
void print(const char* text)
{
printf(“Text: %s\n”, text);
}

/* function compatible with ListRecordOperation */
void printStrLen(const char* text)
{
printf(“Text Length: %s\n”, strlen(text));
}

void listForEach(List* list, ListRecordOperation op)
{
ListRecord* i;

for(i = list; i != NULL; i = i->next)
(*op)(list->text); /* Calling whatever op points to with i->text
as argument */
}

List* listInsert(List* list, const char* text)
{
ListRecord* rec;

rec = (ListRecord*)malloc(sizeof(ListRecord));
rec->text = strdup(text); /* Make a copy of string */
rec->next = list; /* Link in old list */
return list;
}

int main(void)
{
List* list;

list = NULL;
list = listInsert(list, “World!”);
list = listInsert(list, “Hello”);

listForEach(list, print);
listForEach(list, printStrLen);

return 0;
}

Useful tips for programmers
Short hand notation
Function pointers may be used with a shorthand notation. Instead of dereferencing the function pointer with an asterisk:

p = a;
(*p)();

you can use it like this:

p = a;
p();

as if it was an “ordinary” function. Gives C an aesthetic appeal.

Function Pointers

0 comments Table of Contents
1.What are function pointers?
2.What advantages does this give me?
3.Example – Iterating through a list
-Example 1 – Code
-Example 2 – Code
-Example 3 – Code
4.Some useful tips for programmers
-Short hand notation
-Module abstraction and indepenence

What are function pointers?

Function pointers are means to add another level of indirection. Remember pointers to variables? Function pointers are no different.

Let’s say that there are two identical functions a and b (by identical we mean that the functions have the same return type and the same parameter type). We also declare a function pointer p. The function pointer is defined such that it shares the same return type and parameter types as a and b. By assigning the address of a to p, p = a;, calls to p will in effect yield calls to a. Likewise, p can be assigned b, where calls to p yield calls to b. Getting dizzy yet? 😉

Here’s a very simple example which works with C and C++.

#include &ltstdio.h>

void a(void)
{
printf(“a was called.\n”);
}

void b(void)
{
printf(“b was called.\n”);
}

int main(void)
{
void (*p)(void); /* This is a function pointer declaration */

p = a;
(*p)(); /* Using function pointer p */
p = b;
(*p)(); /* Using function pointer p (again) */
return 0; /* Standard exit procedure in UNIX */
}

As you can see, the function pointer declaration looks somewhat complicated. The “standard remedy” for this is to create a new function pointer type by using the typedef operator.

Same example again using the typedef operator.

#include &ltstdio.h>

typedef void (*FuncType)(void); /* FuncType is a function pointer type */

void a(void)
{
printf(“a was called.\n”);
}

void b(void)
{
printf(“b was called.\n”);
}

int main(void)
{
FuncType p; /* This is a function pointer declaration */

p = a;
(*p)(); /* Using function pointer p */
p = b;
(*p)(); /* Using function pointer p (again) */
return 0; /* Standard exit procedure in UNIX */
}

What advantage does this give me?

As you probably learned in your first programming courses, pointers to variables allows you to modify variable contents from a non-local environment. This gives the flexibility of writing generic functions which do not alter “known” global variables, but references to “unknown” variables. Such functions can be reused. Function pointers gives you the same flexibility, but at a higher level. Instead of calling a “known” function, one can call any arbitrary “unknown” function. This is the main advantage of function pointers: greater flexibility and better code reuse.

Example – Iterating through a list

In this example I’ll show a very common (and naive) solution for iterating through a list, then a somewhat “better” solution and last I’ll show a general and resuable solution.

The list is a list of strings and we want to iterate it for printing to screen. As a twist, we also want to print out the a list of the string lengths rather than the strings.

Example 1 – Code:
This is a very naive implementation.

#include &ltstdio.h>

typedef struct ListRecord List;

struct ListRecord {
char* text;
List* next;
};

List* listInsert(List* list, const char* text)
{
ListRecord* rec;

rec = (ListRecord*)malloc(sizeof(ListRecord));
rec->text = strdup(text); /* Make a copy of string */
rec->next = list; /* Link in old list */
return list;
}

int main(void)
{
List* list;
ListRecord* i;

list = NULL;
list = listInsert(list, “World!”);
list = listInsert(list, “Hello”);

printf(“List begins\n”);
for(i = list; i != NULL; i = i->next)
printf(“Text: %s\n”, i->text);
printf(“List ends\n”);

printf(“List begins (lengths)\n”);
for(i = list; i != NULL; i = i->next)
printf(“Text Length: %d\n”, strlen(i->text));
printf(“List ends\n”);

return 0;
}

Example 2 – Code:
This is a better implementation. Functionality has been moved out into separate functions. printList and printListStrLen are new functions.

#include &ltstdio.h>

typedef struct ListRecord List;

struct ListRecord {
char* text;
List* next;
};

void printList(List* list)
{
ListRecord* i;

printf(“List begins\n”);
for(i = list; i != NULL; i = i->next)
printf(“Text: %s\n”, i->text);
printf(“List ends\n”);
}

void printListStrLen(List* list)
{
ListRecord* i;

printf(“List begins (reversed)\n”);
for(i = list; i != NULL; i = i->next)
printf(“Text Length: %s\n”, strlen(i->text));
printf(“List ends\n”);
}

List* listInsert(List* list, const char* text)
{
ListRecord* rec;

rec = (ListRecord*)malloc(sizeof(ListRecord));
rec->text = strdup(text); /* Make a copy of string */
rec->next = list; /* Link in old list */
return list;
}

int main(void)
{
List* list;

list = NULL;
list = listInsert(list, “World!”);
list = listInsert(list, “Hello”);

printList(list);
printListStrLen(list);

return 0;
}

Example 3 – Code:
This solution is the best of the three since it allows for high code reuse. It makes use of function pointers for performing the actual printing and it separates the “for-looping” into a function of its own. The three new key features in this example is ListRecordOperation, print, printStrLen and listForEach. Note that adding new features such as printing the text in reverse is now very easy. Just add a function that is compatible with the ListRecordOperation type and call listForEach with the function as argument. No more tedious moments of writing for-loops and such, now you can focus on the problem at hand instead.

#include &ltstdio.h>

typedef void (*ListRecordOperation)(const char*);

typedef struct ListRecord List;

struct ListRecord {
char* text;
List* next;
};

/* function compatible with ListRecordOperation */
void print(const char* text)
{
printf(“Text: %s\n”, text);
}

/* function compatible with ListRecordOperation */
void printStrLen(const char* text)
{
printf(“Text Length: %s\n”, strlen(text));
}

void listForEach(List* list, ListRecordOperation op)
{
ListRecord* i;

for(i = list; i != NULL; i = i->next)
(*op)(list->text); /* Calling whatever op points to with i->text
as argument */
}

List* listInsert(List* list, const char* text)
{
ListRecord* rec;

rec = (ListRecord*)malloc(sizeof(ListRecord));
rec->text = strdup(text); /* Make a copy of string */
rec->next = list; /* Link in old list */
return list;
}

int main(void)
{
List* list;

list = NULL;
list = listInsert(list, “World!”);
list = listInsert(list, “Hello”);

listForEach(list, print);
listForEach(list, printStrLen);

return 0;
}

Useful tips for programmers
Short hand notation
Function pointers may be used with a shorthand notation. Instead of dereferencing the function pointer with an asterisk:

p = a;
(*p)();

you can use it like this:

p = a;
p();

as if it was an “ordinary” function. Gives C an aesthetic appeal. 😉

Advertisements

Daemon Process

What is a Daemon?

Every multitasking operating system supports a special type of process, a process that is usually kept a lower priority, performing a specific task over and over. Those processes are kept out of sight, performing their function in the background, without any direct intervention by the user. In the Unix operating system terminology, among other operating systems as well, background processes are called daemons.This tutorial will introduce you to daemon programming. You will write a simple daemon in Linux, C/C++ and a Bash Script, just to get a grip on what daemons are, and what they are capable of, only to move on to coding your first daemon in C. Daemons can be easily created under GNU/Linux, they mostly follow a specific convention. To begin coding your first daemon, you will need to find a use for it. Daemons can handle many tasks that could otherwise bother users and affect their productivity, which brings us to the next section. 

Putting Daemons to Use

Daemons usually handle tasks that require no user intervention, and consume low CPU power. CPU-intensive background tasks are not typically termed daemons, as bringing down computers to a sluggish performance can be hardly satisfying for any user, but decreasing the priority of these tasks can qualify them for that without sacrificing their performance, since CPUs are normally idle more than 90% of their time.A daemon usually handles a single task, and accepts commands through means of IPC (Inter-Process Communication), which you will be briefly exposed to in this tutorial. Tasks handled by daemons include serving web pages, transferring emails, caching name service requests, logging, and for the purposes of this site, serving game clients. 

Daemon game servers handle incoming game requests through a network, process these requests, update its persistent storage (database or flat files), and finally sends back responses to the clients. A major issue with game servers, among other servers, is that clients cannot be trusted, since a modified or reverse engineered version of the client can wreck havoc if the server is not ready to handle it. This enforces that clients should not keep a copy of the current game data, they should only send actions, not states, to the server, which would in turn validate those actions, and update the game status.

Structure of a Daemon

Daemons typically have the same structure, regardless of their functionality. A daemon starts off by initializing its variables. It then sets its IPC interface up, which could simply be signal handlers. The daemon then executes its body, which is almost always an infinite loop.Most daemons start off by forking. Forking is a method that allows a process to clone itself, creating an identical child. A daemon, as a parent process, usually forks off and terminates (or dies), while its child is left executing the main loop. The child is usually called an orphan process. In Unixes, orphan processes are automatically adopted by the “init” process, and this action is known as re-parenting. 

For a more practical approach, the following sections dissect the two previously mentioned daemons. Links to their sources are found at the end of the tutorial.

Writing a Daemon in Linux

In this tutorial, you will be introduced to creating daemons in Linux-based operating systems. The tutorial will cover the basic concepts underlying daemons, will guide you through the sample code of a daemon process, and then introduce you to what Inter-Process Communication is and how you could use it.

We need first to define what a daemon is. But then to do that, we would have to go a little farther, as far as source code is from a daemon. When you write a program, let us say in C, and you compile it, the compiler produces what you should probably already know as executable or binary. This created file, although it is executable, is not in fact entirely so. You do not just ask the operating system to start executing the first instruction in that file.

However, what actually happens is that the operating system loads this file into memory, and there it becomes known as a Process. A Process is different from that executable program you had on your disk drive, in that it is associated with information that the operating system uses to maintain running of the program. Without going into much detail, let us take a simple example to illustrate the difference between a program file on your disk and that same program when loaded into memory. Modern Operating Systems all support Multi-tasking; the ability to switch between two or more running processes. In a system with single a processor, the operating system actually switches between running processes, giving each a fraction of a second and thus giving you the illusion of several programs running simultaneously.

So, how does this example make a compiled binary different from processes!? Well, before the operating system switches from one running program to another, it has to save the first program’s state, so that it could return to the next correct instruction after it switches from the second. This is called the Program Counter, it is a counter that specifies which instruction the operating system has to execute next. Before switching to another running program, this Counter must be stored.

So, a process is not only the code contained in your binary program. It contains additional information that allows the operating system to maintain the running of that program. But how does this relate to daemons?

A daemon is a process, or more accurately, a background process. A daemon is not associated with any input or output streams, that is to say, you cannot give it input or read output from it interactively. And a daemon, a daemon does not have a parent process.

A parent process you may ask? Yes. In UNIX-like operating systems processes are structured in a tree. No process can actually emerge or come into existence from nowhere, it must be forked from a parent process. We have the “init” process as the root process, and any new process must fork from it or from one of its children.

So, if every process has a parent in that tree, where would our newly created daemon be placed!? Let us try to picture what would happen, by taking syslogd as an example (syslogd is the System Log Daemon. Though it should be apparent from its name, it is irrelevant to us what it actually does).

syslogd is stored on your disk drive as a program. When you start that program from the shell, the operating system loads it as a new process. Till now, it is no different from your standard computer program, it still can read input and produce output, and the shell is its parent process.

Then, syslogd would initiate a few steps to become a daemon: it forks from itself a new child process, and then kills the parent process. Since the parent was killed, and since our mighty Unix and Unix-like systems are too kind and could not leave an orphant process behind, “init” automatically adopts this newly forked process as its child.

Let us now jump into some code. The following code was adapted from syslogd.c:

pid = fork();
if (pid > 0)
 exit(0);
else if (pid == 0) {
       daemon_init(argv);
}

In the first line, our daemon process which we just ran forks itself, thus creating a new process. fork() is a system call that copies a process into another one, and then the former would be called the parent and the later would be called the child. fork()’s return value is different in the child process from the parent one. When the process is forked, the child process, which was just created, will start executing in the line just after the fork() call. Remember above we talked about the Program Counter being part of the Process, so when it is copied, that counter’s value is copied to the child as well.

Hence, we now have both processes, the parent and the child, positioned to execute the instruction after the fork() call. But what would distinguish them!?

In the parent process, fork() returns an Identifier that uniquely identifies the child process among all other processes running in the system, this identifier is known as the Process ID, or as usually abbreviated, PID. Meanwhile, in the child process, fork() returns 0.

Thus, what our daemon does is to check for the value returned by fork(). If this value was greater than 0, then it must have been executing within the parent process. If this value was 0, then we must have been executing within the child process.

Since we want this to be a background process, what we will do next is to exit the parent process. This way, our child process becomes orphan and gets adopted by init. In the shell, since the input and output streams were attached to a process that now exited, then we return to the prompt while the child process is still running in memory.

Or is it!? To go with further demonstration, let us consider the following program, which is basically the same as the one before but in a more complete form:

#include
#include
#include
#include
#include
#include 

void daemon_entry_point()
{
 // Do Nothing
}

int main(int argc, char * argv)
{
 // fork this process and start the daemon
 pid_t pid = fork();

 if (0 > pid)
 {
  // If the child was not succesfully, created,
  // -1 will be returned to the parent.

  printf("Failed to fork. Now exiting...\n");
  exit(EXIT_FAILURE);
 }
 else if (0 < pid)
 {
  // If the return value is larger than 0, then
  // this part of code will only be executed by
  // the parent. We exit the parent.

  printf("Process forked. Parent now exiting...\n");
  exit(EXIT_SUCCESS);
 }

 // Coming here, it must be the child, whose fork() returned 0.
 // What we now do is close the Standard File Descriptors since
 // we won't be reading or writing to them.

 printf("Daemon Starting...\n");

 close(STDIN_FILENO);
 close(STDOUT_FILENO);
 close(STDERR_FILENO);

 // Call daemon_entry_point which would be responsible for
 // further initialization and startup routines for your daemon.

 daemon_entry_point();

 return 0;
}

Now, compile this program

gcc -o my1stdaemon my1stdaemon.c

Run it

./my1stdaemon

It should now have returned you back to the shell. At this point, the parent process have exited after forking the child, to see the child process running, type:

ps -e | grep my1stdaemon

ps is a program that reports a snapshot of information about the currently running processes. A sample output would be:

6894 pts/1    00:00:20 my1stdaemon

The first column shows the Process ID of the daemon. To shut the daemon down, we use that Process ID as follows:

kill -9 6894

This sends a KILL (9) signal to the daemon that forces it to exit.

Now that we have understood, written and tried our first daemon, we need to see how we can communicate with it. If a daemon cannot read or write from stdin, how could we tell it what to do and know what it is doing!?

This brings us to Inter-Process Communication!

Inter-Process Communication (IPC) refers to the set of mechanisms which we could use to make two processes to communicate with each other. There are several Inter-Process Communication methods, each has its own set of advantages and disadvantages. In this tutorial we would guide you throw using a FIFO, also known as a Named Pipe, to send data from one daemon to the other.

FIFOs, or Named Pipes, were created as an extension to Pipes, which later became known as Anonymous Pipes. Anonymous Pipes are an IPC mechanism that allow for uni-directional communication between two processes. Anonymous Pipes are a wildly popular mechanism for communication between processes, and can been seen in pipelines, where a set of processes are chained by their standard streams: the first one writes to its standard output, the second process reads from the first’s standard output and writes to it standard output, and so on. An example of a pipeline is our usage of the command “ps” above to pipe its output to the program “grep” which then outputted the result to the standard output stream.

So, what is a FIFO? A FIFO (First In First Out) is a Pipe that is associated with a file in your file system. Anonymous Pipes are different in that they have no name and do not persist after the process exists. With Named Pipes on the other hand, you have to specifically “unlink” or delete the file after you have no more need for it.

Now, what we want to do is to make my1stdaemon send the text “Hello World!” to a second daemon, my2nddaemon. This second daemon would then write the same text it received into a file /tmp/target.

To do this, we will first modify the function daemon_entry_point in my1stdaemon as follows:

void daemon_entry_point()
{
 // Create a FIFO (Named Pipe) in /tmp/myfifo
 mkfifo("/tmp/myfifo", 0644);

 // A FIFO is accessed exactly like a normal
 // file. Here, we would open it with "open"
 // and write to it with "write"

 int fifofd = open("/tmp/myfifo", O_WRONLY);

 if ( -1 == fifofd )
 {
  exit(EXIT_FAILURE);

  // Since we already closed the standard
  // streams, we cannot print an error
  // message as usual. Before exiting, we
  // should have actually written to a log
  // file, but this has been left out for
  // simplicity.
 }

 // Put some text in the FIFO, and sleep for 6
 // seconds. Repeat this for 10 times.

 char * text = "Hello World!\n";

 int i;
 for (i = 0; i < 10; i++)
 {
  write(fifofd, text, strlen(text));
  sleep(6);
 }

 // Close the FIFO
 close(fifofd);
}

Now, compile my1stdaemon as before and run it. Open another shell window and type

cat /tmp/myfifo

There you would find that cat, which is another process, is in fact reading what we have written by my1stdaemon. One more thing, while you are there, type ls -l /tmp/myfifo, you would get:

prw-r--r--  1 leaf users 0 2006-07-25 22:56 /tmp/myfifo

The first character, ‘p’, indicates that the type of /tmp/myfifo is a Pipe, contrary to standard files which would be ‘-‘, and directories, which would be ‘d’.

Let us make our second daemon, that reads from the FIFO created by the first one. We will start our second daemon from the same code base, but will implement daemon_entry_point differently. Here is the implementation of this function for my2nddaemon

void daemon_entry_point()
{
 // Open the FIFO

 int fifofd = open("/tmp/myfifo", O_RDONLY);

 if ( -1 == fifofd )
 {
  exit(EXIT_FAILURE);
 }

 // Open a target file in which we would write
 // what we have read from the FIFO

 int targetfd = open("/tmp/target", O_WRONLY | O_CREAT, 0644);

 if ( -1 == targetfd )
 {
  exit(EXIT_FAILURE);
 }

 // Pipe the data from the FIFO to the target file.

 char text [50];
 memset(text, '', sizeof(text));

 int i;
 for (i = 0; i < 10; i++)
 {
  read(fifofd, text, sizeof(text));
  write(targetfd, text, strlen(text));
 }

 // Close the file handles
 close(fifofd);
 close(targetfd);
}

Compile this using

gcc -o my2nddaemon my2nddaemon.c

Run both daemons

./my1stdaemon
./my2nddaemon

Now, to see data while it is written to /tmp/target, type:

tail -f /tmp/target

That’s it.

You should now have an understanding of the basics you need to create a daemon in Linux, and how you can make this daemon communicate with other processes.

Fork off and Die: C/C++ Daemons

Prerequisites

You’ll need to have GCC (The GNU Compiler Collection) installed. Enter “gcc –version” at the shell, and it should echo back the current GCC version. You will also need to have glibc, the GNU standard C library. You could try compiling a simple “Hello World” program just to make sure everything is setup properly, which is usually the case, but you should make sure anyway. Also, some hands-on experience with the C programming language will definitely prove useful.

The Code

The following code implements the very same daemon explained in the previous section, but using C. To compile your daemon, you first need to save the file under “uptlogd.c”. At the shell, enter “gcc -o uptlogd uptlogd.c” to compile and link your daemon. You can now use “./uptlogd” to start it.
// uptlogd - A simple C daemon

#include 

#include 

#include 

#include 

#include 

#include 

#define FILENAME_SIZE 15

#define LINE_SIZE_MAX 100

int logfd = -1;

int logging = 1;

char *logfile = NULL;

char *line = NULL;

The file basically has a little more includes than your average “Hello World” program! The header files are “stdio.h”, which defines “printf”, among other standard I/O functions, “unistd.h”, which defines lots of constants and functions, including “getpid”, “fork”, and others, “fcntl.h”, which defines the arguments used by the “open” function, “sys/types.h”, which defines several data types, among which is “pid_t”, “errno.h”, which is responsible for the basic error reporting facilities, and “signal.h” for handling signals.

The global variables are “logfd”, the file descriptor for the log file, “logging”, the logging flag, “logfile”, the name of the log file, and “line”, which temporarily holds the log message before it is written to the log file.

void trigger_logging(int signum)

{

	logging = (logging == 1) ? 0 : 1;

}

void clean_up(int signum)

{

	// Free up the resources

	if (logfd != -1)

		close(logfd);

	if (logfile != NULL)

		free(logfile);

	if (line != NULL)

		free(line);

	exit(0);

}

Those two functions are defined as “callbacks”; they are called automatically when their associated signal is intercepted. The “trigger_logging” function enables/disables logging, while the “clean_up” function closes the file and deallocates the strings before exiting.

int main(int argc, char *argv[])

{

	// Fork off

	pid_t pid = fork();

	if (pid == -1)

	{

		// Out of memory: not likely to happen!

		printf ("Error: not enough memory to initiate!\n");

		return 1;

	}

	else if (pid != 0)

	{

		// ... and die!

		printf("uptlogd PID is %d\n", (int) pid);

		printf("Logging started ...\n");

		return 0;

	}

The main function starts off by forking through calling the “fork” function. “fork” returns -1 on failure, which only happens if not enough memory for cloning the current process is available, which is quite uncommon. “fork” returns the child PID in the parent’s thread, and zero in the child’s thread. Here, the parent outputs the child’s PID and exits, while the child continues to execute the remaining code.

	// Child continues executing here

	// Set the signal handlers up

	signal(SIGUSR1, trigger_logging);

	signal(SIGTERM, clean_up);

The “signal” function sets up a signal handler. The code handles SIGUSR1 by calling “trigger_logging”, and SIGTERM by calling “clean_up”, refer to those functions to get the whole picture.

	// Set the log file up

	pid = getpid();

	logfile = malloc(sizeof (char) * FILENAME_SIZE);

	sprintf(logfile, "LOGFILE_%06d", (int) pid);

	// Open the log file

	logfd = open(logfile, O_CREAT | O_WRONLY, 00644);

	if (logfd == -1)

	{

		printf("%s\n", strerror(errno));

		return 1;

	}

The log filename is allocated, and a unique name is used by concatenating the PID to the string “LOGFILE_”. A handle to the file is acquired using “open”. A defensive programming practice is to make sure the acquired file handles are valid, several problems can cause “open” to return -1.

	// Prepare the loop variables

	int count;

	int timesec = 0;

	line = malloc(sizeof (char) * LINE_SIZE_MAX);

	// Loop forever

	while (1) {

		// Write the log to the file, if logging is enabled

		if (logging == 1)

		{

			sprintf(line, "Uptime: %d seconds\n", timesec);

			count = write(logfd, line, strlen (line));

			if (count == -1)

			{

				printf("%s\n", strerror (errno));

				return 1;

			}

		}

		timesec += 5;

		// Sleep for 5 seconds

		usleep(5000000);

	}

	return 0;

}

The daemon now executes its main loop. The loop starts by writing the log message, formatted in the “line” variable, to the log file. Another good programming practice is to check the length of the written message, which is the return value of “write”, compare with it the expected size, and act accordingly, but for simplicity purposes, the code only checks if the function failed. The daemon then updates its uptime, and sleeps for five seconds, only to repeat the loop all over again.

A Simple BASH Script Daemon

Prerequisites

You will need to have BASH, which is the current default shell for most, if not all, Unixes. You also could use some basic BASH programming knowledge.

The Code

The following BASH code simply logs its uptime every five seconds to a file. As a quick introduction to signal trapping, the logging can be disabled and enabled while the daemon is running. To run the following script, you first need to save it under “uptlogd.sh”. Now, from the shell, type “chmod 755 uptlogd.sh” to make the file executable, and “./uptlogd.sh &” to run the file in the background.
#!/bin/bash

# uptlogd - A simple BASH script daemon

# Daemon initialization

echo "uptlogd PID is $$"

echo "Logging started ..."

logfile="LOGFILE_$$"

# Set the variables up

logging=true

timesec=0

The daemon starts by printing its PID ($$). It then uses a unique name for its log file using its PID. Variable initializations follow, where logging is on, and the uptime is zero initially.

# Set the signal handler up

trap 'if [$logging==true]; then logging=false; else logging=true; fi' SIGUSR1

The trap command allows the daemon to intercept a signal and handle it. The daemon handles “SIGUSR1” by triggering the logging, enabling it if it is disabled, and vice versa.

# Loop forever

while true

do

	# Log the currently logged-in users if logging is enabled

	if [ $logging == true ]

	then

		echo "Uptime: $timesec" >> $logfile

	fi

	timesec=`expr $timesec + 5`

	# Sleep for 5 seconds

	sleep 5

done

The daemon moves on to the main loop. It echoes the uptime to the log file if logging is enabled, updates its uptime, sleeps five seconds, and repeats. To interact with the daemon, you can use the “kill” command from the shell, which sends a signal to a running process. Using the PID reported by the daemon, use “kill ” to terminate the daemon by sending the default signal SIGTERM. You can also use “kill -SIGUSR1 ” to enable/disable logging.

The code is very simple, but who uses BASH to code daemons anyway..

15 interesting facts about LInux and Kernel

On 14th March 1994, Linux kernel version 1.0.0 was humbly released for the world to tinker with.

1. A 21 year-old Finnish college student created the Linux kernel as a hobby. (Do you know him?)

2. An asteroid was named after the creator of the Linux kernel.

3. Thousands of developers/programmers scattered all around the world are continuously contributing to the development of the Linux kernel.

4. The Linux kernel’s official mascot is a penguin named Tux.

5. According to a study funded by the European Union, the estimated cost to redevelop the most recent kernel versions would be at $1.14 billion USD.

6. As of today, only 2% of the Linux kernel has been written by Linus Torvalds.

7. The Linux kernel is written in the version of the C programming language.

8. Linux is now one of the most widely ported operating system kernels, running on a diverse range of systems from handheld computers to mainframe servers.

9. Linux kernel 1.0.0 was released with 176,250 lines of code. The latest Linux kernel has over 10 million lines of code.

10. Microsoft Windows and the Linux kernel can run simultaneously in parallel on the same machine using a software called Cooperative Linux (coLinux).

11. At first, Torvalds wanted to call the kernel he developed Freax (a combination of “free”, “freak”, and the letter X to indicate that it is a Unix-like system), but his friend Ari Lemmke, who administered the FTP server where the kernel was first hosted for downloading, named Torvalds’ directory linux.

12. A guy name William Della Croce, Jr. trademarked the name Linux and eventually demanded royalties for its use. He later agreed to assign the trademark to Torvalds.

13. The Linux kernel can be found on more than 87% of systems on the world’s Top 500 supercomputers.

14. A “vanilla kernel” is not an ice cream flavor but an unmodified version of the Linux kernel.

15. The Linux Kernel is not in any way related to the army rank called ‘Colonel’. (hehe)

Cheers!

Install Linux on USB stick (Pen drive)

USB Pendrive Linux install from Linux

The Pendrivelinux team has put together a USB Pen Drive Linux package based purely on Debian Linux. The USB Linux package is currently available in .img format. Installation is simple and just requires copying the .img to a USB device and then creating a live-rw partition if you wish to store your changes. We think you will find this personalized USB Linux version easy to install, navigate and use.

Credits extend to the Debian-Live team for creating Live-Helper script used in this project. (Aicrom) Márcio Santos for the custom Penguin artwork, Theme-Graphics thanks to Carlos

This Pendrivelinux version is obsolete and no longer supported.

Basic Essentials:

  • 1GB or larger USB flash drive (512MB will work but isn’t recommended)
  • Pendrivelinux.img
  • Linux environment (Debian used in this example)

Obtaining and installing Pendrivelinux to USB:

  1. Insert a 1GB or larger USB flash pen drive
  2. Start your PC (booting from a Linux OS)
  3. Download the pendrivelinux.img
  4. Open a terminal and type sudo su
  5. From the terminal, change to the directory where you saved pendrivelinux.img
  6. Type fdisk -l and note which device is your USB device. Example:/dev/sdX (X represents your USB drive letter. Through the rest of this tutorial, replace X with your actual drive letter)
  7. Type dd if=pendrivelinux.img of=/dev/sdX

Optional – Create a second partition for saving changes:

  1. Type fdisk /dev/sdX
    1. Type n (makes a new partition)
    2. Type p (makes the new partition a primary partition)
    3. Type 2 (makes this the 2nd primary partition)
    4. Hit enter to accept the default first cylinder
    5. Hit enter again to accept the default last cylinder
    6. Type w (writes the new partition information to the USB drive)
  2. Type umount /dev/sdX1 and then remove and reinsert your USB drive
  3. Type mkfs.ext2 -b 4096 -L live-rw /dev/sdX2
  4. Reboot your computer and set boot priority to boot from the USB stick

You should now be booting into USB Pen Drive Linux from your USB drive!

Notes: You must boot by typing live persistent at the boot prompt if you wish to use the second partition to save or restore changes. Otherwise the system will boot in LIVE mode.

No root password has been set by default. To set a root password open a terminal and type sudo passwd root and then set the password you would like to use for root access.

The default username is user. Default user password is live

Key Board Shortcut (Linux)

< Virtual terminals >

Ctrl + Alt + F1
Switch to the first virtual terminal. In Linux, you can have several virtual terminals at the same time. The default is 6.

Ctrl + Alt + Fn
Switch to the nth virtual terminal. Because the number of virtual terminals is 6 by default, n = 1…6.

tty
Typing the tty command tells you what virtual terminal you’re currently working in.

Ctrl + Alt + F7
Switch to the GUI. If you have the X Window System running, it runs in the seventh virtual terminal by default in most Linux distros. If X isn’t running, this terminal is empty.
Note: in some distros, X runs in a different virtual terminal by default. For example, in Puppy Linux, it’s 3.

< X Window System >

Ctrl + Alt + +
Switch to the next resolution in the X Window System. This works if you’ve configured more than one resolution for your X server. Note that you must use the + in your numpad.

Ctrl + Alt + -
Switch to the previous X resolution. Use the – in your numpad.

MiddleMouseButton
Paste the highlighted text. You can highlight the text with your left mouse button (or with some other highlighting method, depending on the application you’re using), and then press the middle mouse button to paste. This is the traditional way of copying and pasting in the X Window System, but it may not work in some X applications.

If you have a two-button mouse, pressing both of the buttons at the same time has the same effect as pressing the middle one. If it doesn’t, you must enable 3-mouse-button emulation.

This works also in text terminals if you enable the gpm service.

Ctrl + Alt + Backspace
Kill the X server. Use this if X crashes and you can’t exit it normally. If you’ve configured your X Window System to start automatically at bootup, this restarts the server and throws you back to the graphical login screen.

< Command line – input >

Home or Ctrl + a
Move the cursor to the beginning of the current line.

End or Ctrl + e
Move the cursor to the end of the current line.

Alt + b
Move the cursor to the beginning of the current or previous word. Note that while this works in virtual terminals, it may not work in all graphical terminal emulators, because many graphical applications already use this as a menu shortcut by default.

Alt + f
Move the cursor to the end of the next word. Again, like with all shortcuts that use Alt as the modifier, this may not work in all graphical terminal emulators.

Tab
Autocomplete commands and file names. Type the first letter(s) of a command, directory or file name, press Tab and the rest is completed automatically! If there are more commands starting with the same letters, the shell completes as much as it can and beeps. If you then press Tab again, it shows you all the alternatives.

This shortcut is really helpful and saves a lot of typing! It even works at the lilo prompt and in some X applications.

Ctrl + u
Erase the current line.

Ctrl + k
Delete the line from the position of the cursor to the end of the line.

Ctrl + w
Delete the word before the cursor.

< Command line – output >

Shift + PageUp
Scroll terminal output up.

Shift + PageDown
Scroll terminal output down.

clear
The clear command clears all previously executed commands and their output from the current terminal.

Ctrl + l
Does exactly the same as typing the clear command.

reset
If you mess up your terminal, use the reset command. For example, if you try to cat a binary file, the terminal starts showing weird characters. Note that you may not be able to see the command when you’re typing it.

< Command line – history >

history
When you type the history command, you’ll see a list of the commands you executed previously.

ArrowUp or Ctrl + p
Scroll up in the history and edit the previously executed commands. To execute them, press Enter like you normally do.

ArrowDown or Ctrl + n
Scroll down in the history and edit the next commands.

Ctrl + r
Find the last command that contained the letters you’re typing. For example, if you want to find out the last action you did to a file called “file42.txt“, you’ll press Ctrl + r and start typing the file name. Or, if you want to find out the last parameters you gave to the “cp” command, you’ll press Ctrl + r and type in “cp“.

< Command line – misc >

Ctrl + c
Kill the current process.

Ctrl + z
Send the current process to background. This is useful if you have a program running, and you need the terminal for awhile but don’t want to exit the program completely. Then just send it to background with Ctrl+z, do whatever you want, and type the command fg to get the process back.

Ctrl + d
Log out from the current terminal. If you use this in a terminal emulator under X, this usually shuts down the terminal emulator after logging you out.

Ctrl + Alt + Del
Reboot the system. You can change this behavior by editing /etc/inittab if you want the system to shut down instead of rebooting.

Kernel compilation (2.6 version)

Compiling custom kernel has its own advantages and disadvantages. However, new Linux user / admin find it difficult to compile Linux kernel. Compiling kernel needs to understand few things and then just type couple of commands. This step by step howto covers compiling Linux kernel version 2.6.xx under RPM (Fedora ) GNU Linux. However, instructions remains the same for any other distribution except for yum/apt-get command.

Step # 1 Get Latest Linux kernel code

Visit http://kernel.org/ and download the latest source code. File name would be linux-x.y.z.tar.bz2, where x.y.z is actual version number. For example file inux-2.6.35.tar.bz2 represents 2.6.35 kernel version. Use wget command to download kernel source code:
$ cd /tmp
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-x.y.z.tar.bz2

Note: Replace x.y.z with actual version number.

Step # 2 Extract tar (.tar.bz or .tar.bz2) file

Type the following command:
# tar -xjvf linux-2.6.35.tar.bz2 -C /usr/src
# cd /usr/src

Step # 3 Configure kernel

Before you configure kernel make sure you have development tools (gcc compilers and related tools) are installed on your system. If gcc compiler and tools are not installed then use apt-get command under Debian Linux to install development tools.
# apt-get install gcc  (ubuntu users)

# yum groupinstall 'Development Tools'  (fedora users)

Now you can start kernel configuration by typing any one of the command:

  • $ make menuconfig – Text based color menus, radiolists & dialogs. This option also useful on remote server if you wanna compile kernel remotely.
  • $ make xconfig – X windows (Qt) based configuration tool, works best under KDE desktop
  • $ make gconfig – X windows (Gtk) based configuration tool, works best under Gnome Dekstop.

For example make menuconfig command launches following screen:
$ make menuconfig

You have to select different options as per your need. Each configuration option has HELP button associated with it so select help button to get help.

Step # 4 Compile kernel

Start compiling to create a compressed kernel image, enter:
$ make
Start compiling to kernel modules:
$ make modules

Install kernel modules (become a root user, use su command):
$ su -
# make modules_install

Step # 5 Install kernel

So far we have compiled kernel and installed kernel modules. It is time to install kernel itself.
# make install

It will install three files into /boot directory as well as modification to your kernel grub configuration file:

  • System.map-2.6.35
  • config-2.6.35
  • vmlinuz-2.6.35

Step # 6: Create an initrd image

Type the following command at a shell prompt:
# cd /boot
# mkinitrd -o initrd.img-2.6.35 2.6.35

initrd images contains device driver which needed to load rest of the operating system later on. Not all computer requires initrd, but it is safe to create one.

Step # 7 Modify Grub configuration file – /boot/grub/menu.lst

(only for ubuntu users)

Open file using vi:
# vi /boot/grub/menu.lst

title           ubuntu (2.6.35.fc14.i686)
root            (hd0,0)
kernel          /boot/vmlinuz root=/dev/hdb1 ro
initrd          /boot/initrd.img-2.6.35
savedefault
boot

Remember to setup correct root=/dev/hdXX device. Save and close the file. If you think editing and writing all lines by hand is too much for you, try out update-grub command to update the lines for each kernel in /boot/grub/menu.lst file. Just type the command:
# update-grub
Neat. Huh?

Step # 8 : Reboot computer and boot into your new kernel

Just issue reboot command:
# reboot