Re: Forking from Gtk - Problem solved!

2008-07-09 Thread G Hasse


On Tue, Jul 08, 2008 at 08:59:45PM -0400, James Scott Jr wrote:
 
 On Tue, 2008-07-08 at 23:23 +0200, G Hasse wrote:
  On Tue, Jul 08, 2008 at 01:52:00PM -0400, James Scott Jr wrote:
   G,
   
   I've seen most of the other responses, and better understand what you
   are trying to do.  And like others -- fork() is not recommended. 

Now I can recommend it! (If it fits your need).
 
  I can't belive this... Certanly a forground process must be able to
  start a process that completly detatch from the parent. Gtk or not
  it could not matter. If I fork a Gtk program I migt have a lot of
  GtkWidget pointers that are of no use - but if I bother I should be
  able to free those. The gtk_main loop runs around to find out if
  signals have been emitted. So if I exit this loop no sutch activity
  should be going on.

Yes - and it was a simple solution... The solution was:
Set a flag in the signal mask that we don't want to wait
for children and (make a dummy signal handler...)

//--
// Just to ignore the signal
//--
void MySigIgnore(int dummy)
{
   printf(I don't want to be zombie...\n);
}

//--
// Main
//--
main()
{



  struct sigaction act;

  act.sa_handler = MySigIgnore;
  sigemptyset(act.sa_mask); /* non-standard */
  act.sa_flags = SA_NOCLDWAIT;
  
  sigaction(SIGCHLD, act, NULL);

}

So now my program works as I want it to. And there is no
problem to fork from a foreground process, let the
child do its job and then die in peace.

Tanks all for your help!

-- 
Göran Hasse


Göran Hasse   email: [EMAIL PROTECTED]  Tel: 019-450105
Raditex AB http://www.raditex.se
Planiavägen 15, 1tr Mob: 070-5530148
131 34  NACKA, SWEDEN OrgNr: 556240-0589
VAT: SE556240058901
--

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Forking from Gtk

2008-07-08 Thread Gabriele Greco
On Mon, Jul 7, 2008 at 11:03 PM, G Hasse [EMAIL PROTECTED] wrote:

 Hello,

 I have a small demo app. This works on FreeBSD but I can't
 get to work on Linux. I know that in Linux setsid will fail
 if the child has the same session_id as the parent. So on
 Linux you must fork twice. But it also seems that the parent
 must do an exit. And I don't want that. The code is not very
 long - so I include it here.



I think you should avoid fork and use one of the functions glib provide to
spawn processes (
http://library.gnome.org/devel/glib/stable/glib-Spawning-Processes.html), or
a thread if you need to simply call a function.

In general using fork() in a GUI program is a bad idea.


-- 
Bye,
 Gabry
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Forking from Gtk

2008-07-08 Thread jcupitt
Hi,

2008/7/7 G Hasse [EMAIL PROTECTED]:
 I have a small demo app. This works on FreeBSD but I can't
 get to work on Linux.

I tried your code on my Ubuntu machine and it works fine. I had to add:

// needed for fork()
#include unistd.h

// needed for umask()
#include sys/types.h
#include sys/stat.h

near the top, but that's all. You have the child doing
gtk_main_quit(), which I don't think is necessary. It works fine
without that line.

 I know that in Linux setsid will fail
 if the child has the same session_id as the parent. So on
 Linux you must fork twice.

I don't think that's correct. Linux setsid() will fail if the calling
process is already a process group leader, the same as freebsd. So you
can't setsid() from your main process, you have to do it from a child.

Other posters have said don't use fork() and they are correct. You
should not make any gtk_*() calls from the child process.
g_timeout_*() for simple cases, and g_thread*() for complex ones are
much better.

There are however legitimate uses for fork(). I do this myself when I
have to run a complex command-line program from a GUI front end. I
think fork() is quite reasonable in this case.

You could also consider popen() and friends if you want to capture
program output to display in a window.

John
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Forking from Gtk

2008-07-08 Thread G Hasse
On Mon, Jul 07, 2008 at 10:58:36PM -0400, James Scott Jr wrote:
 G,
 
 The basic design decision to use fork() as a way to do work in the
 background flawed.  fork()ing is not practical for gtk program.  While
 fork() has been a valid option for many non-gui programs in the absence
 of threads, either g_thread_create() or pthread_create().  Today it is
 not very useful -- as in stop doing it now!
 
 Consider instead using a valid multi-threaded implementation like
 g_threads_xxx() for GTK based programs.  Or if full multi-threading is
 not required, look at g_timeout_add() which is a background timer
 routine that can serve as one or more background execution units; neatly
 inside an gtk context.

This is not a very practical solution if I want to quit the gtk program
and go home... The example I gave was just an example. I want to create
a process that run for a VERY long time. (a week). And to have the GUI
running allong is not a solution. This process don't need to communicate
with the GUI. And if so I can connect to the process with a socket and
ask for services.

 
 $ devhelp
 $ gtk-demo
 
 The above two program you be pre-installed on your Linux machine:
 devhelp has the gtk and glib api documentation, and gtk-demo shows you
 many of the gtk/glib features in action.
 
 Having said the multi-thread phrase, here is another word of caution.
 In GTK only the main or ONE thread can safely interface with GTK api
 calls that change the display.  Using more than one thread to call gtk
 apis at the same time will fail or cause a sigfault.  The context of GTK
 being your front-end to X11 is the source of this
 none-thread-safe-caution; it is in how gtk MUST interact with X that
 placing the multi-thread restriction.  There are elegant work-arounds
 this issue.
 
 Here is a link to the classic FAQ answer on Multi-threaded GTK programs:
 http://library.gnome.org/devel/gtk-faq/stable/x482.html
 
 Regards,
 James,

Tanks for your answer but I don't thing threads is the solution in my
case.

 
 On Mon, 2008-07-07 at 23:03 +0200, G Hasse wrote:
  Hello,
  
  I have a small demo app. This works on FreeBSD but I can't
  get to work on Linux. I know that in Linux setsid will fail
  if the child has the same session_id as the parent. So on
  Linux you must fork twice. But it also seems that the parent
  must do an exit. And I don't want that. The code is not very
  long - so I include it here.
  
  ---snipp---
  //--
  //
  //  $Id: GtkFork.c,v 1.2 2008/07/07 20:29:17 gorhas Exp $
  //
  //  Experiment to run a thing in background
  //  This works on FreeBSD but not on Linux...
  //
  //  Build with
  //
  //  CFLAGS := `pkg-config glib-2.0 --cflags` `pkg-config gtk+-2.0 
  --cflags`
  //  LDFLAGS := `pkg-config glib-2.0 --libs` `pkg-config gtk+-2.0 --libs`
  //
  //  cc $(CFLAGS) -o GtkFork GtkFork.c $(LDFLAGS)
  //
  //--
  
  #include gtk/gtk.h
  #include stdlib.h
  #include stdio.h
  #include time.h
  #include string.h
  
  //--
  // run_btn_callback
  //
  // Try to run something in the background
  //
  //--
  static void run_btn_callback (GtkWidget *button, gpointer data)
  {
  
 int loops_to_run = 0;
 int i = 0;
 int pid = -1;
 int ret = -1;
  
 // Skriv ut innehållet på skärmen 
 printf(Clicked..\n);
 printf(Data was: %s\n, gtk_entry_get_text( data ));
  
 loops_to_run = atoi( gtk_entry_get_text(data));
  
 // We dont want to wait very long...
 if( loops_to_run  60 )
 {
loops_to_run = 60;
printf(Adjusting to 60 loops...\n);
 }
 printf(Loops to run: %d\n, loops_to_run );
  
  
  
 printf(We make a daemon\n);
 if ( ( pid = fork() )  0 )
 {
// Something went wrong
printf(We could not fork just exit);
exit(-1);
 }
 else if ( pid != 0 )
 {

// This is the parent process
printf(The background process have pid:  %d\n, pid);
return;
 }
  
 // Quit gtk
 gtk_main_quit();
  
 // Become session leader
 ret = setsid();
 if( ret == -1 )
 {
perror(We could not be session leader\n);
exit(-1);
 }
  
 // Set umask for safety
 umask(0);
 
 // Set root dir
 chdir(/);

   
 for( i = 0; i  loops_to_run; i++ )
 {
printf(We are running: %d\n, i );
sleep(1);
 } 
  
 exit(0);
  
  }
  
  //--
  // When we quit
  //--
  static void quit_callback()
  {
 gtk_main_quit ();
  }
  
  
  //--
  //  main
  //
  //  

Re: Forking from Gtk

2008-07-08 Thread Dave Howorth
G Hasse wrote:
 But I realy NEED to create a longlived process (running for a week or
 month) and be able to quit the GUI whenever I like. The glib is
 just a wrapper - and i don't se the solution...
 
 I realy WANT to lose contact with the child process. And there
 is to mutch data from the GUI to pass it on the command line...

IMHO, in this circumstance, you still shouldn't have the GUI start the
long-lived process. You'll probably want some other mechanism to
[re]start the process in the event something goes wrong whilst it's
running. So set up the starting mechanism as a cron job or server
watchdog process. Then the GUI can just write the appropriate parameters
to a database or file or socket as you wish and the starting mechanism
will do the rest. No threads or forks in the GUI.

Cheers, Dave

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Forking from Gtk

2008-07-08 Thread James Scott Jr
G,

I've seen most of the other responses, and better understand what you
are trying to do.  And like others -- fork() is not recommended. 

I had similar problem and resolved it in this codeset.
http://gfhcm.sourceforge.net  -- a monitor for the [EMAIL PROTECTED] project

First, like you I needed to start several executables in the background,
resolve their identify via pid number, and monitor their cpu utilization
and associated artifacts to gage their progress.  

I approached it two ways: with standalone gfhcm, and then in
client/server way using gfhcmc  gfhcmd; gfhcmc is the gtk gui and
gfhcmd is a glib helper daemon.

For your issue: I suggest g_[a]sync_command_line() as a way to launch a
background process from a gtk app.  Then using either ipc Queues, pipes,
or sockets to connect to process to echange commands and information.
Having a formal daemon will help the issue of starting/stopping the
background thread. and Finally a dedicated gui that expects to use an
IPC to communication with the process.

Anyway that you would like to proceed - I think we all can offer
solutions.  But be clear, I and maybe we think, forking is a bad ideal
for GTK program period.

My website may have something of interest:
http://mysite.verizon.net/skoona/id2.html

James,

On Tue, 2008-07-08 at 06:51 +0200, G Hasse wrote:
 On Mon, Jul 07, 2008 at 10:58:36PM -0400, James Scott Jr wrote:
  G,
  
  The basic design decision to use fork() as a way to do work in the
  background flawed.  fork()ing is not practical for gtk program.  While
  fork() has been a valid option for many non-gui programs in the absence
  of threads, either g_thread_create() or pthread_create().  Today it is
  not very useful -- as in stop doing it now!
  
  Consider instead using a valid multi-threaded implementation like
  g_threads_xxx() for GTK based programs.  Or if full multi-threading is
  not required, look at g_timeout_add() which is a background timer
  routine that can serve as one or more background execution units; neatly
  inside an gtk context.
 
 This is not a very practical solution if I want to quit the gtk program
 and go home... The example I gave was just an example. I want to create
 a process that run for a VERY long time. (a week). And to have the GUI
 running allong is not a solution. This process don't need to communicate
 with the GUI. And if so I can connect to the process with a socket and
 ask for services.
 
  
  $ devhelp
  $ gtk-demo
  
  The above two program you be pre-installed on your Linux machine:
  devhelp has the gtk and glib api documentation, and gtk-demo shows you
  many of the gtk/glib features in action.
  
  Having said the multi-thread phrase, here is another word of caution.
  In GTK only the main or ONE thread can safely interface with GTK api
  calls that change the display.  Using more than one thread to call gtk
  apis at the same time will fail or cause a sigfault.  The context of GTK
  being your front-end to X11 is the source of this
  none-thread-safe-caution; it is in how gtk MUST interact with X that
  placing the multi-thread restriction.  There are elegant work-arounds
  this issue.
  
  Here is a link to the classic FAQ answer on Multi-threaded GTK programs:
  http://library.gnome.org/devel/gtk-faq/stable/x482.html
  
  Regards,
  James,
 
 Tanks for your answer but I don't thing threads is the solution in my
 case.
 
  
  On Mon, 2008-07-07 at 23:03 +0200, G Hasse wrote:
   Hello,
   
   I have a small demo app. This works on FreeBSD but I can't
   get to work on Linux. I know that in Linux setsid will fail
   if the child has the same session_id as the parent. So on
   Linux you must fork twice. But it also seems that the parent
   must do an exit. And I don't want that. The code is not very
   long - so I include it here.
   
   ---snipp---
   //--
   //
   //  $Id: GtkFork.c,v 1.2 2008/07/07 20:29:17 gorhas Exp $
   //
   //  Experiment to run a thing in background
   //  This works on FreeBSD but not on Linux...
   //
   //  Build with
   //
   //  CFLAGS := `pkg-config glib-2.0 --cflags` `pkg-config gtk+-2.0 
   --cflags`
   //  LDFLAGS := `pkg-config glib-2.0 --libs` `pkg-config gtk+-2.0 --libs`
   //
   //  cc $(CFLAGS) -o GtkFork GtkFork.c $(LDFLAGS)
   //
   //--
   
   #include gtk/gtk.h
   #include stdlib.h
   #include stdio.h
   #include time.h
   #include string.h
   
   //--
   // run_btn_callback
   //
   // Try to run something in the background
   //
   //--
   static void run_btn_callback (GtkWidget *button, gpointer data)
   {
   
  int loops_to_run = 0;
  int i = 0;
  int pid = -1;
  int ret = -1;
   
  // Skriv ut innehållet på skärmen 
  printf(Clicked..\n);
  

Re: Forking from Gtk

2008-07-08 Thread James Scott Jr

On Tue, 2008-07-08 at 23:23 +0200, G Hasse wrote:
 On Tue, Jul 08, 2008 at 01:52:00PM -0400, James Scott Jr wrote:
  G,
  
  I've seen most of the other responses, and better understand what you
  are trying to do.  And like others -- fork() is not recommended. 
 
 I can't belive this... Certanly a forground process must be able to
 start a process that completly detatch from the parent. Gtk or not
 it could not matter. If I fork a Gtk program I migt have a lot of
 GtkWidget pointers that are of no use - but if I bother I should be
 able to free those. The gtk_main loop runs around to find out if
 signals have been emitted. So if I exit this loop no sutch activity
 should be going on.
 
 I have been doing this on FreeBSD for a long time and I have no
 problem there. 
 
 The only problem I realy have on Linux is that the forked process
 is marked as defunct and probably take a process slot until the
 parent exits. In FreeBSD I don't notice this behaviour.
 
 The cenario you tell below is not quite applicable since my program
 don't know in advance what should be run. I only need the Gtk program
 to set a lot of parameters and then fire of the process. I klient
 server, socket or pipe solution would just make the solution 
 more complicated. And I don't need to minitor the processes during
 calculation.
 
  I had similar problem and resolved it in this codeset.
  http://gfhcm.sourceforge.net  -- a monitor for the [EMAIL PROTECTED] project
  
  First, like you I needed to start several executables in the background,
  resolve their identify via pid number, and monitor their cpu utilization
  and associated artifacts to gage their progress.  
  
  I approached it two ways: with standalone gfhcm, and then in
  client/server way using gfhcmc  gfhcmd; gfhcmc is the gtk gui and
  gfhcmd is a glib helper daemon.
  
  For your issue: I suggest g_[a]sync_command_line() as a way to launch a
  background process from a gtk app.  Then using either ipc Queues, pipes,
  or sockets to connect to process to echange commands and information.
  Having a formal daemon will help the issue of starting/stopping the
  background thread. and Finally a dedicated gui that expects to use an
  IPC to communication with the process.
  
  Anyway that you would like to proceed - I think we all can offer
  solutions.  But be clear, I and maybe we think, forking is a bad ideal
  for GTK program period.

Sorry. I don't se this. What i see is forking from a foreground process
and letting the foreground process still live on is a bad idea on 
*LINUX*. Or...

Göran

Ok, the glib/gtk apis can be used to meet the processing conditions you
describe.  I note that you aware of the increased complexity caused by a
design different from what your accustomed to on BSD. I think those of
us who have done a bit of gtk programming in varied situations, see a
solution that does require more effort and design.

John jcupitt stated that he got your code to work on Ubuntu with a few
minor additions. And I presume, using some type of gui toolkit on BSD
you been doing this for a while.  So with John's comment and your
experience, I think you can take it from here and use fork().  

However, if you want to redesign to take full advantage of the resources
and capability of GTK/GLIB and LINUX for the benefit of your users
experience; I got some time and would be willing to help you build a
framework -- just send me code or specs to look at.

The design changes to redo your code are not complicated or burdensome;
just different.  I think the outcome of the rework will be a better
piece of software with greater opportunity to please your users - even
if the user is only you.

James,

  My website may have something of interest:
  http://mysite.verizon.net/skoona/id2.html
  
  James,
  
  On Tue, 2008-07-08 at 06:51 +0200, G Hasse wrote:
   On Mon, Jul 07, 2008 at 10:58:36PM -0400, James Scott Jr wrote:
G,

The basic design decision to use fork() as a way to do work in the
background flawed.  fork()ing is not practical for gtk program.  While
fork() has been a valid option for many non-gui programs in the absence
of threads, either g_thread_create() or pthread_create().  Today it is
not very useful -- as in stop doing it now!

Consider instead using a valid multi-threaded implementation like
g_threads_xxx() for GTK based programs.  Or if full multi-threading is
not required, look at g_timeout_add() which is a background timer
routine that can serve as one or more background execution units; neatly
inside an gtk context.
   
   This is not a very practical solution if I want to quit the gtk program
   and go home... The example I gave was just an example. I want to create
   a process that run for a VERY long time. (a week). And to have the GUI
   running allong is not a solution. This process don't need to communicate
   with the GUI. And if so I can connect to the process with a socket and
   ask for services.
   

Forking from Gtk

2008-07-07 Thread G Hasse
Hello,

I have a small demo app. This works on FreeBSD but I can't
get to work on Linux. I know that in Linux setsid will fail
if the child has the same session_id as the parent. So on
Linux you must fork twice. But it also seems that the parent
must do an exit. And I don't want that. The code is not very
long - so I include it here.

---snipp---
//--
//
//  $Id: GtkFork.c,v 1.2 2008/07/07 20:29:17 gorhas Exp $
//
//  Experiment to run a thing in background
//  This works on FreeBSD but not on Linux...
//
//  Build with
//
//  CFLAGS := `pkg-config glib-2.0 --cflags` `pkg-config gtk+-2.0 
--cflags`
//  LDFLAGS := `pkg-config glib-2.0 --libs` `pkg-config gtk+-2.0 --libs`
//
//  cc $(CFLAGS) -o GtkFork GtkFork.c $(LDFLAGS)
//
//--

#include gtk/gtk.h
#include stdlib.h
#include stdio.h
#include time.h
#include string.h

//--
// run_btn_callback
//
// Try to run something in the background
//
//--
static void run_btn_callback (GtkWidget *button, gpointer data)
{

   int loops_to_run = 0;
   int i = 0;
   int pid = -1;
   int ret = -1;

   // Skriv ut innehållet på skärmen 
   printf(Clicked..\n);
   printf(Data was: %s\n, gtk_entry_get_text( data ));

   loops_to_run = atoi( gtk_entry_get_text(data));

   // We dont want to wait very long...
   if( loops_to_run  60 )
   {
  loops_to_run = 60;
  printf(Adjusting to 60 loops...\n);
   }
   printf(Loops to run: %d\n, loops_to_run );



   printf(We make a daemon\n);
   if ( ( pid = fork() )  0 )
   {
  // Something went wrong
  printf(We could not fork just exit);
  exit(-1);
   }
   else if ( pid != 0 )
   {
  
  // This is the parent process
  printf(The background process have pid:  %d\n, pid);
  return;
   }

   // Quit gtk
   gtk_main_quit();

   // Become session leader
   ret = setsid();
   if( ret == -1 )
   {
  perror(We could not be session leader\n);
  exit(-1);
   }

   // Set umask for safety
   umask(0);
   
   // Set root dir
   chdir(/);
  
 
   for( i = 0; i  loops_to_run; i++ )
   {
  printf(We are running: %d\n, i );
  sleep(1);
   } 

   exit(0);

}

//--
// When we quit
//--
static void quit_callback()
{
   gtk_main_quit ();
}


//--
//  main
//
//  Creates a gtk windows to specify how many loops
//  the daemon should run.
//
//--
int 
main (int argc, char **argv)
{

  GtkWidget *mainwin = 0L;
  GtkWidget *number_entry = 0L;
  GtkWidget *run_btn = 0L;
  GtkWidget *vbox = 0L;

  /* Initialize i18n support */
  printf(Locale is: %s\n, gtk_set_locale () );

  /* Initialize the widget set */
  gtk_init (argc, argv);

  /* Create the main window */
  mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  /* Set up our GUI elements */
  vbox = gtk_vbox_new (FALSE, 0);

  number_entry = gtk_entry_new();

  run_btn = gtk_button_new_with_label(Just run);

  gtk_container_add (GTK_CONTAINER (mainwin), vbox);
  gtk_box_pack_start (GTK_BOX (vbox), number_entry, TRUE, TRUE, 0);
  gtk_box_pack_start (GTK_BOX (vbox), run_btn, TRUE, TRUE, 0);

  
  // Function to call when main window is destroyed
  g_signal_connect (G_OBJECT (mainwin),
destroy,
GTK_SIGNAL_FUNC (quit_callback),
NULL);

  // Function to call when we click the button
  g_signal_connect(GTK_OBJECT(run_btn), clicked,
 G_CALLBACK(run_btn_callback),
 number_entry);

  /* Show the application window */
  gtk_widget_show_all (mainwin);

  /* Enter the main event loop, and wait for user interaction */
  gtk_main ();

  /* The user lost interest */
  return 0;

}

//--
// END
//--

---snipp---

-- 
Göran Hasse


Göran Hasse   email: [EMAIL PROTECTED]  Tel: 019-450105
Raditex AB http://www.raditex.se
Planiavägen 15, 1tr Mob: 070-5530148
131 34  NACKA, SWEDEN OrgNr: 556240-0589
VAT: SE556240058901
--

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Forking from Gtk

2008-07-07 Thread James Scott Jr
G,

The basic design decision to use fork() as a way to do work in the
background flawed.  fork()ing is not practical for gtk program.  While
fork() has been a valid option for many non-gui programs in the absence
of threads, either g_thread_create() or pthread_create().  Today it is
not very useful -- as in stop doing it now!

Consider instead using a valid multi-threaded implementation like
g_threads_xxx() for GTK based programs.  Or if full multi-threading is
not required, look at g_timeout_add() which is a background timer
routine that can serve as one or more background execution units; neatly
inside an gtk context.

$ devhelp
$ gtk-demo

The above two program you be pre-installed on your Linux machine:
devhelp has the gtk and glib api documentation, and gtk-demo shows you
many of the gtk/glib features in action.

Having said the multi-thread phrase, here is another word of caution.
In GTK only the main or ONE thread can safely interface with GTK api
calls that change the display.  Using more than one thread to call gtk
apis at the same time will fail or cause a sigfault.  The context of GTK
being your front-end to X11 is the source of this
none-thread-safe-caution; it is in how gtk MUST interact with X that
placing the multi-thread restriction.  There are elegant work-arounds
this issue.

Here is a link to the classic FAQ answer on Multi-threaded GTK programs:
http://library.gnome.org/devel/gtk-faq/stable/x482.html

Regards,
James,


On Mon, 2008-07-07 at 23:03 +0200, G Hasse wrote:
 Hello,
 
 I have a small demo app. This works on FreeBSD but I can't
 get to work on Linux. I know that in Linux setsid will fail
 if the child has the same session_id as the parent. So on
 Linux you must fork twice. But it also seems that the parent
 must do an exit. And I don't want that. The code is not very
 long - so I include it here.
 
 ---snipp---
 //--
 //
 //  $Id: GtkFork.c,v 1.2 2008/07/07 20:29:17 gorhas Exp $
 //
 //  Experiment to run a thing in background
 //  This works on FreeBSD but not on Linux...
 //
 //  Build with
 //
 //  CFLAGS := `pkg-config glib-2.0 --cflags` `pkg-config gtk+-2.0 
 --cflags`
 //  LDFLAGS := `pkg-config glib-2.0 --libs` `pkg-config gtk+-2.0 --libs`
 //
 //  cc $(CFLAGS) -o GtkFork GtkFork.c $(LDFLAGS)
 //
 //--
 
 #include gtk/gtk.h
 #include stdlib.h
 #include stdio.h
 #include time.h
 #include string.h
 
 //--
 // run_btn_callback
 //
 // Try to run something in the background
 //
 //--
 static void run_btn_callback (GtkWidget *button, gpointer data)
 {
 
int loops_to_run = 0;
int i = 0;
int pid = -1;
int ret = -1;
 
// Skriv ut innehållet på skärmen 
printf(Clicked..\n);
printf(Data was: %s\n, gtk_entry_get_text( data ));
 
loops_to_run = atoi( gtk_entry_get_text(data));
 
// We dont want to wait very long...
if( loops_to_run  60 )
{
   loops_to_run = 60;
   printf(Adjusting to 60 loops...\n);
}
printf(Loops to run: %d\n, loops_to_run );
 
 
 
printf(We make a daemon\n);
if ( ( pid = fork() )  0 )
{
   // Something went wrong
   printf(We could not fork just exit);
   exit(-1);
}
else if ( pid != 0 )
{
   
   // This is the parent process
   printf(The background process have pid:  %d\n, pid);
   return;
}
 
// Quit gtk
gtk_main_quit();
 
// Become session leader
ret = setsid();
if( ret == -1 )
{
   perror(We could not be session leader\n);
   exit(-1);
}
 
// Set umask for safety
umask(0);

// Set root dir
chdir(/);
   
  
for( i = 0; i  loops_to_run; i++ )
{
   printf(We are running: %d\n, i );
   sleep(1);
} 
 
exit(0);
 
 }
 
 //--
 // When we quit
 //--
 static void quit_callback()
 {
gtk_main_quit ();
 }
 
 
 //--
 //  main
 //
 //  Creates a gtk windows to specify how many loops
 //  the daemon should run.
 //
 //--
 int 
 main (int argc, char **argv)
 {
 
   GtkWidget *mainwin = 0L;
   GtkWidget *number_entry = 0L;
   GtkWidget *run_btn = 0L;
   GtkWidget *vbox = 0L;
 
   /* Initialize i18n support */
   printf(Locale is: %s\n, gtk_set_locale () );
 
   /* Initialize the widget set */
   gtk_init (argc, argv);
 
   /* Create the main window */
   mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
   /* Set up our GUI elements */
   vbox = gtk_vbox_new (FALSE, 0);
 
   number_entry = gtk_entry_new();
 
   run_btn =