EmbLogic's Blog

IPC_PIPE

Introduction

The Linux IPC (Inter-process communication) facilities provide a method for multiple processes to communicate with one another. There are several methods of IPC available to Linux C programmers.

These facilities, when used effectively, provide a solid framework for client/server development on any Linux system (including Linux).
Half-duplex Linux pipes
Simply put, a pipe is a method of connecting the standard output of one process to the standard input of another. Pipes are the eldest of the IPC tools, having been around since the earliest incarnations of the Linux operating system. They provide a method of one-way communications (hence the term half-duplex) between processes.

This feature is widely used, even on the Linux command line (in the shell).

ls | sort | lp

The above sets up a pipeline, taking the output of ls as the input of sort, and the output of sort as the input of lp. The data is running through a half duplex pipe, traveling (visually) left to right through the pipeline.

Although most of us use pipes quite religiously in shell script programming, we often do so without giving a second thought to what transpires at the kernel level.

When a process creates a pipe, the kernel sets up two file descriptors for use by the pipe. One descriptor is used to allow a path of input into the pipe (write), while the other is used to obtain data from the pipe (read). At this point, the pipe is of little practical use, as the creating process can only use the pipe to communicate with itself.
If the process sends data through the pipe (fd0), it has the ability to obtain (read) that information from fd1. However, there is a much larger objective of the simplistic sketch above. While a pipe initially connects a process to itself, data traveling through the pipe moves through the kernel. Under Linux, in particular, pipes are actually represented internally with a valid inode. Of course, this inode resides within the kernel itself, and not within the bounds of any physical file system. This particular point will open up some pretty handy I/O doors for us, as we will see a bit later on.
At this point, the pipe is fairly useless. After all, why go to the trouble of creating a pipe if we are only going to talk to ourself? At this point, the creating process typically forks a child process. Since a child process will inherit any open file descriptors from the parent, we now have the basis for multiprocess communication (between parent and child).
We see that both processes now have access to the file descriptors which constitute the pipeline. It is at this stage, that a critical decision must be made. In which direction do we desire data to travel? Does the child process send information to the parent, or vice-versa? The two processes mutually agree on this issue, and proceed to “close” the end of the pipe that they are not concerned with. For discussion purposes, let’s say the child performs some processing, and sends information back through the pipe to the parent.
Construction of the pipeline is now complete! The only thing left to do is make use of the pipe. To access a pipe directly, the same system calls that are used for low-level file I/O can be used (recall that pipes are actually represented internally as a valid inode).

To send data to the pipe, we use the write() system call, and to retrieve data from the pipe, we use the read() system call. Remember, low-level file I/O system calls work with file descriptors! However, keep in mind that certain system calls, such as lseek(), do not work with descriptors to pipes.

Posted in Uncategorized | Tagged | Leave a comment

Article On Command Line Arguments

Command Line Arguments

  • Getting the arguments from command prompt in c is known as command line arguments.
  • Command line is that it consists of a sequence of words,typically separated by space. Main program can receive these words as an array of strings,one word per string.
  • main function will accept 2 parameters ,argv and argc
  • argc will be the count of the number of strings given on the command line.
  • argv will be the array of the arguments.since each word is a string argv is an array of pointers to char
  • Example:
    int main(int argc,char *argv[]){statements to be executed}
  • The strings at the command line are stored in memory and address of the first string is stored in argv[0],address of the second string is stored in argv[1] and so on.
  • we can give any name instead of argv and argc
    Example:
    main(int count,char*str[]){…..}
  • Example Program
    #include<stdio.h>
    int main(int argc,char *argv[])
    {
    int i;
    printf(“Number of Arguments passed=%d\n”,argc);
    for(i=0;i<argc;i++)
    printf(“argv[%d]=%s\n”,i,argv[i]);
    return;
    }
    Output
    emblogic@host:~/$ ./a.out g h k
    Number of Arguments passed=4
    argv[0]=./a.out
    argv[1]=g
    argv[2]=h
    argv[3]=k

Command Line Arguments in Unix/Linux:

  • Most Unix/Linux applications lets the user to specify command-line arguments (parameters) in 2 forms* Short options
    consist of a – character followed by a single alphanumeric character
    for example for listing the files the command is ls -l
    * Long options (common in GNU applications)
    consists of two – characters (–) followed by a string made up of letters, numbers, and hyphens.
  • Either type of option may be followed by an argument.
  • A space separates a short option from its arguments
  • Either a space or an = separates a long option from an argument.
  • GNU C provides 2 functions, getopt and getopt_long() to parse the command line args specified in the above format
  • getopt – supports parsing only short options
  • getopt_long – supports parsing of both short and long options.

getopt_long()

  • This function is defined in getopt.hSyntax:
    ——-
    int *getopt_long* (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *indexptr)

    Usage:
    ——
    while (getopt_long (argc, argv, shortopts, longopts, index) != -1) {
    }

    Parameters
    ———-
    argc and argv are the command line args passed to main
    shortopts: This is a string containing all the valid short option characters An option character can be followed by
    a colon (:) to indicate that it takes a required argument. (or)
    2 colon (::) to indicate that its argument is optional shortopts can begin with a + to indicate that getopts_long should stop processing on sensing an unexpected arg
    Ex: If we have have a program that can accept the short args -a and -b, the option string would be “ab”Now, if we have to force a mandatory required parameter for -a, but not for -b, the option string would be “a:b::”

     

     

 

Posted in Data Structures with C | Leave a comment

PARALLEL PORT

PARALLEL PORT

Parallel port is the mostly used for interfacing line printers. It was introduced by IBM in early 1980′s. Earlier there was no standard defined for parallel port interfacing. Every company has their own standards for interfacing parallel port. Then came the IEEE 1284 standard (Standard Signaling Method for bi-directional parallel peripheral interface for personal computers).

There are three base addresses defined for parallel port which can be used for interfacing parallel port. Those addresses are

0×378-0x37A

0×278-0x27A

0x3BC-0x3BF

A parallel port is a 25 pin connector having 8 data pins, 5 status pins and 4 control pins and rest of the pins are connected to ground.

2 – 9 = 8 Data Pins

10,11,12,13,15 = Status Pins

1, 14, 16,17 = Control Pins

18 – 25 = Ground Pins

This port will allow the input of up to 9 bits or the output of 12 bits at any one given time.

There are 5 data transfer mode in parallel communication:

      1. Compatibility Mode: Data can be transferred only in one direction using data register.

      2. Nibble mode: Data can be transferred in both direction in half-duplex manner (only four bit at a time).

      3. Byte Mode: 8bit data can be transferred in both direction in half-duplex manner.

      4. EPP Mode.

      5. ECP Mode.

Compatibility, Nibble & Byte modes use just the standard hardware available on the original Parallel Port cards while EPP & ECP modes require additional hardware which can run at faster speeds, while still being compatible with the Standard Parallel Port.

Compatibility Mode:

This mode defines the protocol used by most PCs to transfer data to a printer. It is commonly called the Centronics mode and is the method utilized with the standard parallel port. In this mode, data is placed on the port’s data lines, the printer status is checked for that it is not Busy, and then a data Strobe is generated by the software to send the data to the printer


Compatibility Mode steps:

  1. Write the data to the data register

  2. Program reads the status register to check that the printer is not BUSY

  3. If not BUSY, then Write to the Control Register to assert the STROBE line

  4. Write to the Control register to de-assert the STROBE line

To transfer one byte of data it requires four operation and at least as many additional instructions. The data transfer rate in this protocol is 150K bytes per second. This mode is for the forward channel only. This mode was included as a way to provide backward compatibility with the huge base of installed printers and peripherals. The other modes are used to provide the reverse channel and high performance communication links. Many of the integrated 1284 I/O controllers have implemented a mode that uses a FIFO buffer to transfer data with the Compatibility mode protocol. This mode is referred to as Fast Centronics or Parallel Port FIFO Mode. When this mode is enabled, data written to the FIFO port will be transferred to the printer using hardware generated strobes for the handshaking.

Posted in Device Drivers, Parallel Port Driver | Leave a comment

Inter process communication using named pipes(FIFO)

Inter process communication using named pipes(FIFO)

Earlier we saw the how to create pipes for communication between processes in linux.

One of the major disadvantage of pipes is that the they can not be accesed using their names by any other process other than child and the parent as they do not get listed in the directory tree.

The work around for this porblem is to create a named pipe which is also called as a FIFO, which stands for First in First out, meaning the data that is written into the pipe first will be read out first always.

The fifos get listed in the directory tree and any process can access it using its name by providing the approproiate path.

fifo are created using the function mkfifo() which takes as arguments

1. The name of the fifo that has to be created
2. The permissions for the file.

Once the file is created, it needs to be opened using the system call open() and the data can be read and written from the file using read() and write system calls.

One of the examples you can think of using a named pipe is communication between a server and a client. If ther are two fifos one of the server and the other of the client, then the client can send request to the server on the server fifo which the server will read and respond back with the reply on the client’s fifo.

Another advantage of a fifo over the pipes is that fifo are bidirectoinal, that is the same fifo can be read from as well and written into.

Posted in Project 03: Client Server Communication using Linux and IPC | Leave a comment

article on security ..linux vs windows

Why Linux Is More Secure Than Windows
Article posted by——Rana Brijendra singh

“Security through obscurity” may be a catchy phrase, but it’s not the only thing that’s catching among Windows users.
The expression is intended to suggest that proprietary software is more secure by virtue of its closed nature. If hackers can’t see the code, then it’s harder for them to create exploits for it–or so the thinking goes.
Unfortunately for Windows users, that’s just not true–as evidenced by the never-ending parade of patches coming out of Redmond. In fact, one of Linux’s many advantages over Windows is that it is more secure–much more. For small businesses and other organizations without a dedicated staff of security experts, that benefit can be particularly critical.
Five key factors underlie Linux’s superior security:
1. Privileges
Linux systems are by no means infallible, but one of their key advantages lies in the way account privileges are assigned. In Windows, users are generally given administrator access by default, which means they pretty much have access to everything on the system, even its most crucial parts. So, then, do viruses. It’s like giving terrorists high-level government positions.
With Linux, on the other hand, users do not usually have such “root” privileges; rather, they’re typically given lower-level accounts. What that means is that even if a Linux system is compromised, the virus won’t have the root access it would need to do damage systemwide; more likely, just the user’s local files and programs would be affected. That can make the difference between a minor annoyance and a major catastrophe in any business setting.
Social Engineering
Viruses and worms often spread by convincing computer users to do something they shouldn’t, like open attachments that carry viruses and worms. This is called social engineering, and it’s all too easy on Windows systems. Just send out an e-mail with a malicious attachment and a subject line like, “Check out these adorable puppies!”–or the porn equivalent–and some proportion of users is bound to click without thinking. The result? An open door for the attached malware, with potentially disastrous consequences organizationwide.
Thanks to the fact that most Linux users don’t have root access, however, it’s much harder to accomplish any real damage on a Linux system by getting them to do something foolish. Before any real damage could occur, a Linux user would have to read the e-mail, save the attachment, give it executable permissions and then run the executable. Not very likely, in other words.
3. The Monoculture Effect
However you want to argue the exact numbers, there’s no doubt that Microsoft Windows still dominates most of the computing world. In the realm of e-mail, so too do Outlook and Outlook Express. And therein lies a problem: It’s essentially a monoculture, which is no better in technology than it is in the natural world. Just as genetic diversity is a good thing in the natural world because it minimizes the deleterious effects of a deadly virus, so a diversity of computing environments helps protect users.
Fortunately, a diversity of environments is yet another benefit that Linux offers. There’sUbuntu, there’s Debian, there’s fedora and there are many other distributions. There are also many shells, many packaging systems, and many mail clients; Linux even runs on many architectures beyond just Intel. So, whereas a virus can be targeted squarely at Windows users, since they all use pretty much the same technology, reaching more than a small faction of Linux users is much more difficult. Who wouldn’t want to give their company that extra layer of assurance?
4-Audience Size
Hand-in-hand with this monoculture effect comes the not particularly surprising fact that the majority of viruses target Windows, and the desktops in your organization are no exception. Millions of people all using the same software make an attractive target formalicious attacks.
5. How Many Eyeballs
“Linus’ Law”–named for Linus Torvalds, the creator of Linux–holds that, “given enough eyeballs, all bugs are shallow.” What that means is that the larger the group of developers and testers working on a set of code, the more likely any flaws will be caught and fixed quickly. This, in other words, is essentially the polar opposite of the “security through obscurity” argument.
With Windows, it’s a limited set of paid developers who are trying to find problems in the code. They adhere to their own set timetables, and they don’t generally tell anyone about the problems until they’ve already created a solution, leaving the door open to exploits until that happens. Not a very comforting thought for the businesses that depend on that technology.
In the Linux world, on the other hand, countless users can see the code at any time, making it more likely that someone will find a flaw sooner rather than later. Not only that, but users can even fix problems themselves. Microsoft may tout its large team of paid developers, but it’s unlikely that team can compare with a global base of Linux user-developers around the globe. Security can only benefit through all those extra “eyeballs.”
Once again, none of this is to say that Linux is impervious; no operating system is. And there are definitely steps Linux users should take to make their systems as secure as possible, such as enabling a firewall, minimizing the use of root privileges, and keeping the system up to date. For extra peace of mind there are also virus scanners available for Linux, including ClamAV. These are particularly good measures for small businesses, which likely have more at stake than individual users do.
It’s also worth noting that security firm Secunia recently declared that Apple products have more security vulnerabilities than any others–including Microsoft’s.
Either way, however, when it comes to security, there’s no doubt that Linux users have a lot less to worry about.

 

Posted in Uncategorized | Leave a comment

ipc project :- 3

Fork (system call)

fork is an operation whereby a process creates a copy of itself. It is usually a system call, implemented in the kernal. Fork is the primary (and historically, only) method of process creation on Unix-like operating systems.fork() creates a new process by duplicating the calling process. The new process, referred to as the child, is an exact duplicate of the calling process, referred to as the parent, except for the following points:

The child has its own unique process ID, and this PID does not match the ID of any existing process group.

The child’s parent process ID is the same as the parent’s process ID.

Vfork

Vfork is a variant of fork with the same calling convention and much the same semantics; it originated in the 3BSD version of Unix,the first Unix to support virtual memory. It was standardized by POSIX, which permitted vfork to have exactly the same behavior as fork, but marked obsolescent in the 2004 edition, and has disappeared from subsequent editions.

When a vfork system call is issued, the parent process will be suspended until the child process has either completed execution or been replaced with a new executable image via one of the “exec” family of system calls.

Pipes

A pipe is a chain of processes so that output of one process (stdout) is fed an input (stdin) to another. UNIX shell has a special syntax for creation of pipelines. The commands are written in sequence separated by.

A very useful Linux feature is named pipes which enable different processes to communicate.

Named pipea named pipe (also known as a FIFO for its behavior) is an extension to the traditional pipe concept on Unix and Unix-like systems, and is one of the methods of  (IPC). The concept is also found in Microsoft window, although the semantics differ substantially. A traditional pipe because it exists anonymously and persists only for as long as the process is running. A named pipe is system-persistent and exists beyond the life of the process and must be deleted once it is no longer being used. Processes generally attach to the named pipes (usually appearing as a file) to perform inter-process communication.

I/O operations on a FIFO are essentially the same as for normal pipes, with once major exception. An “open” system call or library function should be used to physically open up a channel to the pipe. With half-duplex pipes, this is unnecessary, since the pipe resides in the kernel and not on a physical filesystem. In our examples, we will treat the pipe as a stream, opening it up with fopen(), and closing it with fclose().

Posted in Project 03: Client Server Communication using Linux and IPC | Leave a comment

Encrypt/Decrypt a file

ENCRYPT a file:

>>gpg -c filename

then enter password  & it will be saved as filename.gpg

DECRYPT a file:

>>gpg filename.gpg

enter password and file is decrypted as filename

Posted in Uncategorized | Leave a comment

Check it out !

See what a python script can do!!

Posted in Uncategorized | Tagged , , | Leave a comment

Log file for nested structures

RCS file: dist_add.c,v
Working file: dist_add.c
head: 1.4
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 4;	selected revisions: 4
description:
This is the base file for adding distances using structures.
----------------------------
revision 1.4
date: 2013/12/12 05:34:44;  author: root;  state: Exp;  lines: +13 -0
Modified the struct distance, added aa new element struct mks *.
allocated space for mks for one struct distance d1.
----------------------------
revision 1.3
date: 2013/12/12 05:26:18;  author: root;  state: Exp;  lines: +20 -8
Total usage of pointers for adding distances using structures.
----------------------------
revision 1.2
date: 2013/12/12 05:10:18;  author: root;  state: Exp;  lines: +14 -7
used structure pointer for adding distances.
Also used malloc () for allocating memory.
Inckuded stdlib.h for supporting malloc().
----------------------------
revision 1.1
date: 2013/12/12 04:31:18;  author: root;  state: Exp;
Initial revision
=============================================================================
Posted in Data Structures with C | Leave a comment

Project 01: A C Programming and Data Structures based Project

PROJECT TITLE:
Multiple Data Compression and Encryption using Iterative Technique.

Abstract:

In digital forms of data storage, data can be represented by patterns of 0s and 1s.
The more the patterns the more data can be compressed. Text may be compressed upto 40% of its original size. The percent of compression that can be done on a piece of text or a file depends on the type of file and the format of the text used.
Compression of a file may not be useful un till it can be decompressed back to its original form for further usage.

The requirement of compressing a file arises form various reasons, some of which may be
:
1. Security purpose.
2. Transmission purpose.(better bit rates, small latencies, etc)
3. Secrecy of the data or file being transferred.(Only some people may access, understand and manipulate data that is visible to all)
4. Storage purpose.(Efficient use of storage space)
etc,

When a file is compressed using any algorithm, it may be decompressed using more or less of that same algorithm in reverse order. An efficient compression may only be tested upon successful decompression of the compressed file if it generates the original file as it was before compression.
General Idea.
Any text file that has some text in it must be compressed depending on the size of the file and distinct characters it have. The same file may be decompressed using suitable algorithm and it must generate a file having same information of the source file used for compression. The program must be able to find number of distinct characters in the text file and store them in am array. In computer architecture (x86 machines) the data encoding scheme used to store, manipulate and transmit data is ASCII(American Standard Code for Information Interchange). It defines that maximum number of distinct characters available are 256 (i.e., 2^8). I used this very property of ASCII codes in my algorithm for compressing and decompressing files of any length but must have 256 distinct characters.

A simple algorithm used in compressing a text file may be :

1) Open a source file that comtains some text.(this file will be subjected to compression and decompression).
2) Read first character from source file.
3) Store first character in an array.
3) Read a character from this source file.
4) Compare the character with already existing character(s) in the array.
if the character matches with any character present in array goto step 4.
otherwise, modify the size of array by appending this character into it.
NOTE : this array now will have all the distinct characters in the file. This is the “key” used to compress and decompress the source file.
5) Now calculate the code length according to the number of elements in the master array. This is the actual size that my character must use in memory.
6) Seek the file position of the opened file to its begining.
7) Read a character from this file.
8. Compare this character with the one’s in array.
if it is present in array then assign its array index into a variable with appropriate shifting and goto step 7.
otherwise goto step 7.
NOTE: step 8 may differently handle the characters depending the code length and algorithm but the working principle is same.
9) Save the newely available coded word(after shifting) in to a new file. This is the compressed file.
10) Close all opened files.
11) Exit.

A simple algorithm used in decompressing a text file may be :

NOTE : I must have the “key” used in compression.(i.e., array holding distinct characters that were present in the source file)
1) Open the compressed file.
2) Read a character from this file.
3) save the bits of this character in different variables with appropriate shifting.
NOTE: step 3 may differently handle the character depending the code length and algorithm but the working principle is same.
4) Save the new bytes(new variables) in a new file.
5) goto step 2.
6) close all the opened files.
7) Exit.

Now to test the compression algorithm, compare the final newely created file’s information with that of original source file’s.

Conclusion:
I used the above algorithm to successfully compress and decompress many source files having variable text lengths.

Thank You.
HARPREET SINGH
ece.harpreetsingh@gmail.com

Posted in Uncategorized | Leave a comment

FTP SERVER CONFIGURATION (Batch-20.02.36)

FTP SERVER CONFIGURATION (Batch-20.02.36)

Any Linux system can operate as an FTP server. It has to run only the server software—an FTP daemon with the appropriate configuration. Transfers are made between user accounts on client and server systems. A user on the remote system has to log in to an account on a server and can then transfer files to and from that account’s directories only.

A special kind of user account, named ftp, allows any user to log in to it with the username “anonymous.” This account has its own set of directories and files that are considered public, available to anyone on the network who wants to download them.

The numerous FTP sites on the Internet are FTP servers supporting FTP user accounts with anonymous login. Any Linux system can be configured to support anonymous FTP access, turning them into network FTP sites. Such sites can work on an intranet or on the Internet.

1.Configuring the ftp Server

The vsftpd RPM package is required to configure a Red Hat Enterprise Linux system as an ftp server. If it is not already installed, install it with rpm commands as described in our pervious article. After it is installed, start the service as root with the command service vsftpd start . The system is now an ftp server and can accept connections. To configure the server to automatically start the service at boot time, execute the command chkconfig vsftpd on as root. To stop the server, execute the command service vsftpd stop. To verify that the server is running, use the command service vsftpd status.

2.Configure vsftpd server

In this example we will configure a vsftpd server and will transfer files from client side.

For this example we are using three systems one linux server one linux clients and one windows xp clients.

 

  • A linux server with ip address 192.168.0.254 and hostname Server
  • A linux client with ip address 192.168.0.1 and hostname Client1
  • A window client with ip address 192.168.0.2 and hostname Client2
  • Updated /etc/hosts file on both linux system
  • Running portmap and xinetd services
  • Firewall should be off on server

4.Check LAN card driver is installed or not.

LAN driver is the top most part for network. To check it run setup command

Select network configuration from list.

5.Check firewall status

Firewall is the necessary security part of Linux system which is connected to Internet. But in exam we are not going to use Internet so it’s good practice to disable it.

6.To disable firewall run setup commands.

  • Now select firewall configuration from list and click on run tool.
  • Select disable and click on ok and quit to return on command prompt.
  • System reboot require to take effect so reboot system with reboot -f commands.

7.Check portmap and xinetd package status

Almost every Linux server needs these two rpm to function properly. First check that these rpm are install or not. If no rpm is install then install them via rpm commands.

  • If you have rpm then check there status via setup commands.
  • Now select system service from menu.
  • put a star in front the portmap service.
  • Now put star in front the xinetd service.
  • Click on ok and select quit to come back on command prompt.

8.Now restart these two service.

  • To keep on these services after reboot on then via chkconfig command.
  • After reboot verify their status. It must be in running condition.
  • Once you have successfully completed these steps you are ready to configure the Linux server .
Posted in Project 00: Linux System / Network Administration | Tagged | Leave a comment

MULTIPLE DATA COMPRESSION

Multiple Data compresion is technique to compress more than 50 percent of the data,by using iteration methods in C language.

before compession and decompession there are certain function we have to perform;-

MASTER ARRAY

Array is the collection of elements of same data type in continous memory location.here,we create the array of all the characters including space and put them in array which is called as master array.from where we call all the repeated character of main string from there index.

CODELENGTH

Codelength is the no.of bits in which we have to keep the data i.e. a character takes 1 byte and integer take 4 byte for its storage but an integer can represent in 4 bits or 3 bits in how many bits we have to represent data  it is decided by code length .

COMPRESSION

logically in compression ,we compress the data i.e. firstly we put all the data in array as described earlier simultaneously we create index and after making index we call the characters through their index .By using bitwise shift operator we shift the index value  and put it into a character (type casting) using bitwise OR (|) the 2 byte data stored in 1 byte.here 50% compression is done.

ch=ch<<4;
ch2=ch|ch1;

DECOMPRESSION

In decompression ,logically we repeat the reverse process of compression

STEPS TO COMPRESS AND DECOMPRESS.

COMPRESSION
1.) Open the file to be compressed.
2.) Find the distinct characters in the file and store it in an array(master array).
3.) From the master array find the maximum number of bits required to represent each distinct character in compressed file.
4.) Read the file character by character.
5.) Replace each character with the index of the corresponding character in master array.
6.) Manipulate the indexes in the form of 1 byte using shift operations.
7.) Write the manipulated indexes to the compressed file.
8.) Store the master array in other file so that it could be used at the time of decompression.

DECOMPRESSION
1.) Open the compressed file.
2.) Open the file containing master array and store it in array.
3.) Form the master array find out the number of bits used to represent each character.
4.) Read the compressed file character by character.
5.) From this read characters filter out the actual ASCII characters using shift operations and indexes.
6.) Save the filtered out ASCII characters to new file.

Posted in Uncategorized | Leave a comment

POINTERS IN C LANGUAGE

POINTERS IN C LANGUAGE

C is the most powerful programming language in the software development world. You can do whatever you want to do regarding development then go through the C language. You can’t even imagine the depth of C language. And the most powerful tool of the C is Pointer. If you are master in the Pointer you can be the master of C language.

So, now your curiosity is some questions arising in your mind, like:

  1. Why Pointer are that much powerful tool?, When we can use the Pointers in our program?

  2. How Pointer works?

  3. How Pointers can increase the efficiency and decrease the length of our program?

 Here are the answers of these question.

Definition of Pointers-: The simple definition of Pointer is the variable which holds the address in memory of some other variable. You can understand this like a arrow pointing towards your home and on the arrow your address is print means the arrow holding the address of your home, and your home is the variable. This Lehman definition will help you to understand what is pointer.

 The declaration of Pointer is as follows:

                   int *pointer;

Here’s the pointer is a variable which is integer type, and * sign is actually an operator to DE-reference a pointer. The only time it means “hey I’m a pointer” is during variable declaration.

And how it holds the address:

                int *pointer;

                int a;

             pointer = &a;

Here, & ampersand sign specify the address of the variable.

In the above expression, variable a is the integer type and pointer is holding the address of a with the help of & sign. The data type int shows, 4 bytes of data the variable stored in.

Pointers in Array-:

Arrays are continuous block of memory holds multiple objects and the type of objects are specified. An array variable is constant. You can’t assign a pointer to an array variable, even if the pointer variable actually points to the same or a different array. You also cannot assign one array variable to another. You can assign an array variable to a pointer though and that is where things get confusing. When assigning the array to the pointer we are actually assigning the address of the first element in the array to the pointer.

 int a[4] = {1,2,3};

int *pointer = a;

printf(“*pointer=%d\n”, *pointer);

 Firstly we initialize the array of integer type. After this we initialize the integer pointer and assign the array variable to it. Since the array variable actually is the memory address of the first element in the array, we have assigned the memory address of the first element in the array to the pointer. This is the same as doing int *pointer = &a[0], explicitly stating the address-of the first element in the array.

 Notice the pointer has to be the same type as the elements of the array, unless the pointer is a void pointer.

Pointers to structure-:

A pointer to a structure holds the memory address of the first memory of structures. And the pointers to structure must be declared to point to the structure type or be void type.

struct person {

int age;

   char *name;

};

struct person first;

struct person *ptr;

 first.age = 21;

char *fullname = “full name”;

first.name = fullname;

ptr = &first;

 printf(“age=%d, name=%s\n”, first.age, ptr->name);

 On the first 6 lines we declare the struct person, a variable to hold a person struct, and a pointer to a person struct. Line 8 we assign a literal int to the age member. Line 9-10 we declare a char pointer to a literal char array and then assign that to the struct name member. Line 11 we assign a reference to the first person struct to our struct pointer variable.

Line 13 we print out the age and name of our struct instance. Notice the two different notations, the . and the ->. With the age field we are accessing the struct instance directly and so we use the . notation. With the name field we are using our pointer to the struct instance and so we use the -> notation. This would be the same as doing (*ptr).name where we first derefence the pointer and then access the name field.

Posted in Uncategorized | Leave a comment

Block Driver

Block driver

we take a look at the
important data structures and driver methods that you are likely to encounter while implementing a block
driver.They are as follows:

register_blkdev – register a new block device

@major: the requested major device number [1..255]. If @major=0, try to
allocate any unused major number.
@name: the name of the new block device as a zero terminated string
The @name must be unique within the system.
The return value depends on the @major input parameter.
– if a major device number was requested in range [1..255] then the
function returns zero on success, or a negative error code
– if any unused major number was requested with @major=0 parameter
then the return value is the allocated major number in range
[1..255] or a negative error code otherwise // /block/genhd.c

—————————————–blk_init_queue————————————————————

blk_init_queue – prepare a request queue for use with a block device
@rfn: The function to be called to process requests that have been
placed on the queue.
@lock: Request queue spin lock
Description:
If a block device wishes to use the standard request handling procedures,
which sorts requests and coalesces adjacent requests, then it must
call blk_init_queue(). The function @rfn will be called when there
are requests on the queue that need to be processed. If the device
supports plugging, then @rfn may not be called immediately when requests
are available on the queue, but may be called at some time later instead.
Plugged queues are generally unplugged when a buffer belonging to one
of the requests on the queue is needed, or due to memory pressure.
@rfn is not required, or even expected, to remove all requests off the
queue, but only as many as it can handle at a time. If it does leave
requests on the queue, it is responsible for arranging that the requests
get dealt with eventually.

The queue spin lock must be held while manipulating the requests on the
request queue; this lock will be taken also from interrupt context, so irq
disabling is needed for it.

Function returns a pointer to the initialized request queue, or %NULL if
it didn’t succeed.

—————————————blk_queue_logical_block_size——————————————–
blk_queue_logical_block_size – set logical block size for the queue
@q: the request queue for the device
@size: the logical block size, in bytes
Description:
This should be set to the lowest possible block size that the
storage device can address. The default of 512 covers most
hardware.

————————————–blk_queue_physical_block_size————————————————
64 * blk_queue_physical_block_size – set physical block size for the queue
@q: the request queue for the device
@size: the physical block size, in byte
Description:
This should be set to the lowest possible sector size that the
hardware can operate on without reverting to read-modify-write
operations.

————————————-blk_fetch_request——————————————————-

blk_fetch_request – fetch a request from a request queue
@q: request queue to fetch a request from

Description:
Return the request at the top of @q. The request is started on
return and LLD can start processing it immediately.
Return:
Pointer to the request at the top of @q if available. Null
otherwise.

* Context:
queue_lock must be held.
It calls blk_peek_request further and the blk_start_request as described below:

————————————blk_peek_request——————————————————–

blk_peek_request – peek at the top of a request queue
@q: request queue to peek at

Description:
Return the request at the top of @q. The returned request
should be started using blk_start_request() before LLD starts
processing it.

Return:
Pointer to the request at the top of @q if available. Null
otherwise.

Context:
queue_lock must be held.

—————————————————blk_start_request————————————————————-

blk_start_request – start request processing on the driver
* @req: request to dequeue
*
Description:
Dequeue @req and start timeout timer on it. This hands off the
request to the driver.

Block internal functions which don’t want to start timer should
call blk_dequeue_request().

Context:
queue_lock must be held.

———————————————————blk_end_request_all——————————————————-

blk_end_request_all – Helper function for drives to finish the request.
@rq: the request to finish
@error: %0 for success, < %0 for error

Description:
Completely finish @rq.

——————————————————–blk_end_request_cur——————————————————-

blk_end_request_cur – Helper function to finish the current request chunk.
@rq: the request to finish the current chunk for
@error: %0 for success, < %0 for error

Description:
* Complete the current consecutively mapped chunk from @rq.
*
Return:
* %false – we are done with this request
%true – still buffers pending for this request

Posted in Uncategorized | Leave a comment

character driver tutorial

HERE I AM GIVING YOU THE IMPLIMENTATION PROCEDURE TO CLEARIFY THE ALL STEP:-
Initialization of driver -> Mapping of system calls from application to the driver -> open call -> Mapping of memory on to the device (including trim function) -> Write call -> Read call -> Seek call ->use of multi threaded application.
We have used command “insmod” to call the initialization macro i.e. module_init() which will insert the driver into the list of modules & “rmmod” to call the cleanup macro i.e. module_exit() which will remove the driver from the list.
Driver starts with the registration using alloc_chrdev_region(). This registration (using alloc_chrdev_region()) is done so as to get the major number dynamically for the driver. Correspondingly a minor number is generated for the first device.
We can also use register_chrdev() to register the driver if we want to assign the user defined major number.
After registration we got a 32 bit number stored in “dev” which is of “dev_t” type. First 12 bits will give major number by using macro “MAJOR” & remaining 20 bits will give the minor number by using macro “MINOR”.
After getting the major & minor number, now its time to initialize the SCULL i.e. Simple character utility for loading localities. SCULL is a char driver that acts on the memory area as though it was a device. This SCULL is defined by a structure “Sculldev” contains blocks of memory called scullqsets which are also called as items and each item contains qsets which are nothing but array of pointers pointing to specific locations known as quantums. The scullqset or item can handle data maximum upto the data equal to product of qset_size and quantum size. Further each quantum can store maximum of bytes equal to quantum_size defined by the developer. We can calculate the number of scullqsets and number of quantums required for storing given number of bytes. One thing which is very important that these “items” or we can say that “scullqsets” should be linked like “link list” so as to store the data in quantums of different scullqsets.
After initializing the structure Sculldev, now we have to initialize the structure C_dev which will give the information of our device i.e. Owner of the device, Major & Minor numbers, operations that our device can perform etc. After this its time to map the system calls to the corresponding functions defined in the driver.
As the mapping is done so now from the application end we will call the open system call which will call our defined function in driver. In normal routine open call creates a stream and after handing over of the stream this call terminates. For our driver we have written our own routines. In our open function we have used a macro “container_of” to map the memory allocated for scull from RAM to the device & along with the link of “Structure inode” with “Structure C_dev & SCULL. This mapping will return the starting address of the SCULL which we will store into the “private data” of the “Structure file”. When ever & where ever if we want to access the sculldev we will fetch the private data. After sending the address of Sculldev we will call the trim function.
If we want to write on to the device, we have to check whether the device is having something onto its memory or not. If we found anything in quantums, we first trim the data nothing but flushing out the previously written bytes.
After trimming we will call write from the application. This write system call will call the write function which we have in our driver as we have already mapped all the operations to be performed by the applications in “Structure file_operations”. Writing here means getting the data from the user buffer & writing it on the quantums present in the SCULL i.e. Memory of device. In the starting of write function we will fetch the private data so as to get the address of SCULL. For writing we will use “Copy_from_user()”. Before writing we will calculate the number of items (scullqsets) to be created along with the number of quantums. Now we want to read what we have written earlier in the quantums. For this we will call the read function. This means reading the data from the quantums & passing it to the user buffer which we will receive in our application. For this we will use “Copy_to_user()”.

Posted in Character Driver, Device Drivers, Uncategorized | Leave a comment