2016-04-01 12 views
0

次のルーチンを使用してファイルをコピーすると、「不正なシーク」エラーが発生します。それは何が原因でしょうか?どちらも普通のファイルです。sendfileを使ってAからBへファイルをコピーする - 不正なシーク?

bool copyfile(const char* src, constchar* dest, bool overwrite_existing) 
{ 
    if (!overwrite_existing && file_exists(dest_filename)) 
    return false; 

    int read_fd; 
    int write_fd; 
    struct stat stat_buf; 
    off_t offset = 0; 

    printf("src_filename=%s\n", src_filename.str()); 

    if (read_fd = open(src_filename, O_RDONLY) == -1) 
    return false; 

    if (fstat(read_fd, &stat_buf) == -1){ 
    perror("fstat\n"); 
    return false; 
    } 

    write_fd = open(dest_filename, O_WRONLY | O_CREAT | O_TRUNC, stat_buf.st_mode); 
    if (write_fd == -1){ 
    close(read_fd); 
    return false; 
    } 

    int result = sendfile(write_fd, read_fd, &offset, stat_buf.st_size); 
    printf("result=%d, err=%s\n", result,strerror(errno)); 

    close(read_fd); 
    close(write_fd); 
    return result > 0; 
} 
+1

使用しているOS(Linux、カーネルバージョンの場合)は何ですか? 'sendfile'はあまり標準化されておらず、しばしばソースとデスティネーションのファイル記述子の種類を熟知しています(初期のLinuxではデスティネーションがソケットでなければなりません。すべてのLinuxはソースが適切な' mmap 'ファイルのようなもの)。サイドノート:最初から最後まで読みたいだけなら、 '&offset'を渡す必要はありません。少なくともLinuxでは、「NULL」を渡すことは「現在のファイル記述子オフセットから読み込みを開始する」ことを意味します。 – ShadowRanger

+3

'if(read_fd = open(src_filename、O_RDONLY)== -1)': '=='は '='より高い優先順位を持ちます。これは、 'open'が成功したと仮定して' read_fd'を0に設定する可能性が最も高いです。したがって、あなたはおそらく 'sendfile'をサポートしていない端末であるあなたの標準入力を' sendfile'しようとしています。 –

+0

@NateEldredge:答えとして投稿してください。それはほぼ確実に問題です。 – ShadowRanger

答えて

5
if (read_fd = open(src_filename, O_RDONLY) == -1) 

あなたは、いくつかの括弧を残しました。 ==演算子は=よりも優先順位が高くなります。したがって、open()が成功すると、read_fdは0に設定されます。したがって、sendfileは通常のファイルではない標準入力からの読み取りを試みています。 sendfileは、通常のファイルからの読み取りのみをサポートしています。したがって、失敗。

gcc -Wallでコンパイルすると、suggest parentheses around assignment used as truth valueという警告が表示されます。

コンパイラの警告を常に使用し、無視しないでください!

関連する問題