⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 procfs-guide.tmpl

📁 linux 内核源代码
💻 TMPL
📖 第 1 页 / 共 2 页
字号:
       to be initialised after the procfs file is created by setting       the <structfield>read_proc</structfield> and/or       <structfield>write_proc</structfield> fields in the       <structname>struct proc_dir_entry*</structname> that the       function <function>create_proc_entry</function> returned:    </para>    <programlisting>struct proc_dir_entry* entry;entry->read_proc = read_proc_foo;entry->write_proc = write_proc_foo;    </programlisting>    <para>      If you only want to use a the      <structfield>read_proc</structfield>, the function      <function>create_proc_read_entry</function> described in <xref      linkend="convenience"/> may be used to create and initialise the      procfs entry in one single call.    </para>    <sect1>      <title>Reading data</title>      <para>        The read function is a call back function that allows userland        processes to read data from the kernel. The read function        should have the following format:      </para>      <funcsynopsis>	<funcprototype>	  <funcdef>int <function>read_func</function></funcdef>	  <paramdef>char* <parameter>buffer</parameter></paramdef>	  <paramdef>char** <parameter>start</parameter></paramdef>	  <paramdef>off_t <parameter>off</parameter></paramdef>	  <paramdef>int <parameter>count</parameter></paramdef>	  <paramdef>int* <parameter>peof</parameter></paramdef>	  <paramdef>void* <parameter>data</parameter></paramdef>	</funcprototype>      </funcsynopsis>      <para>        The read function should write its information into the        <parameter>buffer</parameter>, which will be exactly        <literal>PAGE_SIZE</literal> bytes long.      </para>      <para>        The parameter        <parameter>peof</parameter> should be used to signal that the        end of the file has been reached by writing        <literal>1</literal> to the memory location        <parameter>peof</parameter> points to.      </para>      <para>        The <parameter>data</parameter>        parameter can be used to create a single call back function for        several files, see <xref linkend="usingdata"/>.      </para>      <para>        The rest of the parameters and the return value are described	by a comment in <filename>fs/proc/generic.c</filename> as follows:      </para>      <blockquote>        <para>	You have three ways to return data:       	</para>        <orderedlist>          <listitem>            <para>	      Leave <literal>*start = NULL</literal>.  (This is the default.)	      Put the data of the requested offset at that	      offset within the buffer.  Return the number (<literal>n</literal>)	      of bytes there are from the beginning of the	      buffer up to the last byte of data.  If the	      number of supplied bytes (<literal>= n - offset</literal>) is	      greater than zero and you didn't signal eof	      and the reader is prepared to take more data	      you will be called again with the requested	      offset advanced by the number of bytes	      absorbed.  This interface is useful for files	      no larger than the buffer.	    </para>	  </listitem>	  <listitem>            <para>	      Set <literal>*start</literal> to an unsigned long value less than	      the buffer address but greater than zero.	      Put the data of the requested offset at the	      beginning of the buffer.  Return the number of	      bytes of data placed there.  If this number is	      greater than zero and you didn't signal eof	      and the reader is prepared to take more data	      you will be called again with the requested	      offset advanced by <literal>*start</literal>.  This interface is	      useful when you have a large file consisting	      of a series of blocks which you want to count	      and return as wholes.	      (Hack by Paul.Russell@rustcorp.com.au)	    </para>	  </listitem>	  <listitem>            <para>	      Set <literal>*start</literal> to an address within the buffer.	      Put the data of the requested offset at <literal>*start</literal>.	      Return the number of bytes of data placed there.	      If this number is greater than zero and you	      didn't signal eof and the reader is prepared to	      take more data you will be called again with the	      requested offset advanced by the number of bytes	      absorbed.	    </para>	  </listitem>	</orderedlist>      </blockquote>      <para>        <xref linkend="example"/> shows how to use a read call back        function.      </para>    </sect1>    <sect1>      <title>Writing data</title>      <para>        The write call back function allows a userland process to write        data to the kernel, so it has some kind of control over the        kernel. The write function should have the following format:      </para>      <funcsynopsis>	<funcprototype>	  <funcdef>int <function>write_func</function></funcdef>	  <paramdef>struct file* <parameter>file</parameter></paramdef>	  <paramdef>const char* <parameter>buffer</parameter></paramdef>	  <paramdef>unsigned long <parameter>count</parameter></paramdef>	  <paramdef>void* <parameter>data</parameter></paramdef>	</funcprototype>      </funcsynopsis>      <para>        The write function should read <parameter>count</parameter>        bytes at maximum from the <parameter>buffer</parameter>. Note        that the <parameter>buffer</parameter> doesn't live in the        kernel's memory space, so it should first be copied to kernel        space with <function>copy_from_user</function>. The        <parameter>file</parameter> parameter is usually        ignored. <xref linkend="usingdata"/> shows how to use the        <parameter>data</parameter> parameter.      </para>      <para>        Again, <xref linkend="example"/> shows how to use this call back        function.      </para>    </sect1>    <sect1 id="usingdata">      <title>A single call back for many files</title>      <para>         When a large number of almost identical files is used, it's         quite inconvenient to use a separate call back function for         each file. A better approach is to have a single call back         function that distinguishes between the files by using the         <structfield>data</structfield> field in <structname>struct         proc_dir_entry</structname>. First of all, the         <structfield>data</structfield> field has to be initialised:      </para>      <programlisting>struct proc_dir_entry* entry;struct my_file_data *file_data;file_data = kmalloc(sizeof(struct my_file_data), GFP_KERNEL);entry->data = file_data;      </programlisting>           <para>          The <structfield>data</structfield> field is a <type>void          *</type>, so it can be initialised with anything.      </para>      <para>        Now that the <structfield>data</structfield> field is set, the        <function>read_proc</function> and        <function>write_proc</function> can use it to distinguish        between files because they get it passed into their        <parameter>data</parameter> parameter:      </para>      <programlisting>int foo_read_func(char *page, char **start, off_t off,                  int count, int *eof, void *data){        int len;        if(data == file_data) {                /* special case for this file */        } else {                /* normal processing */        }        return len;}      </programlisting>      <para>        Be sure to free the <structfield>data</structfield> data field        when removing the procfs entry.      </para>    </sect1>  </chapter>  <chapter id="tips">    <title>Tips and tricks</title>    <sect1 id="convenience">      <title>Convenience functions</title>      <funcsynopsis>	<funcprototype>	  <funcdef>struct proc_dir_entry* <function>create_proc_read_entry</function></funcdef>	  <paramdef>const char* <parameter>name</parameter></paramdef>	  <paramdef>mode_t <parameter>mode</parameter></paramdef>	  <paramdef>struct proc_dir_entry* <parameter>parent</parameter></paramdef>	  <paramdef>read_proc_t* <parameter>read_proc</parameter></paramdef>	  <paramdef>void* <parameter>data</parameter></paramdef>	</funcprototype>      </funcsynopsis>            <para>        This function creates a regular file in exactly the same way        as <function>create_proc_entry</function> from <xref        linkend="regularfile"/> does, but also allows to set the read        function <parameter>read_proc</parameter> in one call. This        function can set the <parameter>data</parameter> as well, like        explained in <xref linkend="usingdata"/>.      </para>    </sect1>    <sect1>      <title>Modules</title>      <para>        If procfs is being used from within a module, be sure to set        the <structfield>owner</structfield> field in the        <structname>struct proc_dir_entry</structname> to        <constant>THIS_MODULE</constant>.      </para>      <programlisting>struct proc_dir_entry* entry;entry->owner = THIS_MODULE;      </programlisting>    </sect1>    <sect1>      <title>Mode and ownership</title>      <para>        Sometimes it is useful to change the mode and/or ownership of        a procfs entry. Here is an example that shows how to achieve        that:      </para>      <programlisting>struct proc_dir_entry* entry;entry->mode =  S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH;entry->uid = 0;entry->gid = 100;      </programlisting>    </sect1>  </chapter>  <chapter id="example">    <title>Example</title>    <!-- be careful with the example code: it shouldn't be wider than    approx. 60 columns, or otherwise it won't fit properly on a page    -->&procfsexample;  </chapter></book>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -