給定兩個文件描述符,一個用於輸入,一個用於輸出,下面的函數將數據從輸入到輸出合理可靠。
#include <unistd.h>
/* Copy file from input file descriptor ifd to output file descriptor ofd */
extern int copy_file(int ifd, int ofd);
int copy_file(int ifd, int ofd)
{
char buffer[65536]; // Resize to suit your requirements
ssize_t i_bytes;
while ((i_bytes = read(ifd, buffer, sizeof(buffer))) > 0)
{
ssize_t bytes_left = i_bytes;
char *posn = buffer;
ssize_t o_bytes;
while ((o_bytes = write(ofd, posn, bytes_left)) > 0)
{
bytes_left -= o_bytes;
posn += o_bytes;
}
if (o_bytes < 0)
return -1;
}
if (i_bytes < 0)
return -1;
return 0;
}
裸最小測試程序可能是:
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
…declaration or definition of file_copy()…
int main(void)
{
int rc = EXIT_SUCCESS;
if (copy_file(STDIN_FILENO, STDOUT_FILENO) != 0)
{
int errnum = errno;
rc = EXIT_FAILURE;
fprintf(stderr, "copy_file failed: (%d) %s\n", errnum, strerror(errnum));
}
return rc;
}
從標準輸入到標準輸出這正確地複製文件。我還沒有明確測試過「短寫」。這是非常罕見的情況,最可能的上下文是輸出文件描述符是套接字的時候。測試錯誤路徑也很困難。我打電話給cf89
。一個試驗:
$ (trap '' 13; ./cf89 < /dev/zero) | (sleep 1)
copy_file failed: (32) Broken pipe
$
的trap
忽略SIGPIPE(13),所以寫塊,因爲沒有什麼是閱讀的管道。當sleep
退出時,寫入處理獲得從write()
錯誤 - 由於信號被忽略 - 這生成錯誤消息。
順便說一句,還有那些誰反對都報告錯誤號和基於安全理由的錯誤信息 - 它告訴攻擊者太多的系統,如果他們設法觸發錯誤。我不在這個營地;攻擊者在攻擊這樣的程序時已經知道系統類型。它可能與其他環境相關,比如Web服務器。
'while(true == 0)'is all kinds of strange – StoryTeller
IS there while(true)in C ?.我需要清理我的代碼。我會稍後再做。假設這只是一段時間的真實情況,我需要在第二種情況下打破loopp。 – daniel
而且你不需要「處理」情況三。 shell爲您正確設置流。只需從'stdin'讀取就可以讀取file1的內容。 – StoryTeller