#include <linux/module.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/uaccess.h>

static const char inp_file[] = "/etc/yumex.profiles.conf";
#define BUF_LEN 255

static int __init kread_init( void ) {
    struct file *f;
    char buff[ BUF_LEN + 1 ] = "";
    size_t n;
    long l;
    loff_t file_offset = 0;

    mm_segment_t fs = get_fs();
    set_fs( get_ds() );

    printk( "**** openning file: %s\n", inp_file );
    f = filp_open( inp_file, O_RDONLY, 0 );

    if( IS_ERR( f ) ) {
        printk( KERN_ALERT "file open failed: %s\n", inp_file );
        l = -ENOENT;
        goto fail_oupen;
    }
         
    l = vfs_llseek( f, 0L, 2 ); // 2 means SEEK_END 
    if( l <= 0 ) {
        printk( "failed to lseek %s\n", inp_file );
        l = -EINVAL;
        goto failure;
    }
    printk( "**** file size = %d bytes\n", (int)l );

    vfs_llseek( f, 0L, 0 );    // 0 means SEEK_SET 
    if( ( n = vfs_read( f, buff, l, &file_offset ) ) != l ) {
        printk( "failed to read %s\n", inp_file );
        l = -EIO;
        goto failure;
    }
    buff[ n ] = '\0';
    printk( "%s\n", buff );
    printk( KERN_ALERT "**** close file: %s\n", inp_file );
    l = -EPERM;
failure:
    filp_close( f, NULL );
fail_oupen:
    set_fs(fs);
    return (int)l;
}

module_init( kread_init );
MODULE_LICENSE( "GPL" );

