Question: how to communicate with kernel module.

From: =?ISO-8859-1?Q? (chenyp@brahms.ice.cycu.edu.tw)
Date: Tue Mar 21 2000 - 09:28:28 EST

  • Next message: Tim Waugh: "Re: [patch] 2.3.99-pre3-3: dev_alloc_name"

    Dear all:
    I wrote two programs to test how to communicate with the kernel module.
    The first one is a user program (user.c) , it opens file(rw_test) in the
    /proc, and
    write test data to the rw_test file, then read these data from it.
    Another one is a kernel module(module.c), it register a /proc
    file(rw_test).And
    manipulate read and write opertions.
    I execute the following commands:
    gcc -o user user.c
    gcc -c module.c -D__KERNEL__ -DMODULE -Wall -O
    insmod module.o
    ./user
    but the user program print error(can't open the /proc/rw_test file)
    why??
    I feel so sad.

    Ariel Chen in Taiwan

    the following is the source code I wrote.
    /*========================== user.c =================*/
    /*
     * User program : to write something to module program
     */

    #include<stdio.h>
    #include<unistd.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>

    main(void)
    {
      int fd;
      char test1[80],test2[80];

      sprintf(test1,"This is a test");
      if( (fd=open("/proc/rw_test",O_RDWR))==-1)
          printf("error");
      if( write(fd,test,14)==-1)
        printf("error");
      read(fd,test2,14);
      printf("test2=%s\n",test2);
    }

    /*=================== module.c =========================*/
    /*
     * Module Program : to communicate with user program
     */
    #include <linux/kernel.h> /* We're doing kernel work */
    #include <linux/module.h> /* Specifically, a module */
    #include <linux/stat.h>
    #include <linux/proc_fs.h>
    #include <asm/uaccess.h> /* for get_user and put_user */

    #define MESSAGE_LENGTH 80

    static char Message[MESSAGE_LENGTH];

    static ssize_t module_output(
        struct file *file, /* The file read */
        char *buf, /* The buffer to put data to (in the
                    * user segment) */
        size_t len, /* The length of the buffer */
        loff_t *offset) /* Offset in the file - ignore */
    {
      int i;
      char message[MESSAGE_LENGTH+30];

      sprintf(message, "Last input:%s", Message);
      for(i=0; i<len && message[i]; i++)
        put_user(message[i], buf+i);

      return i; /* Return the number of bytes "read" */
    }

    static ssize_t module_input(
        struct file *file, /* The file itself */
        const char *buf, /* The buffer with input */
        size_t length, /* The buffer's length */
        loff_t *offset) /* offset to file - ignore */
    {
      int i;

      for(i=0; i<MESSAGE_LENGTH-1 && i<length; i++)
        get_user(Message[i], buf+i);
      return i;
    }

    static int module_permission(struct inode *inode, int op)
    {
      if (op == 4 || (op == 2 && current->euid == 0))
        return 0;

      return -EACCES;
    }

    int module_open(struct inode *inode, struct file *file)
    {
      MOD_INC_USE_COUNT;

      return 0;
    }

    int module_close(struct inode *inode, struct file *file)
    {
      MOD_DEC_USE_COUNT;

      return 0; /* success */
    }

    static struct file_operations File_Ops_4_Our_Proc_File =
      {
        NULL, /* lseek */
        module_output, /* "read" from the file */
        module_input, /* "write" to the file */
        NULL, /* readdir */
        NULL, /* select */
        NULL, /* ioctl */
        NULL, /* mmap */
        module_open, /* Somebody opened the file */
        NULL, /* flush, added here in version 2.2 */
        module_close, /* Somebody closed the file */
        NULL,
        NULL,
        NULL,
        NULL,
        NULL
      };

    static struct inode_operations Inode_Ops_4_Our_Proc_File =
      {
        &File_Ops_4_Our_Proc_File,
        NULL, /* create */
        NULL, /* lookup */
        NULL, /* link */
        NULL, /* unlink */
        NULL, /* symlink */
        NULL, /* mkdir */
        NULL, /* rmdir */
        NULL, /* mknod */
        NULL, /* rename */
        NULL, /* readlink */
        NULL, /* follow_link */
        NULL, /* readpage */
        NULL, /* writepage */
        NULL, /* bmap */
        NULL,
        module_permission,
        NULL,
        NULL,
        NULL
      };

    static struct proc_dir_entry Our_Proc_File =
      {
        0,
        7,
        "rw_test",
        S_IFREG | S_IRUGO | S_IWUSR,
        1, /* Number of links (directories where the
             * file is referenced) */
        0, 0, /* The uid and gid for the file -
                * we give it to root */
        80, /* The size of the file reported by ls. */
        &Inode_Ops_4_Our_Proc_File,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        0,0
      };

    int init_module()
    {
      return proc_register(&proc_root, &Our_Proc_File);
    }

    void cleanup_module()
    {
      proc_unregister(&proc_root, Our_Proc_File.low_ino);
    }
    /*====================== End =========================*/

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/



    This archive was generated by hypermail 2b29 : Tue Mar 21 2000 - 11:18:42 EST