0

/devここのチュートリアル(chardev.c)に従ってノードを/dev/chardev作成しました。次のコードを使用して作成したデバイスにアクセスしようとしました:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h> //perror(), errno
#include <string.h>
#define RSIZE 50 

int main()
{
    int fd,err_save;
    char receive_buff[RSIZE];

    //open device and check for error msg
    fd = open("/dev/chardev", "rw");
    err_save = errno;
    if (fd < 0)
        {
        perror("open perror");
        printf("error opening device, fd = %d, err_save = %d \n", fd,err_save);
        }
    else
        {printf("Device opened\n");}

    //read device and check for error msg
    //memset(receive_buff, 0, sizeof(receive_buff)); //<--- strange
    read(fd, receive_buff, RSIZE);
    err_save = errno;
        if (fd < 0)
        {
        perror("read perror");
        printf("error reading device, fd = %d, err_save = %d \n", fd,err_save);
        }
    else
        {
        printf("Device read successful : %s\n",receive_buff);}

    //close device and check for error msg
    fd = close(fd);
    err_save = errno;
    if (fd < 0)
        {
        perror("close perror");
        printf("error closing device, fd = %d, err_save = %d \n", fd,err_save);
        }
    else
        {printf("Device closed\n");}
    return 0;
}    

成功した結果:

Device opened
Device read successful : I already told you 7 times Hello world!
w�0 ����
Device closed

ただし、memset(receive_buff, 0, sizeof(receive_buff));コメントを外すと、次のようになります。

open perror: File exists
error opening device, fd = -1, err_save = 17 
read perror: Bad file descriptor
error reading device, fd = -1, err_save = 9 
close perror: Bad file descriptor
error closing device, fd = -1, err_save = 9 

質問: 追加memset()によって がopen()失敗する原因は何ですか?

4

3 に答える 3

5

open2 番目のパラメーターとして整数を取ります (と混同されていますfopen)。あなたのopen行は次のようになります。

fd = open("/dev/chardev", O_RDWR);

コードが追加されたり削除されたりするときにそれが機能するか失敗するかの理由は、 のアドレスの予測できない値に関係してい"rw"ます。openmemset

于 2011-09-07T03:40:10.750 に答える
2

の 2 番目のパラメータに整数を渡す必要があります。openあなたの場合は ですO_RDWR。呼び出しは次のようになります。

fd = open ("/dev/chardev", O_RDWR);

マニュアルを読む: man 2 open . リンク: http://linux.die.net/man/2/open

アップデート

読み取りエラーを誤ってチェックします。あなたのコード:

read(fd, receive_buff, RSIZE);
err_save = errno;
if (fd < 0)
{
  perror("read perror");
  printf("error reading device, fd = %d, err_save = %d \n", fd,err_save);
}

読み取りエラーがある場合はread呼び出しが返されるため、 ではなく の-1戻り値を確認する必要があります。成功する:readfd

read_bytes = read(fd, receive_buff, RSIZE);
err_save = errno;
if (read_bytes < 0)
{
  perror("read perror");
  printf("error reading device, fd = %d, err_save = %d \n", fd,err_save);
}

2 番目のパラメーターはビット値が設定された単純な整数であり、特定の解釈があるため、コードは正しく実行されます。アドレス (読み込まれた実行可能ファイル内の文字列のベース アドレス) を渡します。これも整数で、特定のフィールドが設定されているものと設定されていないものがあります。フラグを正しく論理和することによってビットが設定されたのか、それともたまたま特定のビットが設定されたランダムな整数であったのかを判断することは不可能です。したがって、関数は、どのビットが設定されているかどうかをチェックすることによって乱数の整数を解釈し、各ビットに割り当てられた解釈に従って機能します。

また、ファイルから読み取るときに、読み取りが成功したかどうかを確認しません。ランダムな整数にファイルセットを読み取るための正しいビットが含まれている場合は、正しく読み取られます。

于 2011-09-07T03:44:52.510 に答える
1

コンパイラが警告すべきことについて警告していないか、警告を無視しています。

open()他の人は、 の 2 番目の引数が int であると既に言っています。文字列リテラルを渡すのは正しくありません。

man ページには、次のopen(2)ものが必要であると書かれています。

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

コンパイラは、関数の可視宣言がないことを少なくとも警告しているはずopen()です。うーん、今確認しました。gcc がデフォルトでこれを行わないことに失望しています。(C99 では、可視宣言なしで関数を呼び出すことは制約違反ですが、ほとんどのコンパイラはデフォルトで C99 をサポートしていません。

おそらくgccを使用しています。より多くの警告を有効にし ( で始まります-Wall -Wextra)、コンパイラーの指示に注意してください。また、使用する関数のマニュアル ページを読んで、必要なヘッダーを確認してください。

于 2011-09-07T04:16:09.437 に答える