Ethan
Ethan

Reputation: 53

Dmesg output in linux kernel from char device module

I'm trying to implement a char device driver in Linux driver. When I try to echo strings into my driver, the result is very weird.

My code to store the strings I input:

int max_size = 1;
char store[1] = {0};
char message[100] = {0};
ssize_t hello_write(struct *filep, const char *buffer, size_t length, loff_t *position)

{
  if(length> max_size)
     length = max_size;
  if(copy_from_user(message, buffer, length))
     return -EFAULT;
  strncpy(store, message, max_size);
  printk(KERN_INFO "Actually stored in kernel:%s", store);
  return max_size;
}
ssize_t hello_read(struct file *filep, char *buffer, size_t length, loff_t *postion)
{
  int error_count = 0;
  error_count = copy_to_user(buffer, store, max_size);
  if(error==0){
    printk(KERN_INFO "read message from kernel: %s", store);
    return 0;
  }
  else{
    printk(KERN_INFO "failed to send %d chars to user", error_count);
    return -EFAULT;
  }
}

Test:

echo ginger > /dev/test
cat /dev/test

I intend to store only the first letter of each input string, anything with the function strncpy?

store the string one by one

Upvotes: 0

Views: 477

Answers (1)

Tsyvarev
Tsyvarev

Reputation: 65928

Value returned by write syscall is interpreted as number of bytes processed.

Like other standard output utilities echo calls write() syscall repeatedly until it processes all input bytes.

So, when you want to store only single byte of the input, you need to return input's full length for mark it as processed.

More correct implementation of .write would be:

ssize_t hello_write(struct *filep, const char * __user buffer, size_t length, loff_t *position)
{
  if((*position == 0) && (length > 0)) {
    // Store the first byte of the first input string.
    if(copy_from_user(message, buffer, 1))
       return -EFAULT;
    strncpy(store, message, 1);
  }
  printk(KERN_INFO "Actually stored in kernel:%s", store);
  // But mark the whole string as processed
  *position += length;
  return length;
}

Upvotes: 2

Related Questions