close(STDOUT_FILENO) haengt

Gast #3573681
Lesenswert?
• ▲
▼
Hallo,

mein Code kommt nicht ueber den Befehl
1
close(STDOUT_FILENO);
nicht hinaus.

Leider kann ich nur mit printf debuggen, und ich kann nicht in die 
close()
Funktion reinspringen.

Deshalb: hat jmd eine Vermutung woran das liegen koennte? Irgendwas, das 
mich evtl auf den richtigen Weg fuehrt?

Danke
Gast #3573692
Lesenswert?
• ▲
▼
Hängt er wirklich, oder siehst Du nur nichts mehr, weil Du stdout 
(worauf printf schreibt) geschlossen hast? Habe noch nie probiert, ob 
das geht, oder was dann passiert...

Leite die Ausgabe mal in eine Datei um.
Gast #3574085
Lesenswert?
• ▲
▼
Also, das Codestueck ist hier.
1
      info("SID: %i", sid);
2
    if (sid < 0) {
3
        error("setsid() failed: %s", strerror(errno));
4
        exit(EXIT_FAILURE);
5
    }
6
    if (chdir("/") < 0) {
7
          info("chdir failed");
8
        error("chdir() failed: %s", strerror(errno));
9
        exit(EXIT_FAILURE);
10
    }
11
      info("__1");
12
    close(STDIN_FILENO);
13
      info("__2");
14
    close(STDOUT_FILENO);
15
      info("__3");
16
      printf("__3.1");
17
    close(STDERR_FILENO);
18
    is_daemon = 1;
19
      info("__4");
20
    info("process was successfully daemonized: pid=%d sid=%d", pid, sid);
21
}
Konsolenausgabe:
1
c:235: Info: SID: -1
2
c:237: Error: setsid() failed: Operation not permitted
3
c:226: Info: PID: 0
4
zynq> 
5
zynq> c:235: Info: SID: 701
6
exit
7
c:245: Info: __1
8
c:247: Info: __2


Tja, ich bin mir nicht sicher, ob das Ding wirklich haengt, oder ob ich 
mit printf() an meine Grenzen stosse. Denn manchmal hoert die Ausgabe 
schon bei "Error: setsid() failed" auf; ist halt ein forked-Prozess.
Und die letze Zeile "info("process was successfully daemonized" stammt 
nicht von mir, sondern ist regulaerer Code einer geprueften 
Implementierung. Aber die letzte Zeile wird nie ausgegeben.

Vielleicht hat's was mit der BusyBox zu tun...
Gast #3574092
Lesenswert?
• ▲
▼
Ich weiß nicht, worauf du arbeitest, aber warum schließt du stdout 
überhaupt? Oder mache nur ich das nicht und es ist schlechter Stil, das 
offen zu lassen?

Ersetze sonst mal die printfs() durch fprintf() in eine Datei. ...Oder 
guck Dir mit strace/gdb an, was dort passiert.

Sieht so aus, als kommt nur nix mehr an. Denn wenn Du eine Tür schließt, 
kannst Du ja auch nicht mehr durchgehen...
Gast #3574209
Lesenswert?
• ▲
▼
olpo schrieb:
> Tja, ich bin mir nicht sicher, ob das Ding wirklich haengt, oder ob ich
> mit printf() an meine Grenzen stosse.

Was macht info()? Ist das nur ein printf? Dann wäre das doch genau das 
erwartete Verhalten. Wenn du stdout schließt, kannst du danach natürlich 
nichts mehr nach stdout schreiben, genau wie bei anderen Files. Was 
hättest du denn erwartet?
(Firma: Brainit GmbH) #3574772
Lesenswert?
• ▲
▼
Aus dem Codestück heraus vermute ich mal, du willst einen daemon 
erzeugen? vorher käme noch ein setsid(), und bitte ein doppeltes fork().

Wenn ja, dann bitte nicht stderr schließen.
1
    /* http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 */
2

3
    pid_t i;
4
    int fd;
5

6

7
    /* Step 1: fork() so that the parent can exit */
8
    i = fork();
9
    if (i < 0) {
10
  error("fork(#1) failed: %s", strerror(errno));
11
  exit(1);
12
    }
13
    if (i != 0)
14
  exit(0);
15

16
    /* Step 2: setsid() to become a process group and session group leader */
17
    setsid();
18

19
    /* Step 3: fork() again so the parent (the session group leader) can exit */
20
    i = fork();
21
    if (i < 0) {
22
  error("fork(#2) failed: %s", strerror(errno));
23
  exit(1);
24
    }
25
    if (i != 0)
26
  exit(0);
27

28
    /* Step 4: chdir("/") to ensure that our process doesn't keep any directory in use */
29
    if (chdir("/") != 0) {
30
  error("chdir(\"/\") failed: %s", strerror(errno));
31
  exit(1);
32
    }
33

34
    /* Step 5: umask(0) so that we have complete control over the permissions of anything we write */
35
    umask(0);
36

37
    /* Step 6: Establish new open descriptors for stdin, stdout and stderr */
38
    /* detach stdin */
39
    if (freopen("/dev/null", "r", stdin) == NULL) {
40
  error("freopen (/dev/null) failed: %s", strerror(errno));
41
  exit(1);
42
    }
43

44
    /* detach stdout and stderr */
45
    fd = open("/dev/null", O_WRONLY, 0666);
46
    if (fd == -1) {
47
  error("open (/dev/null) failed: %s", strerror(errno));
48
  exit(1);
49
    }
50
    fflush(stdout);
51
    dup2(fd, STDOUT_FILENO);
52
    fflush(stderr);
53
    dup2(fd, STDERR_FILENO);
54
    close(fd);

Nachtrag: Hab grad gesehen dass der link tot ist (den hab ich in 
lcd4linux vor gefühlten 100 Jahren verwendet). Zu finden aber u.a. hier: 
http://www.faqs.org/faqs/unix-faq/programmer/faq/
Gast #3575039
Lesenswert?
• ▲
▼
Rolf Magnus schrieb:
> Was macht info()? Ist das nur ein printf? Dann wäre das doch genau das
> erwartete Verhalten. Wenn du stdout schließt, kannst du danach natürlich
> nichts mehr nach stdout schreiben, genau wie bei anderen Files. Was
> hättest du denn erwartet?
Das ist irgendein Makro. Damit bin ich aber zum ersten Mal konfrontiert, 
ich kann das also noch nicht recht lesen.
1
#define info(fmt, ...) tpm_log(TPM_LOG_INFO, "%s:%d: Info: " fmt "\n", \
2
                                __BFILE__, __LINE__, ## __VA_ARGS__)

Michael Reinelt schrieb:
> Aus dem Codestück heraus vermute ich mal, du willst einen daemon
> erzeugen? vorher käme noch ein setsid(), und bitte ein doppeltes fork().
Hmm, nee der macht fork() nur einmal. Wie gesagt, das ist ein opensource 
Projekt, das ich auf ARM und BusyBox laufen lassen will. Ob der Code 
schoen ist, kann ich nicht beurteilen.
http://prdownload.berlios.de/tpm-emulator/tpm_emulator-0.7.4.tar.gz
Gast #3581164
Lesenswert?
• ▲
▼
Ich habe die betreffenden Zeilen jetzt einfach mal auskommentiert. Zwar 
kommt er jetzt bis info(__3), aber die letzte Zeile schafft er immer 
noch nicht. Debuggen mit printf hat wohl seine Grenzen...
1
    info("__1");
2
    close(STDIN_FILENO);
3
    info("__2");
4
 //   close(STDOUT_FILENO);
5
    info("__3");
6
    printf("__3.1");
7
 //   close(STDERR_FILENO);
8
    is_daemon = 1;
9
    info("__4");
10
    info("process was successfully daemonized: pid=%d sid=%d", pid, sid);
Gast #3588523
Lesenswert?
• ▲
▼
Das Problem war tatsächlich BusyBox.
Das kann kein fork(), sondern nur vfork().
Schlau wie BusyBox ist, wird fork() ohne Warnung(!) einfach mit vfork() 
ausgetauscht & ausgeführt. Und mit vfork() klappt Deamonising nicht.
(Firma: Brainit GmbH) #3588545
Lesenswert?
• ▲
▼
olpo schrieb:
> Das Problem war tatsächlich BusyBox.
> Das kann kein fork(), sondern nur vfork().
> Schlau wie BusyBox ist, wird fork() ohne Warnung(!) einfach mit vfork()
> ausgetauscht & ausgeführt. Und mit vfork() klappt Deamonising nicht.

Ähhh... BusyBox ist doch so eine Art "Micro-Shell" wo viele 
Shell-Kommandos von ein und demselben binary ausgeführt werden.

fork() liegt doch wenn in der libc?

oder hast du da eine "Micro-libc" drauf?

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.