Введение

На классической Mac OS (оригинальной операционной системе Apple Macintosh) расширения представляли собой небольшие фрагменты кода, расширяющие функциональность системы. Они запускались при старте системы и работали с помощью различных механизмов, включая перехват вызовов (trap patching) и другие методы модификации кода. Изначально являясь хаком разработчиков Apple, расширения стали стандартным способом создания модульной операционной системы. Значительные объемы важных системных служб, таких как сетевые стеки TCP/IP (MacTCP и Open Transport) и поддержка USB и FireWire, были реализованы как необязательные компоненты в виде расширений. Позже термин "системное расширение" стал включать в себя и фоновые приложения, работающие без видимого интерфейса. Расширения выполняли схожую роль с программами, остающимися в памяти DOS (terminate and stay resident), или демонами Unix, однако, благодаря возможности модификации кода операционной системы, они могли изменять поведение существующей ОС, в отличие от двух последних.

Механизм INIT

Концепция расширений отсутствовала в оригинальном системном программном обеспечении Macintosh, но система, тем не менее, имела механизм скрытого патчинга, которым разработчики вскоре научились пользоваться, используя загрузчик INIT. Этот код искал системные ресурсы типа 'INIT', загружал и запускал их при загрузке системы. Ресурсы кода должны были храниться непосредственно в ресурсной вилке системного файла Mac System, что делало их доступными лишь для "опытных пользователей", умеющих работать с ResEdit или другими редакторами ресурсов. Поскольку использование этого механизма было несанкционированным обходным путем, и таким образом можно было загрузить только 32 INIT-файла, Apple предложила более управляемое решение. Изначально оно представляло собой ресурс 'INIT' с ID 31, размещенный в системном файле, который искал дополнительные файлы типа 'INIT' в системной папке и загружал и запускал ресурсы INIT, содержащиеся в них. (Именно поэтому некоторые ветераны программирования на Mac до сих пор называют механизм загрузки расширений "трюком с INIT 31"). Теперь установить INIT можно было просто, поместив файл в системную папку, что было под силу обычному пользователю. Начиная с System 7, расширения были перемещены в папку Extensions внутри системной папки для удобства, и был реализован механизм автоматической маршрутизации, так что перетаскивание расширения в системную папку фактически помещало файл в соответствующую подпапку. Расширения сохраняли ресурсный тип 'INIT' на протяжении всего времени своего существования, а загрузчик постепенно совершенствовался для поиска этих ресурсов в различных местах, включая ресурсные вилки панелей управления в разных форматах и программу Chooser.

Расширения

INIT превратились в расширения системы, получив дополнительные протоколы, разработанные по мере необходимости, такие как предоставление иконки для отображения при загрузке (это восходит к функции 'ShowINIT'). "Парад фрагментов и иконок" на экране во время загрузки каждого расширения стал привычным зрелищем для всех пользователей Mac. В конечном итоге Apple начала выпускать основные (но необязательные) компоненты операционной системы в виде расширений, такие как QuickTime, QuickDraw 3D и многие другие. Значительное количество служб и драйверов в Mac OS – как официальных, так и сторонних – предоставлялись в виде расширений, что позволяло уменьшить размер ОС, отключая их. Системные расширения часто были причиной нестабильности Macintosh, поскольку сторонний код отличался переменным качеством и нередко вносил изменения в систему, которые работали некорректно. Некоторые расширения не работали друг с другом или требовали загрузки в определенном порядке. Кроме того, разные расширения могли пытаться изменить один и тот же участок системы, что приводило к конфликтам расширений и другим проблемам с устойчивостью. Поиск источников этих проблем был задачей, с которой сталкивался практически каждый пользователь Mac. Диагностика проблем с расширениями Mac OS могла быть длительным процессом, включающим последовательное отключение и тестирование. Самый простой способ загрузить операционную систему в чистом режиме – удерживать клавишу Shift: загрузка расширений будет пропущена. Система 7.5 представила Менеджер расширений, который позволял пользователю быстро включать или отключать отдельные расширения, а также создавать наборы расширений, которые гарантированно работали вместе. Менеджер расширений поставлялся с двумя предустановленными наборами только для чтения: один содержал минимальный набор расширений, необходимый для базовой работы ОС, а другой включал все официальные расширения, поставляемые с ОС, но отключал все сторонние расширения. Порядок загрузки расширений был побочным эффектом функции GetFInfo, которую загрузчик использовал для перечисления файлов в папке Расширений. Хотя Apple всегда утверждала, что порядок, получаемый в результате перечисления файлов с помощью этой функции, не определен, на томах HFS эта функция перечисляла файлы в порядке, в котором они хранились в каталоге HFS. Пользователи обнаружили, что изменение первого символа в имени файла может изменить порядок загрузки расширений, что вызвало проблемы при переходе Mac OS 8.1 на HFS+. В конечном итоге Apple пришлось изменить загрузчик, чтобы сортировать имена файлов, возвращаемые этой функцией, в таблицу и предоставить интерфейс для изменения этой таблицы программным обеспечением.

Конфигурационные и панели управления

У расширений системы не было пользовательского интерфейса: не существовало стандартного механизма, позволяющего пользователю настраивать службы, предоставляемые расширением. Расширения могли изменять графический интерфейс (например, добавлять новые пункты в меню) и таким образом принимать пользовательские настройки, либо поставлялись вместе с приложением, предоставляющим интерфейс конфигурации. Начиная с System 7, панели управления стали отдельными плагинами Finder на диске, которые пользователь мог запускать. Встраивая код INIT в панель управления, стало возможным создавать гибридные расширения/панели управления, которые изменяли операционную систему при загрузке и содержали собственный встроенный интерфейс конфигурации, аналогичный любому другому интерфейсу панели управления операционной системы.

Приложения безликого фона

MultiFinder и System 7 и более поздние версии поддерживали фоновые приложения без видимого интерфейса, аналогичные демонам UNIX или службам Windows, хотя и использующие кооперативную многозадачность. Примеры включают в себя синхронизатор времени (для корректировки времени суток и удаленной синхронизации времени), планировщик обновления программного обеспечения и действия папок (для обработки событий папок). Фоновые приложения без видимого интерфейса были обычными приложениями с ограничением, заключающимся в том, что они не отображались в меню приложений. Единственным техническим отличием между фоновым приложением без видимого интерфейса и обычным приложением являлся флаг "Только фоновый", установленный в ресурсе 'SIZE'. Им было запрещено открывать окна стандартного уровня приложения: в противном случае система зависала. Однако они могли открывать глобальные плавающие окна, поскольку те не могли ни получать, ни терять фокус. Панель управления в Mac OS 8 и 9 являлась примером фонового приложения без видимого интерфейса, отображавшего глобальное плавающее окно для взаимодействия с пользователем. Переключатель приложений (Application Switcher) также был таким приложением. Однако пользователь не осознавал, что панель управления является запущенным процессом; она просто представлялась как дополнительная функция интерфейса. Система описывала фоновые приложения без видимого интерфейса как "системные приложения". Языковые функции в архитектуре Open Scripting Architecture (и, следовательно, в AppleScript) первоначально были реализованы в виде динамически загружаемых плагинов, известных как "скриптовые расширения" или OSAXes. В Mac OS 8 и 9 они дополнялись фоновыми приложениями без видимого интерфейса, которые загружались в фоновом режиме по требованию. Как и в случае с обычными приложениями, к этим приложениям осуществлялся доступ с помощью конструкций `tell`: глобальное пространство имен не обновлялось, в отличие от OSAXes. Операционная система не сообщала о запуске таких процессов и не указывала, работают ли они в данный момент.

Прочие расширения, не относящиеся к INIT

Расширения типа INIT загружались при загрузке системы для обновления операционной системы. Сбивает с толку то, что в папку "Extensions" можно было помещать и другие файлы, многие из которых не загружались при загрузке. Наиболее заметными из них были разделяемые библиотеки, которые часто помещали в папку "Extensions" для удобства поиска. Разделяемые библиотеки не загружались при загрузке. Файлы типа INIT были не единственным типом системных расширений. Другим типом были файлы scri, или расширения WorldScript. Загрузчик BootX Linux был реализован как scri, поскольку такие файлы загружались на очень раннем этапе процесса загрузки, до всех остальных расширений. BootX мог затем отображать диалоговое окно, предлагая пользователю завершить загрузку Mac OS или загрузить Linux вместо этого.