1 /* $Header: /home/yav/catty/fkiss/RCS/bg.c,v 1.10 2000/08/25 06:50:36 yav Exp $
2  * fkiss background task and signal handling
3  * written by yav <yav@bigfoot.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 char id_bg[] = "$Id: bg.c,v 1.10 2000/08/25 06:50:36 yav Exp $";
21 
22 #include <X11/Xlib.h>
23 #include <X11/Xos.h>
24 #include <stdio.h>
25 
26 #include "config.h"
27 
28 #ifdef HAVE_SIGNAL_H
29 #include <signal.h>
30 #endif
31 
32 #ifdef HAVE_SYS_WAIT_H
33 #include <sys/wait.h>
34 #endif
35 
36 #include "headers.h"
37 #include "fkiss.h"
38 #include "work.h"
39 #define PUBLIC_BG_C
40 #include "extern.h"
41 
42 /* for System V signal symbol */
43 #ifndef SIGCHLD
44 #define SIGCHLD SIGCLD
45 #endif
46 
47 static FILE *bgfp = NULL;
48 static char sound_mark[] = "**sound";
49 static char play_command[] = "play";
50 static char shell_command[] = "/bin/sh";
51 
sigchld_handler()52 RETSIGTYPE sigchld_handler()
53 {
54   wait(NULL);
55   signal(SIGCHLD, sigchld_handler); /* reset signal handler for SysV */
56 }
57 
bg_child()58 void bg_child()
59 {
60   FILE *fp;
61   int i, s, sound_mark_len;
62   char *p;
63   char buf[256];
64 
65   signal(SIGCHLD, sigchld_handler);
66   sound_mark_len = strlen(sound_mark);
67   fp = fdopen(0, "r");
68   while (fgets(buf, sizeof(buf), fp) != NULL) {
69     cut_crlf(buf);
70     if (debug_mode)
71       fprintf(stderr, "Background:%s\n", buf);
72     p = buf;
73     s = 0;
74     if (strncmp(p, sound_mark, sound_mark_len) == 0) {
75       p += sound_mark_len + 1;	/* skip sound_mark + ' ' */
76       s = 1;
77     }
78     if (fork() == 0) {
79       /* child process */
80       switch(s) {
81       case 1:			/* Sound function */
82 	if (sound_mode & 1) {
83 	  /* internal sound routine */
84 	  i = sound_play(p);
85 	  switch (i) {
86 	  case 0:		/* no error */
87 	    exit(0);
88 	  case 1:		/* sound file open error */
89 	    msg("W sound file ``%s'' open error.\n", p);
90 	    break;
91 	  case 2:		/* device open error */
92 	    msg("W sound device ``%s'' open error.\n", sound_device);
93 	    break;
94 	  case 3:		/* Not supported format */
95 	    msg("W ``%s'' not supported sound format.\n", p);
96 	    break;
97 	  default:
98 	    msg("W unknown sound error (%d)!?\n", i);
99 	    break;
100 	  }
101 	} else {
102 	  execlp(play_command, play_command, p, NULL);
103 	  /* play_command exec failed, try shell_command */
104 	  execlp(shell_command, shell_command, play_command, p, NULL);
105 	  /* shell_command exec failed */
106 	}
107 	break;
108       default:			/* Other function */
109 	system(p);
110 	exit(0);
111       }
112       exit(1);			/* exec failed */
113     }
114   }
115   exit(0);
116 }
117 
118 /* fork background process */
background()119 int background()
120 {
121   int i;
122   int pfd[2];
123 
124   if (pipe(pfd) < 0)
125     return -1;			/* pipe open failed */
126   i = fork();
127   if (i < 0)
128     return -1;			/* fork failed */
129   if (i == 0) {
130     /* child */
131     close(0);
132     dup(pfd[0]);
133     close(pfd[0]);
134     close(pfd[1]);
135     bg_child();
136     /* NOT REACHED */
137   }
138   /* parent */
139   close(pfd[0]);
140   bgfp = fdopen(pfd[1], "w");
141   return 0;
142 }
143 
bg_shell(str)144 int bg_shell(str)
145      char *str;
146 {
147   if (bgfp != NULL) {
148     fprintf(bgfp, "%s\n", str);
149     fflush(bgfp);
150   }
151   return 0;
152 }
153 
bg_play(name)154 int bg_play(name)
155      char *name;
156 {
157   if (sound_mode && bgfp != NULL) {
158     fprintf(bgfp, "%s %s\n", sound_mark, name);
159     fflush(bgfp);
160   }
161   return 0;
162 }
163 
bg_exit()164 void bg_exit()
165 {
166   if (bgfp != NULL) {
167     fclose(bgfp);
168     bgfp = NULL;
169     wait(NULL);
170   }
171 }
172 
173 
signal_handler(sig)174 RETSIGTYPE signal_handler(sig)
175      int sig;
176 {
177   signal(sig, SIG_IGN);		/* for SysV */
178   if (debug_mode)
179     printf("fkiss: signal %d!\n", sig);
180   kiss_exit(1);
181 }
182 
setup_signal_handler()183 void setup_signal_handler()
184 {
185   int i;
186   static int trap_signals[] = {
187     SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGTERM,
188 #ifdef SIGXCPU
189     SIGXCPU,
190 #endif
191 #ifdef SIGXFSZ
192     SIGXFSZ,
193 #endif
194     0
195   };
196 
197   for (i = 0; trap_signals[i]; i++) {
198     /* Don't trap already ignored signals */
199     if (signal(trap_signals[i], SIG_IGN) != SIG_IGN)
200       signal(trap_signals[i], signal_handler);
201   }
202 }
203 
204 /* End of file */
205