Gentoo Archives: gentoo-commits

From: "Fabian Groffen (grobian)" <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r14745 - in main/branches/prefix: bin pym/portage pym/portage/dbapi
Date: Wed, 28 Oct 2009 19:38:58
Message-Id: E1N3EMA-0001bu-Dt@stork.gentoo.org
1 Author: grobian
2 Date: 2009-10-28 19:38:53 +0000 (Wed, 28 Oct 2009)
3 New Revision: 14745
4
5 Modified:
6 main/branches/prefix/bin/misc-functions.sh
7 main/branches/prefix/pym/portage/__init__.py
8 main/branches/prefix/pym/portage/dbapi/vartree.py
9 Log:
10 Add preserve-libs support for AIX' XCOFF, patch by Michael Haubenwallner
11
12 Modified: main/branches/prefix/bin/misc-functions.sh
13 ===================================================================
14 --- main/branches/prefix/bin/misc-functions.sh 2009-10-28 19:27:43 UTC (rev 14744)
15 +++ main/branches/prefix/bin/misc-functions.sh 2009-10-28 19:38:53 UTC (rev 14745)
16 @@ -436,6 +436,114 @@
17 PORTAGE_QUIET=${tmp_quiet}
18 fi
19
20 + if [[ ${CHOST} == *-aix* ]] && ! hasq binchecks ${RESTRICT}; then
21 + local tmp_quiet=${PORTAGE_QUIET}
22 + local queryline deplib
23 + local insecure_rpath_list= undefined_symbols_list=
24 +
25 + # display warnings when using stricter because we die afterwards
26 + if has stricter ${FEATURES} ; then
27 + unset PORTAGE_QUIET
28 + fi
29 +
30 + rm -f "${PORTAGE_BUILDDIR}"/build-info/NEEDED.XCOFF.1
31 + find "${ED}" -not -type d -exec \
32 + "${EPREFIX}/usr/bin/aixdll-query" '{}' FILE MEMBER FLAGS FORMAT RUNPATH DEPLIBS ';' \
33 + > "${T}"/needed 2>/dev/null
34 +
35 + # Symlinking archive libraries is not a good idea on aix,
36 + # as there is nothing like "soname" on pure filesystem level.
37 + # So we create a copy instead of the symlink.
38 + local prev_FILE=
39 + while read queryline
40 + do
41 + local FILE= MEMBER= FLAGS= FORMAT= RUNPATH= DEPLIBS=
42 + eval ${queryline}
43 +
44 + if [[ ${prev_FILE} != ${FILE} ]]; then
45 + prev_FILE=${FILE}
46 + if [[ -n ${MEMBER} || " ${FLAGS} " == *" SHROBJ "* ]] && [[ -h ${FILE} ]]; then
47 + local target=$(readlink "${FILE}")
48 + if [[ ${target} == /* ]]; then
49 + target=${D}${target}
50 + else
51 + target=${FILE%/*}/${target}
52 + fi
53 + rm -f "${FILE}" || die "cannot prune ${FILE#${ED}}"
54 + cp -f "${target}" "${FILE}" || die "cannot copy ${target#${ED}} to ${FILE#${ED}}"
55 + fi
56 + fi
57 + done <"${T}"/needed
58 +
59 + prev_FILE=
60 + while read queryline
61 + do
62 + local FILE= MEMBER= FLAGS= FORMAT= RUNPATH= DEPLIBS=
63 + eval ${queryline}
64 +
65 + if [[ ${prev_FILE} != ${FILE} ]]; then
66 + # Save NEEDED information for the archive library stub
67 + echo "${FORMAT##* }${FORMAT%%-*};${FILE#${D%/}};${FILE##*/};;" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.XCOFF.1
68 + fi
69 +
70 + # Make sure we disallow insecure RUNPATH's
71 + # Don't want paths that point to the tree where the package was built
72 + # (older, broken libtools would do this). Also check for null paths
73 + # because the loader will search $PWD when it finds null paths.
74 + # And we really want absolute paths only.
75 + if [[ -n $(echo ":${RUNPATH}:" | grep -E "(${PORTAGE_BUILDDIR}|::|:[^/])") ]]; then
76 + insecure_rpath_list="${insecure_rpath_list}\n${FILE}"
77 + fi
78 +
79 + # Although we do have runtime linking, we don't want undefined symbols.
80 + # AIX does indicate this by needing either '.' or '..'
81 + local needed=${FILE##*/}
82 + for deplib in ${DEPLIBS}; do
83 + eval deplib=${deplib}
84 + if [[ ${deplib} == '.' || ${deplib} == '..' ]]; then
85 + undefined_symbols_list="${undefined_symbols_list}\n${FILE}"
86 + else
87 + needed="${needed},${deplib}"
88 + fi
89 + done
90 +
91 + FILE=${FILE#${D%/}}
92 +
93 + [[ -n ${MEMBER} ]] && MEMBER="[${MEMBER}]"
94 + # Save NEEDED information
95 + echo "${FORMAT##* }${FORMAT%%-*};${FILE}${MEMBER};${FILE##*/}${MEMBER};${RUNPATH};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.XCOFF.1
96 + done <"${T}"/needed
97 +
98 + if [[ -n ${undefined_symbols_list} ]]; then
99 + vecho -ne '\a\n'
100 + eqawarn "QA Notice: The following files contain undefined symbols."
101 + eqawarn " Please file a bug about this at http://bugs.gentoo.org/"
102 + eqawarn " with 'prefix' as the maintaining herd of the package."
103 + eqawarn "${undefined_symbols_list}"
104 + vecho -ne '\a\n'
105 + fi
106 +
107 + if [[ -n ${insecure_rpath_list} ]] ; then
108 + vecho -ne '\a\n'
109 + eqawarn "QA Notice: The following files contain insecure RUNPATH's"
110 + eqawarn " Please file a bug about this at http://bugs.gentoo.org/"
111 + eqawarn " with 'prefix' as the maintaining herd of the package."
112 + eqawarn "${insecure_rpath_list}"
113 + vecho -ne '\a\n'
114 + if [[ -n ${x} ]] || has stricter ${FEATURES} ; then
115 + insecure_rpath=1
116 + fi
117 + fi
118 +
119 + if [[ ${insecure_rpath} -eq 1 ]] ; then
120 + die "Aborting due to serious QA concerns with RUNPATH/RPATH"
121 + elif [[ -n ${die_msg} ]] && has stricter ${FEATURES} ; then
122 + die "Aborting due to QA concerns: ${die_msg}"
123 + fi
124 +
125 + PORTAGE_QUIET=${tmp_quiet}
126 + fi
127 +
128 local unsafe_files=$(find "${ED}" -type f '(' -perm -2002 -o -perm -4002 ')')
129 if [[ -n ${unsafe_files} ]] ; then
130 eqawarn "QA Notice: Unsafe files detected (set*id and world writable)"
131 @@ -862,6 +970,167 @@
132 mtree -e -p "${EROOT}" -U -k flags < "${T}/bsdflags.mtree" &> /dev/null
133 }
134
135 +preinst_aix() {
136 + if [[ ${CHOST} != *-aix* ]] || hasq binchecks ${RESTRICT}; then
137 + return 0
138 + fi
139 + local ar strip
140 + if type ${CHOST}-ar >/dev/null 2>&1 && type ${CHOST}-strip >/dev/null 2>&1; then
141 + ar=${CHOST}-ar
142 + strip=${CHOST}-strip
143 + elif [[ ${CBUILD} == "${CHOST}" ]] && type ar >/dev/null 2>&1 && type strip >/dev/null 2>&1; then
144 + ar=ar
145 + strip=strip
146 + elif [[ -x /usr/ccs/bin/ar && -x /usr/ccs/bin/strip ]]; then
147 + ar=/usr/ccs/bin/ar
148 + strip=/usr/ccs/bin/strip
149 + else
150 + die "cannot find where to use 'ar' and 'strip' from"
151 + fi
152 +
153 + local archive prev_archive= archives=()
154 + while read archive; do
155 + archive=${archive#*;}
156 + archive=${archive%%;*}
157 + if [[ ${archive} == *'['*']' ]]; then
158 + archive=${archive%[*}
159 + [[ ${prev_archive} == ${archive} ]] && continue
160 + prev_archive=${archive}
161 + archives[${#archives[@]}]=${archive#${EPREFIX}/}
162 + fi
163 + done < "${PORTAGE_BUILDDIR}"/build-info/NEEDED.XCOFF.1
164 + unset prev_archive
165 +
166 + local libmetadir members preservemembers member contentmember chmod400files=() prunedirs=()
167 + for archive in "${archives[@]}"; do
168 + libmetadir=${ED}${archive%/*}/.${archive##*/}
169 + [[ ! -e ${libmetadir} ]] || rm -rf "${libmetadir}" || die "cannot prune ${libmetadir}"
170 + mkdir "${libmetadir}" || die "cannot create ${libmetadir}"
171 + pushd "${libmetadir}" >/dev/null || die "cannot cd to ${libmetadir}"
172 + ${ar} -X32_64 -x "${ED}${archive}" || die "cannot unpack ${archive}"
173 + members=" $(echo *) "
174 + preservemembers=
175 + if [[ -e ${EROOT}${archive} ]]; then
176 + for member in $(${ar} -X32_64 -t "${EROOT}${archive}"); do
177 + [[ ${members} == *" ${member} "* ]] && continue
178 + preservemembers="${preservemembers} ${member}"
179 + done
180 + if [[ -n ${preservemembers} ]]; then
181 + einfo "preserving (on spec)${preservemembers}"
182 + ${ar} -X32_64 -x "${EROOT}${archive}" ${preservemembers} || die "cannot extract ${preservemembers} from ${EROOT}${archive}"
183 + chmod u+w ${preservemembers} || die "cannot chmod${preservedmembers}"
184 + ${strip} -X32_64 -e ${preservemembers} || die "cannot strip${preservemembers}"
185 + ${ar} -X32_64 -q "${ED}${archive}" ${preservemembers} || die "cannot update ${archive}"
186 + eend $?
187 + fi
188 + fi
189 + for member in ${members}; do
190 + contentmember="${archive%/*}/.${archive##*/}[${member}]"
191 + # portage does os.lstat() on merged files every now
192 + # and then, so keep stamp-files for archive members
193 + # around to get the preserve-libs feature working.
194 + { echo "Please leave this file alone, it is an important helper"
195 + echo "for portage to implement the 'preserve-libs' feature on AIX."
196 + } > "${ED}${contentmember}" || die "cannot create ${contentmember}"
197 + chmod400files[${#chmod400files[@]}]=${ED}${contentmember}
198 + done
199 + popd >/dev/null || die "cannot leave ${libmetadir}"
200 + prunedirs[${#prunedirs[@]}]=${libmetadir}
201 + done
202 + [[ ${#chmod400files[@]} == 0 ]] ||
203 + chmod 0400 "${chmod400files[@]}" || die "cannot chmod ${chmod400files[@]}"
204 + [[ ${#prunedirs[@]} == 0 ]] ||
205 + rm -rf "${prunedirs[@]}" || die "cannot prune ${prunedirs[@]}"
206 + return 0
207 +}
208 +
209 +postinst_aix() {
210 + if [[ ${CHOST} != *-aix* ]] || hasq binchecks ${RESTRICT}; then
211 + return 0
212 + fi
213 + local MY_PR=${PR%r0}
214 + local ar strip
215 + if type ${CHOST}-ar >/dev/null 2>&1 && type ${CHOST}-strip >/dev/null 2>&1; then
216 + ar=${CHOST}-ar
217 + strip=${CHOST}-strip
218 + elif [[ ${CBUILD} == "${CHOST}" ]] && type ar >/dev/null 2>&1 && type strip >/dev/null 2>&1; then
219 + ar=ar
220 + strip=strip
221 + elif [[ -x /usr/ccs/bin/ar && -x /usr/ccs/bin/strip ]]; then
222 + ar=/usr/ccs/bin/ar
223 + strip=/usr/ccs/bin/strip
224 + else
225 + die "cannot find where to use 'ar' and 'strip' from"
226 + fi
227 +
228 + local member contentmember activecontentmembers= prev_archive= archive activearchives=
229 + while read member; do
230 + member=${member#*;} # drop "^type;"
231 + member=${member%%;*} # drop ";soname;runpath;needed$"
232 + [[ ${member##*/} == *'['*']' ]] || continue
233 + contentmember=${member%/*}/.${member##*/}
234 + activecontentmembers="${activecontentmembers}:(${contentmember}):"
235 + archive=${member%[*}
236 + [[ ${prev_archive} != ${archive} ]] || continue
237 + prev_archive=${archive}
238 + activearchives="${activearchives}:(${archive}):"
239 + done < "${PORTAGE_BUILDDIR}"/build-info/NEEDED.XCOFF.1
240 +
241 + local type allcontentmembers= all_archives=()
242 + prev_archive=
243 + while read type contentmember; do
244 + contentmember=${contentmember% *} # drop " timestamp$"
245 + contentmember=${contentmember% *} # drop " hash$"
246 + [[ ${contentmember##*/} == *'['*']' ]] || continue
247 + allcontentmembers="${allcontentmembers}:(${contentmember}):"
248 + member=${contentmember%/.*}/${contentmember##*/.}
249 + archive=${member%[*}
250 + [[ ${prev_archive} != ${archive} ]] || continue
251 + prev_archive=${archive}
252 + all_archives[${#all_archives[@]}]=${archive}
253 + done < "${EPREFIX}/var/db/pkg/${CATEGORY}/${P}${MY_PR:+-}${MY_PR}/CONTENTS"
254 +
255 + local delmembers oldmembers libmetadir prunemembers=() prunedirs=()
256 + for archive in "${all_archives[@]}"; do
257 + [[ -r ${ROOT}${archive} && -w ${ROOT}${archive} ]] ||
258 + chmod a+r,u+w "${ROOT}${archive}" || die "cannot chmod ${archive}"
259 + delmembers= oldmembers=
260 + for member in $(${ar} -X32_64 -t "${ROOT}${archive}"); do
261 + contentmember="${archive%/*}/.${archive##*/}[${member}]"
262 + if [[ ${allcontentmembers} != *":(${contentmember}):"* ]]; then
263 + # not existent any more, just drop it
264 + delmembers="${delmembers} ${member}"
265 + prunemembers[${#prunemembers[@]}]=${ROOT}${contentmember}
266 + elif [[ ${activecontentmembers} != *":(${contentmember}):"* ]]; then
267 + oldmembers="${oldmembers} ${member}"
268 + fi
269 + done
270 + if [[ -n ${delmembers} ]]; then
271 + einfo "dropping${delmembers}"
272 + ${ar} -X32_64 -z -o -d "${ROOT}${archive}" ${delmembers} || die "cannot remove${delmembers} from ${archive}"
273 + eend $?
274 + fi
275 + if [[ -n ${oldmembers} && ${activearchives} != *":(${archive}):"* ]]; then
276 + einfo "preserving (extra)${oldmembers}"
277 + libmetadir=${ROOT}${archive%/*}/.${archive##*/}
278 + [[ ! -e ${libmetadir} ]] || rm -rf "${libmetadir}" || die "cannot prune ${libmetadir}"
279 + mkdir "${libmetadir}" || die "cannot create ${libmetadir}"
280 + pushd "${libmetadir}" >/dev/null || die "cannot cd to ${libmetadir}"
281 + ${ar} -X32_64 -x "${ROOT}${archive}" ${oldmembers} || die "cannot unpack ${archive}"
282 + ${strip} -e ${oldmembers} || die "cannot strip ${oldmembers}"
283 + ${ar} -X32_64 -z -o -r "${ROOT}${archive}" ${oldmembers} || die "cannot update${oldmembers} in ${archive}"
284 + popd > /dev/null || die "cannot leave ${libmetadir}"
285 + prunedirs[${#prunedirs[@]}]=${libmetadir}
286 + eend $?
287 + fi
288 + done
289 + [[ ${#prunedirs[@]} == 0 ]] ||
290 + rm -rf "${prunedirs[@]}" || die "cannot prune ${prunedirs[@]}"
291 + [[ ${#prunemembers[@]} == 0 ]] ||
292 + rm -f "${prunemembers[@]}" || die "cannot prune ${contentmenbers[@]}"
293 + return 0
294 +}
295 +
296 preinst_mask() {
297 if [ -z "${D}" ]; then
298 eerror "${FUNCNAME}: D is unset"
299
300 Modified: main/branches/prefix/pym/portage/__init__.py
301 ===================================================================
302 --- main/branches/prefix/pym/portage/__init__.py 2009-10-28 19:27:43 UTC (rev 14744)
303 +++ main/branches/prefix/pym/portage/__init__.py 2009-10-28 19:38:53 UTC (rev 14745)
304 @@ -5655,6 +5655,7 @@
305 "install_symlink_html_docs"],
306
307 "preinst" : [
308 + "preinst_aix",
309 "preinst_bsdflags",
310 "preinst_sfperms",
311 "preinst_selinux_labels",
312 @@ -5662,6 +5663,7 @@
313 "preinst_mask"],
314
315 "postinst" : [
316 + "postinst_aix",
317 "postinst_bsdflags"]
318 }
319
320
321 Modified: main/branches/prefix/pym/portage/dbapi/vartree.py
322 ===================================================================
323 --- main/branches/prefix/pym/portage/dbapi/vartree.py 2009-10-28 19:27:43 UTC (rev 14744)
324 +++ main/branches/prefix/pym/portage/dbapi/vartree.py 2009-10-28 19:38:53 UTC (rev 14745)
325 @@ -5,7 +5,7 @@
326 from __future__ import print_function
327
328 __all__ = ["PreservedLibsRegistry", "LinkageMap",
329 - "LinkageMapMachO", "LinkageMapPeCoff",
330 + "LinkageMapMachO", "LinkageMapPeCoff", "LinkageMapXCoff"
331 "vardbapi", "vartree", "dblink"] + \
332 ["write_contents", "tar_contents"]
333
334 @@ -26,7 +26,7 @@
335 )
336
337 from portage.const import CACHE_PATH, CONFIG_MEMORY_FILE, \
338 - PORTAGE_PACKAGE_ATOM, PRIVATE_PATH, VDB_PATH, EPREFIX, EPREFIX_LSTRIP
339 + PORTAGE_PACKAGE_ATOM, PRIVATE_PATH, VDB_PATH, EPREFIX, EPREFIX_LSTRIP, BASH_BINARY
340 from portage.data import portage_gid, portage_uid, secpass
341 from portage.dbapi import dbapi
342 from portage.exception import CommandNotFound, \
343 @@ -1479,7 +1479,253 @@
344 arch_map[needed_soname] = soname_map
345 soname_map.consumers.add(obj_key)
346
347 +class LinkageMapXCoff(LinkageMap):
348
349 + """Models dynamic linker dependencies."""
350 +
351 + _needed_aux_key = "NEEDED.XCOFF.1"
352 +
353 + class _ObjectKey(LinkageMap._ObjectKey):
354 +
355 + def __init__(self, obj, root):
356 + LinkageMap._ObjectKey.__init__(self, obj, root)
357 +
358 + def _generate_object_key(self, obj, root):
359 + """
360 + Generate object key for a given object.
361 +
362 + @param object: path to a file
363 + @type object: string (example: '/usr/bin/bar')
364 + @rtype: 2-tuple of types (long, int) if object exists. string if
365 + object does not exist.
366 + @return:
367 + 1. 2-tuple of object's inode and device from a stat call, if object
368 + exists.
369 + 2. realpath of object if object does not exist.
370 +
371 + """
372 +
373 + os = _os_merge
374 +
375 + try:
376 + _unicode_encode(obj,
377 + encoding=_encodings['merge'], errors='strict')
378 + except UnicodeEncodeError:
379 + # The package appears to have been merged with a
380 + # different value of sys.getfilesystemencoding(),
381 + # so fall back to utf_8 if appropriate.
382 + try:
383 + _unicode_encode(obj,
384 + encoding=_encodings['fs'], errors='strict')
385 + except UnicodeEncodeError:
386 + pass
387 + else:
388 + os = portage.os
389 +
390 + abs_path = os.path.join(root, obj.lstrip(os.sep))
391 + try:
392 + object_stat = os.stat(abs_path)
393 + except OSError:
394 + # Use the realpath as the key if the file does not exists on the
395 + # filesystem.
396 + return os.path.realpath(abs_path)
397 + # Return a tuple of the device and inode, as well as the basename,
398 + # because of hardlinks the device and inode might be identical.
399 + return (object_stat.st_dev, object_stat.st_ino, os.path.basename(abs_path.rstrip(os.sep)))
400 +
401 + def file_exists(self):
402 + """
403 + Determine if the file for this key exists on the filesystem.
404 +
405 + @rtype: Boolean
406 + @return:
407 + 1. True if the file exists.
408 + 2. False if the file does not exist or is a broken symlink.
409 +
410 + """
411 + return isinstance(self._key, tuple)
412 +
413 + class _LibGraphNode(_ObjectKey):
414 + __slots__ = ("alt_paths",)
415 +
416 + def __init__(self, obj, root):
417 + LinkageMapXCoff._ObjectKey.__init__(self, obj, root)
418 + self.alt_paths = set()
419 +
420 + def __str__(self):
421 + return str(sorted(self.alt_paths))
422 +
423 + def rebuild(self, exclude_pkgs=None, include_file=None):
424 + """
425 + Raises CommandNotFound if there are preserved libs
426 + and the scanelf binary is not available.
427 + """
428 +
429 + os = _os_merge
430 + root = self._root
431 + root_len = len(root) - 1
432 + self._clear_cache()
433 + self._defpath.update(getlibpaths(self._root))
434 + libs = self._libs
435 + obj_key_cache = self._obj_key_cache
436 + obj_properties = self._obj_properties
437 +
438 + lines = []
439 +
440 + # Data from include_file is processed first so that it
441 + # overrides any data from previously installed files.
442 + if include_file is not None:
443 + lines += grabfile(include_file)
444 +
445 + aux_keys = [self._needed_aux_key]
446 + for cpv in self._dbapi.cpv_all():
447 + if exclude_pkgs is not None and cpv in exclude_pkgs:
448 + continue
449 + lines += self._dbapi.aux_get(cpv, aux_keys)[0].split('\n')
450 + # Cache NEEDED.* files avoid doing excessive IO for every rebuild.
451 + self._dbapi.flush_cache()
452 +
453 + # have to call scanelf for preserved libs here as they aren't
454 + # registered in NEEDED.XCOFF.1 files
455 + if self._dbapi.plib_registry and self._dbapi.plib_registry.getPreservedLibs():
456 + for items in self._dbapi.plib_registry.getPreservedLibs().values():
457 + for x in items:
458 + args = [BASH_BINARY, "-c", ':'
459 + + '; member="' + x + '"'
460 + + '; archive=${member}'
461 + + '; if [[ ${member##*/} == .*"["*"]" ]]'
462 + + '; then member=${member%/.*}/${member##*/.}'
463 + + '; archive=${member%[*}'
464 + + '; fi'
465 + + '; member=${member#${archive}}'
466 + + '; [[ -r ${archive} ]] || chmod a+r "${archive}"'
467 + + '; eval $(aixdll-query "${archive}${member}" FILE MEMBER FLAGS FORMAT RUNPATH DEPLIBS)'
468 + + '; [[ -n ${member} ]] && needed=${FILE##*/} || needed='
469 + + '; for deplib in ${DEPLIBS}'
470 + + '; do eval deplib=${deplib}'
471 + + '; if [[ ${deplib} != "." && ${deplib} != ".." ]]'
472 + + '; then needed="${needed}${needed:+,}${deplib}"'
473 + + '; fi'
474 + + '; done'
475 + + '; [[ -n ${MEMBER} ]] && MEMBER="[${MEMBER}]"'
476 + + '; [[ " ${FLAGS} " == *" SHROBJ "* ]] && soname=${FILE##*/}${MEMBER} || soname='
477 + + '; echo "${FORMAT##* }${FORMAT%%-*};${FILE#${ROOT%/}}${MEMBER};${soname};${RUNPATH};${needed}"'
478 + + '; [[ -n ${member} ]] || echo "${FORMAT##* }${FORMAT%%-*};${FILE#${ROOT%/}};${FILE##*/};;"'
479 + ]
480 + try:
481 + proc = subprocess.Popen(args, stdout=subprocess.PIPE)
482 + except EnvironmentError as e:
483 + if e.errno != errno.ENOENT:
484 + raise
485 + raise CommandNotFound("aixdll-query via " + argv[0])
486 + else:
487 + for l in proc.stdout:
488 + try:
489 + l = _unicode_decode(l,
490 + encoding=_encodings['content'], errors='strict')
491 + except UnicodeDecodeError:
492 + l = _unicode_decode(l,
493 + encoding=_encodings['content'], errors='replace')
494 + writemsg_level(_("\nError decoding characters " \
495 + "returned from aixdll-query: %s\n\n") % (l,),
496 + level=logging.ERROR, noiselevel=-1)
497 + l = l.rstrip("\n")
498 + if not l:
499 + continue
500 + fields = l.split(";")
501 + if len(fields) < 5:
502 + writemsg_level(_("\nWrong number of fields " \
503 + "returned from aixdll-query: %s\n\n") % (l,),
504 + level=logging.ERROR, noiselevel=-1)
505 + continue
506 + fields[1] = fields[1][root_len:]
507 + lines.append(";".join(fields))
508 + proc.wait()
509 +
510 + for l in lines:
511 + l = l.rstrip("\n")
512 + if not l:
513 + continue
514 + fields = l.split(";")
515 + if len(fields) < 5:
516 + writemsg_level(_("\nWrong number of fields " \
517 + "in %s: %s\n\n") % (self._needed_aux_key, l),
518 + level=logging.ERROR, noiselevel=-1)
519 + continue
520 + arch = fields[0]
521 +
522 + def as_contentmember(obj):
523 + if obj.endswith("]"):
524 + if obj.find("/") >= 0:
525 + return obj[:obj.rfind("/")] + "/." + obj[obj.rfind("/")+1:]
526 + return "." + obj
527 + return obj
528 +
529 + obj = as_contentmember(fields[1])
530 + soname = as_contentmember(fields[2])
531 + path = set([normalize_path(x) \
532 + for x in filter(None, fields[3].replace(
533 + "${ORIGIN}", os.path.dirname(obj)).replace(
534 + "$ORIGIN", os.path.dirname(obj)).split(":"))])
535 + needed = [as_contentmember(x) for x in fields[4].split(",") if x]
536 +
537 + obj_key = self._obj_key(obj)
538 + indexed = True
539 + myprops = obj_properties.get(obj_key)
540 + if myprops is None:
541 + indexed = False
542 + myprops = (arch, needed, path, soname, set())
543 + obj_properties[obj_key] = myprops
544 + # All object paths are added into the obj_properties tuple.
545 + myprops[4].add(obj)
546 +
547 + # Don't index the same file more that once since only one
548 + # set of data can be correct and therefore mixing data
549 + # may corrupt the index (include_file overrides previously
550 + # installed).
551 + if indexed:
552 + continue
553 +
554 + arch_map = libs.get(arch)
555 + if arch_map is None:
556 + arch_map = {}
557 + libs[arch] = arch_map
558 + if soname:
559 + soname_map = arch_map.get(soname)
560 + if soname_map is None:
561 + soname_map = self._soname_map_class(
562 + providers=set(), consumers=set())
563 + arch_map[soname] = soname_map
564 + soname_map.providers.add(obj_key)
565 + for needed_soname in needed:
566 + soname_map = arch_map.get(needed_soname)
567 + if soname_map is None:
568 + soname_map = self._soname_map_class(
569 + providers=set(), consumers=set())
570 + arch_map[needed_soname] = soname_map
571 + soname_map.consumers.add(obj_key)
572 +
573 + def getSoname(self, obj):
574 + """
575 + Return the soname associated with an object.
576 +
577 + @param obj: absolute path to an object
578 + @type obj: string (example: '/usr/bin/bar')
579 + @rtype: string
580 + @return: soname as a string
581 +
582 + """
583 + if not self._libs:
584 + self.rebuild()
585 + if isinstance(obj, self._ObjectKey):
586 + obj_key = obj
587 + if obj_key not in self._obj_properties:
588 + raise KeyError("%s not in object list" % obj_key)
589 + return self._obj_properties[obj_key][3]
590 + if obj not in self._obj_key_cache:
591 + raise KeyError("%s not in object list" % obj)
592 + return self._obj_properties[self._obj_key_cache[obj]][3]
593 +
594 class vardbapi(dbapi):
595
596 _excluded_dirs = ["CVS", "lost+found"]
597 @@ -1552,6 +1798,8 @@
598 self.linkmap = LinkageMapMachO(self)
599 elif chost.find('interix') >= 0 or chost.find('winnt') >= 0:
600 self.linkmap = LinkageMapPeCoff(self)
601 + elif chost.find('aix'):
602 + self.linkmap = LinkageMapXCoff(self)
603 else:
604 self.linkmap = LinkageMap(self)
605 self._owners = self._owners_db(self)
606 @@ -3698,6 +3946,8 @@
607 node = LinkageMapMachO._LibGraphNode(path, root)
608 elif chost.find('interix') >= 0 or chost.find('winnt') >= 0:
609 node = LinkageMapPeCoff._LibGraphNode(path, root)
610 + elif chost.find('aix') >= 0:
611 + node = LinkageMapXCoff._LibGraphNode(path, root)
612 else:
613 node = LinkageMap._LibGraphNode(path, root)
614 alt_path_node = lib_graph.get(node)