-
Notifications
You must be signed in to change notification settings - Fork 0
/
SeSig.c
155 lines (137 loc) · 4.6 KB
/
SeSig.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* This file is part of the Seyon, Copyright (c) 1992-1993 by Muhammad M.
* Saggaf. All rights reserved.
*
* See the file COPYING (1-COPYING) or the manual page seyon(1) for a full
* statement of rights and permissions for this program.
*/
/*
* signals -
* An Xt Intrinsics signal handler developed based on discussions
* in comp.windows.x and written by someone who wishes to be
* anonymous. [Modified by me -- M.S.]
*
* A pipe is created and the read side is passed off to
* XtAppAddInput(). Everytime a signal occurs a byte, indicating
* which signal, is written by the signal handler on the write
* side of the pipe. This causes the Intrinsics to call the
* input handler which then invokes the correct callback.
*
* The potential for deadlock exists if the pipe is ever filled!
*
* $Id: signals.c,v 1.1 92/12/10 08:51:01 ware Exp $
* $Log: signals.c,v $
* Revision 1.1 92/12/10 08:51:01 ware
* Initial revision
*
*/
#include "SeSig.h"
#include <X11/Intrinsic.h>
#include <signal.h> /* signal stuff */
#include <string.h> /* for memset */
#include <sys/types.h> /* for pipe */
#include <unistd.h>
#if __STDC__ == 1
#if defined(SVR4)
/*
* This is a hack. On the system V release 4 unix, NSIG *is* defined
* but it NOT defined if the compiler is in ANSI mode. Presumably the
* use of this symbol should be avoided.
*/
#ifndef NSIG
#define NSIG (SIGXFSZ + 1)
#endif
#endif
#endif
static _XoSignalData sig_info[NSIG + 1]; /* NSIG is max signal value */
static int pipefd[2]; /* the input & output pipes */
static void _xsig_handler(
#if NeedFunctionPrototypes
int sig, int code
#endif
);
static void _xsig_pipe_handler(
#if NeedFunctionPrototypes
XtPointer client_data, int *source, XtInputId *id
#endif
);
/*
* XoAppAddSignal -
* Install a handler for a particular signal. There can be only
* a single handler per signal (it might be nice to use a callback).
*/
XoSignalCallbackProc XoAppAddSignal(context, sig, handler, client_data)
XtAppContext context; /* application context */
int sig; /* which signal */
XoSignalCallbackProc handler; /* the handler */
XtPointer client_data; /* private data */
{
static int firsttime = True;
/*
* We need to create the pipe and tell the intrinsics about
* the new file descriptor
*/
if (firsttime) {
firsttime = False;
pipe(pipefd);
XtAppAddInput(context, pipefd[0], (XtPointer)XtInputReadMask,
_xsig_pipe_handler, (XtPointer)NULL);
}
sig_info[sig].handler = handler;
sig_info[sig].client_data = client_data;
return (XoSignalCallbackProc)signal(sig, (void (*)())_xsig_handler);
} /* XoAppAddSignal */
/*
* XoAppRemoveSignal -
* Uninstalls a handler for a particular signal. The values
* of handler and client_data most match in order to remove the
* particular signal handler. If there are no more remaining
* signal handlers for that signal then SIG_DFL is installed.
*
* Of course, the current implementation only allows one handler
* per signal but in the future when multiple ones are added this
* will continue to work. The application context is not used
* and is left merely for consistency.
*/
void XoAppRemoveSignal(context,
sig) XtAppContext context; /* application context */
int sig; /* which signal */
{
signal(sig, SIG_DFL); /* restore old signal handler */
sig_info[sig].handler = (XoSignalCallbackProc)NULL;
sig_info[sig].client_data = NULL;
} /* XoAppRemoveSignal */
void XoAppIgnoreSignal(context,
sig) XtAppContext context; /* application context */
int sig; /* which signal */
{
signal(sig, SIG_IGN); /* ignore signal */
sig_info[sig].handler = (XoSignalCallbackProc)NULL;
sig_info[sig].client_data = NULL;
} /* XoAppIgnoreSignal */
/*
* _xsig_handler -
* the actual signal handler (custom), writes a byte to a pipe
*/
static void _xsig_handler(sig, code) int sig;
int code;
{
char sig_value;
sig_value = sig;
write(pipefd[1], &sig_value, 1);
} /* _xsig_handler */
/*
* _xsig_pipe_handler -
* reads input from the pipe and executes the corresponding callback.
*/
static void _xsig_pipe_handler(client_data, source, id) XtPointer client_data;
int *source;
XtInputId *id;
{
unsigned char sig_value;
int sig;
read(pipefd[0], &sig_value, 1);
sig = sig_value;
if (sig > 0 && sig < NSIG && sig_info[sig].handler)
(*sig_info[sig].handler)(sig, sig_info[sig].client_data);
} /* _xsig_pipe_handler */