]>
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 | ||
99 | for (i=0; i<NFDBITS/sizeof(int); i++) { | |
100 | gdb_crfds.fds_bits[i] = 0; | |
101 | gdb_cwfds.fds_bits[i] = 0; | |
102 | gdb_cefds.fds_bits[i] = 0; | |
103 | } | |
104 | ||
105 | /* | |
106 | * Initialize the server/client layer | |
107 | */ | |
108 | gdb_i_srv(); | |
109 | ||
110 | /* | |
111 | * Ignore the signal generated when writing to a pipe which has been | |
112 | * closed at the other end. gdb_move_data handles this condition | |
113 | * synchronously. | |
114 | */ | |
115 | (void) signal(SIGPIPE, SIG_IGN); | |
116 | ||
117 | /* | |
118 | * Make a note of the local host and user name | |
119 | */ | |
120 | if (gethostname(hostname, sizeof(hostname)-1)!=0) | |
121 | (void) strcpy(hostname, "????"); | |
122 | gdb_host = db_alloc(strlen(hostname)+1); | |
123 | (void) strcpy(gdb_host, hostname); | |
124 | ||
125 | uid = getuid(); | |
126 | ||
127 | pw_struct = getpwuid(uid); | |
128 | ||
129 | if (pw_struct != NULL && pw_struct ->pw_name != NULL && | |
130 | *pw_struct->pw_name !='\0') | |
131 | uname = pw_struct->pw_name; | |
132 | else | |
133 | uname = "????"; | |
ceae5ffd | 134 | gdb_uname = db_alloc(strlen(uname)+1); |
5580185e | 135 | (void) strcpy(gdb_uname, uname); |
136 | ||
137 | return 0; | |
138 | } | |
139 | /*----------------------------------------------------------*/ | |
140 | /* | |
141 | /* g_chk_init | |
142 | /* | |
143 | /* Make sure gdb has been initialized, blow up if not. | |
144 | /* | |
145 | /*----------------------------------------------------------*/ | |
146 | ||
147 | int | |
148 | g_chk_init() | |
149 | { | |
150 | if (!g_inited) | |
151 | GDB_GIVEUP("You must call gdb_init before using GDB services.") | |
152 | } | |
153 | ||
154 | /*----------------------------------------------------------*/ | |
155 | /* | |
156 | /* g_bitcount | |
157 | /* | |
158 | /* Count the number of bits in a word. Adapted from | |
159 | /* K&R. | |
160 | /* | |
161 | /*----------------------------------------------------------*/ | |
162 | ||
163 | int | |
164 | g_bitcount(inp) | |
165 | unsigned int inp; | |
166 | { | |
167 | register unsigned int x = inp; /* the word to check */ | |
168 | register int count; /* the count to return */ | |
169 | ||
170 | for (count=0; x !=0; x=x>>1) | |
171 | if (x & 01) | |
172 | count++; | |
173 | ||
174 | return count; | |
175 | } | |
176 | ||
177 | /*----------------------------------------------------------*/ | |
178 | /* | |
179 | /* gdb_fstring | |
180 | /* | |
181 | /* Utility routine to conditionally free a null | |
182 | /* terminated string. | |
183 | /* | |
184 | /*----------------------------------------------------------*/ | |
185 | ||
186 | int | |
187 | gdb_fstring(str) | |
188 | char *str; | |
189 | { | |
190 | if (str != NULL) | |
191 | db_free(str, strlen(str)+1); | |
192 | } | |
193 | ||
194 | /*----------------------------------------------------------*/ | |
195 | /* | |
196 | /* g_givup | |
197 | /* | |
198 | /* Called when a fatal error occurs. | |
199 | /* | |
200 | /*----------------------------------------------------------*/ | |
201 | ||
202 | int | |
203 | g_givup(errormsg) | |
204 | char *errormsg; | |
205 | { | |
206 | fprintf(gdb_log,"\n\nFATAL GDB ERROR:\n\n\t"); | |
207 | fprintf(gdb_log,errormsg); | |
208 | fprintf(gdb_log,"\n\n"); | |
209 | exit(100); | |
210 | } | |
211 | ||
212 | /*----------------------------------------------------------*/ | |
213 | /* | |
214 | /* connection_perror | |
215 | /* | |
216 | /* Acts like gdb_perror, but takes its errno from | |
217 | /* the connection. Resets errno as a side effect. | |
218 | /* THIS ROUTINE IS A NO_OP IF connection_status(con)!=CON_STOPPING | |
219 | /* | |
220 | /*----------------------------------------------------------*/ | |
221 | ||
222 | int | |
223 | connection_perror(con, msg) | |
224 | CONNECTION con; | |
225 | char *msg; | |
226 | { | |
227 | if (con == NULL || connection_status(con) != CON_STOPPING) | |
228 | return; | |
229 | errno = connection_errno(con); | |
230 | gdb_perror(msg); | |
231 | } | |
232 | ||
233 | /*----------------------------------------------------------*/ | |
234 | /* | |
235 | /* gdb_perror | |
236 | /* | |
237 | /* Performs same function as system perror, but does | |
238 | /* it on gdb_log instead of stderr. | |
239 | /* | |
240 | /*----------------------------------------------------------*/ | |
241 | ||
242 | int | |
243 | gdb_perror(msg) | |
244 | char *msg; | |
245 | { | |
246 | if(msg != NULL) | |
247 | fprintf(gdb_log, "%s: ", msg); | |
248 | if(errno < sys_nerr) | |
249 | fprintf(gdb_log, "%s.\n", sys_errlist[errno]); | |
250 | else | |
251 | fprintf(gdb_log, "errno %d is out of range of message table.\n"); | |
252 | } | |
253 |