Aus einem C++ - Programm, ist es möglich zu überprüfen, ob stderr in stdout umgeleitet wird oder umgekehrt? Grundsätzlich möchte ich wissen, ob diese beiden Dateideskriptoren auf den gleichen Ort zeigen. Plattformspezifische Lösungen, die native APIs verwenden, sind in Ordnung.Einchecken eines Programms, wenn stderr zu stdout umgeleitet wird
Antwort
Linux, möglicherweise auch andere Unix-Likes: fstat beide Fds und vergleichen dev: ino-Paare.
Das scheint gut für meine Bedürfnisse zu funktionieren, danke! Jetzt brauche ich nur eine Lösung für Windows ... – usta
für Windows 7 und höher Konsole Griffe - das ist echte Datei behandelt (auf XP ist dies nicht wahr, über Vista - nicht erinnern). Wir können diese 2 Handles durch Aufruf GetStdHandle mit STD_OUTPUT_HANDLE und STD_ERROR_HANDLE bekommen. aber dann muss man Dateien irgendwie mit handle vergleichen. Dieser ungleiche direkte Vergleich behandelt Werte - weil zwei verschiedene Handles auf dieselbe Datei zeigen können. selbst wenn wir einen Zeiger auf FILE_OBJECT von handle bekommen (dies ist möglich aus dem Benutzermodus) - zwei verschiedene FILE_OBJECTs können auf dieselbe Datei zeigen (wenn wir über Dateisystemdateien sprechen). so gut denke ich hier - habe Namen von beiden Dateien - und vergleichen - sind sie gleich. Dies kann durch ZwQueryObject erfolgen. Code kann wie dieser
NTSTATUS QueryName(HANDLE hFile, PUNICODE_STRING Name)
{
union {
PVOID buf;
POBJECT_NAME_INFORMATION poni;
};
static volatile UCHAR guz;
PVOID stack = alloca(guz);
ULONG cb = 0, rcb = 512;
NTSTATUS status;
do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
if (0 <= (status = ZwQueryObject(hFile, ObjectNameInformation, buf, cb, &rcb)))
{
return RtlDuplicateUnicodeString(0, &poni->Name, Name);
}
} while (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_BUFFER_OVERFLOW);
return status;
}
NTSTATUS AreFilesTheSame(HANDLE h1, HANDLE h2, PBOOL pb)
{
if (h1 == h2)
{
*pb = TRUE;
return STATUS_SUCCESS;
}
if (!h1 || !h2)
{
*pb = FALSE;
return STATUS_SUCCESS;
}
UNICODE_STRING name1, name2;
NTSTATUS status;
if (0 <= (status = QueryName(h1, &name1)))
{
if (0 <= (status = QueryName(h2, &name2)))
{
*pb = RtlEqualUnicodeString(&name1, &name2, TRUE);
RtlFreeUnicodeString(&name2);
}
RtlFreeUnicodeString(&name1);
}
return status;
}
BOOL b;
AreFilesTheSame(GetStdHandle(STD_OUTPUT_HANDLE), GetStdHandle(STD_ERROR_HANDLE), &b);
sein, aber für xp wird dies nicht GetFinalPathNameByHandle
Danke! Ich habe diesen Code unter Windows 7 kompiliert und verlinkt, aber leider funktioniert es nicht wie gewünscht. Selbst wenn das Programm mit "2> & 1" gestartet wird, sind die Namen unterschiedlich, z. '\ REGISTRY \ MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ AktuelleVersion \ Image File Execut' ... für stdout vs.' \ KnownDlls' ... für stderr. Funktioniert dieser Code wie gewünscht für Sie? – usta
Auch wenn ein gegebenes Handle eine Pipe ist, d.h. wenn die Ausgabe des Programms in die Eingabe eines anderen Programms umgeleitet wird, schlägt 'NtQueryObject()' mit 'STATUS_OBJECT_PATH_INVALID' (0xc0000039) fehl. – usta
@usta - natürlich funktioniert dieser Code. und NtQueryObject kann nicht STATUS_OBJECT_PATH_INVALID – RbMm
- 1. Warum wird STDERR auf STDOUT umgeleitet
- 2. Dupliziere stdout zu stderr
- 3. stderr Umleitung zu stdout
- 4. über stdout/stderr Umleitungen
- 5. Bash speichern/redirect stdout und stderr wenn Programm getötet wird
- 6. Speichern Sie stdout, stderr und stdout + stderr synchron
- 7. Log stdout & stderr, wenn Programm in Bildschirm gestartet wird
- 8. Capturing STDOUT und STDERR eines externen Programms * während * es ist die Ausführung (Rubin)
- 9. LLVM stdin/stdout/stderr
- 10. ABAP Stdout und Stderr
- 11. paramiko kombinieren stdout und stderr
- 12. Keine in umgeleitet stdout
- 13. vim filter und stdout/stderr
- 14. umleiten stderr zu stdout in c-shell
- 15. Redirect STDOUT und STDERR zu Datei "> &"
- 16. Redirect stdout und stderr zu Funktion
- 17. Apache Spark Stderr und Stdout
- 18. redirect stdout/stderr in C
- 19. Capturing stderr, aber nicht stdout
- 20. Piping popen stderr und stdout
- 21. tcl exec zu stdout Bedarf umgeleitet Ergebnis zu zu speichernden
- 22. Wie erfasse ich Aufforderungen in stdout/stderr?
- 23. Wie Umleitung Child-Prozess stdout/stderr auf den Hauptprozess stdout/stderr in Java?
- 24. Fledermaus Redirecting stderr zu stdout hat seltsames Verhalten
- 25. Wie "stdout" auf ein Label-Widget umgeleitet wird?
- 26. Wie stdout/stderr mit googletest erfassen?
- 27. Warum wird wget in stderr anstatt stdout ausgegeben?
- 28. Capture stderr von Python Subprozess.Popen (Befehl, stderr = subprocess.PIPE, stdout = subprocess.PIPE)
- 29. Bestimmen, ob stdout für einen Python-Prozess umgeleitet wird
- 30. Unterdrücken stdout/stderr Drucken von Python-Funktionen
Versuchen Sie werden arbeiten. Ich bin mir nicht sicher, ob es für Rohre funktioniert oder nicht, aber es ist einen Versuch wert. –
@HarryJohnston Versuchte 'GetFinalPathNameByHandle' auf Windows 7, und leider funktionierte es nicht für' GetStdHandle (STD_OUTPUT_HANDLE) '. Es ist fehlgeschlagen, wobei 'GetLastError() '' ERROR_INVALID_HANDLE' zurückgegeben hat. – usta