<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[pipe, fork, exec und dup&#x2F;dup2 (Programmieren einer Shell)]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe die Aufgabe, eine einfache Shell zu programmieren, welche aber auf jeden Fall das Suspendieren von Prozessen und damit eine einfache Jobverwaltung können muss.</p>
<p>Suspendiert man einen Prozess und stellt ihn dann in den Hintergrund, so sollte er natürlich seine Standardeingabe nicht mehr direkt vom Filedeskriptor 0 beziehen können. Um dies vom Elternprozess (also der Shell selbst) aus noch manipulieren zu können, ist es notwendig, dass Shell- und Kindprozess über eine Pipe kommunizieren und der Kindprozess seine Standardeingabe aus dieser Pipe bezieht.<br />
Wird der Kindprozess nun in den Hintergrund gestellt, so muss die Shell nur noch genau diese Kommunikationsverbindung vorrübergehend kappen.</p>
<p>Wie das Umleiten der Standardeingabe aus einer Pipe (für Kindprozess) funktioniert, ist mir klar und das macht auch keine Probleme.<br />
Ich habe allerdings noch nicht wirklich verstanden, wie ich denn auf der Elternseite (vor dem fork) die Pipe zu erzeugen und diverse Filedeskriptoren zu duplizieren habe.<br />
Ich habe schon sehr viel rumexperimentiert, bin aber zu keinem richtigen Ergebnis gekommen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/topic/146978/pipe-fork-exec-und-dup-dup2-programmieren-einer-shell</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Apr 2026 11:59:41 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/146978.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 12 May 2006 14:46:44 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to pipe, fork, exec und dup&#x2F;dup2 (Programmieren einer Shell) on Fri, 12 May 2006 14:46:44 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe die Aufgabe, eine einfache Shell zu programmieren, welche aber auf jeden Fall das Suspendieren von Prozessen und damit eine einfache Jobverwaltung können muss.</p>
<p>Suspendiert man einen Prozess und stellt ihn dann in den Hintergrund, so sollte er natürlich seine Standardeingabe nicht mehr direkt vom Filedeskriptor 0 beziehen können. Um dies vom Elternprozess (also der Shell selbst) aus noch manipulieren zu können, ist es notwendig, dass Shell- und Kindprozess über eine Pipe kommunizieren und der Kindprozess seine Standardeingabe aus dieser Pipe bezieht.<br />
Wird der Kindprozess nun in den Hintergrund gestellt, so muss die Shell nur noch genau diese Kommunikationsverbindung vorrübergehend kappen.</p>
<p>Wie das Umleiten der Standardeingabe aus einer Pipe (für Kindprozess) funktioniert, ist mir klar und das macht auch keine Probleme.<br />
Ich habe allerdings noch nicht wirklich verstanden, wie ich denn auf der Elternseite (vor dem fork) die Pipe zu erzeugen und diverse Filedeskriptoren zu duplizieren habe.<br />
Ich habe schon sehr viel rumexperimentiert, bin aber zu keinem richtigen Ergebnis gekommen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1056542</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1056542</guid><dc:creator><![CDATA[razlo]]></dc:creator><pubDate>Fri, 12 May 2006 14:46:44 GMT</pubDate></item><item><title><![CDATA[Reply to pipe, fork, exec und dup&#x2F;dup2 (Programmieren einer Shell) on Fri, 12 May 2006 15:12:19 GMT]]></title><description><![CDATA[<p>Im Grunde genommen einfach, wenn man es denn mal verstanden hat <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Angenommen wir betrachten erstmal nur eine Pipe, und zwar eine aus der der Elternprozess die Daten lesen kann die der Kindprozess auf stdout schreibt.</p>
<p>Zunächst wird die Pipe ja erzeugt, mittels pipe() auf einem zwei-elementigen Integer-Array. Danach ist Element 0 die Lese-Seite (Eselsbrücke: 0 ist immer die Nummer von stdin) und Element 1 die Schreib-Seite (1 ist auch immer die Nummer von stdout).</p>
<p>Danach wird geforked, wodurch der Prozess gespalten wird. Auf der Kindseite möchten wir jetzt dass der Prozess jede Ausgabe auf den Descriptor 1 in Wirklichkeit in unsere Pipe schreibt. Dafür dupen wir die Schreib-Seite der pipe nachdem wir stdout geschlossen haben (das Betriebssystem nimmt immer die niedrigste mögliche Dateinummer beim Öffnen). Die Lese-Seite der Pipe schliessen wir auch, da die ja vom Elternprozess benutzt werden soll.</p>
<p>Im Elternprozess schliessen wir nun noch die Schreib-Seite der Pipe, aus demselben Grund.</p>
<p>(Fast) Pseudocode:</p>
<pre><code class="language-cpp">int pipefd[2];

pipe(pipefd);

if (fork() == kind) {
  close(1); // stdout schliessen
  dup(pipefd[1]); // pipefd[1] doppeln, ergibt 1 (niedrigste freie Nummer)
  // Abkürzung für diese beiden Befehle:
  // dup2(1, pipefd[1]);

  close(pipefd[0]); // Lese-Seite wird hier nicht gebraucht
  exec(...);
  _exit(127);
}

// Elternprozess
close(pipefd[1]); // Schreib-Seite wird hier nicht gebraucht
read(pipefd[0], buffer, sizeof(buffer); // ...
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1056569</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1056569</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Fri, 12 May 2006 15:12:19 GMT</pubDate></item><item><title><![CDATA[Reply to pipe, fork, exec und dup&#x2F;dup2 (Programmieren einer Shell) on Fri, 12 May 2006 15:29:29 GMT]]></title><description><![CDATA[<p>Danke für die schnelle Antwort.<br />
Das Problem ist jedoch, dass der Kindprozess DIE Daten aus der Pipe holen können muss, welche der Elternprozess als Standardeingabe hat.</p>
<p>Wie gesagt, es muss dem Elterprozess möglich sein, seinem Kindprozess die Standardeingabe zu entziehen und zu einem späteren Zeitpunkt wiederherzustellen.</p>
<p>Das Kind darf also auf keinen Fall seine Standardeingabe von FD 0 beziehen, sondern muss hierfür einen anderen Filedeskriptor zugewiesen bekommen.<br />
Der Elternprozess jedoch ist dafür verantwortlich, dass auf diesem Filedeskriptor auch wirklich die Daten ankommen, die jemand auf der Tastatur tippt.</p>
<p>Es wäre also zusagen keine pipe &quot;aus der der Elternprozess die Daten lesen kann die der Kindprozess auf stdout schreibt&quot;.</p>
<p>Sondern eine pipe, aus der der Kindprozess die Daten lesen kann, die beim Elternprozess auf stdin ankommen.</p>
<p>Ich kann mir ja selbst nicht so richtig erklären wie das genau funktionieren soll, ohne dass der Elternprozess explizit die Daten von stdin liest und aktiv an das Kind weiterleitet.<br />
Aber es geht wohl wirklich irgendwie anders.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1056584</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1056584</guid><dc:creator><![CDATA[razlo]]></dc:creator><pubDate>Fri, 12 May 2006 15:29:29 GMT</pubDate></item><item><title><![CDATA[Reply to pipe, fork, exec und dup&#x2F;dup2 (Programmieren einer Shell) on Fri, 12 May 2006 15:37:12 GMT]]></title><description><![CDATA[<p>Fällt mir ehrlichgesagt ohne länger drüber nachzudenken auch nichts ein, aber folgendes hilft Dir vielleicht weiter:</p>
<p><a href="http://www.gnu.org/software/libc/manual/html_node/Implementing-a-Shell.html#Implementing-a-Shell" rel="nofollow">Implementing a Shell - The GNU C Library</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1056594</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1056594</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Fri, 12 May 2006 15:37:12 GMT</pubDate></item><item><title><![CDATA[Reply to pipe, fork, exec und dup&#x2F;dup2 (Programmieren einer Shell) on Fri, 12 May 2006 16:11:53 GMT]]></title><description><![CDATA[<p>Danke! Werd ich mir mal anschauen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1056621</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1056621</guid><dc:creator><![CDATA[razlo]]></dc:creator><pubDate>Fri, 12 May 2006 16:11:53 GMT</pubDate></item><item><title><![CDATA[Reply to pipe, fork, exec und dup&#x2F;dup2 (Programmieren einer Shell) on Fri, 12 May 2006 21:00:56 GMT]]></title><description><![CDATA[<p>In dieser Beschreibung wird die Funktion &quot;tcsetpgrp(...)&quot; benutzt, um eine Prozessgruppe in den Vordergrund zu holen. D.h. ihr stdin als Eingabe zuzuweisen.</p>
<blockquote>
<p>int tcsetpgrp(int fd, pid_t pgrp);</p>
<p>The function tcsetpgrp() makes the process group with process group ID pgrp the foreground process group on the terminal associated to fd, which<br />
must be the controlling terminal of the calling process, and still be associated with its session. Moreover, pgrp must be a (nonempty) process<br />
group belonging to the same session as the calling process.</p>
</blockquote>
<p>Das wäre zwar eventuell eine Möglichkeit, aber das muss man auch alles manuell über pipe und mittels dup lösen können.</p>
<p>Falls also noch jemand eine Idee haben sollte, dann immer her damit. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1056805</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1056805</guid><dc:creator><![CDATA[razlo]]></dc:creator><pubDate>Fri, 12 May 2006 21:00:56 GMT</pubDate></item></channel></rss>