Wednesday, August 09, 2006

I am back

This is part of self realization. I am back. Going back to the basics, discovering myself.

Speaking the truth and and having knowledge leads to fearlessness and that leads to charm.

x^=y^=x^=y;

Saturday, December 11, 2004

Find endian-ness of machine - a simple C program


/*Author: Nishant Agarwal, mail: nishant@purecode.us*/
#include
int main ()
{
unsigned int a;
unsigned char* ptr;
int count = 4;
a = 0x11223344;

ptr = (unsigned char*)&a;
while (count > 0)
{
printf("%x\n", *ptr);
++ptr;
--count;
if (count == 0)
{
--ptr;
if ((unsigned int)*ptr == 0x44)
printf("Machine is little endian\n");
else printf ("Machine is big endian\n");
}
}

return 0;
}


Java Socket Programming Tutorial

Look it up at:
http://www.geocities.com/nishant_unix/javasockettutorial/javaSocket.htm

Port Scanner script in Perl

#!/usr/usc/bin/perl
#nishant@purecode.us
use strict;
use IO::Socket;
#this is the victim machine :)
#tell how to use if user didnt enter any machine ip or name
my $peer = shift @ARGV;
if (!$peer) {
print "Usage: perl scan.pl [victim] \n";
exit;
}
#get the string of well-known ports 1 to 1023
my $wellknown = &getWellKnownPortList;
#now get a hash which has keys as port number and value as the well known service
my %hash = split /:/, $wellknown;
%hash = reverse %hash;
#now get a list of port numbers in sorted order
my @ports = sort {$a <=> $b} keys %hash;
#try to create a new socket on each of these ports , the $peer is the machine on which you want to run port scanner
my $sock;
foreach (@ports) {
$sock = IO::Socket::INET->new("$peer:$_");
print "\nPort $_ $hash{$_} open\n" if ($sock);
}
print "Done.\n";
exit;
#this is the long list of well known ports downloaded from internet , port numbers 1 to 1023
#the file is in /etc/services
sub getWellKnownPortList {

"tcpmux:1:compressnet:2:compressnet:3:rje:5:echo:7:discard:9:systat:11: .... and so on, I dont
put all ports here for clarity... mail me for complete code or look up on website at www.purecode.us }

What is Pure code anyway?

I have been asked by many as to what and why is my website id
www.purecode.us, pure code is a dirty alias for re-entrant code, or
non self modifying code. I wanted to give an explanation. Nothing
works better then an example. See the compilation unit given below in
c. Notice the various data types declared, they include static
variables, global variables, constant data types, pointers and so on.
Now see the assembly dump below that, and see in which sections did
they all go. I assume familiarity with the sections of a unix process:
text, read only data, initalized data, bss -> unitialized data, stack
and the heap. Naturally, we cant examine the contents of the stack and
the heap so easily, but we can find out whats in the other sections.
For code to be pure, or re-entrant, or non self modifying, the
requirement is that the code should be contained only in the text and
the .rodata (read-only) sections of the process. Static and global
data fall into the .bss and .data sections unless they are constants.
If the process is entirely in the text and .rodata sections, then we
can have multiple threads playing around with it, or we can have
multiple users sharing the pages via segmentation or paging virtual
memory implementations, and not worry about any damage to the code. It
is non-self modifying. Multiple calls to the same code will not modify
it too. Now ever wonder why we ever created the heck out of it of
making const objects and having const qualified class methods.
Thread-safe, pure, re-entrant, non self modifying....
-----------------------------------------------------------------------------------------------------
#include
const int i = 3;
float b = 3.4;
static int m = 3;
int x;
int *p;
int main()
{
x = i;
static int l = 5;
p = (int*) malloc (sizeof(int)*2);
int a = 3 + 4;
free(p);
return 0;
}
--------------------------------------------------------------------------------------------------------------
.file "fun.c"
.global b
.section ".data"
.align 4
.type b, #object
.size b, 4
b:
.long 1079613850
.align 4
.type m, #object
.size m, 4
m:
.long 3
.global x
.section ".bss"
.align 4
.type x, #object
.size x, 4
x:
.skip 4
.global p
.align 4
.type p, #object
.size p, 4
p:
.skip 4
.section ".data"
.align 4
.type _ZZ4mainE1l, #object
.size _ZZ4mainE1l, 4
_ZZ4mainE1l:
.long 5
.section ".text"
.align 4
.global main
.type main, #function
.proc 04
main:
.LLFB3:
!#PROLOGUE# 0
save %sp, -120, %sp
.LLCFI0:
!#PROLOGUE# 1
sethi %hi(x), %g1
or %g1, %lo(x), %o5
mov 3, %g1
st %g1, [%o5]
sethi %hi(p), %g1
or %g1, %lo(p), %l0
mov 8, %o0
call malloc, 0
nop
mov %o0, %g1
st %g1, [%l0]
mov 7, %g1
st %g1, [%fp-20]
sethi %hi(p), %g1
or %g1, %lo(p), %g1
ld [%g1], %o0
call free, 0
nop
mov 0, %g1
mov %g1, %i0
ret
restore
.LLFE3:
.size main, .-main
.section ".rodata"
.align 4
.type i, #object
.size i, 4
i:
.long 3
.ident "GCC: (GNU) 3.3.2"

Wednesday, November 03, 2004

Function Pointers demystified

A TO THE POINT EXPLANATION OF POINTERS TO FUNCTIONS OR FUNCTION POINTERS
-- Nishant Agarwal , nishant@purecode.us
The basic idea is that functions too are nothing but addresses. A function may be
called 100 times, but each time the same function is called, its because view the
function as an service requested from that address.
So, this gives the idea that functions too can be passed as arguments to functions,
and used as rvalues, just as addresses of variables or ADTs can.
A good example of this is the C qsort function.
int qsort (ary, N, sizeofeachelement, comparator)
Here, ary is the address of the starting block of memory which contains your
array or collection, N is the length of the collection, the third argument is the
size of each individual entity in the collection, and the fourth is the address of
the function which compares two entities of the collection.
so now, if your function is:
int comparator( Object a, Object b) , then in order to use this function in the above
qsort call, you would just write the name of the function as the fourth argument. What
you are doing is just passing the address of the function, just like you pass the
address of the first argument or any address.
The fun begins when you want to incorporate polymorphism in this idea. You dont want
to bind this call at compile time. So, declare a function pointer which can hold the
address of such a function, just like you would declare an int* p to hold the address
of an integer.
int (*pf) (int a, int b);
this is the function pointer which points to a function which can return an int
and takes the two arguments specified.
Now, suppose you have a comparator function which wants to sort in ascending order,
and one comparator which wants to sort in descending order.
//ascending
int comparator1 (int a, int b) {
if (a == b) return 0;
return a > b ? a : b;
}
//descending
int comparator2 (int a, int b) {
if (a==b) return 0;
return a > b ? b : a;
}
now, you got an array , a[20] of twenty integers. You want to sort in ascending order,
so you would call qsort, but first assign the correct function to your comparator
pointer function:
pf = comparator1;
qsort (a, 20, sizeof(a[0]), pf);
for descending order:
pf = comparator2;
qsort(a, 20, sizeof(a[0]), pf);
voila!! now you got run-time polymorphism akin to virtual functions in C
( do we really need C++ hmmmm).
A further point to note is that you can generalize the pointer to function definitions
even further by using the void * castings.
void* (*pf) (void* a, void* b);
Can this point to compartor 1 and comparator 2? I leave this to you to find out.
Also, what will this do:
int (*pf)[ ] (int a, int b);

Concurr and Conquer

CONCURR AND CONQUER
There has been a paradigm shift from the way computers are programmed
to do what we wanted to do. There is nothing more entertaining then
the beauty of the electron. Right from the moment you hit the enter on
the keyboard, to when the compiler generates the object files, the
linker links it up with the libraries and other objects, the assembler
churns out the assembly language for the native machine, loader puts
in the binary image of the 0s and the 1s into the memory, the sequence
of bits is interpreted as the micro-codes in the processor registers,
and life flows into the flip flops and the transistors, the drift
velocity of the electrons carrying them to and fro across the
channels, turning the silicon on and off.
This view can no longer be localized into just one processor. We dont
need embarassingly parallel problems to justify parallel architectures
or vice versa.
In my opinion, there has been no better mother of change, then the
need of managing complexity. The order of growth of complexity has
driven the IT revolution. Procedural to functional to Object oriented,
all due to one basic need of managing complexity. Flat to network to
relational to object oriented databases, again same reason. This is
taking an amortized view, mind that. If you go into intricacies of the
baud, it stops at the bits and the electrons, if you take an aggregate
view, it zooms in towards the white light shining far beyond the
matrix of the human race.
Coming back to what I was talking about earlier, there is a difference
in concurrency and parallelism. Concurrency is when two events can
occur in any order without affecting the outcome of the execution.
Parallelism is when these events occur on different processors. These
processors might share a common memory and clock, or they might be
loosely coupled and not share a common bus and a clock. As a
programmer, I would always program concurrently, and know that the
program, if run on a parallel architecture would exploit parallelism
as well, and get me more bang for the buck for my multi-threaded
application.
When do you thread your code?
1. Independent Tasks : When you can have tasks in your system, which
run independent of each other, the order of their execution doesnt
affect the outcome.
2. I/O use: When some tasks are I/O intensive, you dont want them to
hog up the system resources doing nothing, while other tasks could use
that time.
3. CPU use: when some tasks are CPU intensive, you dont want them to
use the CPU always, and starve other tasks.
4. Asynchronous event handling: Some task is expected to receive
service requests or signals asynchronously, I had rather thread that
task then make it busy wait or poll for the event to fire.
5. Resource sharing : As opposite it may sound to the first goal of
independent tasks, threading can enable tasks to share the global
process wide state of text and read only data, while maintaining their
own private execution states in the stacks and register sets.
Communication and Syncrhonization can be facilitated via message
passing, shared memory or other IPC mechanisms. This leads to an
important form of parallel execution: Pipelining. Think of it as a
pipelining in software, pipelining in thought, in the mind.
6. Existing multi-process code: As a rule of the thumb, if you already
have a multi-process code, you would most of the time benefit by
making it multi-threaded. Threads are light weight componenets
compared to processes. It has two major advantages: cost in context
switch is low, and also more work is done in user space then in kernel
space.
7. Concurrency inducive class of problems: As I talked of the
embarassingly parallel problems earlier, there are various problems
which are more easily, naturally and conducively solved via concurrent
thinking and algorithms. For eg: matrix multiplication.

...and now I am tired and very sleepy, will add to this list
soon, if you have suggestions, mail me at nishant@purecode.us