My output value from IOCTL command doesn`t work

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

 



Hi,
I`ve written some ioctl`s to my simple char device. I created inside
the device some number called "secretTreasure" and programs using
ioctl function would set and get this number (manipulate it). So i
have two ioctl commands: IO_SET_TREASURE and IO_GET_TREASURE. First
one works very well, but second has some bugs. In my "demo
application" I just want to get this treasure to some output value not
as return value from function. This way works as well but I can`t
manage with output values. Here is the source code. At the beginning
my "first.h" file:

#ifndef FIRST_H
#define FIRST_H

/* header`s files */
#include <linux/ioctl.h>

/* some constants for my device drivers */
#define    FIRST_MAJOR    250
#define	   FIRST_MAGIC	  'E'
#define    DEV_LICENSE    "GPL"
#define    SUCCESS     	  0
#define    DEVICE_NAME    "MyFirstDevice"
#define    BUF_LEN        128

/* there is, our ioctls */
#define IO_SET_TREASURE _IOW(FIRST_MAGIC, 0, unsigned long)
#define IO_GET_TREASURE _IOR(FIRST_MAGIC, 1, unsigned long)

/* and name of device */
#define DEVICE_FILE_NAME	"MyFirstDevice"
#endif

I think whole *.c file with code of device driver will be too big and
unnecessary, so I will paste only ioctl function:
static int	FirstModule_Ioctl(struct inode* inode, struct file* file,
unsigned int number, unsigned long param)
{
 int   err = 0;
	
	/* checking numbes to decode */
	if (_IOC_TYPE(number) != FIRST_MAGIC) return -ENOTTY;
	if (_IOC_NR(number) > 2) return -ENOTTY;

	/* checking access mode */
	if (_IOC_DIR(number) & _IOC_READ)
		err = !access_ok(VERIFY_WRITE, (void __user *)param, _IOC_SIZE(number));
	else if (_IOC_DIR(number) & _IOC_WRITE)
		err = !access_ok(VERIFY_READ, (void __user *)param, _IOC_SIZE(number));
	if (err)
		return -EFAULT;

	switch(number){
	  case IO_SET_TREASURE:
		secretTreasure = param;
		printk(KERN_INFO "New Secret Treasure has been set up as: %d\n",
secretTreasure);
		break;

	  case IO_GET_TREASURE:
		put_user(secretTreasure, (unsigned long *)param);
		printk(KERN_INFO "Secret Treasure is: %d\n and param is: %d",
secretTreasure, param);
		//return secretTreasure;
		break;
	}
	return SUCCESS;
}
As You can see I commented "return secretTreasure". It works but i
don`t want solve my trouble in that way. Return value must be for
error-checking not for secret number. I was trying to use some
put_user() macro. Of course it didn`t help me. Here is my demo
program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include "first.h"

void ioctl_set_trs(int fd, unsigned long new_number)
{
	int ret;
	if((ret = ioctl(fd, IO_SET_TREASURE, new_number)) < 0)
	{
		printf("IOCTL (set_trs) failed: %d\n", ret);
		perror("ioctl");
		exit(-1);
	}
}

void ioctl_get_trs(int fd)
{
 int ret;
 unsigned treasure;

 	if( (ret = ioctl(fd, IO_GET_TREASURE, treasure)) < 0)
	{
		printf("IOCTL failed: %d\n", ret);
		perror("ioctl");
		exit(-1);
	}
	printf("Here is secret number for You: %d and ret: %d\n", treasure,ret);
}
int main()
{
	int fd, ret;
	unsigned long new_treasure = 47;

	fd = open("/dev/MyFirstDevice",0);
	if(fd < 0){
		printf("I can`t open %s\n", DEVICE_FILE_NAME);
		perror("open");
		exit(-1);
	}
	ioctl_set_trs(fd, new_treasure);
	ioctl_get_trs(fd);
	return 0;
}
When i fire up this application I can see this message: <<Here is
secret number for You: 0 and ret: 0>> Of course ret == 0 but why does
my param value equal to zero ? When i look at dmesg output there is
something like this:
"New Secret Treasure has been set up as: 47
Secret Treasure is: 47"
And this comes from IO_GET_TREASURE, so everything in kernel mode is
set properly but not in userspace. Thanks for any help
-- 
-----BEGIN GEEK CODE BLOCK-----
GCS d- s:- a--- C+++ P L+++>+++++ E---- W+ N+ o? K- w--- O- M- V? PS++
PE++ Y PGP++ t--- 5? X R tv-- b+ DI+ D- G++ e- h! !r(--) !z+
------END GEEK CODE BLOCK------

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at 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