[英]Reading continuously from stdin
我剛開始學習 C,如果我錯過了一些明顯的東西,我很抱歉。 作為一種實踐,我想編寫自己的 posix cat
,並且幾乎可以正常工作,但是當沒有 arguments 時,它不會從 stdin 讀取多個文件。
這是預期的行為(忽略這一點,因為這是我不知道的 Zsh 功能):
$ cat < hello.txt < world.txt
hello
world
$
但是我的cat
因“分段錯誤”而崩潰(我有一個沒有崩潰的版本,但它也沒有 output 任何東西)
這是代碼:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
char opt;
while ((opt = getopt(argc, argv, "u")) != EOF) {
switch(opt) {
case 'u':
/* Make the output un-buffered */
setbuf(stdout, NULL);
break;
default:
break;
}
}
argc -= optind;
argv += optind;
int i = 0, fildes, fs = 0;
do {
/* Check for operands, if none or operand = "-". Read from stdin */
if (argc == 0 || !strcmp(argv[i], "-")) {
fildes = STDIN_FILENO;
} else {
fildes = open(argv[i], O_RDONLY);
}
/* Check for directories */
struct stat fb;
if (!fstat(fildes, &fb) && S_ISDIR(fb.st_mode)) {
fprintf(stderr, "cat: %s: Is a directory\n", argv[i]);
i++;
continue;
}
/* Get file size */
fs = fb.st_size;
/* If bytes are read, write them to stdout */
char buf[fs];
while ((read(fildes, buf, fs)) > 0)
write(STDOUT_FILENO, buf, fs);
/* Close file if it's not stdin */
if (fildes != STDIN_FILENO)
close(fildes);
i++;
} while (argv[i] != NULL || argc == 0);
return 0;
}
當您使用帶有-fsanitize=address
的 gcc 編譯代碼時,代碼顯示:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==604950==ERROR: AddressSanitizer: stack-overflow on address 0x7ffea6d94000 (pc 0x55b9a63dfb57 bp 0x7ffea6d90d20 sp 0x7ffea6d90b80 T0)
#0 0x55b9a63dfb57 in main /tmp/10/1.c:56
#1 0x7f1403c17b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
#2 0x55b9a63df3dd in _start (/tmp/.ccrun.604893.exefile+0x23dd)
SUMMARY: AddressSanitizer: stack-overflow /tmp/10/1.c:56 in main
==604950==ABORTING
片段:
do {
...
++i;
} while (argv[i] != NULL || argc == 0); // HERE!
argc
始終為0
,因此while(...)
始終在執行,而++i
始終在遞增。 argc[...]
被越界訪問,直到出現段錯誤。
我認為您應該將其更改為} while (argv[i];= NULL && argc != 0);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.