Archive

Archive for the ‘Programming’ Category

Listing out the sysconf() values

Ever wondered how you could list out the defined sysconf() arguments constants and the sysconf() values for them. Well here is a simple bash script that worked for me:

#!/bin/bash

rm -f test.c

echo “#include <unistd.h>” >> test.c
echo “#include <stdio.h>” >> test.c
echo “main()” >> test.c
echo “{” >> test.c

for x in `echo “#include <unistd.h>” | cpp | grep _SC_ | cut -d ‘,’ -f 1 | awk ‘{print $1}’`
do
echo “printf(\”$x : %d\\n\”, sysconf($x));” >> test.c
done

echo “}” >> test.c

gcc test.c -o test

./test

rm -f test{,.c}

Categories: Programming

Macro arguments – be careful with them

8 January, 2007 Leave a comment

Debugging applications that has lots of macro()s are considered to be very tough. And it seems that most people prefer to expand macros as blocks with new temporary variables. Let us try to find out why one would not prefer to use the macro arguments directly in their block code. Consider for example a macro that returns the square of a number. Normally, any careful programmer would write the macro as given below:

#define square(a) ((a) * (a))

And yes, what the macro will do is precisely what we would expect of it. The above macro is just perfect as long as what we provide as argument to it is a plain value – like a variable or a constant. For example:

int i = 10;

printf("square : %d\n", square(i));

would print 100 as we had desired. The preprocessed text is just the expression ((i) * (i)). This will continue to go on fine until you start to do some fancy tricks like the following:

int i = 10;

printf("square : %d\n", square(++i));

Obviously, what we had expected was the square of 11 but the one we got was that of 12(for gcc, can change for others). So, how did that happen? Yes.. after preprocessing, your code became ((++i) * (++i)) and according to gcc, the values of i used in the expression is that after doing all the pre-increments in the expression. Since there are 2 pre-increments, the compiler takes the expression as ((12) * (12)).

Apart from the wrong answer we got, another side effect that we have to acknowledge is that the variable i has been incremented twice after calling square(), instead of just once. So, what is the solution for such a situation? Simple, use only dummy variables for computations:

#define square(a) ({ typeof(a) var=(a); var*var; })

so thats it ! you dont need to worry at all about the new variable that you have created above – compilers are intelligent enough to nullify its overhead. Well, so now our problem is solved :-) we can create new ones ;-)

Categories: Programming

The essence of do{ } while(0)

6 January, 2007 Leave a comment

This is something that I’ve been longing to document in my blog. Many times I have wondered why almost all the #define macros in linux kernel is made up of do-while blocks rather than simple {} blocks. The reason is illustrated below:

Consider for example a swap() macro defined in the two different ways as shown below:

#define swap(a,b) { \

typeof(a) tmp; \

tmp=a; a=b; b=tmp; \

}

and

#define swap(a,b) do { \

typeof(a) tmp; \

tmp=a;a=b;b=tmp; \

} while(0)

At a glance both seem to do the same job of creating a new block of code where the variable tmp is created and the values a and b are swapped through it. And they both will work similarly under all circumstances except the following:

if(a<b)

swap(a,b);

else

printf("a is already greater than b\n");

The above code when using the first form of swap() macro will expand as following:

if(a<b)

{

typeof(a) tmp;

tmp=a;a=b;b=tmp;

}

;

else

printf("a is already greater than b\n");

The issue here is that the semicolon (;) that we have put after swap() infact terminates the if block and remains as an empty statement. This causes the else keyword not to be attached to the if block anymore and will cause a compilation error saying that the else keyword is misplaced. huh !

Anyway, good that we got a workaround for this problem, otherwise writing system software would have become a hell :-D . By the way, if you are using gcc, you can use ({ }) blocks as well which would be very much helpful if your macro needs to return some value ;-) – the return value is the last evaluated expression.

Categories: Programming

How to capture stdin, stdout and stderr of child program!

22 December, 2006 10 comments

This is an article that I had posted in my livejournal on 21st-Apr-2006 05:28 pm. I’m trying to migrate the most valuable stuff to wordpress.

Hi everyone,

I have been asking this particular question to everyone for some time, the solution of which I found just now. What I wanted was to capture the standard file streams of a child process. Also that, I wanted not to use any named pipes for this purpose. One of the many ways I found was using a popen() system call. But, it seem to give to the parent either of stdin or stdout, but not both, and most importantly never stderr.

I used to wonder how various IDE’s used to execute compilers and debuggers in the background providing them with proper input and interpret their output. Anyway, I could find a solution to my problem. The basic fact is that “the child process always inherits the parent’s file descriptors”. ie, if a child can be made to inherit the file descriptors 0, 1 and 2, which actually points to some pipes with their other end in the parent process, the the parent effectively captures the child’s standard file descriptors.

So, what should be done is that, before fork(), the parent has to create the required number of pipes(one pipe for each stream) and make its own standard descriptors point to the file descriptors of the child end(supposed) of the pipes. After doing the fork(), the child will have its standard descriptors as what the parent had till the fork is called(ie, one of the ends of pipes).

Suppose you have to write something to the stdin of a child program. The steps to follow are as given below:

1. Create a pipe – use pipe() – the pipe will have a read end and a write end – two descriptors
2. Duplicate parent’s stdin – use oldstream=dup(). this is just like to save our original stream
3. Close stdin – So that we can assign the read end(child’s stdin) of the pipe to file descriptor 0
4. Make read end of pipe as stdin – use dup2() to duplicate the read end fd as 0
5. do the fork() – From now on whatever the parent and child reads from stdin will come from the read end of pipe.
6. Close unnecessary fds – Close the read and write end file descriptors from the child – it’ll use only stdin from now on. You may also close read end from parent since the parent is only going to write to the pipe.
7. Restore parent’s stdin – close the fd 0, use dup2() to use the saved(oldstream) copy of the parent’s stdin.
8. Start writing to child – Now start writing to the write end of the pipe to write to the stdin of child.

The above steps may be confusing. But if spent little time to think, you’ll surely get the idea. For more help see the code given below which captures both stdin and stdout of the child which is here the ‘bc’ calculator:

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

main()
{

int outfd[2];
int infd[2];

int oldstdin, oldstdout;

pipe(outfd); // Where the parent is going to write to
pipe(infd); // From where parent is going to read

oldstdin = dup(0); // Save current stdin
oldstdout = dup(1); // Save stdout

close(0);
close(1);

dup2(outfd[0], 0); // Make the read end of outfd pipe as stdin
dup2(infd[1],1); // Make the write end of infd as stdout

if(!fork())
{

char *argv[]={“/usr/bin/bc”,
“-q”,
0};close(outfd[0]); // Not required for the child
close(outfd[1]);
close(infd[0]);
close(infd[1]);

execv(argv[0],argv);

}
else
{

char input[100];close(0); // Restore the original std fds of parent
close(1);
dup2(oldstdin, 0);
dup2(oldstdout, 1);

close(outfd[0]); // These are being used by the child
close(infd[1]);

write(outfd[1],”2^32\n”,5); // Write to child’s stdin

input[read(infd[0],input,100)] = 0; // Read from child’s stdout

printf(“%s”,input);

}

}

I apologise for such a lengthy post.

bye for now.

Categories: Programming

crosstool a valuable tool for embedded development

15 December, 2006 Leave a comment

Hi all,

So, this time I’m here to talk about the crosstool, a must have tool for anyone starting out to develop applications for embedded targets. The tool can automatically configure and build the complete cross development tool chain for most of the embedded platforms. This time I was trying to build the compiler for sh4 target. The procedure was simple:

  1. Get the crosstool from the website (I had used 0.43)
  2. Modify the variables TARBALLS_DIR, RESULT_TOP,GCC_LANGUAGES in demo-sh4.sh according to where you want the package source code to be downloaded, the place where the resulting binaries to be installed and the list of languages the GCC need to build respectively.
  3. If you don’t have internet(or if ur internet has any firewall blocking FTP), you may download the packages(*.tar.bz2) manually into TARBALLS_DIR directory. By inspecting the demo-sh4.sh file, I understood that the it is using gcc-4.1.0-glibc-2.3.6.dat to get the details of the package versions to obtain.
  4. Run demo-sh4.dat.

Its very nice to observe how the crosstool has cleanly built the cross compilation tool chain. The problem that I faced next was with the compilation of linux kernel(crosstool-0.43 uses linux-2.6.15.4) that was lacking adequate support for sh4 arch. Then I manually downloaded linux-2.6.19(the latest as of today) and compiled with the newly built development tools. The steps I had followed are the following:

  1. Download and untar linux-2.6.19 kernel source package and cd into it.
  2. Run make ARCH=sh CROSS_COMPILE=/opt/crosstool/gcc-4.1.0-glibc-2.3.6/sh4-unknown-linux-gnu/bin/sh4-unknown-linux-gnu- xconfig
  3. Do the necessary configuration for the kernel. By running make ARCH=sh CROSS_COMPILE=/opt/crosstool/gcc-4.1.0-glibc-2.3.6/sh4-unknown-linux-gnu/bin/sh4-unknown-linux-gnu- help you may get the list of default configurations available for various Architecture specific targets (sh). For example, the one that I used was systemh_defconfig. Running make ARCH=sh CROSS_COMPILE=/opt/crosstool/gcc-4.1.0-glibc-2.3.6/sh4-unknown-linux-gnu/bin/sh4-unknown-linux-gnu- systemh_defconfig you can generate the configuration default for the systemh board following which you may do manual configuration using the menuconfig, xconfig, gconfig, etc.
  4. Just run make.

Voila :-) Our kernel and the modules are ready to be deployed on the target board. So, now that the kernel compilation was successful, its time to do it the crosstool way. For making crosstool to use this kernel version(mind you, the only use of linux kernel for crosstool is to install the kernel headers for userland apps), I modified the LINUX_DIR variable in gcc-4.1.0-glibc-2.3.6.dat to linux-2.6.19 and copied linux-2.6.19.tar.bz2 to the TARBALLS_DIR. That’s it. Running demo-sh4.sh again is the only step required to make the tool chain use our new kernel headers.

Note that, by default the crosstool extracts the packages and build them relative to the current directory where we run the demo-sh4.sh. Inorder to have a different build directory we may modify the variable BUILD_DIR inside the all.sh script file.

Categories: Programming

Counting 1′s in a binary number

13 December, 2006 Leave a comment

This is an article that I had posted in my livejournal on 17th-May-2006 04:23 pm. I’m trying to migrate the most valuable stuff to wordpress.

Hi everyone,

I just wanted to find the number of ones in a binary number. In the course of finding it, I met with a few ones who claimed they are the best. But through a few tests things became clear. Of course, there could be better one tomorrow… but till the sun rises the next day, let me hope this entry of mine will hold true… The best one that I have found till now is shown below:


main()
{

unsigned int number;
while(1)
{

int cnt = 0;
scanf("%u", &number);
if(number == 0)

break;

while(number)
{

cnt++;
number = number & (number-1);

}
printf("%d\n", cnt);

}

}

The counting loop can be in many other ways as given below in the order of their ranking in performance:


while(number)
{

cnt ++;
number = number & (number ^ (-number));

}

while(number)
{

cnt += number & 1;
number >>= 1;

}

and ultimately the worst one I ever found:


power = 9999999;
while ( number > 0 && power > 0)
{

cnt++;
power = (int)(log(number)/log(2));
number = number - ( 1 << power );

}

I don’t understand why one would write such a code. May be if the log() is optimized for base 2, things could change. Right now I’m doing more rigorous tests on the above algorithms. Note that, the difference in these algorithms can be noticed only when large numbers are given as input. ie, log2() of the number should be as large as possible.

Enjoy.

Categories: Programming
Follow

Get every new post delivered to your Inbox.