Re: Proc read function and long output

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Friday 07 May 2004 03:32, Danilo Reinhardt wrote:
> Thanks Jim!
>
> I think about your suggested code, and maybe i dont understand what
> your variables stand for, or ....  ok, i think i dont understand ;)
>
> Thats the lines i dont understand.
>
> pos = begin + len;	// pos is file offset of last byte in buffer
> if (pos < off)  {
> 	len = 0; 	// We havn't hit offset yet, start over
> 	begin = pos;
> }
>
> How do you calc begin? begin = page+off ?

'begin' is initialized to 0.  begin and pos are both offsets.


> If so, the if statement would never been true. Because, offset it's
> small , in my case up to 1024, and pos is a memory address, really
> big... do you has the complete function source?

Variables names are different, but this is a generic version
of what I have.  The my_lock isn't needed for this example, but
I just left it in because some sort of locking will likely be needed
in any real code.  The POS_CHECK macro comes in handy if you
have multiple loops.

static rwlock_t my_lock = RW_LOCK_UNLOCKED;
/*
 * handler for a /proc file that
 * prints out 1000 lines of "foo bar"
 *
 * Note: 'buffer' is one page long and 'length' will
 * never be more then 3KiB.
 */
int my_read_proc(char *buffer, char **start, off_t offset,
                 int length, int *eof, void *data) {
    
  off_t pos = 0;
  off_t begin = 0;
  int len = 0;
  int i;

#define POS_CHECK() do {                        \
    pos = begin + len;                          \
    if (pos < offset) {                         \
      len = 0;                                  \
      begin = pos;                              \
    }                                           \
    if (pos > offset + length)                  \
      goto done;                                \
  } while (0)

  read_lock(&my_lock);

  for (i=0; i<1000; i++) {
      len += sprintf(buffer+len, "foo ");
      len += sprintf(buffer+len, "bar\n");

      POS_CHECK();
  }

  *eof = 1;

 done:
  read_unlock(&my_lock);

  *start = buffer + (offset - begin);
  len -= (offset - begin);
  if (len > length)
    len = length;
  if (len < 0)
    len = 0;
  return len;
}


--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux