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