0

I'm newie programming Linux modules: I'm making a proc to add and show values of a list. (and later remove)

This is the code:

(without the includes here)

int ret,temp,temp2;

struct k_list {
    struct list_head links;
    int data;
};

struct list_head my_list;

int pop_queue(struct file *filp,char *buf,size_t count,loff_t *offp) 
{
    char kbuf[128];
    struct list_head *iter;
    struct k_list *objPtr;

    printk(KERN_INFO "--Listing inserted numbers--");

    int contador = 0;
    list_for_each(iter,&my_list) {
        objPtr = list_entry(iter, struct k_list, links);
        printk(KERN_INFO "%d ", objPtr->data);            
        contador++;
    }
    printk(KERN_INFO "--End of list--");

    return count;
}

int push_queue(struct file *filp,const char *buf,size_t count,loff_t *offp)
{
    char kbuf[128];
    int w;
    temp=copy_from_user(kbuf,buf,count);
    if(sscanf(kbuf,"add %i",&w)==1){
        printk(KERN_INFO "\n add = %i \n" ,w);
        struct k_list * newNode = (struct  k_list *)vmalloc(sizeof(struct k_list));
        if (newNode == NULL){
            printk(KERN_INFO "Something went wrong");
        }
        newNode->data = w;
        //INIT_LIST_HEAD(&newNode->links);
        list_add_tail(&newNode->links,&my_list);
    }
    if(sscanf(kbuf,"remove %i",&w)==1) {
        printk(KERN_INFO "\n remove = %i \n" ,w);
    }

    return count;
}

struct file_operations proc_fops = {
    .read = pop_queue, 
    .write = push_queue,
};

int queue_init (void) {
    INIT_LIST_HEAD(&my_list);
    proc_create("queue",0666,NULL,&proc_fops);
    return 0;
}

void queue_cleanup(void) {
    remove_proc_entry("queue",NULL);
}

MODULE_LICENSE("GPL"); 
module_init(queue_init);
module_exit(queue_cleanup);

If if use "echo add X > /proc/queue" (X is an int) I can add values to the list, but when I try to show the list I enter in an infinite loop and its not the list_for_each inside the read function, because all the function is in loop:

[ 7382.404493] --End of list----Listing inserted numbers--
[ 7382.404497] 1 2 
[ 7382.404498] 3 4 
[ 7382.404499] --End of list----Listing inserted numbers--
[ 7382.404503] 1 2 
[ 7382.404504] 3 4 
[ 7382.404505] --End of list----Listing inserted numbers--
[ 7382.404509] 1 2 
[ 7382.404510] 3 4 
[ 7382.404511] --End of list--[ 7382.404493] --End of list----Listing inserted numbers--
[ 7382.404497] 1 2 
[ 7382.404498] 3 4 
[ 7382.404499] --End of list----Listing inserted numbers--
[ 7382.404503] 1 2 
[ 7382.404504] 3 4 
[ 7382.404505] --End of list----Listing inserted numbers--
[ 7382.404509] 1 2 
[ 7382.404510] 3 4 
[ 7382.404511] --End of list--

I'm adding nice the nodes? Why I enter in an infinite loop when reading?

Thanks everyone who reads until here :)

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
SugusTHC
  • 37
  • 4
  • Like in the duplicate question you forgot to adjust `offp` argument after reading. – Tsyvarev Jun 02 '17 at 17:01
  • Sorry, i didn´t see the other post... Anyway im not getting it... I put this to update the offp after reading ( *offp+=count; ) and still exist a loop :/ – SugusTHC Jun 02 '17 at 17:21
  • You should also check `*offp` at the beginning of the reading - it points to the last read position. If it points at the end of your file, you should return 0 instead of `count`. – Tsyvarev Jun 02 '17 at 17:31
  • See also [this question](https://stackoverflow.com/questions/44316739/implement-a-read-operation-list-in-debugfs/44334598#44334598) about implementing read from list-like file. – Tsyvarev Jun 02 '17 at 17:41
  • Thanks Tsyvarev, now i got it :D – SugusTHC Jun 02 '17 at 17:47

0 Answers0