Ich versuche read
zu verwenden, um von stdin
zu lesen und die gelesenen Bytes an stdout
zu senden und die Dateien, die als Argumente übergeben werden (die tee
Befehl imitieren). Allerdings, wenn ich ausführen:C lesen Funktion lesen mehr Bytes als angefordert
echo AAAAAAAAAA | ./tee -a file
ich
AAAAAAAAAA
Â7þhý6þhý¥g¢c¾
@ERROR: failed to write whole buffer (140726359686392 != 2880)
Sie können sehen, dass read
eine Zahl zurückgibt, die viel größer als die angeforderte Puffergröße ist. write
schreibt auch mehr als angefordert, aber während die von read
zurückgegebene Zahl mit jeder Ausführung variiert, gibt writes
immer 2880 zurück, unabhängig von der Größe der Eingabe. Hier
ist der Code:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 64
extern int optind;
void exit_err(char *format, ...)
{
va_list args;
fflush(stdout);
va_start(args, format);
fprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\n");
fflush(stderr);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
if (argc < 2 || strncmp(argv[1], "--help", 6) == 0)
exit_err("USAGE: %s [-a] [OUTPUTFILE]", argv[0]);
bool append = false;
char opt;
while ((opt = getopt(argc, argv, "a")) != -1) {
switch (opt)
{
case 'a':
append = true;
break;
default: /* ? */
exit_err("USAGE: %s [-a] [OUTPUTFILE]", argv[0]);
}
}
if (optind >= argc) {
exit_err("ERROR: expected argument after options");
exit(EXIT_FAILURE);
}
int open_flags = O_WRONLY | O_CREAT;
if (append)
open_flags |= O_APPEND;
else
open_flags |= O_TRUNC;
mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP;
int num_output_files = argc - optind + 1;
int output_fd[num_output_files];
output_fd[0] = STDOUT_FILENO;
int i;
for (i = 1; i < num_output_files; ++i, ++optind) {
output_fd[i] = open(argv[optind], open_flags, permissions);
if (output_fd[i] == -1)
exit_err("ERROR: failed to open %s", argv[optind]);
}
ssize_t num_read, num_written;
char buffer[BUFFER_SIZE];
while ((num_read = read(STDIN_FILENO, buffer, BUFFER_SIZE)) > 0)
for (i = 0; i < num_output_files; ++i)
if ((num_written = write(output_fd[i], buffer, BUFFER_SIZE)) != num_read)
exit_err("ERROR: failed to write whole buffer (%zd != %zd)", num_read, num_written);
if (num_read == -1)
exit_err("ERROR: failed to read from stdin");
for (i = 0; i < num_output_files; ++i)
if (close(output_fd[i]) == -1)
exit_err("ERROR: failed to close file");
exit(EXIT_SUCCESS);
}
Aaaaaaaaaaarg, wie könnte ich das nicht sehen ... –