Bei zwei Dateideskriptoren, einer für die Eingabe, einer für die Ausgabe, kopiert die folgende Funktion die Daten von der Eingabe in die Ausgabe einigermaßen zuverlässig.
#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;
}
könnte Ein nacktes minimales Testprogramm sein:
#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;
}
Diese korrekt kopieren Dateien von der Standardeingabe auf der Standardausgabe. Ich habe nicht definitiv einen 'kurzen Schreibvorgang' getestet. Es ist ein ziemlich seltenes Szenario, und der wahrscheinlichste Kontext ist, wenn der Ausgabedateideskriptor ein Socket ist. Das Testen der Fehlerpfade ist ebenfalls schwieriger. Ich habe das Programm cf89
aufgerufen. Ein Test war:
$ (trap '' 13; ./cf89 < /dev/zero) | (sleep 1)
copy_file failed: (32) Broken pipe
$
Die trap
ignoriert SIGPIPE (13), so dass die Schreibblöcke, weil nichts liest das Rohr. Wenn der sleep
beendet wird, erhält der Schreibprozess einen Fehler von write()
- weil das Signal ignoriert wird - und es generiert die Fehlermeldung.
Nebenbei, es gibt diejenigen, die aus Sicherheitsgründen gegen die Meldung der Fehlernummer und der Fehlermeldung sprechen - es erzählt dem Angreifer zu viel über das System, wenn es ihnen gelingt, einen Fehler auszulösen. Ich bin nicht in diesem Lager; Der Angreifer kennt den Systemtyp bereits, wenn er ein solches Programm angreift. Es könnte in anderen Kontexten, wie etwa einem Webserver, relevant sein.
'while (wahr == 0)' ist alle Arten von seltsamen – StoryTeller
IS gibt es während (wahr) in C ?. Ich muss meinen Code aufräumen. Ich werde es später tun. Angenommen, es ist nur eine Weile wahr und irgendwie muss ich den Loop im zweiten Fall durchbrechen. – daniel
Und Sie müssen Fall drei nicht "behandeln". Die Shell richtet den Stream für Sie korrekt ein. Das einfache Lesen von 'stdin' zieht den Inhalt von file1. – StoryTeller