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