![Wohin gehen die Daten, die in einen Dateideskriptor geschrieben wurden, der nie geöffnet wurde?](https://rvso.com/image/89176/Wohin%20gehen%20die%20Daten%2C%20die%20in%20einen%20Dateideskriptor%20geschrieben%20wurden%2C%20der%20nie%20ge%C3%B6ffnet%20wurde%3F.png)
Ich habe die Ausgabe mit folgendem Befehl erfasst:
$ strace -f -e trace=process,socketpair,open,close,dup,dup2,read,write -o rsync.log rsync -avcz --progress src/ dst/
es ist ein bisschen lang, deshalb habe ich es hochgeladenHier. Jetzt möchte ich diese Datei analysieren.
Die folgende Ausgabe zeigt die per clone
Systemaufruf erzeugten Prozesse/Threads:
# SPAWNED PROCESSES/THREADS
$ grep 'clone(' rsync.log | awk '{print $1 " -> " $NF}'
1399 -> 1400
1400 -> 1401
Die folgende Ausgabe zeigt, dass die Daten meistens write
im Dateideskriptor mit der Nummer n enthalten waren 4
:
# PID, FD, NO OF CALLING WRITE SYSCALL
$ cat <(grep 'write(' rsync.log | egrep -v 'unfinished|resumed') <(paste <(grep write rsync.log | grep unfinished) <(grep write rsync.log | grep resumed)) | cut -d',' -f1 | sed 's%write(%%' | awk '{a[$0]++}END{print "PID FD COUNT"; for(i in a){print i " " a[i]}}'
PID FD COUNT
1399 4 1622
1400 1 7
1401 3 307
1401 4 7
1399 1 15
Die folgende Ausgabe zeigt, dass der 4
Deskriptor nie per Systemaufruf geöffnet wurde open
(1 ist STDOUT, daher gehe ich davon aus, dass dieser FD nicht geöffnet werden muss):
# LIST OF FILE DESCRIPTORS THAT WAS OPEN
$ grep 'open(' rsync.log | awk 'BEGIN {FS=" = "} {print $NF}' | grep '^[0-9]\+$' | sort | uniq
0
3
6
Zwei Fragen:
I. Wenn 4
der Deskriptor nicht open
angegeben wurde, wohin gehen diese Daten und wie ist es möglich, dass das rsync
wie erwartet funktioniert hat?:
$ grep 'write(4' rsync.log | head
1399 write(4, "\37\0\0\0", 4 <unfinished ...>
1399 write(4, "I\0\0\7\5(\1.\0\0\0W}%i\360\220\261\177\21\370A\0\0\0\203\347\6vbox"..., 77 <unfinished ...>
1401 write(4, "\4\0\0\7\376\377\377\377", 8) = 8
1399 write(4, "\177\301\0\7\3\n\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\177\377\354\226C\214.\0\260"..., 49539) = 49539
1399 write(4, "\2\301\0\7\177\377a\353\35\2433\1\332m\301\330\266\315\216\3557\352\330\266m\333\366\33\333\266;v"..., 49414) = 49414
1399 write(4, "\21\302\0\7\177\377\236mTNG\356\304\376u\237\214\275\310\300*\317\264\221W\372\340\307\36\345%\330"..., 49685 <unfinished ...>
1399 write(4, "\360\300\0\7\177\377\27W\357\24$\f\23,\v\216\355\371\306\266m\333\266m\333\266m\333\266m\333\266"..., 49396 <unfinished ...>
1399 write(4, "\223\301\0\7\177\377D\214# D\304\2\25xA\fY\310U\201Q*e\25\235\20\213\v\320~\331"..., 49559 <unfinished ...>
1399 write(4, "\370\300\0\7\177\377l\275cs.\0\27$\30\334\330\266}c\333\266m\333\266\235<\261m\333\266m"..., 49404 <unfinished ...>
1399 write(4, "\20\301\0\7\177\377\25\255\252Q\223\340\244w3\247\252\322Z\235\310\2424g\330\274\354\3150\237B\26"..., 49428) = 49428
II. Kann ich irgendwie auch Daten (entsprechende Zeilen) abrufen, die zwischen Prozessen übertragen wurden, zB: von 1399
nach 1400
oder von 1399
nach 1401
usw. (falls es welche gibt)?
Danke
Antwort1
Daten, die in einen Dateideskriptor geschrieben werden, der nie geöffnet wurde, gehen nirgendwohin. Der write
Systemaufruf schlägt mit EBADF
(ungültiger Dateideskriptor) fehl.
Abermeeh bemerkteopen
ist nicht die einzige Möglichkeit, eine Datei zu öffnen. Es gibt auch die Möglichkeit, ein pipe
Paar Pipe-Enden zu erstellen, socketpair
ein Paar Sockets zu erstellen, die miteinander kommunizieren, socket
und accept
Sockets zu erstellen, die mit einer Remote-Adresse kommunizieren usw. (Ganz zu schweigen von Dateitypen, auf die Sie nicht zugreifen können write
, wie z. B. Verzeichnisse, Inotify-Ereigniswarteschlangen usw.)