title: Linux kernel module making a proc entry does not print on reading the proc entry to user
body: <p>In the book <em>Operating System Concepts: 10th edition</em>, there's a programming project to log some information about a process by providing its pid <code>echo</code>'d to the <code>/proc</code> entry made while initializing the module, namely here, <code>/proc/pid</code>.</p>
  <pre class="lang-c prettyprint-override"><code>/**
   * This function is called each time the /proc/pid is read.
   * 
   * This function is called repeatedly until it returns 0, so
   * there must be logic that ensures it ultimately returns 0
   * once it has collected the data that is to go into the 
   * corresponding /proc file.
   */
  static ssize_t proc_read(struct file *file, char __user *usr_buf, size_t count, loff_t *pos)
  {
          int rv = 0;
          char buffer[BUFFER_SIZE];
          static int completed = 0;
          struct task_struct *tsk = NULL;
  
          if (completed) {
                  completed = 0;
                  return 0;
          }
  
          /* l_pid is a global that gets set properly when the proc entry is read. */
          tsk = pid_task(find_vpid(l_pid), PIDTYPE_PID);
          
          if (tsk == NULL) {
              rv = -1;
              return rv;
          }
  
          completed = 1;
          rv = sprintf(buffer, &quot;pid = [%d], command = [%s], state = [%ld]\n&quot;, 
                      tsk-&gt;pid, tsk-&gt;comm, tsk-&gt;state);
  
          if (copy_to_user(usr_buf, buffer, rv)) {
                  rv = -1;
          }
          
          return rv;
  }
  </code></pre>
  <p>My problem is with the <code>proc_read</code> function. The way I understand it (as explained in the book) is that <code>rv</code> has to be 0 eventually because the function specified as the <code>.read</code> field in the <code>file_operations</code> struct keeps getting called till returning 0.</p>
  <p>The problem is that I do not understand the necessity of having all this &quot;complete&quot; logic. If I change the code to be like this:</p>
  <pre class="lang-c prettyprint-override"><code>static ssize_t proc_read(struct file *file, char __user *usr_buf, size_t count, loff_t *pos)
  {
          int rv = 0;
          char buffer[BUFFER_SIZE];
          struct task_struct *tsk = NULL;
  
          /* l_pid is a global that gets set properly when the proc entry is read. */
          tsk = pid_task(find_vpid(l_pid), PIDTYPE_PID);
          
          if (tsk == NULL) {
              rv = -1;
              return rv;
          }
  
          int num_bytes = sprintf(buffer, &quot;pid = [%d], command = [%s], state = [%ld]\n&quot;, 
                      tsk-&gt;pid, tsk-&gt;comm, tsk-&gt;state);
  
          if (copy_to_user(usr_buf, buffer, num_bytes)) {
                  rv = -1;
          }
          
          return rv;
  }
  </code></pre>
  <p>To my understanding, when the proc entry is read, this function will get called, either returning -1 (if <code>tsk == NULL</code> or could not copy from <code>buffer</code> to <code>usr_buf</code>) <em>and thus get called again</em>. Or it will return 0 on success.</p>
  <p>The problem with this change (of course) is that it does not work. It does not print anything to the console when issuing <code>cat /proc/pid</code>. However, by <code>printk</code>ing the string inside <code>buffer</code>, it appears to be correct (at least in the <em>kernel log buffer</em>).</p>