Взаимодействие z/OS MVS и z/OS UNIX в программе PL/I?

Я искал разные ресурсы в Интернете, но не смог найти однозначного ответа, который понял, поэтому я спрашиваю здесь:

Как я могу вызвать z/OS UNIX-код из z/OS MVS?

Я знаю что BPXBATCH PGM ... может вызвать программу z/OS UNIX из z/OS MVS TSO.

Но можно ли это сделать, например, внутри программы z/OS MVS PL/I?

Что я хочу сказать,

  • Могу ли я статически связать вместе объектные модули z/OS MVS PL/I и объектные модули z/OS UNIX C? (Есть ли разница между обоими, кроме разных языков программирования?)
  • Или я могу динамически связать оба?

Мой пример использования: у меня есть старая библиотека PL / I 1970-х годов, которая теперь требует сетевого взаимодействия. И, насколько я понял, работа в сети в мире z/OS UNIX прошла гладко.

Старая библиотека PL / I статически связана с множеством других программ, на которые я не могу влиять напрямую.

PS: Может кто-то с большей репутацией, пожалуйста, установите тег PLI Stackru?;-)

3 ответа

Одной из целей среды исполнения IBM Language Environment (LE) было обеспечение взаимодействия между COBOL, PL/I, Assembler и FORTRAN. C и C++ позже пришли на прогулку.

Компиляторы, которые генерировали код, не соответствующий требованиям LE, не очень хорошо взаимодействовали друг с другом (если бы вы были осторожны, вы могли бы заставить всех игроков работать вместе). Компиляторы, которые генерируют код, соответствующий LE, хорошо играют друг с другом. Я написал код на языке COBOL, который использует подпрограммы времени выполнения C (fopen, fseek, fread, fclose, различные подпрограммы регулярных выражений), и это работало нормально благодаря LE.

Ваш ответ "Ну, вроде" на мой вопрос о том, используете ли вы IBM Enterprise PL/I, может указывать на то, что вы уже находитесь в неподдерживаемой конфигурации.

Если ваша среда выполнения - LE, вы должны нормально вызывать подпрограммы времени выполнения C, которые поставляет IBM. Если ваша среда выполнения включает в себя некоторые из старых неподдерживаемых подпрограмм OS PL/I, вы могли бы получать вызовы к подпрограммам C времени выполнения, которые IBM поставляет на работу, - но в таком случае я не мог бы спать спокойно. Если вы можете связать свой старый код с использованием LE-версий старых подпрограмм времени выполнения OS PL/I, вы можете оказаться на более прочной основе.

Существует большая путаница в отношениях между z/OS и сервисами UNIX, но следует помнить, что это не две разные вещи... практически любая задача может стать процессом UNIX и выполнять вызовы функций USS с правильная настройка.

Так что на самом деле ваш вопрос состоит из двух вопросов в одном:

  1. Как мне перезаписать мою задачу как процесс UNIX, чтобы я мог запускать функции ядра USS?
  2. Совместим ли мой PL/I-компилятор со средой выполнения LE и с объектными библиотеками, код которых построен с использованием других языков LE?

Первая часть - как дублировать ваш процесс как процесс UNIX - довольно проста. Подход IBM требует, чтобы вы были подключены к ядру USS (адресному пространству OMVS), прежде чем вы сможете вызывать функции UNIX, но обычно это происходит автоматически при первом запуске функции USS.

Вам необходимо определенное количество настроек системы, прежде чем использовать USS. Конечно, сама OMVS должна быть активной (хотя в наши дни ее не бывает). Ваш администратор безопасности должен дать вам номер UID и, возможно, создать домашний каталог для вас. Предполагая, что с этой частью все в порядке, все, что вам нужно сделать, это вызвать функцию USS, и теперь вы - процесс UNIX Services.

Практически любое приложение может вызывать вызываемые службы IBM USS (это все модули с именами, начинающимися с BPX1/BPX4) - все, что нужно, это что-то, поддерживающее стандартную связь ОС. Действительно, это в значительной степени то, что делают библиотеки времени выполнения IBM. Хорошим тестом будет вызов BPX1GPI (это UNIX "getpid()")... он возвращает ваш идентификатор процесса UNIX, и если вы можете заставить это работать, вы можете использовать большинство других сервисов UNIX. Если бы вы следили за реализацией LE "getpid()", вы бы обнаружили, что это не намного больше, чем тонкий слой над BPX1GPI, поэтому нет никаких причин, по которым вы не можете вызывать базовую функцию самостоятельно... это работает с большинством из функций ядра USS, а не просто getpid(), поэтому, если вы не можете понять, как открыть сокет, вызов BPX1SOC всегда является хорошим "планом B".

Имейте в виду, что есть разница между процессом UNIX и работой под чем-то вроде оболочки bash... оболочка выполняет такие вещи, как настройка STDIN/OUT/ERR и т. Д. - если вам это нужно, вам нужно это самостоятельно, если вы просто подключаетесь к USS из ниоткуда. Вы не можете вызывать такие вещи, как printf(), пока не настроите стандартные дескрипторы файлов.

Простой способ начать работу - это написать себе короткую C-программу, которая запускается как процесс UNIX, настроить STDIN/OUT/ERR (и все, что вам нужно), а затем вызвать вашу текущую PL/I-программу. Это "оборачивает" ваш текущий код таким образом, что настраивает любые элементы USS, в которых вы нуждаетесь, без необходимости делать это в PL/I. Вы также можете найти этот удобный способ сделать некоторые вещи, которые в противном случае являются сложными в PL/I, такие как вызов функций DLL... просто напишите короткую функцию C, чтобы сделать то, что вам нужно, и затем вызовите эту функцию из вашего PL / Я кодирую.

Что касается второй части вашего вопроса, если ваш PL/I использует среду выполнения LE (что будет, если только она не очень старая), то смешивание кода из других библиотек будет намного проще, чем кажется. Что касается основной среды выполнения, в большинстве случаев функции среды выполнения LE достаточно умны, чтобы быть "бимодальными" в том смысле, что одна и та же функция времени выполнения работает как в процессах USS, так и в процессах, не связанных с USS. Код объекта - это объектный код, и разница между (скажем) открытым файлом z/OS и открытым файлом служб UNIX не более чем то, вызывает ли среда выполнения вызовы SVC 19 (для z/OS OPEN) или BPX1OPN (для файлов служб UNIX). Это просто означает, что после того, как ваш код перезаписан как процесс USS, вы можете в большинстве случаев смешивать функции z/OS и USS по своему усмотрению.

Это также означает, что нет причин, по которым вы не можете использовать такие вещи, как "libxyz.a" в программе PL/I, при условии, что на уровне LE нет несовместимости и так далее. Может оказаться сложной задачей заставить связывателя решить все так, как вы ожидаете, но все должно работать, если вы будете настойчивы.

Там будет несколько вещей, которые трудно от PL/I (и я прошу прощения - я не эксперт PL/I). Примером может быть вызов чего-то похожего на ваш пример libcurl, где библиотека представляет собой DLL, а не статический архив. Опять же, хитрость здесь может заключаться в использовании короткого "заглушки" C, который вы можете вызвать из PL/I, и этот код может сделать магию, необходимую для загрузки и вызова DLL. В противном случае, я думаю, вы найдете это довольно простое упражнение, как только соберете все части.

Ответьте только на часть вопроса "статическое связывание объектов C и PL/I".

Скомпилированный объект из C или PL/I - это просто скомпилированные объекты. Где вы их компилируете (TSO или USS) не имеет значения; а также где они находятся (каталог PDS/PDSE или HFS) также не имеют значения.

Фактически вы можете легко скопировать из HFS (например, hello.o) на PDS.

cp hello.o "//'MYHLQ.OBJ(HELLO)'"

или даже скомпилировать в USS и вывести.o на PDS

c89 -c hello.c -o "//'MYHLQ.OBJ(HELLO)'"

и затем используйте BINDER для связи (или наоборот, скопируйте OBJECT из PDS в HFS и используйте ld для связи)

Однако существует 2 формата объектных файлов: XOBJ и GOFF.

GOFF - более новый формат, и если вы используете XPLINK, это предварительное требование. Программа 64bit LE на z/OS также требует XPLINK. Сам GOFF также предварительно требует PDS/E.

Другие вопросы по тегам