Provided by: manpages-pl-dev_4.27.0-1_all 

NAZWA
copy_file_range - kopiuje zakres danych z jednego pliku do drugiego
BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)
SKŁADNIA
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
ssize_t copy_file_range(int fd_in, off_t *_Nullable off_in,
int fd_out, off_t *_Nullable off_out,
size_t len, unsigned int flags);
OPIS
Wywołanie systemowe copy_file_range() przeprowadza kopiowanie wewnątrz jądra pomiędzy dwoma deskryptorami
plików, bez dodatkowego kosztu transferu danych z jądro do przestrzeni użytkownika, a następnie z
powrotem do jądra. Kopiuje maksymalnie len bajtów danych ze źródłowego deskryptora pliku fd_in do
docelowego deskryptora pliku fd_out, nadpisując wszelkie dane, które istniały w żądanym zakresie pliku
docelowego.
off_in jest objęte następującą semantyką i podobne stwierdzenia odnoszą się do off_out:
• Jeśli off_in wynosi NULL, to bajty są odczytywane z fd_in począwszy od przesunięcia pliku, a
przesunięcie pliku jest dostosowywane o liczbę skopiowanych bajtów.
• Jeśli off_in nie wynosi NULL, to off_in musi wskazywać na bufor określający początkowe przesunięcie,
od którego zostaną odczytane bajty z fd_in. Przesunięcie pliku fd_in nie jest zmieniane, ale off_in
jest odpowiednio dostosowywane.
fd_in i fd_out mogą odnosić się do tego samego pliku. Jeśli odnoszą się do tego samego pliku, to zakres
źródłowy i docelowy nie mogą na siebie nachodzić.
Argument flags jest przeznaczony na przyszłe rozszerzenia i obecnie musi być ustawiony na 0.
WARTOŚĆ ZWRACANA
Po pomyślnym zakończeniu, copy_file_range() zwróci liczbę bajtów skopiowanych pomiędzy dwoma plikami.
Może być to długość mniejsza od pierwotnie żądanej. Jeśli przesunięcie pliku fd_in znajduje się na końcu,
lub za końcem, pliku, to nie są kopiowane żadne bajty, a copy_file_range() zwraca zero.
W razie wystąpienia błędu copy_file_range zwraca -1 i ustawia errno, wskazując błąd.
BŁĘDY
EBADF Jeden lub więcej deskryptorów plików nie jest prawidłowych.
EBADF fd_in nie jest otwarty do odczytu; albo fd_out nie jest otwarty do zapisu.
EBADF Znacznik O_APPEND jest ustawiony na opis otwartego pliku (ODF, zob. open(2)), do którego odnosi
się deskryptor pliku fd_out.
EFBIG Podjęto próbę zapisu w pozycji poza maksymalnym przesunięciem pliku obsługiwanym przez jądro.
EFBIG Podjęto próbę zapisu zakresu, który przekracza maksymalny dopuszczalny rozmiar pliku. Maksymalny
rozmiar pliku różni się pomiędzy implementacjami systemów plików i może być inny niż maksymalne
dopuszczalne przesunięcie pliku.
EFBIG Podjęto próbę zapisu poza limit zasobu procesu dotyczący rozmiaru pliku. Może to też spowodować
otrzymanie przez proces sygnału SIGXFSZ.
EINVAL Argument flags nie wynosi 0.
EINVAL fd_in i fd_out odnoszą się do tego samego pliku, a źródłowy i docelowy zakres nachodzą na siebie.
EINVAL fd_in albo fd_out nie jest zwykłym plikiem.
EIO Przy kopiowaniu wystąpił niskopoziomowy błąd wejścia/wyjścia.
EISDIR fd_in albo fd_out odnoszą się do katalogu.
ENOMEM Brak pamięci.
ENOSPC Na docelowym systemie plików nie ma wystarczająco dużo miejsca, aby ukończyć kopiowanie.
EOPNOTSUPP (od Linuksa 5.19)
System plików nie obsługuje tej operacji.
EOVERFLOW
Żądany zakres źródłowy lub docelowy jest zbyt duży, aby dało się go przedstawić w podanych typach
danych.
EPERM fd_out odnosi się do niezmiennego pliku (ang. immutable).
ETXTBSY
fd_in albo fd_out odnoszą się do aktywnego pliku wymiany.
EXDEV (przed Linuksem 5.3)
Pliki, do których odnoszą się fd_in i fd_out nie są położone w tym samym systemie plików.
EXDEV (od Linuksa 5.19)
Pliki, do których odnoszą się fd_in i fd_out nie są położone w tym samym systemie plików, a
źródłowy i docelowy system plików nie jest tego samego typu lub nie obsługuje kopii pomiędzy
systemami plików.
WERSJE
W Linuksie 5.3 doszło do znaczącej modyfikacji implementacji w jądrze. Jasno zdefiniowano miejsca w API,
którym wcześniej tego brakowało, a granice API są znacznie ściślej sprawdzane, niż we wcześniejszych
jądrach.
Od Linuksa 5.19, możliwe jest kopiowanie pomiędzy systemami plików, jeśli oba są tego samego typu i dany
system plików zaimplementował wsparcie tej operacji. W USTERKACH opisano zachowanie przed Linuksem 5.19.
Aplikacje powinny dostosować się do zachowania i wymogów Linuksa 5.19, które zostało również
przeportowane na wcześniejsze stabilne jądra.
STANDARDY
Linux, GNU.
HISTORIA
Linux 4.5, lecz glibc 2.27 dostarcza emulację w przestrzeni użytkownika tam, gdzie wywołanie nie jest
dostępne.
UWAGI
Jeśli fd_in jest rzadkim (ang. sparse) plikiem, to copy_file_range() może wykroczyć poza istniejące
dziury w żądanym zakresie. Użytkownicy mogą zechcieć wywoływać copy_file_range() w pętli, korzystając z
operacji SEEK_DATA i SEEK_HOLE wywołania lseek(2), aby odnaleźć położenie segmentów danych.
copy_file_range() daje systemom plików sposobność na implementację technik „przyspieszonego kopiowania”,
takich jak korzystanie z dowiązań lekkich (reflinków tj. dwóch lub więcej i-węzłów, które dzielą
wskaźniki do tych samych bloków dyskowych kopii przy zapisie) lub kopiowania po stronie serwera (w
przypadku NFS).
_FILE_OFFSET_BITS powinno być zdefiniowane jako 64 w kodzie, który używa wartości off_in lub off_out
innych niż null lub takim, który przyjmuje adres copy_file_range, jeśli kod ma być przenośny na
tradycyjne, 32-bitowe platformy x86 i ARM, w których szerokość off_t domyślnie wynosi 32 bity.
USTERKI
W Linuksie 5.3 do Linuksa 5.18, kopie pomiędzy systemami plików były zaimplementowane w jądrze, jeśli
operacja nie była obsługiwana przez poszczególne systemy plików. Jednak w niektórych wirtualnych
systemach plików, kopiowanie się nie powodziło, a mimo to wywołanie wciąż zgłaszało sukces.
PRZYKŁADY
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
int fd_in, fd_out;
off_t len, ret;
struct stat stat;
if (argc != 3) {
fprintf(stderr, "Użycie: %s <źródło> <cel>\n", argv[0]);
exit(EXIT_FAILURE);
}
fd_in = open(argv[1], O_RDONLY);
if (fd_in == -1) {
perror("open (argv[1])");
exit(EXIT_FAILURE);
}
if (fstat(fd_in, &stat) == -1) {
perror("fstat");
exit(EXIT_FAILURE);
}
len = stat.st_size;
fd_out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd_out == -1) {
perror("open (argv[2])");
exit(EXIT_FAILURE);
}
do {
ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0);
if (ret == -1) {
perror("copy_file_range");
exit(EXIT_FAILURE);
}
len -= ret;
} while (len > 0 && ret > 0);
close(fd_in);
close(fd_out);
exit(EXIT_SUCCESS);
}
ZOBACZ TAKŻE
lseek(2), sendfile(2), splice(2)
TŁUMACZENIE
Tłumaczenie niniejszej strony podręcznika: Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać
zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ
ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-
list@lists.sourceforge.net.
Linux man-pages 6.9.1 15 czerwca 2024 r. copy_file_range(2)