#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include<linux/sched.h>
#include <asm/uaccess.h>
#include<linux/slab.h>
#include<linux/kfifo.h>

#define  FIFO_SIZE 32

ssize_t size;
int flag=1;
char entries[]={'a','b','c','d','e','f','g','h'};
DEFINE_KFIFO(test,char,FIFO_SIZE);
ssize_t read_proc(struct file *filp,char *buf,size_t count,loff_t *offp ) 
{
int ret,size;
char *temp,*start;
temp=kmalloc(sizeof(char)*10,GFP_KERNEL);
start=temp;
if(flag==0) {
		size=0;
		flag=1;
		printk(KERN_INFO "in if");
		}
else {
		if(kfifo_is_empty(&test)) {
				temp="FIFO empty\n";
				printk(KERN_INFO "in empty");
				size=strlen(temp);
				simple_read_from_buffer(buf,count,offp,temp,size);
		}
		else {
		ret=kfifo_get(&test,temp);
		temp=temp+1;
		printk(KERN_INFO "in else %d",ret);
		*temp='\n';
		simple_read_from_buffer(buf,count,offp,start,ret+1);
		size=ret+1;
		}
		flag=flag-1;
}
return size;
}

struct file_operations proc_fops = {
read:	read_proc
};
void create_new_proc_entry(void) 
{
proc_create("fifo",0,NULL,&proc_fops);
}


int proc_init (void) {
	int i=0;
	create_new_proc_entry();
	for(i=0;i<6;i++)
		kfifo_put(&test,entries[i]);

	return 0;
}

void proc_cleanup(void) {
		remove_proc_entry("fifo",NULL);
}

MODULE_LICENSE("GPL");	
module_init(proc_init);
module_exit(proc_cleanup);