]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * $Source$ | |
3 | * $Header$ | |
4 | */ | |
5 | ||
6 | #ifndef lint | |
7 | static char *rcsid_gdb_c = "$Header$"; | |
8 | #endif lint | |
9 | ||
10 | ||
11 | /************************************************************************/ | |
12 | /* | |
13 | /* gdb.c | |
14 | /* | |
15 | /* Global Database Library - main controlling functions and globally | |
16 | /* shared routines. | |
17 | /* | |
18 | /* Author: Noah Mendelsohn | |
19 | /* | |
20 | /* Copyright: 1986 MIT Project Athena | |
21 | /* | |
22 | /* | |
23 | /* In addition to defining the main routines for gdb, this source | |
24 | /* file #includes gdb_lib.h, which does the external definitions | |
25 | /* for all global data used by the library. Everyone else gets | |
26 | /* externs for this data defined by gdb.h. | |
27 | /* | |
28 | /************************************************************************/ | |
29 | ||
30 | #include <stdio.h> | |
31 | #include <strings.h> | |
32 | #include <signal.h> | |
33 | #include <pwd.h> | |
34 | #include "gdb.h" | |
35 | #include "gdb_lib.h" | |
36 | #include <errno.h> | |
37 | #ifdef POSIX | |
38 | #include <sys/utsname.h> | |
39 | #endif | |
40 | ||
41 | extern int sys_nerr; | |
42 | extern char *sys_errlist[]; | |
43 | ||
44 | extern int errno; | |
45 | ||
46 | /* This global is defined to make sure that Moira clients are linked | |
47 | * against the correct library. | |
48 | */ | |
49 | int link_against_the_moira_version_of_gdb = 0; | |
50 | int g_inited = FALSE; /* gdb_init has not been */ | |
51 | /* called */ | |
52 | ||
53 | /*----------------------------------------------------------*/ | |
54 | /* | |
55 | /* gdb_init | |
56 | /* | |
57 | /* Initialize the global database facility. Must be | |
58 | /* called before any of the other gdb functions | |
59 | /* are used. Among other things, this function | |
60 | /* sets to ignore signals for writing on broken pipes. | |
61 | /* | |
62 | /*----------------------------------------------------------*/ | |
63 | ||
64 | int | |
65 | gdb_init() | |
66 | { | |
67 | register int i; | |
68 | char hostname[255]; /* name of local host */ | |
69 | extern uid_t getuid(); | |
70 | int uid; /* Unix user-i.d. number */ | |
71 | char *uname; /* string form of i.d. */ | |
72 | ||
73 | struct passwd *pw_struct; /* passwd entry comes back */ | |
74 | /* here */ | |
75 | #ifdef POSIX | |
76 | struct utsname nameposix; | |
77 | struct sigaction act; | |
78 | ||
79 | sigemptyset(&act.sa_mask); | |
80 | act.sa_flags = 0; | |
81 | #endif | |
82 | ||
83 | /* | |
84 | * So we know we've been initialized, and we do it only once | |
85 | */ | |
86 | if (g_inited) | |
87 | return 0; | |
88 | g_inited = TRUE; | |
89 | ||
90 | /* | |
91 | * Initialize the system defined types table | |
92 | */ | |
93 | gdb_i_stype(); | |
94 | ||
95 | /* | |
96 | * Initialize the connection control data structures. | |
97 | */ | |
98 | gdb_mcons = 0; /* number of connections */ | |
99 | /* in use so far */ | |
100 | for (i=0; i<GDB_MAX_CONNECTIONS; i++) { | |
101 | gdb_cons[i].id = GDB_CON_ID; | |
102 | gdb_cons[i].in.stream_buffer = NULL; | |
103 | gdb_cons[i].in.stream_buffer_length = GDB_STREAM_BUFFER_SIZE; | |
104 | } | |
105 | /* | |
106 | * Initialize the fd maps | |
107 | */ | |
108 | gdb_mfd = 0; | |
109 | ||
110 | FD_ZERO(&gdb_crfds); | |
111 | FD_ZERO(&gdb_cwfds); | |
112 | FD_ZERO(&gdb_cefds); | |
113 | ||
114 | /* | |
115 | * Initialize the server/client layer | |
116 | */ | |
117 | gdb_i_srv(); | |
118 | ||
119 | /* | |
120 | * Ignore the signal generated when writing to a pipe which has been | |
121 | * closed at the other end. gdb_move_data handles this condition | |
122 | * synchronously. | |
123 | */ | |
124 | #ifdef POSIX | |
125 | act.sa_handler = (void(*)()) SIG_IGN; | |
126 | (void) sigaction(SIGPIPE, &act, NULL); | |
127 | #else | |
128 | (void) signal(SIGPIPE, SIG_IGN); | |
129 | #endif | |
130 | ||
131 | /* | |
132 | * Make a note of the local host and user name | |
133 | */ | |
134 | #ifdef POSIX | |
135 | (void) uname(&nameposix); | |
136 | strncpy(hostname, nameposix.nodename, sizeof(hostname) - 1); | |
137 | #else | |
138 | if (gethostname(hostname, sizeof(hostname)-1)!=0) | |
139 | (void) strcpy(hostname, "????"); | |
140 | #endif | |
141 | gdb_host = db_alloc(strlen(hostname)+1); | |
142 | (void) strcpy(gdb_host, hostname); | |
143 | ||
144 | uid = getuid(); | |
145 | ||
146 | pw_struct = getpwuid(uid); | |
147 | ||
148 | if (pw_struct != NULL && pw_struct ->pw_name != NULL && | |
149 | *pw_struct->pw_name !='\0') | |
150 | uname = pw_struct->pw_name; | |
151 | else | |
152 | uname = "????"; | |
153 | gdb_uname = db_alloc(strlen(uname)+1); | |
154 | (void) strcpy(gdb_uname, uname); | |
155 | ||
156 | return 0; | |
157 | } | |
158 | /*----------------------------------------------------------*/ | |
159 | /* | |
160 | /* g_chk_init | |
161 | /* | |
162 | /* Make sure gdb has been initialized, blow up if not. | |
163 | /* | |
164 | /*----------------------------------------------------------*/ | |
165 | ||
166 | int | |
167 | g_chk_init() | |
168 | { | |
169 | if (!g_inited) | |
170 | GDB_GIVEUP("You must call gdb_init before using GDB services.") | |
171 | } | |
172 | ||
173 | /*----------------------------------------------------------*/ | |
174 | /* | |
175 | /* g_bitcount | |
176 | /* | |
177 | /* Count the number of bits in a word. Adapted from | |
178 | /* K&R. | |
179 | /* | |
180 | /*----------------------------------------------------------*/ | |
181 | ||
182 | int | |
183 | g_bitcount(inp) | |
184 | unsigned int inp; | |
185 | { | |
186 | register unsigned int x = inp; /* the word to check */ | |
187 | register int count; /* the count to return */ | |
188 | ||
189 | for (count=0; x !=0; x=x>>1) | |
190 | if (x & 01) | |
191 | count++; | |
192 | ||
193 | return count; | |
194 | } | |
195 | ||
196 | /*----------------------------------------------------------*/ | |
197 | /* | |
198 | /* gdb_fstring | |
199 | /* | |
200 | /* Utility routine to conditionally free a null | |
201 | /* terminated string. | |
202 | /* | |
203 | /*----------------------------------------------------------*/ | |
204 | ||
205 | int | |
206 | gdb_fstring(str) | |
207 | char *str; | |
208 | { | |
209 | if (str != NULL) | |
210 | db_free(str, strlen(str)+1); | |
211 | } | |
212 | ||
213 | /*----------------------------------------------------------*/ | |
214 | /* | |
215 | /* g_givup | |
216 | /* | |
217 | /* Called when a fatal error occurs. | |
218 | /* | |
219 | /*----------------------------------------------------------*/ | |
220 | ||
221 | int | |
222 | g_givup(errormsg) | |
223 | char *errormsg; | |
224 | { | |
225 | fprintf(gdb_log,"\n\nFATAL GDB ERROR:\n\n\t"); | |
226 | fprintf(gdb_log,errormsg); | |
227 | fprintf(gdb_log,"\n\n"); | |
228 | exit(100); | |
229 | } | |
230 | ||
231 | /*----------------------------------------------------------*/ | |
232 | /* | |
233 | /* connection_perror | |
234 | /* | |
235 | /* Acts like gdb_perror, but takes its errno from | |
236 | /* the connection. Resets errno as a side effect. | |
237 | /* THIS ROUTINE IS A NO_OP IF connection_status(con)!=CON_STOPPING | |
238 | /* | |
239 | /*----------------------------------------------------------*/ | |
240 | ||
241 | int | |
242 | connection_perror(con, msg) | |
243 | CONNECTION con; | |
244 | char *msg; | |
245 | { | |
246 | if (con == NULL || connection_status(con) != CON_STOPPING) | |
247 | return; | |
248 | errno = connection_errno(con); | |
249 | gdb_perror(msg); | |
250 | } | |
251 | ||
252 | /*----------------------------------------------------------*/ | |
253 | /* | |
254 | /* gdb_perror | |
255 | /* | |
256 | /* Performs same function as system perror, but does | |
257 | /* it on gdb_log instead of stderr. | |
258 | /* | |
259 | /*----------------------------------------------------------*/ | |
260 | ||
261 | int | |
262 | gdb_perror(msg) | |
263 | char *msg; | |
264 | { | |
265 | if(msg != NULL) | |
266 | fprintf(gdb_log, "%s: ", msg); | |
267 | if(errno < sys_nerr) | |
268 | fprintf(gdb_log, "%s.\n", sys_errlist[errno]); | |
269 | else | |
270 | fprintf(gdb_log, "errno %d is out of range of message table.\n"); | |
271 | } | |
272 |