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

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)