Created
May 1, 2018 17:01
-
-
Save saadismail/bbe30a9aaef1d3a7cee22bfa09f88185 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/module.h> | |
#include <linux/init.h> | |
#include <linux/kernel.h> | |
#include <linux/proc_fs.h> | |
#include <linux/fs.h> | |
#include <linux/seq_file.h> | |
#include <linux/slab.h> // for kmalloc() | |
static int limit = 1000; | |
module_param(limit, int, S_IRUGO); | |
static int* prime_ptr; | |
static void* ct_seq_start(struct seq_file *s, loff_t *pos) | |
{ | |
int count, countD, currNum, i; | |
printk(KERN_INFO "Entering start(), pos = %Ld.\n", *pos); | |
if ((*pos) >= limit) { // are we done? | |
printk(KERN_INFO "Apparently, we're done.\n"); | |
return NULL; | |
} | |
// Allocate an integer to hold our increasing prime value. | |
prime_ptr = kmalloc(sizeof(int), GFP_KERNEL); | |
if (!prime_ptr) // fatal kernel allocation error | |
return NULL; | |
printk(KERN_INFO "In start(), prime_ptr = %pX.\n", prime_ptr); | |
currNum = 2; | |
count = 0; | |
while (count < (*pos)) { | |
countD = 0; | |
currNum++; | |
for (i = 2; i < currNum; i++) { | |
if (currNum % i == 0) countD++; | |
} | |
if (countD == 0) count++; | |
} | |
*prime_ptr = currNum; | |
return prime_ptr; | |
} | |
static int ct_seq_show(struct seq_file *s, void *v) | |
{ | |
printk(KERN_INFO "In show(), prime = %d.\n", *((int*)v)); | |
seq_printf(s, "The current value of the prime number is %d\n", | |
*((int*)v)); | |
return 0; | |
} | |
static void* ct_seq_next(struct seq_file *s, void *v, loff_t *pos) | |
{ | |
int* val_ptr; | |
int currNum, countD; | |
int i; | |
printk(KERN_INFO "In next(), v = %pX, pos = %Ld.\n", v, *pos); | |
(*pos)++; // increase my position counter | |
if ((*pos) >= limit) // are we done? | |
return NULL; | |
val_ptr = (int *) v; // address of current prime value | |
currNum = *val_ptr; | |
while (true) { | |
countD = 0; | |
currNum++; | |
for (i = 2; i < currNum; i++) { | |
if (currNum % i == 0) countD++; | |
} | |
if (countD == 0) break; | |
} | |
(*val_ptr) = currNum; // increase it by two | |
return v; | |
} | |
static void ct_seq_stop(struct seq_file *s, void *v) | |
{ | |
printk(KERN_INFO "Entering stop().\n"); | |
if (v) { | |
printk(KERN_INFO "v is %pX.\n", v); | |
} else { | |
printk(KERN_INFO "v is null.\n"); | |
} | |
printk(KERN_INFO "In stop(), prime_ptr = %pX.\n", prime_ptr); | |
if (prime_ptr) { | |
printk(KERN_INFO "Freeing and clearing prime_ptr.\n"); | |
kfree(prime_ptr); | |
prime_ptr = NULL; | |
} else { | |
printk(KERN_INFO "prime_ptr is already null.\n"); | |
} | |
} | |
static struct seq_operations ct_seq_ops = { | |
.start = ct_seq_start, | |
.next = ct_seq_next, | |
.stop = ct_seq_stop, | |
.show = ct_seq_show | |
}; | |
static int ct_open(struct inode *inode, struct file *file) | |
{ | |
return seq_open(file, &ct_seq_ops); | |
}; | |
static struct file_operations ct_file_ops = { | |
.owner = THIS_MODULE, | |
.open = ct_open, | |
.read = seq_read, | |
.llseek = seq_lseek, | |
.release = seq_release | |
}; | |
static int ct_init(void) | |
{ | |
proc_create("primes", 0, NULL,&ct_file_ops); | |
return 0; | |
} | |
static void ct_exit(void) | |
{ | |
remove_proc_entry("primes", NULL); | |
} | |
module_init(ct_init); | |
module_exit(ct_exit); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment