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