Blame docs/faq/html/x496.html

Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>Why does this strange 'x io error' occur when I
Packit 98cdb6
fork() in my GTK+ app? [GTK 2.x]
Packit 98cdb6
>
Packit 98cdb6
NAME="GENERATOR"
Packit 98cdb6
CONTENT="Modular DocBook HTML Stylesheet Version 1.79">
Packit 98cdb6
REL="HOME"
Packit 98cdb6
TITLE="GTK+ FAQ"
Packit 98cdb6
HREF="book1.html">
Packit 98cdb6
REL="UP"
Packit 98cdb6
TITLE="Development with GTK+: general questions"
Packit 98cdb6
HREF="c466.html">
Packit 98cdb6
REL="PREVIOUS"
Packit 98cdb6
TITLE="What's an easy way to run a function in the thread with
Packit 98cdb6
the main loop? [GTK 2.x]"
Packit 98cdb6
HREF="x490.html">
Packit 98cdb6
REL="NEXT"
Packit 98cdb6
TITLE="Why don't the contents of a button move when the button
Packit 98cdb6
is pressed? Here's a patch to make it work that way... [GTK 2.x]"
Packit 98cdb6
HREF="x509.html">
Packit 98cdb6
>
Packit 98cdb6
CLASS="SECT1"
Packit 98cdb6
BGCOLOR="#FFFFFF"
Packit 98cdb6
TEXT="#000000"
Packit 98cdb6
LINK="#0000FF"
Packit 98cdb6
VLINK="#840084"
Packit 98cdb6
ALINK="#0000FF"
Packit 98cdb6
>
Packit 98cdb6
CLASS="NAVHEADER"
Packit 98cdb6
>
Packit 98cdb6
SUMMARY="Header navigation table"
Packit 98cdb6
WIDTH="100%"
Packit 98cdb6
BORDER="0"
Packit 98cdb6
CELLPADDING="0"
Packit 98cdb6
CELLSPACING="0"
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
COLSPAN="3"
Packit 98cdb6
ALIGN="center"
Packit 98cdb6
>GTK+ FAQ
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
WIDTH="10%"
Packit 98cdb6
ALIGN="left"
Packit 98cdb6
VALIGN="bottom"
Packit 98cdb6
>
Packit 98cdb6
HREF="x490.html"
Packit 98cdb6
ACCESSKEY="P"
Packit 98cdb6
><<< Previous
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
WIDTH="80%"
Packit 98cdb6
ALIGN="center"
Packit 98cdb6
VALIGN="bottom"
Packit 98cdb6
>Development with GTK+: general questions
Packit 98cdb6
>
Packit 98cdb6
WIDTH="10%"
Packit 98cdb6
ALIGN="right"
Packit 98cdb6
VALIGN="bottom"
Packit 98cdb6
>
Packit 98cdb6
HREF="x509.html"
Packit 98cdb6
ACCESSKEY="N"
Packit 98cdb6
>Next >>>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
ALIGN="LEFT"
Packit 98cdb6
WIDTH="100%">
Packit 98cdb6
>
Packit 98cdb6
CLASS="SECT1"
Packit 98cdb6
>
Packit 98cdb6
CLASS="SECT1"
Packit 98cdb6
>
Packit 98cdb6
NAME="AEN496"
Packit 98cdb6
>Why does this strange 'x io error' occur when I
Packit 98cdb6
Packit 98cdb6
CLASS="LITERAL"
Packit 98cdb6
>fork()
Packit 98cdb6
> in my GTK+ app? 
Packit 98cdb6
CLASS="EMPHASIS"
Packit 98cdb6
>[GTK 2.x]
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>This is not really a GTK+ problem, and the problem is
Packit 98cdb6
not related to 
Packit 98cdb6
CLASS="LITERAL"
Packit 98cdb6
>fork()
Packit 98cdb6
> either. If the 'x io
Packit 98cdb6
error' occurs then you probably use the 
Packit 98cdb6
CLASS="LITERAL"
Packit 98cdb6
>exit()
Packit 98cdb6
> function
Packit 98cdb6
in order to exit from the child process.
Packit 98cdb6
>
Packit 98cdb6
>When GDK opens an X display, it creates a socket file
Packit 98cdb6
descriptor. When you use the 
Packit 98cdb6
CLASS="LITERAL"
Packit 98cdb6
>exit()
Packit 98cdb6
>
Packit 98cdb6
function, you implicitly close all the open file descriptors,
Packit 98cdb6
and the underlying X library really doesn't like this.
Packit 98cdb6
>
Packit 98cdb6
>The right function to use here is
Packit 98cdb6
Packit 98cdb6
CLASS="LITERAL"
Packit 98cdb6
>_exit()
Packit 98cdb6
>.
Packit 98cdb6
>
Packit 98cdb6
>Erik Mouw contributed the following code example to
Packit 98cdb6
illustrate handling fork() and exit().
Packit 98cdb6
>
Packit 98cdb6
BORDER="0"
Packit 98cdb6
BGCOLOR="#E0E0E0"
Packit 98cdb6
WIDTH="100%"
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
CLASS="PROGRAMLISTING"
Packit 98cdb6
>/*-------------------------------------------------------------------------
Packit 98cdb6
 * Filename:      gtk-fork.c
Packit 98cdb6
 * Version:       0.99.2
Packit 98cdb6
 * Copyright:     Copyright (C) 1999, Erik Mouw
Packit 98cdb6
 * Author:        Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
Packit 98cdb6
 * Description:   GTK+ fork example
Packit 98cdb6
 * Created at:    Thu Sep 23 21:37:55 1999
Packit 98cdb6
 * Modified by:   Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
Packit 98cdb6
 * Modified at:   Thu Sep 23 22:39:39 1999
Packit 98cdb6
 * Modified by:   Tony Gale <gale@gtk.org>
Packit 98cdb6
 * Modified at:   Wed Jan 14 12:38:00 2004
Packit 98cdb6
 *-----------------------------------------------------------------------*/
Packit 98cdb6
/*
Packit 98cdb6
 * Compile with:
Packit 98cdb6
 *
Packit 98cdb6
 * cc -o gtk-fork gtk-fork.c `pkg-config gtk+-2.0 --cflags --libs`
Packit 98cdb6
 *
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include <stdio.h>
Packit 98cdb6
#include <stdlib.h>
Packit 98cdb6
#include <signal.h>
Packit 98cdb6
#include <sys/types.h>
Packit 98cdb6
#include <sys/wait.h>
Packit 98cdb6
#include <unistd.h>
Packit 98cdb6
#include <gtk/gtk.h>
Packit 98cdb6
Packit 98cdb6
void sigchld_handler(int num)
Packit 98cdb6
{
Packit 98cdb6
  sigset_t set, oldset;
Packit 98cdb6
  pid_t pid;
Packit 98cdb6
  int status, exitstatus;
Packit 98cdb6
Packit 98cdb6
  /* block other incoming SIGCHLD signals */
Packit 98cdb6
  sigemptyset(&set);
Packit 98cdb6
  sigaddset(&set, SIGCHLD);
Packit 98cdb6
  sigprocmask(SIG_BLOCK, &set, &oldset);
Packit 98cdb6
Packit 98cdb6
  /* wait for child */
Packit 98cdb6
  while((pid = waitpid((pid_t)-1, &status, WNOHANG)) > 0)
Packit 98cdb6
    {
Packit 98cdb6
      if(WIFEXITED(status))
Packit 98cdb6
	{
Packit 98cdb6
	  exitstatus = WEXITSTATUS(status);
Packit 98cdb6
Packit 98cdb6
	  fprintf(stderr, 
Packit 98cdb6
		  "Parent: child exited, pid = %d, exit status = %d\n", 
Packit 98cdb6
		  (int)pid, exitstatus);
Packit 98cdb6
	}
Packit 98cdb6
      else if(WIFSIGNALED(status))
Packit 98cdb6
	{
Packit 98cdb6
	  exitstatus = WTERMSIG(status);
Packit 98cdb6
Packit 98cdb6
	  fprintf(stderr,
Packit 98cdb6
		  "Parent: child terminated by signal %d, pid = %d\n",
Packit 98cdb6
		  exitstatus, (int)pid);
Packit 98cdb6
	}
Packit 98cdb6
      else if(WIFSTOPPED(status))
Packit 98cdb6
	{
Packit 98cdb6
	  exitstatus = WSTOPSIG(status);
Packit 98cdb6
Packit 98cdb6
	  fprintf(stderr,
Packit 98cdb6
		  "Parent: child stopped by signal %d, pid = %d\n",
Packit 98cdb6
		  exitstatus, (int)pid);
Packit 98cdb6
	}
Packit 98cdb6
      else
Packit 98cdb6
	{
Packit 98cdb6
	  fprintf(stderr,
Packit 98cdb6
		  "Parent: child exited magically, pid = %d\n",
Packit 98cdb6
		  (int)pid);
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* re-install the signal handler (some systems need this) */
Packit 98cdb6
  signal(SIGCHLD, sigchld_handler);
Packit 98cdb6
  
Packit 98cdb6
  /* and unblock it */
Packit 98cdb6
  sigemptyset(&set);
Packit 98cdb6
  sigaddset(&set, SIGCHLD);
Packit 98cdb6
  sigprocmask(SIG_UNBLOCK, &set, &oldset);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  return(FALSE);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void destroy(GtkWidget *widget, gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  gtk_main_quit();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void fork_me(GtkWidget *widget, gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  pid_t pid;
Packit 98cdb6
Packit 98cdb6
  pid = fork();
Packit 98cdb6
Packit 98cdb6
  if(pid == -1)
Packit 98cdb6
    {
Packit 98cdb6
      /* ouch, fork() failed */
Packit 98cdb6
      perror("fork");
Packit 98cdb6
      exit(-1);
Packit 98cdb6
    }
Packit 98cdb6
  else if(pid == 0)
Packit 98cdb6
    {
Packit 98cdb6
      /* child */
Packit 98cdb6
      fprintf(stderr, "Child: pid = %d\n", (int)getpid());
Packit 98cdb6
Packit 98cdb6
      execlp("ls", "ls", "-CF", "/", NULL);
Packit 98cdb6
      
Packit 98cdb6
      /* if exec() returns, there is something wrong */
Packit 98cdb6
      perror("execlp");
Packit 98cdb6
Packit 98cdb6
      /* exit child. note the use of _exit() instead of exit() */
Packit 98cdb6
      _exit(-1);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      /* parent */
Packit 98cdb6
      fprintf(stderr, "Parent: forked a child with pid = %d\n", (int)pid);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
int main(int argc, char *argv[])
Packit 98cdb6
{
Packit 98cdb6
  GtkWidget *window;
Packit 98cdb6
  GtkWidget *button;
Packit 98cdb6
Packit 98cdb6
  gtk_init(&argc, &argv);
Packit 98cdb6
Packit 98cdb6
  /* the basic stuff: make a window and set callbacks for destroy and
Packit 98cdb6
   * delete events 
Packit 98cdb6
   */
Packit 98cdb6
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
Packit 98cdb6
Packit 98cdb6
  g_signal_connect(G_OBJECT (window), "delete_event",
Packit 98cdb6
		     G_CALLBACK(delete_event), NULL);
Packit 98cdb6
          
Packit 98cdb6
  g_signal_connect(G_OBJECT (window), "destroy",
Packit 98cdb6
		     G_CALLBACK(destroy), NULL);
Packit 98cdb6
Packit 98cdb6
#if (GTK_MAJOR_VERSION == 1) && (GTK_MINOR_VERSION == 0)
Packit 98cdb6
  gtk_container_border_width(GTK_CONTAINER (window), 10);
Packit 98cdb6
#else  
Packit 98cdb6
  gtk_container_set_border_width(GTK_CONTAINER (window), 10);
Packit 98cdb6
#endif
Packit 98cdb6
Packit 98cdb6
  /* add a button to do something useful */
Packit 98cdb6
  button = gtk_button_new_with_label("Fork me!");
Packit 98cdb6
          
Packit 98cdb6
  g_signal_connect(G_OBJECT (button), "clicked",
Packit 98cdb6
		     G_CALLBACK(fork_me), NULL);
Packit 98cdb6
Packit 98cdb6
  gtk_container_add(GTK_CONTAINER(window), button);
Packit 98cdb6
          
Packit 98cdb6
  /* show everything */
Packit 98cdb6
  gtk_widget_show (button);
Packit 98cdb6
  gtk_widget_show (window);
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
  /* install a signal handler for SIGCHLD signals */
Packit 98cdb6
  signal(SIGCHLD, sigchld_handler);
Packit 98cdb6
Packit 98cdb6
  
Packit 98cdb6
  /* main loop */
Packit 98cdb6
  gtk_main ();
Packit 98cdb6
Packit 98cdb6
  exit(0);         
Packit 98cdb6
}
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
CLASS="NAVFOOTER"
Packit 98cdb6
>
Packit 98cdb6
ALIGN="LEFT"
Packit 98cdb6
WIDTH="100%">
Packit 98cdb6
SUMMARY="Footer navigation table"
Packit 98cdb6
WIDTH="100%"
Packit 98cdb6
BORDER="0"
Packit 98cdb6
CELLPADDING="0"
Packit 98cdb6
CELLSPACING="0"
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
WIDTH="33%"
Packit 98cdb6
ALIGN="left"
Packit 98cdb6
VALIGN="top"
Packit 98cdb6
>
Packit 98cdb6
HREF="x490.html"
Packit 98cdb6
ACCESSKEY="P"
Packit 98cdb6
><<< Previous
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
WIDTH="34%"
Packit 98cdb6
ALIGN="center"
Packit 98cdb6
VALIGN="top"
Packit 98cdb6
>
Packit 98cdb6
HREF="book1.html"
Packit 98cdb6
ACCESSKEY="H"
Packit 98cdb6
>Home
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
WIDTH="33%"
Packit 98cdb6
ALIGN="right"
Packit 98cdb6
VALIGN="top"
Packit 98cdb6
>
Packit 98cdb6
HREF="x509.html"
Packit 98cdb6
ACCESSKEY="N"
Packit 98cdb6
>Next >>>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
WIDTH="33%"
Packit 98cdb6
ALIGN="left"
Packit 98cdb6
VALIGN="top"
Packit 98cdb6
>What's an easy way to run a function in the thread with
Packit 98cdb6
the main loop? 
Packit 98cdb6
CLASS="EMPHASIS"
Packit 98cdb6
>[GTK 2.x]
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
WIDTH="34%"
Packit 98cdb6
ALIGN="center"
Packit 98cdb6
VALIGN="top"
Packit 98cdb6
>
Packit 98cdb6
HREF="c466.html"
Packit 98cdb6
ACCESSKEY="U"
Packit 98cdb6
>Up
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
WIDTH="33%"
Packit 98cdb6
ALIGN="right"
Packit 98cdb6
VALIGN="top"
Packit 98cdb6
>Why don't the contents of a button move when the button
Packit 98cdb6
is pressed? Here's a patch to make it work that way... 
Packit 98cdb6
CLASS="EMPHASIS"
Packit 98cdb6
>[GTK 2.x]
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>
Packit 98cdb6
>