1. ホーム
  2. c

[解決済み] ioctl - 無効な引数

2022-02-07 05:50:36

質問

私は

#define IOCTL_ALLOC_MSG _IO(MAJOR_NUM, 0) 
#define IOCTL_DEALLOC_MSG _IO(MAJOR_NUM, 1)

をヘッダーファイルの中に入れてください。

と私が書いたドライバファイルの中にあります。

struct file_operations memory_fops = {
  unlocked_ioctl: device_ioctl,
  open: memory_open,
  release: memory_release
};


int memory_init(void) {
  int result;

  /* Registering device */
  result = register_chrdev(MAJOR_NUM, "memory", &memory_fops);
  if (result < 0) {
    printk("<1>memory: cannot obtain major number %d\n", MAJOR_NUM);
    return result;
  }

  allocfunc();

  printk("<1>Inserting memory module\n");
  return 0;

}

int device_ioctl(struct inode *inode,   /* see include/linux/fs.h */
         struct file *file, /* ditto */
         unsigned int ioctl_num,    /* number and param for ioctl */
         unsigned long ioctl_param)
{
    /* 
     * Switch according to the ioctl called 
     */
    printk ( "<l> inside ioctl \n" );
    switch (ioctl_num) {
    case IOCTL_ALLOC_MSG:
        allocfunc();
        break;
    case IOCTL_DEALLOC_MSG:
        deallocfunc();
        break;
    }

    return 0;
}

のように文字ファイルを作成しました。

mknod /dev/memory c 60 0

アプリの呼び出しに失敗する

int main(int argc, char *argv[]) {
    FILE * memfile;

    /* Opening the device parlelport */
    memfile=fopen("memory","r+");
    if ( memfile <0) {
        printf ( " cant open file \n");
        return -1;
    }

    /* We remove the buffer from the file i/o */
    int ret_val;
    if ( argc > 1 ) {
        if ( strcmp (argv[1], "mem" ) ==0 ) {


            ret_val = ioctl(memfile, IOCTL_ALLOC_MSG);

            if (ret_val < 0) {
                printf("ioctl failed. Return code: %d, meaning: %s\n", ret_val, strerror(errno));
                return -1;
            }
        }

アプリを実行すると、"ioctl failed.と表示されます。リターンコードは -1, 意味: 無効な引数です" in : strerror(errno)

printkです。

Inserting memory module

fyi, 私は "/dev/memory" "memory" を異なる名前とメジャー番号の組み合わせで実験しましたが、無駄でした。

解決するには?

を渡すと FILE* から ioctl() 関数は、ファイルディスクリプタを期待しますが、それは int .

少なくとも、ポインタをキャストによらずに整数に変換しているという大きな警告が出るはずですよね?

明らかな解決策は2つあります。

  1. を使用します。 fileno() 関数でファイルディスクリプタを取得します。 FILE* . 次のようなものでなければなりません。 ioctl(fileno(memfile), IOCTL_ALLOC_MSG) .
  2. 使用方法 open() の代わりに fopen() . この方法は、低レベルのコードを書いている場合に推奨される方法です。 FILE* が課すものです(すべてのバッファリングに関するものなど)。