外部コールの使用

プログラム中のインクリメントとデクリメント関数は、特定のプラットフォームに応じた共有ライブラリ libunits.sl または libunits.so を介して、あるいは、libcrement.dll のようなDLLを介して、GT.Mで利用できます。サフィックス .sl は、.sl または .so のどちらかを表す次の例で至る所で使用されています。お使いのプラットフォーム用に適切なサフィックスを使用してください。

GT.Mでは、Cの型指定されたデータへおよびその逆に、Mの型のないデータをマップするには "外部コール·テーブル"を使用します。外部コールテーブルは、次ようなフォーマットの1つ以上の指定行に続いて共有ライブラリファイルのパス名を含む最初の行を持ちます。

entryref: return-value routine-name (parameter, parameter, ... )        

エントリ参照(entryref) は M の entryref ですが、

return-value is gtm_long_t, gtm_status_t, or void.

そして:

parameters are in the format: direction:type [num]

ここで、[num]は、この章の後半で説明する事前に割り当てする値(pre-allocation valu)を示します。

正しいディレクションは、入力、出力、入力/出力 はそれぞれ、I、O、IOです。

次の表は、Cのヘッダーファイル $gtm_dist/gtmxc_types.h で定義されている正しい型式について説明します。

Type : Usage

Void: Specifies that the function does not return a value.

gtm_status_t : Type int. もし関数がゼロ(0)を返すならば、成功を返します。もし非ゼロの値を返すならば、GT.MはMへ戻った時にエラーを通知します。

gtm_long_t : 32-bit signed integer on 32-bit platforms and 64-bit signed integer on 64-bit platforms (except on Tru64 UNIX where GT.M remains a 32-bit application).

gtm_ulong_t : 32-bit unsigned integer on 32-bit platforms and 64-bit signed integer on 64-bit platforms.

gtm_long_t* : For passing a pointer to long [integers].

gtm_float_t* : For passing a pointer to floating point numbers.

gtm_double_t* : Same as above, but double precision.

gtm_char_t*: For passing a "C" style string - null terminated.

gtm_char_t** : For passing a pointer to a "C" style string.

gtm_string_t* : For passing a structure in the form {int length;char *address}. GT.Mから、または、GT.Mへ、メモリのブロックを移動する際に有益です

gtm_pointertofunc_t : For passing callback function pointers. For details see “Callback Mechanism”.

[注意] 注意

If an external call's function argument is defined in the external call table, GT.M allows invoking that function without specifying a value of the argument. All non-trailing and output-only arguments arguments which do not specify a value translate to the following default values in C:

  • All numeric types: 0

  • gtm_char_t * and gtm_char_t **: Empty string

  • gtm_string_t *: A structure with 'length' field matching the preallocation size and 'address' field being a NULL pointer.

In the mathpak package example, the following invocation translate inval to the default value, that is, 0.

GTM>do &mathpak.increment(,.outval)

If an external call's function argument is defined in the external call table and that function is invoked without specifying the argument, ensure that the external call function appropriately handles the missing argument. As a good programming practice, always ensure that count of arguments defined in the external call table matches the function invocation.

gtmxc_types.h also includes definitions for the following entry points exported from libgtmshr:

void gtm_hiber_start(gtm_uint_t mssleep);
void gtm_hiber_start_wait_any(gtm_uint_t mssleep)
void gtm_start_timer(gtm_tid_t tid, gtm_int_t time_to_expir, void (*handler)(), gtm_int_t hdata_len, void \*hdata);
void gtm_cancel_timer(gtm_tid_t tid);

これは:

gtm_hiber_start() always sleeps until the time expires; gtm_hiber_start_wait_any() sleeps until the time expires or an interrupt by any signal (including another timer). gtm_start_timer() starts a timer but returns immediately (no sleeping) and drives the given handler when time expires unless the timer is canceled.

[重要] 重要

GT.M continues to support xc_* equivalent types of gtm_* for upward compatibility. gtmxc_types.h explicitly marks the xc_* equivalent types as deprecated.

The first parameter of each called routine is an int (for example, int argc in decrement.c and increment.c) that specifies the number of parameters passed. このパラメータは、暗黙的であり、コールされるルーチンの中だけで表示します。コール テーブルの仕様で、または、Mの呼び出しで表示されません。もし明示的なパラメータが存在しない場合、この値はカウントに自分自身を含まないので、コールテーブル仕様では 0(ゼロ)の値を持つでしょう。もし仮パラメータよりも少ない実パラメータがある場合、コールは、Mプログラムによって与えられた値によって指定されたパラメータによって決定されます。残りのパラメータは未定義です。もし仮パラメータ以上の実パラメータがある場合、GT.Mはエラーを報告します。

There may be only a single occurrence of the type gtm_status_t for each entryref.

GT.M 外部インターフェイスへデータベース暗号化の拡張

To support Database Encryption, GT.M provides a reference implementation which resides in $gtm_dist/plugin/gtmcrypt.

参照実装には次のものが含まれます:

  • すべてのソース・ファイルとスクリプトを含む $gtm_dist/plugin/gtmcrypt サブディレクトリにあります。The scripts include those needed to build/install libgtmcrypt.so and "helper" scripts, for example, add_db_key.sh (see below).

  • GT.Mが期待するプラグイン・インタフェースは、gtmcrypt_interface.h で定義されています。このファイルを変更しないでください。プラグインが提供しなければならないインターフェースを定義します。

  • $gtm_dist/plugin/libgtmcrypt.so is the shared library containing the executables which is dynamically linked by GT.M and which in turn calls the encryption packages. $gtm_dist/utf8 ディレクトリが存在する場合、../pluginへのシンボリックリンクが含まれているはずです。

  • Source code is provided in the file $gtm_dist/plugin/gtmcrypt/source.tar which includes build.sh and install.sh scripts to respectively compile and install libgtmcrypt.so from the source code.

To support the implementation of a reference implementation, GT.M provides additional C structure types (in the gtmxc_types.h file):

  • gtmcrypt_key_t - キーへのハンドルであるデータ型。GT.Mデータベースエンジン自体はキーを操作しません。プラグインはキーを保持し、GT.Mデータベース・エンジンがキーを参照するために使用するキーへのハンドルを提供します。

  • xc_fileid_ptr_t - ファイルを一意に識別するためにGT.Mによって維持される構造体へのポインタ。ファイルには、絶対パス名と相対パス名の結果としてだけでなく、シンボリック・リンクのために、またファイルシステムをファイル名階層の複数の場所にマウントできるため、複数の名前があることに注意してください。GT.Mはファイルを一意に識別できる必要があります。

カスタマイズされたプラグイン実装で使用する必要はありませんが、GT.Mは、ファイルを一意に識別するために次の関数を提供します(また参照実装でも使用します):

  • xc_status_t gtm_filename_to_id(xc_string_t *filename, xc_fileid_ptr_t *fileid) - ファイル名をとり、そのファイルのファイルID構造を提供する関数。

  • xc_status_t gtm_is_file_identical(xc_fileid_ptr_t fileid1, xc_fileid_ptr_t fileid2) - 2つのファイルIDが同じファイルにマップされるかどうかを決定する関数。

  • gtm_xcfileid_free(xc_fileid_ptr_t fileid) - ファイルID構造体を解放する関数。

Mumps、MUPIPおよびDSEプロセスは、共有ライブラリにあるプラグインインタフェース関数に動的にリンクします。The functions serve as software "shims" to interface with an encryption library such as libmcrypt or libgpgme / libgcrypt.

プラグイン・インタフェース関数は次のとおりです:

  • gtmcrypt_init()

  • gtmcrypt_getkey_by_name()

  • gtmcrypt_getkey_by_hash()

  • gtmcrypt_hash_gen()

  • gtmcrypt_encode()

  • gtmcrypt_decode()

  • gtmcrypt_close()

  • and gtmcrypt_strerror()

GT.Mデータベースは複数のデータベースファイルで構成されていますが、それぞれに独自の暗号化キーがありますが、複数のファイルに同じキーを使用できます。したがって、gtmcrypt* 関数は、複数のデータベース・ファイルの複数のキーを管理することができます。これらの関数のプロトタイプは gtmcrypt_interface.h にあります。

The core plugin interface functions, all of which return a value of type gtm_status_t are:

  • gtmcrypt_init() は初期化を行います。環境変数 $gtm_passwd が存在し、文字列値が空の場合、GT.Mは最初のMプログラムがロードされる前にgtmcrypt_init() を呼び出します: そうでなければ、暗号化されたデータベースファイルに対して最初の操作を試みるときに gtmcrypt_init() を呼び出します。

  • Generally, gtmcrypt_getkey_by_hash or, for MUPIP CREATE, gtmcrypt_getkey_by_name perform key acquisition, and place the keys where gtmcrypt_decode() and gtmcrypt_encode() can find them when they are called.

  • Whenever GT.M needs to decode a block of bytes, it calls gtmcrypt_decode() to decode the encrypted data. GT.Mデータベース暗号化が動作するレベルでは、数値データ、MまたはUTF-8モードの文字列データ、照合アルゴリズムによって変更されたかどうかは関係ありません。暗号化と復号化は、単純に一連のバイトで動作します。

  • Whenever GT.M needs to encode a block of bytes, it calls gtmcrypt_encode() to encode the data.

  • 暗号化が使用されている場合( gtmcrypt_init() が以前に呼び出され成功した場合)、GT.Mはプロセス終了時およびコアファイルを生成する前に gtmcrypt_close() を呼び出します。gtmcrypt_close() は、コアファイルにクリアテキスト・キーが表示されないように、メモリ内のキーを消去する必要があります。

より詳細な説明が続きます。

  • gtmcrypt_key_t *gtmcrypt_getkey_by_name(gtm_string_t *filename) - MUPIP CREATE uses this function to get the key for a database file. この関数は、メモリ・キーリング内の指定されたファイル名を検索し、その対称暗号キーへのハンドルを返します。指定されたファイル名に対して複数のエントリがある場合、参照実装は、そのファイル名の最後に発生するものに一致するエントリをマスター・キー・ファイルに返します。

  • gtm_status_t gtmcrypt_hash_gen(gtmcrypt_key_t *key, gtm_string_t *hash) - MUPIP CREATE uses this function to generate a hash from the key then copies that hash into the database file header. 最初のパラメータはキーのハンドルで、2番目のパラメータは256バイトのバッファを指します。使用されるハッシュ・アルゴリズムが256バイトより小さいハッシュを提供する場合、gtmcrypt_hash_gen() は、256バイトバッファ内の未使用領域をゼロで埋める必要があります。

  • gtmcrypt_key_t *gtmcrypt_getkey_by_hash(gtm_string_t *hash) - GT.M uses this function at database file open time to obtain the correct key using its hash from the database file header. この関数は、メモリ・キー・リング内の指定されたハッシュを検索し、対応する対称暗号キーへのハンドルを返します。MUPIP LOAD, MUPIP RESTORE, MUPIP EXTRACT, MUPIP JOURNAL および MUPIP BACKUP -BYTESTREAM は、入力に使用するファイルが派生した現在または以前のデータベースに対応するキーを見つけるためにこれを使用します。

  • gtm_status_t gtmcrypt_encode(gtmcrypt_key_t *key, gtm_string_t *inbuf, gtm_string_t *outbuf) and gtm_status_t gtmcrypt_decode(gtmcrypt_key_t *key, gtm_string_t *inbuf, gtm_string_t *outbuf)- GT.M uses these functions to encode and decode data. The first parameter is a handle to the symmetric cipher key, the second a pointer to the block of data to encode or decode, and the third a pointer to the resulting block of encoded or decoded data. Using the appropriate key (same key for a symmetric cipher), gtmcrypt_decode() must be able to decode any data buffer encoded by gtmcrypt_encode(), otherwise the encrypted data is rendered unrecoverable.7 As discussed earlier, GT.M requires the encrypted and cleartext versions of a string to have the same length.

  • char *gtmcrypt_strerror() - GT.Mはこの関数を使用して、プラグインがエラー・ステータスを返すと、プラグインから追加エラー・コンテキストを取得します。この関数は、最後に発生したエラーに関連する追加のテキストへのポインタを返します。GT.Mはこのテキストをエラー報告の一部として表示します。エラーに追加のコンテキストや説明がない場合、この関数はnull文字列を返します。.

これらの機能のリファレンス実装の完全なソースコードは、GT.Mと同じ条件でライセンスされています。あなたは、あなたの特定のGT.Mデータベースの暗号化ニーズに合わせて変更する自由があります。変更内容を他の人に再配布することを検討したい場合は、GT.Mライセンスを確認してください。

For more information and examples, refer to the Database Encryption Technical Bulletin.

出力パラメータの事前割り当て

指示出力が参照によって渡される定義済みのパラメータは事前に割り当てられる値の仕様を含めることができます。これは、ユーザが外部ルーチンにパラメータを渡す前に割り当てることをGT.Mに要求しているメモリの単位の数です。For example, in the case of type gtm_char_t *, the pre-allocation value would be the number of bytes to be allocated before the call to the external routine.

事前割り当て値の仕様は、次の規則に従う必要があります:

  • Pre-allocation is an unsigned integer value specifying the number of bytes to be allocated on the system heap with a pointer passed into the external call.

  • Pre-allocating on a type with a direction of input or input/output results in a GT.M error.

  • Pre-allocation is meaningful only on types gtm_char_t * and gtm_string_t *. 他のすべてのタイプで指定された事前割り当ての値は無視され、パラメータはその型のデフォルト値が割り当てられます。With gtm_string_t * arguments make sure to set the 'length' field appropriately before returning control to GT.M. On return from the external call, GT.M uses the value in the length field as the length of the returned value, in bytes.

  • もしユーザが任意の値を指定しない場合、デフォルトの事前割り当て値がパラメータに割り当てられます。

  • "スカラ(scalar)" のタイプ(値によって渡されるパラメータ)の事前割り当ての仕様ではエラーになります。

[重要] 重要

Pre-allocation is optional for all output-only parameters except gtm_string_t * and gtm_char_t *. Pre-allocation yields better management of memory for the external call.

コールバックのメカニズム

GT.Mは、コールバックのメカニズムを介して外部コールのためにGT.Mランタイム ライブラリの内部にある特定の機能を公開しています。外部コールを作成しながら、GT.Mは、関数をコールバックするアドレスを含む関数ポインタのテーブルを移入し公開します。

目次

機能

引数

説明

0

hiber_start

   

指定時間スリープ

   

slp_time

integer

スリープする ミリ秒

1

hiber_start_wait_any

   

指定した時間、または、任意の割り込みまでの、どちらか早い方のスリープ

   

slp_time

integer

スリープする ミリ秒

2

start_timer

   

タイマーを開始し、タイマーの有効期限が切れたときにハンドラ関数を呼び出す

   

tid

integer

このタイマーのユニークユーザが指定した識別子

   

time_to_expire

integer

ハンドラが呼び出される前の ミリ秒

   

handler

pointer to function

呼び出すためのハンドラ関数のエントリを指定

   

hlen

integer

ハンドラ引数を介して渡される データ長

   

hdata

pointer to char

ハンドラ関数に渡すデータ (もしあれば)

3

cancel_timer

   

もしそれがまだ有効期限が切れていない場合、以前 start_timer() で開始したタイマを停止

   

tid

integer

ユニークユーザが指定した、キャンセルするタイマーの識別子

4

gtm_malloc

   

ヒープからのプロセスのメモリを割り当て

   

<return-value>

void へのポインタ

割り当てられた領域のアドレス

   

space_needed

32-bit platforms: 32-bit unsigned integer

64-bit platforms: 64-bit unsigned integer

bytes of space to allocate. This has the same signature as the system malloc() call.

5

gtm_free

   

gtm_malloc() 以前に割り当てられたメモリを戻す

   

free_address

void へのポインタ

割り当てられたスペースのアドレス

外部ルーチンは、次のようなメカニズムのいずれかで、コールバック関数にアクセスし呼び出すことができます。

  • 外部コールを作りながら、GT.Mは、上記のテーブルの開始アドレス(10進の整数値)を含む文字列を指すように、環境変数 GTM_CALLIN_START をセットします。外部ルーチンは、この環境変数を読み込み、整数値に文字列を変換し、適切なGT.M関数をコールする適切なエントリをインデックスすべき、必要があります。

  • GT.M also provides an input-only parameter type gtm_pointertofunc_t that can be used to obtain call-back function pointers via parameters in the external routine. If a parameter is specified as I:gtm_pointertofunc_t and if a numeric value (between 0-5) is passed for this parameter in M, GT.M interprets this value as the index into the callback table and passes the appropriate callback function pointer to the external routine.

[注意] 注意

FIS strongly discourages the use of signals, especially SIGALARM, in user written C functions. GT.M assumes that it has complete control over any signals that occur and depends on that behavior for recovery if anything should go wrong. The use of exposed timer APIs should be considered for timer needs.

外部プログラムの制限事項

GT.Mランタイム環境と外部C関数の両方が同じプロセス空間で実行されるため、以下の制限が外部関数に適用されます:

  1. GT.Mは、シグナルを使用するように設計され、GT.Mが正しく動作するように機能しなければならないシグナルハンドラを持っています。コールバックに関連するタイマは、sleep()のようにSIGALRMを使用する任意のライブラリやシステムコールの代わりに使用する必要があります。外部呼び出しコードによるシグナルの使用は、GT.Mの失敗を引き起こす可能性があります。

  2. mallocとfreeを提供するGT.Mを使用するには、デバッグツールの番号を持つ統合されたヒープ管理システムを作成します。FISは、メモリ管理の問題が外部コールで発生する場合に備えて、優れたデバッグ機能を提供する外部関数の gtm_malloc / gtm_free の使用を推奨します。

  3. 外部関数の exit システムコールの使用は強く反対します。GT.M は、ランタイム環境とすべてのアクティブなリソースを正しくシャットダウンするための exit ハンドラを使用しているので、システムコール _exit は外部関数で使用されることはけっしてありません。

  4. GT.Mは、中断されるシステムコールの可能性が高いほど頻繁に、タイマーのシグナルを使用します。そういうわけで、もしシグナルによって中断された場合、外部プログラム内のすべてのシステムコールは、EINTRを返すことができます。

  5. start_timer で呼び出されたハンドラ関数は、シグナルハンドラ(または安全であると同定されていない)のために安全でないオペレーティングシステムのドキュメンテーションによって識別されるサービスを呼び出すことはできません。 - このような情報については、システムドキュメンテーションまたはmanページを参照してください。それらが再入可能であると誤って仮定し、それらを呼び出そうとして、関数によって中断された時に、そのようなサービスは非決定的な障害を引き起こします。

外部コールの使用

foo: void bar (I:gtm_float_t*, O:gtm_float_t*)

パッケージごとに1つの外部コールテーブルがあります。環境変数 "GTMXC" は、デフォルトパッケージの外部コールテーブルファイルの名前を付ける必要があります。デフォルト以外のパッケージの外部コールテーブルファイルは、 "GTMXC_name" 形式の環境変数によって識別される必要があります。

The first of the external call tables is the location of the shareable library. The location can include environment variable names.

例:

% echo $GTMXC_mathpak
/user/joe/mathpak.xc
% echo lib /usr/
% cat mathpak.xc
$lib/mathpak.sl
exp: gtm_status_t xexp(I:gtm_float_t*, O:gtm_float_t*)
% cat exp.c
...
int xexp(count, invar, outvar)
int count;
float *invar;
float *outvar;
       {
        ...
       }
% gtm
... 
GTM>d &mathpak.exp(inval,.outval)
GTM>

例:事前割り当て:

% echo $GTMXC_extcall
/usr/joe/extcall.xc
% cat extcall.xc
/usr/lib/extcall.sl
prealloc: void gtm_pre_alloc_a(O:gtm_char_t *[12])
% cat extcall.c
#include <stdio.h>
#include <string.h>
#include "gtmxc_types.h"
void gtm_pre_alloc_a (int count, char *arg_prealloca)
{
    strcpy(arg_prealloca, "New Message");
    return;
}

例:コールバックメカニズム

% echo $GTMXC 
/usr/joe/callback.xc 
% cat /usr/joe/callback.xc 
$MYLIB/callback.sl 
init:     void   init_callbacks() 
tstslp:  void   tst_sleep(I:gtm_long_t) 
strtmr: void   start_timer(I:gtm_long_t, I:gtm_long_t) 
% cat /usr/joe/callback.c 
#include <stdio.h> 
#include <stdlib.h>
 
#include "gtmxc_types.h"
 
void **functable; 
void (*setup_timer)(int , int , void (*)() , int , char *); 
void (*cancel_timer)(int ); 
void (*sleep_interrupted)(int ); 
void (*sleep_uninterrupted)(int ); 
void* (*malloc_fn)(int); 
void (*free_fn)(void*);
 
void  init_callbacks (int count) 
{
   char *start_address;
 
   start_address = (char *)getenv("GTM_CALLIN_START");
 
   if (start_address == (char *)0)
   {
           fprintf(stderr,"GTM_CALLIN_START is not set\n");
      return;
   }
   functable = (void **)atoi(start_address);
   if (functable == (void **)0)
   {
     perror("atoi : ");
     fprintf(stderr,"addresses defined by GTM_CALLIN_START not a number\n");
     return;
   }
   sleep_uninterrupted = (void (*)(int )) functable[0];
   sleep_interrupted = (void (*)(int )) functable[1];
   setup_timer = (void (*)(int , int, void (*)(), int, char *)) functable[2];
   cancel_timer = (void (*)(int )) functable[3];
 
   malloc_fn = (void* (*)(int)) functable[4];
   free_fn = (void (*)(void*)) functable[5];
 
   return; 
}
 
void  sleep (int count, int time) 
{
   (*sleep_uninterrupted)(time); 
}
 
void timer_handler () 
{
   fprintf(stderr,"Timer Handler called\n");
   /* Do something */ 
}
 
void  start_timer (int count, int time_to_int, int time_to_sleep) 
{
   (*setup_timer)((int )start_timer, time_to_int, timer_handler, 0, 0);
   return; 
} 
void* xmalloc (int count) 
{   
return (*malloc_fn)(count); 
}
 
void  xfree(void* ptr) 
{
   (*free_fn)(ptr); 
} 

Example:gtm_malloc/gtm_free callbacks using gtm_pointertofunc_t

% echo $GTMXC
/usr/joe/callback.xc
% cat /usr/joe/callback.xc
/usr/lib/callback.sl
init: void init_callbacks(I:gtm_pointertofunc_t, I:gtm_pointertofunc_t)
% gtm
GTM> do &.init(4,5)
GTM>
% cat /usr/joe/callback.c
#include <stdio.h>
#include <stdlib.h>
#include "gtmxc_types.h"
void* (*malloc_fn)(int);
void (*free_fn)(void*);
void init_callbacks(int count, void* (*m)(int), void (*f)(void*))
{
    malloc_fn = m;
    free_fn = f;
}
inserted by FC2 system