Może ktoś wyjaśnić co robi dup () w C?
Wiem, że dup, dup2, dup3 "tworzy kopię deskryptora pliku oldfd "(ze stron podręcznika). Jednak nie mogę go przetrawić.
Jak wiem deskryptory plików są po prostu liczbami , aby śledzić lokalizacje plików i ich kierunek(wejście/wyjście). Wouldn ' t it be easier to just
fd=fd2;
Kiedy chcemy powielić deskryptor pliku?
I coś jeszcze..dup () używa najniższego nieużywanego deskryptora dla nowego deskryptor.
Czy to oznacza, że może również przyjmować wartość stdin, stdout lub stderr jeśli założymy, że mamy close () -ed jeden z nich?
7 answers
Chciałem odpowiedzieć sobie na drugie pytanie po odrobinie eksperymentów.
Odpowiedź brzmi Tak . Utworzony deskryptor pliku może przyjmować wartość 0, 1, 2, jeśli stdin, stdout lub stderr są zamknięte.
Przykład:
close(1); //closing stdout
newfd=dup(1); //newfd takes value of least available fd number
Gdzie to się dzieje z deskryptorami plików:
0 stdin .--------------. 0 stdin .--------------. 0 stdin
1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd
2 stderr '--------------' '--------------' 2 stderr
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-13 20:42:26
Deskryptor pliku to coś więcej niż liczba. Niesie ze sobą również różne częściowo ukryte Stany (niezależnie od tego, czy jest otwarty, czy nie, do którego opisu Pliku się odnosi, a także niektóre flagi). dup
powiela te informacje, dzięki czemu można np. zamknąć oba deskryptory niezależnie. Nie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-22 18:54:37
Najważniejszą rzeczą w dup () jest to, że Zwraca najmniejszą liczbę całkowitą dostępną dla nowego deskryptora pliku. To podstawa przekierowania:
int fd_redirect_to = open("file", O_CREAT);
close(1); /* stdout */
int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */
close(fd_redirect_to); /* we don't need this */
Po tym wszystko, co jest zapisane do deskryptora pliku 1 (stdout), magicznie przechodzi do "file".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-03 08:04:31
Załóżmy, że piszesz program powłoki i chcesz przekierować stdin i stdout w programie, który chcesz uruchomić. Może to wyglądać mniej więcej tak:
fdin = open(infile, O_RDONLY);
fdout = open(outfile, O_WRONLY);
// Check for errors, send messages to stdout.
...
int pid = fork(0);
if(pid == 0) {
close(0);
dup(fdin);
close(fdin);
close(1);
dup(fdout);
close(fdout);
execvp(program, argv);
}
// Parent process cleans up, maybe waits for child.
...
Dup2() jest nieco wygodniejszym sposobem, aby to zrobić close() dup () można zastąpić przez:
dup2(fdin, 0);
dup2(fdout, 1);
Powodem, dla którego chcesz to zrobić, jest to, że chcesz zgłaszać błędy na stdout (lub stderr), więc nie możesz po prostu ich zamknąć i otworzyć nowego pliku w procesie potomnym. Po drugie, byłoby marnotrawstwem zrobić widelec, jeśli albo wywołanie open() zwróciło błąd.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-22 18:51:26
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-22 18:19:19
Wystarczy wskazówka o " powielaniu standardowego wyjścia ".
Na niektórych systemach uniksowych (ale nie GNU/Linux)
fd = open("/dev/fd/1", O_WRONLY);
Jest równoważne:
fd = dup(1);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-03 17:52:12
Przykład:
close(1); //closing stdout newfd=dup(1); //newfd takes value of least available fd number
Gdzie to się dzieje z deskryptorami plików:
0 stdin .--------------. 0 stdin .--------------. 0 stdin 1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd 2 stderr '--------------' '--------------' 2 stderr
Znowu pojawiło się pytanie: Jak mogę
dup()
deskryptor pliku, który już zamknąłem?
Wątpię, czy przeprowadziłeś powyższy eksperyment z pokazanym wynikiem, ponieważ nie byłoby to zgodne ze standardem-por. dup :
Funkcja dup () zawodzi, jeśli:
[EBADF] Argument fildes nie jest poprawnym otwartym plikiem deskryptor.
Więc po pokazanej sekwencji kodu newfd
musi być nie 1
, ale raczej -1
, a errno
EBADF
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-28 09:10:55