33

Can someone give me proc_create() example?

Earlier they used create_proc_entry() in the kernel but now they are using proc_create().

Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
Rahul
  • 1,607
  • 3
  • 23
  • 41

3 Answers3

39

This example will create a proc entry which enables reading access. I think you can enable other kinds of access by changing the mode argument passed to the function. I haven't passed a parent directory because there is no need to. The structure file_operations is where you setup your reading and writing callbacks.

struct proc_dir_entry *proc_file_entry;

static const struct file_operations proc_file_fops = {
 .owner = THIS_MODULE,
 .open  = open_callback,
 .read  = read_callback,
};

int __init init_module(void){
  proc_file_entry = proc_create("proc_file_name", 0, NULL, &proc_file_fops);
  if(proc_file_entry == NULL)
   return -ENOMEM;
  return 0;
}

You can check this example for more details: https://www.linux.com/learn/linux-training/37985-the-kernel-newbie-corner-kernel-debugging-using-proc-qsequenceq-files-part-1

Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
Fred
  • 16,367
  • 6
  • 50
  • 65
  • Looking at kernel sources I should make a remark. `proc_file_fops` must not be lacated in a stack memory (function local variable). It must be a global variable or be located in memory allocated with some heap memory function. – Alex P. Feb 17 '17 at 14:55
  • in this way you create it under /proc how to create it under /proc/pid/ ? – Zibri Feb 06 '19 at 16:26
  • 2
    The link you provided is broken. Could you please fix it with a relevant one? – St.Antario Oct 12 '19 at 10:42
28

Here is a 'hello_proc' code, which makes use of the newer 'proc_create()' interface.

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

static int hello_proc_show(struct seq_file *m, void *v) {
  seq_printf(m, "Hello proc!\n");
  return 0;
}

static int hello_proc_open(struct inode *inode, struct  file *file) {
  return single_open(file, hello_proc_show, NULL);
}

static const struct file_operations hello_proc_fops = {
  .owner = THIS_MODULE,
  .open = hello_proc_open,
  .read = seq_read,
  .llseek = seq_lseek,
  .release = single_release,
};

static int __init hello_proc_init(void) {
  proc_create("hello_proc", 0, NULL, &hello_proc_fops);
  return 0;
}

static void __exit hello_proc_exit(void) {
  remove_proc_entry("hello_proc", NULL);
}

MODULE_LICENSE("GPL");
module_init(hello_proc_init);
module_exit(hello_proc_exit);

This code has been taken from http://pointer-overloading.blogspot.com/2013/09/linux-creating-entry-in-proc-file.html

jpihl
  • 7,941
  • 3
  • 37
  • 50
Alhaad Gokhale
  • 371
  • 4
  • 3
  • 1
    Thanks for a link, really useful. I recommend to read to those, who want to understand how it works. – Ivan Baidakou Jul 05 '15 at 20:02
  • 2
    This example with [QEMU + Buildroot test boilerplate](https://github.com/cirosantilli/linux-kernel-module-cheat/blob/4727fadcc8f6e0685f80dc88a2913995a8df01f3/kernel_module/procfs.c). – Ciro Santilli OurBigBook.com Jul 27 '17 at 08:23
  • in this way you create it under /proc how to create it under /proc/pid/ ? – Zibri Feb 06 '19 at 16:26
  • Thanks for the answer + the link. I posted an update that makes your code work on kernels > 5.6 -> https://stackoverflow.com/a/66926881/1724025 – luv2learn Apr 03 '21 at 01:10
5

This reply is just an update to @Alhaad Gokhale's great answer. The hello world module, as of kernels > 5.6 looks like this:

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

static int hello_proc_show(struct seq_file *m, void *v) {
  seq_printf(m, "Hello proc!\n");
  return 0;
}

static int hello_proc_open(struct inode *inode, struct  file *file) {
  return single_open(file, hello_proc_show, NULL);
}

static const struct proc_ops hello_proc_fops = {
  .proc_open = hello_proc_open,
  .proc_read = seq_read,
  .proc_lseek = seq_lseek,
  .proc_release = single_release,
};

static int __init hello_proc_init(void) {
  proc_create("hello_proc", 0, NULL, &hello_proc_fops);
  return 0;
}

static void __exit hello_proc_exit(void) {
  remove_proc_entry("hello_proc", NULL);
}

MODULE_LICENSE("GPL");
module_init(hello_proc_init);
module_exit(hello_proc_exit);

Key differences to note are:

  1. struct proc_ops replaces struct file_operations.
  2. member name changes from .open, .read to .proc_open, .proc_read...
  3. Need to remove the .owner line.

Further information:

luv2learn
  • 606
  • 8
  • 12