Skip to content

Instantly share code, notes, and snippets.

@saadismail
Created May 1, 2018 17:01
Show Gist options
  • Save saadismail/bbe30a9aaef1d3a7cee22bfa09f88185 to your computer and use it in GitHub Desktop.
Save saadismail/bbe30a9aaef1d3a7cee22bfa09f88185 to your computer and use it in GitHub Desktop.
#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