1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Authors: Jeffrey Stedfast <fejj@ximian.com>
5 * Copyright 2003 Ximian, Inc. (www.ximian.com)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
33 #include <sys/types.h>
42 ldd_parser_new (int fd
, LddSharedLibCallback shlib_cb
, void *user_data
)
46 ldd
= g_new (LddParser
, 1);
47 parser_init ((Parser
*) ldd
, fd
);
49 ldd
->linebuf
= g_malloc (128);
50 ldd
->lineptr
= ldd
->linebuf
;
53 ldd
->shlib_cb
= shlib_cb
;
54 ldd
->user_data
= user_data
;
61 ldd_parser_free (LddParser
*ldd
)
66 g_free (ldd
->linebuf
);
72 ldd_shared_lib_free (LddSharedLib
*shlib
)
77 g_free (shlib
->libname
);
83 /* " libc.so.6 => /lib/libc.so.6 (0x40e50000)\n" */
86 ldd_parse_linebuf (LddParser
*ldd
)
88 register unsigned char *inptr
;
92 shlib
= g_new (LddSharedLib
, 1);
95 while (*inptr
== '\t' || *inptr
== ' ')
98 shlib
->libname
= inptr
;
99 while (*inptr
&& !(inptr
[0] == ' ' && inptr
[1] == '=' && inptr
[2] == '>') && *inptr
!= '(')
102 shlib
->libname
= (unsigned char *)g_strndup ((char *)shlib
->libname
, inptr
- shlib
->libname
);
104 if (!strncmp ((char *)inptr
, " =>", 3))
107 while (*inptr
== ' ' || *inptr
== '\t')
111 while (*inptr
&& *inptr
!= '(')
115 /* error - no address component; ignore */
116 g_free (shlib
->libname
);
121 if (inptr
== shlib
->path
) {
122 /* special case - no path component */
123 if (shlib
->libname
[0] != '/') {
125 g_free (shlib
->libname
);
131 shlib
->path
= (unsigned char *)g_strdup ((char *)shlib
->libname
);
134 if (inptr
[-1] == ' ')
136 shlib
->path
= (unsigned char *)g_strndup ((char *)shlib
->path
, inptr
- shlib
->path
);
140 shlib
->addr
= strtoul ((const char *) inptr
, &inend
, 16);
142 ldd
->shlib_cb (ldd
, shlib
, ldd
->user_data
);
146 ldd
->lineleft
+= (ldd
->lineptr
- ldd
->linebuf
);
147 ldd
->lineptr
= ldd
->linebuf
;
151 #define ldd_backup_linebuf(ldd, start, len) G_STMT_START { \
152 if (ldd->lineleft <= len) { \
153 unsigned int llen, loff; \
155 llen = loff = ldd->lineptr - ldd->linebuf; \
156 llen = llen ? llen : 1; \
158 while (llen < (loff + len + 1)) \
161 ldd->linebuf = g_realloc (ldd->linebuf, llen); \
162 ldd->lineptr = ldd->linebuf + loff; \
163 ldd->lineleft = llen - loff; \
166 memcpy (ldd->lineptr, start, len); \
167 ldd->lineptr += len; \
168 ldd->lineleft -= len; \
173 ldd_parser_step (LddParser
*ldd
)
175 register unsigned char *inptr
;
176 unsigned char *start
;
180 parser
= (Parser
*) ldd
;
182 if ((ret
= parser_fill (parser
)) == 0) {
184 } else if (ret
== -1) {
188 start
= inptr
= parser
->inptr
;
189 *parser
->inend
= '\n';
191 while (inptr
< parser
->inend
) {
192 while (*inptr
!= '\n')
195 if (inptr
== parser
->inend
)
199 ldd_backup_linebuf (ldd
, start
, inptr
- start
);
200 ldd_parse_linebuf (ldd
);
205 ldd_backup_linebuf (ldd
, start
, inptr
- start
);
207 parser
->inptr
= inptr
;
214 ldd_parser_flush (LddParser
*ldd
)
216 Parser
*parser
= (Parser
*) ldd
;
218 if (parser
->inptr
< parser
->inend
)
219 return ldd_parser_step (ldd
);