next up previous
Next: Lucrul cu directoare Up: Operatii de intrare/iesire (I/O) Previous: lseek

dup/dup2

Operatiile dup/dup2 au ca rezultat crearea unui duplicat al unui descriptor de fisier, in asa fel incat vechiul descriptor sau noul descriptor pot fi folositi oricand si in orice ordine, avand cea mai mare parte din caracterisitici identice.

Sintaxa de apel este

#include <unistd.h>

int dup (int oldfd);
int dup2 (int oldfd, int newfd);

dup va folosi descriptorul de fisier cu indexul cel mai mic posibil pentru noul descriptor; dup2 va duplica descriptorul oldfd in descriptorul newfd; daca newfd era un descriptor pentru un fisier deschis, acesta va fi inchis. Ambele intorc noul descriptor creat (in cazul lui dup2 chiar newfd), in caz de succes, sau -1, in caz de eroare.

Pentru a duplica spre exemplu un fisier in intrarea standard (stdin), adica o citire de la stdin sa insemne o citire din fisier, putem folosi dup sau dup2, ca mai jos:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

...
        int fd;

        fd = open ("myfile.txt", O_RDONLY);
        if (fd < 0) {
                perror ("open");
                exit (EXIT_FAILURE);
        }

        /*
         * inchidem intrarea standard; aceasta are indexul 0 in tabela
         * de descriptori a procesului deci un apel dup va folosi acest
         * descriptor (este cel mai mic posibil)
         */
        close (STDIN_FILENO);

        /* duplicam descriptorul fd in intrarea standard */
        if (dup (fd) < 0) {
                perror ("dup");
                exit (EXIT_FAILURE);
        }

...

        /*
         * alternativ, putem folosi dup2 fara a mai inchide explicit
         * intrarea standard
         */
        if (dup2 (fd, 0) < 0) {
                perror ("dup2");
                exit (EXIT_FAILURE);
        }

...

Trebuie retinut faptul ca o operatie dup conserva cursorul de fisier. Astfel, orice schimbare efectuata asupra cursorului de fisier pentru descriptorul original va afecta in mod identic cel de-al doilea descriptor. Astfel, in cadrul urmatorului exemplu,

...

        int fd1, fd2, fd3;
        char buf1[5], buf2[5];

        fd1 = open ("myfile.txt", O_RDONLY);
        fd2 = dup (fd1);
        fd3 = dup (fd2);

        lseek (fd3, 1024, SEEK_SET);
        read (fd1, buf1, 4);
        read (fd2, buf2, 4);

...

se vor citi 4 caractere din fisierul myfile.txt incepand cu al 1024-lea caracter si, apoi, alte 4 caractere incepand cu cel de-al 1028-lea caracter.

Informatii complete despre operatiile I/E sincrone gasiti accesand pagina de manual info. Folositi comanda

$ info libc ``Low-Level I/O'' 
Alternativ puteti accesa pagina de web http://www.gnu.org/software/libc/manual/html_node si apoi sa accesati link-ul ``Low-Level I/O''.


next up previous
Next: Lucrul cu directoare Up: Operatii de intrare/iesire (I/O) Previous: lseek
Razvan Adrian Deaconescu 2005-10-01