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--
Thursday, March 28, 2013
Tuesday, March 19, 2013
Redirection Using dup & dup2
Posted by
umencs
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)".
// File Name: redirect.c
#include
void main()
{
// File descriptor
// 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
Posted by
umencs
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.
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
Posted by
umencs
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);
}
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
Posted by
umencs
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.
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 );
}
.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
Posted by
umencs
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.
Subscribe to:
Posts (Atom)