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