Advertisement
xosski

Buffer_char_device

Jan 9th, 2025
11
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.12 KB | None | 0 0
  1. // SPDX-License-Identifier: GPL
  2. #include <linux/init.h>
  3. #include <linux/module.h>
  4. #include <linux/moduleparam.h>
  5. #include <linux/fs.h>
  6. #include <linux/cdev.h>
  7. #include <linux/slab.h>
  8. #include <linux/uaccess.h> // for copy_from_user, copy_to_user
  9.  
  10. MODULE_LICENSE("GPL");
  11.  
  12. static void *local_buf;
  13. static int local_buf_size = 10; // Default buffer size
  14. static int hello_count = 1;
  15. static dev_t hello_dev;
  16. static struct cdev hello_cdev;
  17. static ssize_t hello_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
  18. static ssize_t hello_read(struct file *file, char __user *buf, size_t count, loff_t *ppos);
  19. static char *whom = "world";
  20. module_param(whom, charp, S_IRUGO | S_IWUSR);
  21. module_param(local_buf_size, int, S_IRUGO | S_IWUSR); // Buffer size as a module parameter
  22.  
  23. static struct file_operations hello_fops = {
  24. .owner = THIS_MODULE,
  25. .read = hello_read,
  26. .write = hello_write
  27. };
  28.  
  29. static int lowercase_count = 0; // Track lowercase letters in the buffer
  30.  
  31. // Function to count lowercase letters in the buffer
  32. static void count_lowercase(void) {
  33. int i;
  34. lowercase_count = 0;
  35. for (i = 0; i < local_buf_size; i++) {
  36. if (((char *)local_buf)[i] >= 'a' && ((char *)local_buf)[i] <= 'z') {
  37. lowercase_count++;
  38. }
  39. }
  40. }
  41.  
  42. static ssize_t hello_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
  43. int to_transfer = min(local_buf_size - (int)(*ppos), count);
  44. int i;
  45.  
  46. if (to_transfer == 0) {
  47. pr_err("Write: No space left in buffer\n");
  48. return -ENOMEM;
  49. }
  50.  
  51. if (copy_from_user(local_buf + (int)(*ppos), buf, to_transfer)) {
  52. return -EFAULT;
  53. } else {
  54. // Count lowercase letters in the newly written data
  55. for (i = 0; i < to_transfer; i++) {
  56. if (((char *)local_buf)[i] >= 'a' && ((char *)local_buf)[i] <= 'z') {
  57. lowercase_count++;
  58. }
  59. }
  60.  
  61. pr_info("Lowercase letter count: %d\n", lowercase_count);
  62. *ppos += to_transfer; // Update position
  63. return to_transfer;
  64. }
  65. }
  66.  
  67. static ssize_t hello_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) {
  68. int len = strlen(local_buf + (int)(*ppos));
  69. int to_transfer = min(len, count);
  70. char *message;
  71.  
  72. if (to_transfer == 0) {
  73. pr_info("Read: No data to transfer\n");
  74. return 0;
  75. }
  76.  
  77. // Provide feedback on the lowercase count
  78. if (lowercase_count < 4) {
  79. message = "Number of lowercase letters is less than 4\n";
  80. pr_info("Number of lowercase letters is less than 4\n");
  81. } else {
  82. message = "Number of lowercase letters is 4 or greater than 4\n";
  83. pr_info("Number of lowercase letters is 4 or greater than 4\n");
  84. }
  85.  
  86. // Copy the message to the user
  87. if (copy_to_user(buf, message, to_transfer)) {
  88. return -EFAULT;
  89. }
  90.  
  91. *ppos += to_transfer;
  92. return to_transfer;
  93. }
  94.  
  95. static int __init hello_init(void) {
  96. int err;
  97.  
  98. pr_info("Hello, %s\n", whom);
  99.  
  100. local_buf = kzalloc(local_buf_size, GFP_KERNEL); // Dynamically allocate buffer
  101. if (!local_buf) {
  102. pr_err("Buffer allocation failed\n");
  103. err = -ENOMEM;
  104. goto err_exit;
  105. }
  106.  
  107. if (alloc_chrdev_region(&hello_dev, 0, hello_count, "hello")) {
  108. pr_err("Failed to allocate chrdev region\n");
  109. err = -ENODEV;
  110. goto err_free_buff;
  111. }
  112.  
  113. pr_info("Major: %d, Minor: %d\n", MAJOR(hello_dev), MINOR(hello_dev));
  114.  
  115. cdev_init(&hello_cdev, &hello_fops);
  116. if (cdev_add(&hello_cdev, hello_dev, hello_count)) {
  117. pr_err("Failed to add cdev\n");
  118. err = -ENODEV;
  119. goto err_dev_unregister;
  120. }
  121.  
  122. return 0;
  123.  
  124. err_dev_unregister:
  125. unregister_chrdev_region(hello_dev, hello_count);
  126.  
  127. err_free_buff:
  128. kfree(local_buf);
  129.  
  130. err_exit:
  131. return err;
  132. }
  133.  
  134. static void __exit hello_exit(void) {
  135. pr_info("Goodbye, cruel %s\n", whom);
  136. cdev_del(&hello_cdev);
  137. unregister_chrdev_region(hello_dev, hello_count);
  138. kfree(local_buf);
  139. }
  140.  
  141. module_init(hello_init);
  142. module_exit(hello_exit);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement