Power of plain text, the power of being simple

As we see the convergence of technologies through web, I think plain text is going to play a crucial role in delivering a standard cross platform solution for communication. It has already taken the center stage in form of XML. Debate on simplicity (or human side of technology) and performance will, I think, have a positive shift towards the former (people love faster development and simpler use more these days I think.. Rubyist view)

why plain text?

pragmatic programmers answer it with bullets – insurance against obsolescence, leverage (lot of tools available for talking to plain text) and easier testing. and I as always agree.

The concern is there although. Concern is that in addition to being human readable, the text should be human understandable as well. Using names which are semantically correct and contextually relevant is going to act as a substantial catalyst in helping dealing with these plain text files (whether it is a database or configuration file or data-transfer format).

Being always biased towards keeping configuration and databases (good old unix way) I am going to take care of this as a specification in almost all (not everything is driven by me!) development I do. You should also do the same so that your database outlasts your application!

Advertisements

failed to retrieve keys – Automatix !

After installing Automatix on the Ubuntu, when I started it , it sleeps for some time (seemingly) and then says – failed to retrieve keys.

Looking at the `ps -aef’ output I could find that it has been trying to get the keys with a timeout value and when the timeout occurs, it shows the error.

So something to do with firewall ! or proxy settings ! I tried shutting the firewall down. did not help.

Then I went to System -> Preferences -> Network Proxy and put the proxy information there. Worked !!

return and exit from main: difference

What is the difference between returning from main with some exit code and calling exit giving the exit code as parameter ?

Basically the difference between following programs !

//ret.c
int main()
{
return 43;
}

//exit.c
int main()
{
exit(43);
}

well, there are three ways for the processes to exit: –

1. Voluntary exit (implicit)
2. Voluntary exit (explicit)
3. Involunatary exit

Voluntary exit can be implicit e.g. in case of return and explicit e.g.
in case of a call to exit(). Involuntary exit is like being killed by a
third process, receiving a SIGSTP signal (or other signals whose default ot set
behavior results in terminating the process).

+ ‘return’ is an implicit voluntary termination of process
+ ‘exit’ is an explicit voluntary termination.

Note: both calls actually execute code in the function ‘do_exit’ ultimately.

I also tried writing above programs and inspecting the assembly just to know if
there is any difference in the code ultimately. Here are they:

[ used ‘objdump -d’ function and showing here only the function ‘main’ disassembly]

//ret.o – main
080482f4 :
80482f4: 55 push %ebp
80482f5: 89 e5 mov %esp,%ebp
80482f7: 83 ec 08 sub $0x8,%esp
80482fa: 83 e4 f0 and $0xfffffff0,%esp
80482fd: b8 00 00 00 00 mov $0x0,%eax
8048302: 29 c4 sub %eax,%esp
8048304: b8 2b 00 00 00 mov $0x2b,%eax
8048309: c9 leave
804830a: c3 ret
804830b: 90 nop

//exit.o – main
08048324 :
8048324: 55 push %ebp
8048325: 89 e5 mov %esp,%ebp
8048327: 83 ec 08 sub $0x8,%esp
804832a: 83 e4 f0 and $0xfffffff0,%esp
804832d: b8 00 00 00 00 mov $0x0,%eax
8048332: 29 c4 sub %eax,%esp
8048334: 83 ec 0c sub $0xc,%esp
8048337: 6a 2b push $0x2b
8048339: e8 26 ff ff ff call 8048264
804833e: 90 nop
804833f: 90 nop

So there is some difference and looking closely it is that in case of ‘exit’
and explicit ‘call’ is made using call instruction (and hence pushing of
arguments to the stack) while this overhead is avoided in case of a return.

Ok. so that was a short dip in the code for two empty programs – result of a free mind.

fork and vfork

quick question: what’s the difference between fork() and vfork() system calls ?

quick answer: vfork() system call creates a process that shares the memory address space of its parent.

details:

fork() is implemented by linux as a clone() system call whose flags parameter specifies both a SIGCHLD signal and all the clone flags cleared and whose child_stack parameter is 0.

vfork() is implemented by linux as a clone() system call whose flags parameter specifies both a SGCHLD signal and flags CLONE_VM and CLONE_VFORK and whose second parameter is 0.

[ discussion: copy on write ]

This is a concept of making the process creation using fork() efficient in that instead of copying the parent’s address space while process creation, it is shared but as soon as either of them write on the page, kernel allocates a new page and assigns it to the writer process.

Most of the time, forking is required just to run a new process in which case it’s a waste to copy the whole parent address space.

handling interrupts stackability

An interrupt is an asynchronous event caused by devices to the kernel which must be processed urgently and in system context. Since this is not handled in process context, this cannot access u area and other process specific data structures. Only penalty that the interrupted process makes is that interrupt handling uses the time slice of the interrupted process. unfair !

Since there are several different events that may cause interrupts, so an interrupt may arrive when another one is being serviced. Again, there may be a different level of urgency associated with the interrupts. Linux gives the urgency a technical term i.e. interrupt priority level (ipl).

In the processor status word, linux stores current and previous ipl(s). When interrupt arrive, a check is made if new ipl > old ipl. If not then interrupts are saved in special registers and blocked until ipl drops enough (higher ipls get serviced). If it is, then a new context layer is created saving the process context, PSW, current ipl is set to the new ipl and handler is invoked. Old ipl is extracted from the saved PSW, again checks are made for other interrupts being available and if available, next interrupt context is unblocked and executed similarly.

I think its a poor description. I will try to improve upon that some other time.

setting effective UID/GID on linux

There are several ways to change the real or effective UID/GID of a process: –

* exec system call, when used to execute a program installed in suid (set uid) mode, changes the effective UID of the process to the effective UID of the owner of the program file. This the trick used by passwd program. Similarly, effective GID changes for the programs installed in sgid mode.

* setuid system call can be used for changing the effective UID  of the process. A process having real UID of 0 i.e. root can change the real UID as well using the same system call. Similaly, setgid can be used for setting effective and real (by root) GIDs.

UID, GID – real and effective – difference !

Reading the book by Uresh Vahalia, Unix Internals, I could understand exactly what is the concept behind real and effective UID and GID. I immediately thought of blogging it for reference.

The effective UID and effective GID affect file creation and access. During file creation, the kernel sets the owner attributes of the file to the effective UID and effective GID of the creating process. During file access, the kernel uses the effective UID and effective GID of the process to determine if it can access the file.

The real UID and real GID identify the real owner of the process and affect the permissions for sending signals. A process without superuser privilege can signal another process only if the sender’s real UID matches with the real UID of the receiver.

Child inherits the  credentials from the parent. since parent-child share the credentials, they can signal each other. CMIIW.

setting DISPLAY on linux while ssh’ing

If you are also fed up of exporting DISPLAY manually everytime you need to use gvim or anything else requiring ‘X’ then you will get a relief reading this post. you can use -X option

ssh -X [IP | Host]

If you use ssh -X, ssh will tunnel your X connection for you and automatically set up the appropriate X authentication. But its not all candies, there is a risk involved. I ran through the man page and found this

-X Enables X11 forwarding. This can also be specified on a per-host
basis in a configuration file.

X11 forwarding should be enabled with caution. Users with the
ability to bypass file permissions on the remote host (for the
user’s X authorization database) can access the local X11 display
through the forwarded connection. An attacker may then be able
to perform activities such as keystroke monitoring.

So take care.

verifying user space addresses in kernel

We can verify a user space address while executing in kernel by using the following function

int access_ok(int type, const void *addr, unsigned long size);

Defined in <asm/uaccess.h>, this function returns 1 if the address addr is a user space address and 0 if its a kernel space address (talking of the virtual address of course). argument type can be VERIFY_READ in case you ought to read from the address addr and VERIFY_WRITE if you ought to write to the address addr. VERIFY_WRITE is a superset of VERIFY_READ, hence if you need to read as well as write then use VERIFY_WRITE. argument size is the byte size of the data to be read or written.

This comes handy to be used in drivers and should return -EFAULT if the address is a kernel address where you expect a user space address e.g. in implementation of ioctls.