Самый легкий способ работы с совместно используемыми библиотеками — игнорировать тот факт, что она совместная. Компилятор С автоматически задействует совместно используемые библиотеки вместо статических, если ему явно не указано обратное.
Тем не менее, существуют и три других способа взаимодействия с совместно используемыми библиотеками. Первый способ, явно загружающий и выгружающий библиотеки из программы во время ее работы, называется динамической загрузкой и рассматривается в главе 27. Два других способа описаны ниже.
8.6.1. Использование деинсталлированных библиотек
После запуска программы динамический загрузчик обычно ищет необходимые программе библиотеки в кэше (/etc/ld.so.cache
, созданном ldconfig
) библиотек, которые находятся в каталогах, записанных в /etc/ld.so.conf
. Однако если установлена переменная окружения LD_LIBRARY_PATH
, поиск осуществляется сначала в каталогах, перечисленных в ней. Это значит, что если вы хотите использовать измененную версию библиотеки С при работе с определенной программой, эту библиотеку можно поместить в любой каталог и соответствующим образом изменить LD_LIBRARY_PATH
. Например, некоторые версии браузера Netscape, скомпонованные с версией 5.2.18 библиотеки С, не будут работать вследствие ошибки сегментации при запуске со стандартной библиотекой С 5.3.12. Это происходит из-за более строгой политики malloc()
. Многие помещают копию библиотеки С 5.2.18 в отдельный каталог, например, /usr/local/netscape/lib/
, переносят туда исполняемый файл браузера Netscape и заменяют /usr/local/bin/netscape
сценарием оболочки, который выглядит примерно так:
#!/bin/sh
export LD_LIBRARY_PATH=/usr/local/netscape/lib:$LD_LIBRARY_PATH
exec /usr/local/netscape/lib/netscape $*
8.6.2. Предварительная загрузка библиотек
В некоторых случаях вместо замены целой библиотеки совместно использования возникает необходимость замены лишь нескольких функций. Вследствие того, что динамический загрузчик выполняет поиск функций, начиная с первой загруженной библиотеки, и продолжает искать в порядке очереди среди массы библиотек, было бы удобно иметь возможность помещать альтернативную библиотеку в начало списка для замены только необходимых функций.
Пример может служить zlibc
. Эта библиотека заменяет файловые функции библиотеки С функциями, которые работают со сжатыми файлами. При открытии файла zlibc
ищет как запрашиваемый файл, так и gzip-версию файла. Если запрашиваемый файл существует, zlibc
в точности воспроизводит функцию библиотеки С, но если файла нет, а вместо него обнаруживается gzip-версия, библиотека распаковывает gzip-файл безо всякого уведомления приложения. Связанные с ней ограничения описаны в документации, zlibc
позволяет значительно увеличить количество свободного пространства на диске, разумеется, за счет снижения скорости. Существуют два способа предварительной загрузки библиотеки. Для действия только на определенные программы, можно установить переменную окружения для необходимых случаев:
LD_PRELOAD=/lib/libsomething.o exec /bin/someprogram $*
Кроме того, как и с zlibc
, может возникнуть потребность предварительно загрузить библиотеку для всех программ в системе. Самый простой способ для этого — добавить в файл /etc/ld.so.preload
строку, которая указывает библиотеку, подлежащую загрузке. Для случая zlibc
строка будет выглядеть следующим образом:
/lib/uncompress.о
Глава 9
Системное окружение Linux
В этой главе рассматривается процесс запроса системных служб, включая низкоуровневые средства ядра и высокоуровневые возможности библиотек.
9.1. Окружение процесса
Как подробно описано в главе 10, в каждом выполняющемся процессе есть переменные окружения. Переменные окружения представляют собой пары "имя-значение", и некоторые из них представляют ценность для программистов на языке С. (Многие переменные в первую очередь используются при программировании оболочки, как ускоренные альтернативы запуску программ, вызывающих функции библиотек; в этой книге они описываться не будут.)