Чт, 26.12.2024, 22:07
Приветствую Вас Гость | RSS
Главная | Как определить в какой среде выполняется программа? - Форум | Регистрация | Вход
Форма входа
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Как определить в какой среде выполняется программа?
GregoryДата: Ср, 20.09.2017, 22:46 | Сообщение # 1
Генерал-майор
Группа: Доверенные
Сообщений: 482
Репутация: 22
Статус: Offline
Программа в z/OS может быть выполнена:
1. в задании // EXEC PGM=...
2. в TSO // EXEC PGM=IKJEFT01,PARM=' CALL ...'
3. в ISPF // EXEC PGM=IKJEFT01,PARM=' ISPSTART PGM(...)'
4. в shell // EXEC PGM=BPXBATCH,PARM='pgm ...'
5. в CICS region как транзакция CICS
6. в IMS region как транзакция IMS
7. в TSO под управлением CAF // EXEC PGM=IKJEFT01,PARM=' DSN ...'
8. в DB2 как внешняя хранимая процедура
etc...

ограничиваясь 1-4 (так как в 5-8 не может быть выполнена любая программа), как определить, в какой именно среде выполняется программа?

Идеи:
- выполнить какой-нибудь вызов сервиса данной среды, например, чтобы определить 3. выполнить какой-нибудь ISPCALL, скажем 'VDEFINE ...' и если код возврата равен 0, то считать что программа вызвана из ISPF. Поскольку вызов сервиса не должен приводить к abend  в других средах, не очень понятно, какие вызовы для этого использовать.
- использовать IRXSUBCM, чтобы установить наличие определенных host environment:
CALL IRXSUBCM('QUERY   ',SCRPTR,32,'ISPEXEC ',ENVBPTR,RETCODE);
или эквивалент 'SUBCOM имя' в REXX. Этот подход выглядит многообещающе, и действительно, позволяет легко различить 1-3 (проверка среды TSO, ISPEXEC), но я не смог применить его для shell (4).
Несмотря на то, что среда SH существует, вызов
CALL IRXSUBCM('QUERY   ',SCTPTR,32,'SH        ',ENVBPTR,RETCODE);
возвращает код 28, и таким способом не получается различить 1 и 4
- анализ управляющих блоков? а каких именно?

Для начала задам частный вопрос - как отличить 1 и 4, иными словами, как определить что программа выполняется в z/OS UNIX (shell)?


Сообщение отредактировал Gregory - Чт, 21.09.2017, 09:36
 
BibizyanДата: Сб, 23.09.2017, 12:48 | Сообщение # 2
Подполковник
Группа: Проверенные
Сообщений: 131
Репутация: 0
Статус: Offline
А просто прочесть JCL и сделать парсинг? 
Ну или ещё проще - добавить опциональный параметр.
 
AKonevДата: Сб, 23.09.2017, 21:18 | Сообщение # 3
Лейтенант
Группа: Проверенные
Сообщений: 66
Репутация: 5
Статус: Offline
Для начала TSO-Batch TSO-ONLINE

         L     R2,TCBJSCB              my JSCB                                  
         USING IEZJSCB,R2                                                       
         ICM   R3,B'1111',JSCBPSCB     TSO PSCB                                 
         JNZ   INIT645L                TSO, jump                                
INIT645N OI    NON_TSO,L'NON_TSO                                                
         J     INIT680                 no TSO, no ISPF                          
INIT645L ST    R3,PSCB@                save PSCB address                        
         MVC   UPT@,PSCBUPT-PSCB(R3)   save ECT address                         
         L     R3,PSAAOLD-PSA(,0)      point at ASCB                            
         USING ASCB,R3                                                          
         L     R4,ASCBASXB             my ASXB                                  
         L     R4,ASXBLWA-ASXB(,R4)    Logon Work Area                          
         ST    R4,LWA@                 save LWA address                         
         USING LWA,R4                                                           
         MVC   ECT@,LWAPECT            SAVE FOR PUTLINE                         
         ICM   R14,B'1111',ASCBTSB     check TSB address                        
         JNZ   INIT645T                TSO on-line, jump                        
INIT645B OI    TSO_BATCH,L'TSO_BATCH                                            
         J     INIT645X                                                         
INIT645T OI    TSO_ON_LINE,L'TSO_ON_LINE
 
GregoryДата: Вс, 24.09.2017, 22:53 | Сообщение # 4
Генерал-майор
Группа: Доверенные
Сообщений: 482
Репутация: 22
Статус: Offline
Цитата Bibizyan ()
А просто прочесть JCL и сделать парсинг?
не могли бы Вы пояснить?

Цитата Bibizyan ()
Ну или ещё проще - добавить опциональный параметр.
Это, конечно, решение. Но, согласитесь, странно сообщать программе то, что она может узнать сама... Да, подобные параметры существуют, например:

//   EXEC PGM=IEBGENER
...
//SYSIN DD *
GENERATE TYPORG=PS
RECORD FILED=(80)

программа выдает сообщение об ошибке, так как в GENERATE нужно указать, сколько будет операторов RECORD:
GENERATE TYPORG=PS,MAXFLDS=10

как будто программа сама определить это не в состоянии...


Сообщение отредактировал Gregory - Вс, 24.09.2017, 23:17
 
GregoryДата: Вс, 24.09.2017, 22:59 | Сообщение # 5
Генерал-майор
Группа: Доверенные
Сообщений: 482
Репутация: 22
Статус: Offline
Цитата AKonev ()
Для начала TSO-Batch TSO-ONLINE
А такая задача не ставилась :-)
Как в batch TSO, так и в online TSO все сервисы TSO доступны и могут использоваться. То же касается и online ISPF / batch ISPF.
 
AKonevДата: Пн, 25.09.2017, 11:12 | Сообщение # 6
Лейтенант
Группа: Проверенные
Сообщений: 66
Репутация: 5
Статус: Offline
Цитата Gregory ()
А такая задача не ставилась :-)
А как же позиция 2 smile
Ну да ладно,
Позиция 1, без команд

- из своего TCB определяем TCB шага задания (TCBJSTCB)
- читаем адрес текущего RB (TCBRBP)
- идем по цепочке RB (CDCHAIN), до нужного, то есть когда адрес следующего RB равен адресу TCBшага (RBLINKB)
- читаем CDE (RBCDE)
- на всякий случай убеждаемся что CDE - главное
- из CDE читаем имя (CDNAME)
- сравниваем с своим именем, при равенстве - запуск по EXEC
Как-то так (возможны варианты smile )

С запуском в шелл, надо посмотреть решение поэлегантнее, но в принципе метод может быть тем же (наш модуль вряд ли  будет в начале цепочки RB).
Плюс могут быть разные варианты запуска нашего модуля (spawn или exec) или еще какой-нибудь OMVS-экзот
 
BibizyanДата: Пн, 25.09.2017, 12:18 | Сообщение # 7
Подполковник
Группа: Проверенные
Сообщений: 131
Репутация: 0
Статус: Offline
Цитата Gregory ()
Это, конечно, решение. Но, согласитесь, странно сообщать программе то, что она может узнать сама...
Зато просто! И всегда абсолютно точный результат.

Цитата Gregory ()
не могли бы Вы пояснить?
Надо поискать, где-то у меня должно быть... Точно помню, что писали код, который добирается до текста (читает JESJCL? не помню точно), и потом уже тупо делает парсинг в поисках нужного.
 
GregoryДата: Пн, 25.09.2017, 13:59 | Сообщение # 8
Генерал-майор
Группа: Доверенные
Сообщений: 482
Репутация: 22
Статус: Offline
Цитата Bibizyan ()
Точно помню, что писали код, который добирается до текста (читает JESJCL? не помню точно), и потом уже тупо делает парсинг в поисках нужного.
интересно было бы взглянуть, несмотря на то, что это способ принципиально не может гарантировать абсолютно достоверный результат:
//  EXEC PGM=IKJEFT01
//STEPLIB DD DSN=MY.LOADLIB
это TSO? :-)
 
AKonevДата: Пн, 25.09.2017, 15:05 | Сообщение # 9
Лейтенант
Группа: Проверенные
Сообщений: 66
Репутация: 5
Статус: Offline
Метод поиска текста JCL не годится
1. Можем стартовать например процедурой под SUB=MSTR, если нам ничего не нужно от JES-а, а там добраться до JCL проблематично (JCT вроде бы и есть, а фактически его нет, неизвестно как его искать)
2. наша программа чаще всего под USS выполняется в дочернем адресном пространстве USS, а не в родительском (зависит от настроек), опять же JCT есть только у родительского
3. есть еще много вариантов, когда адресное пространство есть, программа там выполняется, а JCL как бы нет или оно чужое
 
GregoryДата: Пн, 25.09.2017, 16:01 | Сообщение # 10
Генерал-майор
Группа: Доверенные
Сообщений: 482
Репутация: 22
Статус: Offline
Цитата AKonev ()
- из своего TCB определяем TCB шага задания (TCBJSTCB)
- читаем адрес текущего RB (TCBRBP)
- идем по цепочке RB (CDCHAIN), до нужного, то есть когда адрес следующего RB равен адресу TCBшага (RBLINKB)
- читаем CDE (RBCDE)
- на всякий случай убеждаемся что CDE - главное
- из CDE читаем имя (CDNAME)
- сравниваем с своим именем, при равенстве - запуск по EXEC
спасибо, сейчас посмотрю, что получается!

кстати, нашел обсуждение аналогичного вопроса
 
GregoryДата: Пн, 25.09.2017, 16:33 | Сообщение # 11
Генерал-майор
Группа: Доверенные
Сообщений: 482
Репутация: 22
Статус: Offline
в тему biggrin
 
BibizyanДата: Пн, 25.09.2017, 19:01 | Сообщение # 12
Подполковник
Группа: Проверенные
Сообщений: 131
Репутация: 0
Статус: Offline
ну я ж говорю - самый быстрый, надёжный и точный способ, это передавать параметр!

Добавлено (25.09.2017, 19:01)
---------------------------------------------

Цитата Gregory ()
//  EXEC PGM=IKJEFT01//STEPLIB DD DSN=MY.LOADLIB
это TSO? :-)
а вот в VSE в явном виде пишется, откуда именно загружен модуль...
 
GregoryДата: Вт, 26.09.2017, 11:55 | Сообщение # 13
Генерал-майор
Группа: Доверенные
Сообщений: 482
Репутация: 22
Статус: Offline
Цитата Bibizyan ()
самый быстрый, надёжный и точный способ, это передавать параметр!
Так тогда уж лучше использовать разные точки входа в программу: ABCTSO, ABCJCL, ABCUSS etc. Передача параметров требует изменений в вызывающей программе и не всегда так уж проста.
 
BibizyanДата: Ср, 27.09.2017, 10:24 | Сообщение # 14
Подполковник
Группа: Проверенные
Сообщений: 131
Репутация: 0
Статус: Offline
ну так разные точки входа тоже же требуют изменений в вызывающей программе!
а что сложного в передаче ассемблерной программе ешё одного, опционального, параметра?
 
AKonevДата: Чт, 28.09.2017, 11:53 | Сообщение # 15
Лейтенант
Группа: Проверенные
Сообщений: 66
Репутация: 5
Статус: Offline
Может быть пригодится

В блоке CSCB есть такая информация

CHTRKID  DS    CL1 -     CSCB TYPE IDENTIFIER            
CHTSID   EQU   X'01' -   TIME SHARING USER IDENTIFIER    
CHJOBID  EQU   X'02' -   JOB IDENTIFIER                  
CHINITID EQU   X'03' -   INITIATOR IDENTIFIER            
CHSASID  EQU   X'04' -   SYSTEM ADDRESS SPACE IDENTIFIER
CHATXPID EQU   X'05' -   ATX ADDRESS SPACE IDENTIFIER   

Последнее - это APPC, так что не актуально

System Automaition еще как-то различает MOUNT и Started Task
Других делений по типу адресного пространства нет.
Unix-процесс может быть порожден совершенно разными способами, так что для него остается один выход - сканировать CDE и по именам модулей определять кто же нас вызвал
 
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск: