#include #include #include #include #include #include #include #include #define STRING_INIT {0, 0, 0} struct string { char *data; size_t len; size_t space; }; void add(struct string* s, const char *addition, size_t count){ size_t space_left = s->space - s->len; size_t addition_len = strlen(addition); if(count && addition_len > count) // Thanks Anna, the second part of this was backwards addition_len = count; if(space_left < addition_len){ s->data = krealloc(s->data, s->len + addition_len, GFP_KERNEL); s->space = s->len + addition_len; } strcpy(s->data + s->len, addition); // This could cause a buffer overflow! s->len += addition_len; } void reserve(struct string* s, size_t capacity){ if(capacity < s->len) return; s->data = krealloc(s->data, capacity, GFP_KERNEL); s->space = capacity; } void set_length_by_null(struct string* s){ s->len = strlen(s->data); } #define PROC_FILE_NAME "realloc_demo" struct string contents = STRING_INIT; ssize_t read_simple(struct file *filp,char *buf,size_t count,loff_t *offp ) { size_t copysize = count; size_t potential_copy = contents.len - *offp; printk("READ: buf = %lx, count = %lu, *loff_t = %llu\n", (long unsigned int)buf, count, *offp); if(*offp >= contents.len) return 0; if(potential_copy < count) copysize = potential_copy; memcpy(buf, contents.data + *offp, copysize); *offp += copysize; return copysize; } unsigned int call_count = 0; ssize_t write_simple(struct file *filp,const char *buf,size_t count,loff_t *offp) { add(&contents, buf, count); printk("WRITE: buf = %lx, count = %lu, *loff_t = %llu, contents.len = %lu\n", (long unsigned int)buf, count, *offp, contents.len); *offp += count; return count; } struct proc_ops proc_fops = { proc_read: read_simple, proc_write: write_simple }; int init_module (void) { proc_create(PROC_FILE_NAME,0,NULL,&proc_fops); return 0; } void cleanup_module(void) { remove_proc_entry(PROC_FILE_NAME,NULL); } MODULE_LICENSE("GPL");