dup(2) System Calls Manual dup(2) NAZWA dup, dup2, dup3 - duplikuje deskryptor pliku BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include int dup(int oldfd); int dup2(int oldfd, int newfd); #define _GNU_SOURCE /* Zob. feature_test_macros(7) */ #include /* Definicja stalych O_* */ #include int dup3(int oldfd, int newfd, int flags); OPIS Wywolanie systemowe dup() przydziela nowy deskryptor pliku odnoszacy sie do tego samego opisu otwartego pliku (OFD), jak deskryptor oldfd (wyjasnienie opisow otwartych plikow znajduje sie w podreczniku open(2)). Gwarantuje sie, ze nowy numer deskryptora pliku bedzie najnizszym numerem deskryptora pliku, ktory nie byl uzywany w trakcie procesu wywolywania. Po pomyslnym zakonczeniu, stary i nowy deskryptor moga byc uzywane zamiennie. Oba deskryptory odnosza sie do tego samego opisu otwartego pliku, zatem wspoldziela one przesuniecie pliku i znaczniki statusu pliku np. jesli przesuniecie pliku zmieni sie w wyniku uzyciu lseek(2) na jednym z deskryptorow pliku, zmieni sie ono takze dla drugiego deskryptora pliku. Oba deskryptory nie dziela znacznikow deskryptora pliku (znacznika zamknij-przy-wykonaniu). Znacznik zamknij-przy-wykonaniu (FD_CLOEXEC; zob. fcntl(2)) dla duplikatu deskryptora jest wylaczony. dup2() Wywolanie systemowe dup2() wykonuje takie samo zadanie jak dup(), lecz zamiast uzywac najnizszego numeru nieuzywanego deskryptora pliku, uzywa numeru deskryptora pliku podanego w newfd. Innymi slowy, deskryptor pliku newfd jest dostosowywany tak, aby wskazywal teraz na ten sam opis otwartego pliku (ODF) jak oldfd. Jesli deskryptor pliku newfd byl uprzednio otwarty, jest zamykany przed ponownym uzyciem; zamkniecie jest przeprowadzane po cichu (tj. ewentualne bledy przy zamknieciu nie sa zglaszane przez dup2()). Kroki zamykania i ponownego uzycia deskryptora pliku newfd sa wykonywane niepodzielnie. Jest to istotne, poniewaz proba zaimplementowania rownowaznej funkcjonalnosci za pomoca close(2) i dup() prowadzilaby do hazardu, gdzie newfd moglby byc uzyty ponownie pomiedzy oboma krokami. Mogloby sie tak zdarzyc, gdyby glowny program zostal przerwany procedura obslugi sygnalu przydzielajacego deskryptor plikow lub gdyby rownolegle watki przydzielaly deskryptor plikow. Prosze zauwazyc, co nastepuje: o Jesli oldfd nie jest prawidlowym deskryptorem pliku, to wywolanie zawiedzie, a newfd nie jest zamykane. o Jesli oldfd jest prawidlowym deskryptorem pliku, a newfd ma te sama wartosc co oldfd, to dup2() niczego nie dokona i zwroci newfd. dup3() dup3() dziala jak dup2(), tyle ze: o Wywolujacy moze wymusic, aby znacznik zamkniecia-przy-wykonaniu byl ustawiony dla nowego deskryptora pliku podajac O_CLOEXEC w flags. Prosze zapoznac sie z opisem tego samego znacznika w open(2), aby przekonac sie, dlaczego moze byc to uzyteczne. o Jesli oldfd rowna sie newfd, to dup3() zawodzi z bledem EINVAL. WARTOSC ZWRACANA W przypadku powodzenia, te wywolania zwracaja nowy deskryptor pliku. W razie wystapienia bledu zwracane jest -1 i ustawiane jest errno wskazujac blad. BLEDY EBADF oldfd nie jest otwartym deskryptorem pliku. EBADF newfd jest poza dozwolonym przedzialem dla deskryptorow pliku (zob. opis RLIMIT_NOFILE w getrlimit(2)). EBUSY (tylko Linux) Blad moze byc zwrocony przez dup2() lub dup3() w razie wystapienia wyscigu z open(2) i dup(). EINTR Wywolanie dup2() lub dup3() przerwano sygnalem; zob. signal(7). EINVAL (dup3()) flags zawiera nieprawidlowa wartosc. EINVAL (dup3()) oldfd bylo rowne newfd. EMFILE Zostalo osiagniete ograniczenie na liczbe otwartych deskryptorow plikow dla procesu (zob. opis RLIMIT_NOFILE w getrlimit(2)). STANDARDY dup() dup2() POSIX.1-2008. dup3() Linux. HISTORIA dup() dup2() POSIX.1-2001, SVr4, 4.3BSD. dup3() Linux 2.6.27, glibc 2.9. UWAGI Blad zwracany przez dup2() jest inny niz zwracany przez fcntl(..., F_DUPFD, ...) gdy newfd jest poza zakresem. W niektorych systemach dup2() zwraca tez czasem EINVAL jako F_DUPFD. Jesli newfd byl otwarty, wszelkie bledy, ktore moglyby zostac zgloszone w chwili wykonania close(2) zostana utracone. Jesli jest to istotne, to - o ile program jest jednowatkowy i nie przydziela deskryptorow pliku w procedurach obslugi sygnalu - prawidlowym podejsciem jest nie zamykanie newfd przez wywolanie dup2(), ze wzgledu na sytuacje hazardu opisana powyzej. Zamiast tego, mozna uzyc kodu podobnego do ponizszego: /* Pozyskanie duplikatu 'newfd', ktorego mozna nastepnie uzyc do sprawdzenia bledow close(); blad EBADF oznacza, ze 'newfd' nie byl otwarty. */ tmpfd = dup(newfd); if (tmpfd == -1 && errno != EBADF) { /* Obsluga nieoczekiwanego bledu dup(). */ } /* Niepodzielne zduplikowanie 'oldfd' w 'newfd'. */ if (dup2(oldfd, newfd) == -1) { /* Obsluga bledu dup2(). */ } /* Teraz sprawdzenie bledow close() pliku, do ktorego 'newfd' odnosil sie pierwotnie. */ if (tmpfd != -1) { if (close(tmpfd) == -1) { /* Obsluga bledow z close. */ } } ZOBACZ TAKZE close(2), fcntl(2), open(2), pidfd_getfd(2) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: Przemek Borys , Andrzej Krzysztofowicz i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.06 31 pazdziernika 2023 r. dup(2)