[so] descriptori deschsi

Stefan Bucur stefan.bucur at gmail.com
Sat Nov 3 00:02:52 EET 2007


On Nov 2, 2007 11:22 PM, Catalin Iacob <iacobcatalin at gmail.com> wrote:
> > On Friday 02 November 2007 22:28:53 Stefan Bucur wrote:
> >
> > Hm... mi se paruse ca era corect. Adica dupa ce apelezi dup2, "1" si
> > "a" vor puncta catre aceeasi resursa (fisier) - daca "1" este inchis,
> > "a" va tine in continuare acel fisier deschis (si viceversa).
>
> Corect nu se poate sa fi fost fiindca daca il inchizi pe a inainte sa faci
> exec programul executat va avea stdout inchis si deci nu va putea sa scrie in
> el. De asta am revenit cu reply-ul.

Deci daca am 2 descriptori catre acelasi fisier deschis, si il inchid
pe unul dintre ei, nici celalalt nu mai poate fi utilizat? Chestia
asta nu prea se potriveste cu ce stiam eu. Am facut un program care sa
testeze lucrul acesta, si vad ca totusi un descriptor inchis nu il
invalideaza si pe celalalt:


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

#define FILE_NAME       "test.txt"

int main() {
        int origfd;
        int newfd;

        char buff[] = "Testing message\n";
        int bufflen = strlen(buff);

        origfd = creat(FILE_NAME, 0644);

        if (origfd < 0) {
                fprintf(stderr, "Could not open file\n");
                return 1;
        }

        if (write(origfd, buff, bufflen) < 0) {
                fprintf(stderr, "Could not write on original\n");
                close(origfd);
                return 1;
        }

        newfd = 123;

        if (dup2(origfd, newfd) < 0) {
                fprintf(stderr, "Could not duplicate\n");
                close(origfd);
                return 1;
        }

        close(origfd);

        if (write(newfd, buff, bufflen) < 0) {
                fprintf(stderr, "Could not write on duplicate\n");
                close(newfd);
                return 1;
        }


        close(newfd);
        return 0;
}

In fisierul test.txt vor aparea ambele mesaje de test, unul scris pe
descriptorul original, celalalt scris pe cel nou, dupa ce primul a
fost inchis.



>
> > Atata vreme cat "a" nu este close on exec, el va ramane deschis dupa exec(),
> > deci chit ca uitam noi sa-l inchidem daca nu faceam exec(), chit ca
> > nu-l inchide noul program incarcat de exec(), e acelasi lucru:
> > sistemul de operare va inchide descriptorul acesta pentru noi la
> > sfarsit. Iar daca este permis sa lasam descriptori deschisi inainte de
> > exec(), de ce am 'pacatui' mai mult daca am uita descriptori deschisi
> > si in programul nostru, pe care i-ar inchide oricum sistemul?
>
> Solutia cea mai corecta ca sa zic asa e sa se seteze intr-adevar close on exec
> pe a fiindca nu-l putem inchide de mana inainte (programul executat l-ar
> primi inchis), nu-l putem inchide dupa fiindca daca exec reuseste nu mai
> putem face chestii dupa exec. Asa, cu close on exec ni-l inchide sistemul la
> exec.
>
> Chestia cu close on exec nu e cea mai importanta din tema dar in general e
> bine sa cureti resursele chiar daca le va curata sistemul de operare. Daca
> zici ca nu e nevoie e ca si cum ai zice "eu nu fac free pe memoria alocata
> dinamic fiindca oricum cand programul se termina elibereaza memoria, de ce sa
> mai fac free de mana ca se pierde timp cu el". Ori nu-i asa; foarte multe
> programe trebuie sa ruleze mai mult timp (poate ani) si leak-urile se
> acumuleaza devenind inacceptabile.

Total de acord :) Nu doresc sa contest aceste practici bune, ci doar
mi s-a parut un subiect interesant de abordat, mai ales in contextul
in care unele chestii mi se pare ca se contrazic (see the example
above)

Stefan Bucur


More information about the so mailing list