Thursday, March 28, 2013

Getting FILE information Via Stat in C Language

We know that Linux/Unix file system stores information for every file. Some of the information can be obtain by stat - A Unix system call. This system call is defined in < sys/stat.h> header file.

stat structure has the following fields.

struct stat {
    dev_t     st_dev;     /* ID of device containing file */
    ino_t     st_ino;     /* inode number */
    mode_t    st_mode;    /* protection */
    nlink_t   st_nlink;   /* number of hard links */
    uid_t     st_uid;     /* user ID of owner */
    gid_t     st_gid;     /* group ID of owner */
    dev_t     st_rdev;    /* device ID (if special file) */
    off_t     st_size;    /* total size, in bytes */
    blksize_t st_blksize; /* blocksize for file system I/O */
    blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
    time_t    st_atime;   /* time of last access */
    time_t    st_mtime;   /* time of last modification */
    time_t    st_ctime;   /* time of last status change */
};


Now lets write a small program to get the file information using stat system call.

// File name Stat.c

#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char **argv)
{
    if(argc != 2)   
        return 1;

    struct stat fileInfo;
    // getting file information into fileInfo using stat
    if(stat(argv[1],&fileInfo) < 0)   
        return 1;

    // printing file information
    printf("Information for %s\n",argv[1]);
    printf("---------------------------------------------------\n");
    printf("File Size: \t\t%d bytes\n",fileInfo.st_size);
    printf("Number of Links: \t%d\n",fileInfo.st_nlink);
    printf("File inode: \t\t%d\n",fileInfo.st_ino);

    // S_ISDIR, S_IRUSR,....are marcos
    printf("File Permissions Are: \t");
    printf( (S_ISDIR(fileInfo.st_mode)) ? "d" : "-");
    printf( (fileInfo.st_mode & S_IRUSR) ? "r" : "-");
    printf( (fileInfo.st_mode & S_IWUSR) ? "w" : "-");
    printf( (fileInfo.st_mode & S_IXUSR) ? "x" : "-");
    printf( (fileInfo.st_mode & S_IRGRP) ? "r" : "-");
    printf( (fileInfo.st_mode & S_IWGRP) ? "w" : "-");
    printf( (fileInfo.st_mode & S_IXGRP) ? "x" : "-");
    printf( (fileInfo.st_mode & S_IROTH) ? "r" : "-");
    printf( (fileInfo.st_mode & S_IWOTH) ? "w" : "-");
    printf( (fileInfo.st_mode & S_IXOTH) ? "x" : "-");
    printf("\n");

    return 0;
}


To Run: gcc Stat.c
              ./a.out Stat.c  // giving Stat.c file name as input

Out Put: 
Information for Stat.c
----------------------------------------
File Size:         1256 bytes
Number of Links:     1
File inode:         2367639
File Permissions Are:     -rw-r--r--

Tuesday, March 19, 2013

Redirection Using dup & dup2

dup and dup2 are basic I/O Unix system calls. Following program shows a sequence of dup operations that temporarily redirect the standard out put to "stdout.log" file. If we then want to use the original standard output we can duplicate that using dup2 system call, with help of already saved file descriptor fd.


// File Name: redirect.c

 #include <stdio.h>

   void main()
    {
        // File descriptor        

         int    fd;

        // This object is used to specify a position within a file     
         fpos_t pos;

        printf("\n stdout is normal ");
        fflush(stdout);

        //Getting current position in stream
        fgetpos(stdout, &pos);

        // Redirecting standard output to stdout.log file
        fd = dup(fileno(stdout));
        freopen("stdout.log", "w", stdout);

        fun();
        fflush(stdout);

        // Standard output is restoring to original settings
        dup2(fd, fileno(stdout));
        close(fd);
        clearerr(stdout);
        fsetpos(stdout, &pos);

        printf("\n stdout is normal again\n");
    }

    fun()
    {
    printf("stdout in f() is redirected to this file(stdout.log)");
    }

To run : gcc redirect.c
              ./a.out

After running above 2 commands you can see a file named stdout.log in your current directory with content "stdout in f() is redirected to this file(stdout.log)".

Monday, March 11, 2013

Run Applications Through C Program

Some times our project demands to start a particular application through C program. Here i will show you how to do that.

To start a application through C program, we can use a system call called execlp, which comes under exec family of UNIX system calls.

// Compiler: GCC
//File Name: execute.c
#include <stdio .h>
#include <unistd .h>
void main()
{
pid_t pid = fork();
switch (pid) {
       case 0:
        execlp("/bin/sh", "sh", "-c", "firefox http://umencs.blogspot.in", NULL);
            //execlp("/bin/sh", "sh", "-c", "gedit", NULL);
            //execlp("/bin/sh", "sh", "-c", "nautilus", NULL);
       case -1:
        printf("Error: can't execute command: fork() failed\n");
       }
}

In execlp system call -c option is used to read commands from the command_string operand instead of from the standard input.

To run above program use following commands
$gcc execute.c
$./a.out

the above program will open  http://umencs.blogspot.in in Firefox.


Building GUI using GtkBuilder in C Project

GLADE is a RAD(Rapid Application Development) Tool which is used for quick and easy development of GUI for GTK+ toolkit and GNOME Desktop environment.

GUI designed by glade, can be saved in XML file (it can be saved in .C or .glade file also). Using GtkBuilder (A GTK+ object), this GUI xml can be loaded by applications dynamically.

By using GtkBuilder, Glade XML files can be used in numerous programming languages including C, C++, C#, Vala, Java, Perl, Python and others.
Building GUI using GtkBuilder in C-Program:

Assume we have designed a GUI using glade, which is saved as gem.glade /gem.xml /gem.c. Irrespective of their extensions all these files contains XML format strings/tags only, which contains information to build GUI. For example, if we consider gem.c file, it contains the code as shown below
gem.c
********

Now we send gui_buffer (see above code) as a parameter to GtkBuilder, which builds required GUI of our application. To access gui_buffer in any file make a declaration

extern const char *gui_buffer;

//Code to build gui by GtkBuilder
 try {
        widgets = Gtk::Builder::create_from_string(gui_buffer);
    } catch (Gtk::BuilderError &e) {
        printf("Error building GUI: %s\n", e.what().c_str());
        exit(EXIT_FAILURE);
    }

Tuesday, March 5, 2013

Storing Function parameters in Registers instead of Stack

Generally whenever we call a function, the function parameters will store in a stack (in RAM). During the execution of that function, lot of push and pop operations done on that stack which eventually slow down the execution of that function. To increase the speed of execution we can store function parameters in cpu registers (ecx, edx).

In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully. The keyword __attribute__allows you to specify special attributes when making a declaration. This keyword is followed by an attribute specification inside double parentheses.

For example, please see the following code, where I am storing ADD function variables X and Y in CPU registers instead of stack using __attribute__.


// FASTCALL.c

#include <stdio.h >

__attribute__((fastcall,noinline)) int ADD (int X, int Y)
{
  return X + Y;
}

int main () {
  int Z = ADD (10, 20);
  printf("\n Z = %d \n", Z );
}
 Command to Execute

$gcc FASTCALL.c
$./a.out

To see whether these variable X, Y are stored in registers are not, type the following command in command line to generate assembly code of FASTCALL.c It create a file FASTCALL.s which contains the assembly code of FASTCALL.c.

Command to generate assembler Code

 
 $gcc -O2 -S -c FASTCALL.c

The content of  FASTCALL.s is as follows.

        .file    "FASTCALL.c"
    .text
    .p2align 4,,15
.globl ADD
    .type    ADD, @function
ADD:
    pushl    %ebp
    movl    %esp, %ebp
    leal    (%edx,%ecx), %eax
    popl    %ebp
    ret
    .size    ADD, .-ADD
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string    "\n Z = %d \n"
    .text
    .p2align 4,,15
.globl main
    .type    main, @function
main:
    pushl    %ebp
    movl    $20, %edx
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $10, %ecx
    call    ADD
    movl    $.LC0, 4(%esp)
    movl    $1, (%esp)
    movl    %eax, 8(%esp)
    call    __printf_chk
    leave
    ret
    .size    main, .-main
    .ident    "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

In the above assembler code, you can find that X and Y are stored in edx, ecx registers instead of esp. If you want to check the time difference without and with __attrribute_, you can use clock_t in your code.

Friday, March 1, 2013

LOGIC to prove SIMILAR Objects are EQUAL



While developing GEM (GEstures with Mouse) the biggest problem i faced is, "the user drawn gesture is most of the times smaller / bigger than already defined gesture" but they are almost same in shape. So, i used a logic to prove SIMILAR Objects (Different in size but with same shapes ) are EQUAL.

LOGIC:
Let us consider two similar circles A, B as shown in picture.
The co-ordinates of Circle A are
(x1, y1) = (6, 4)
(x2, y2) = (8, 6)
(x3, y3) = (6, 8)
(x4, y4) = (4, 6)

The co-ordinates of Circle B are
(X1, Y1) = (6, 3)
(X2, Y2) = (9, 6)
(X3, Y3) = (6, 9)
(X4, Y4) = (3, 6)

now we re-calculate the  above co-ordinates using following formulas

X =  [X - [Xmax+Xmin]/2] / [Xmax-Xmin]+ 0.5 ---------(1)

        where Xmin = min(x1,x2,x3,x4) for circle A
                   Xmax = max(x1,x2,x3,x4) for circle A
                   X = x1, x2, x3, x4 for circle A

                   Xmin = min(X1,X2,X3,X4) for circle B               
                   Xmax = max(X1,X2,X3,X4) for circle B
                   X = X1, X2, X3, X4 for circle B

Y =  [Y - [Ymax+Ymin]/2] / [Ymax-Ymin]+ 0.5 ------------(2)

        where Ymin = min(y1,y2,y3,y4) for circle A
                    Ymax = max(y1,y2,y3,y4) for circle A
                    Y = y1, y2, y3, y4 for circle A
                   
                   Ymin = min(Y1,Y2,Y3,Y4) for circle B
                   Ymax = max(Y1,Y2,Y3,Y4) for circle B
                   Y = Y1, Y2, Y3, Y4 for circle B
                  
Re-Calculating Circle A points:

Xmin = min(6, 8, 4, 6) = 4
Xmax = max(6, 8, 4, 6) = 8


Ymin = min(4, 6, 6, 8) = 4
Ymax = max(4, 6, 6, 8) = 8

new x1 =  (6 - (8+4) / 2)/4 + 0.5 = 0.5
new y1 =  (4 - (8+4) / 2)/4 + 0.5 = 0.0

in the same manner

new x2 = 1.0
new y2 = 0.5

new x3 = 0.5
new y3 = 1.0

new x4 = 0.0
new y4 = 0.5

Re-Calculating Circle B points:

Xmin = min(6, 9, 6, 3) =3
Xmax = max(6, 9, 6, 3) =9

Ymin = min(3, 6, 9, 6) =3
Ymax = max(3, 6, 9, 6) =9

new X1 = (6 - (9+3)/2)/(9-3) + 0.5 = 0.5
new Y1 = (3 - (9+3)/2)/(9-3) + 0.5 = 0.0

in the same manner

new X2 = 1.0
new Y2 = 0.5

new X3 = 0.5
new Y3 = 1.0

new X4 = 0.0
new Y4 = 0.5

After Re-calculating Circle A & B points using Formula (1) and (2)

x1 = X1; x2 = X2; x3 = X3; x4 = X4; and 
y1 = Y1; y2 = Y2; y3 = Y3; y4 = Y4;


Hence, SIMILAR Circles A and B are EQUAL

Note: Not only circles using this formulas any two similar drawing shapes can be proved to equal.