Ez most újra előjött! Illetve nem tudom, hogy ugyanez-e (mert az előzőt elfelejtettem), de mindenesetre a non-blocking connect 'sikert' jelez, akkor is amikor a korábbi verziók EWOULDBLOCK-ot adtak... na most akkor mi legyen? Talán az, hogy ilyenkor per dac azt mondjuk, hogy najó, kézileg hazudjuk rá, hogy EWOULDBLOCK.
Újabb mérések szerint viszont mégiscsak a "rendes" errno-t használja (LOCAL#DEFAULT.ICXCGLOB+64 nem pedig ORACLE$USER.ICXCGLOB+64), tehát azt kellene felülírni a "régifajta" hibakóddal... vagy az a legtisztább, ha mindkettőt felülírjuk?
Kivéve a hibakezelést... ugyanis az Oracle az ICXCGLOB-ból is saját példányt hoz (abban van az errno). Cserébe nem férünk hozzá a rendes C-runtime-hoz. Megoldás:
Pontosabban: a leírás szetint a nemnulla 'flags'-ra hibát ad, a gyakorlatban viszont ignorálja... tehát az MSG_PEEK -et is figyelmen kívül hagyja... marad a 'getpeername'.
Annak mondjuk nincs akadálya, hogy csináljunk egy saját YSOLNK-t, amely exportálja a régi hívásokat, a régiekre visszavezetve, pl "gethostbyname" a régiben "YSOGHBN", az újban "YS6GHBN". Változtak továbbá az errno-kódok (pl: régi SCEWOULDBLOCK=35, SCEAGAIN=11 új EWOULDBLOCK=EAGAIN=211), és a SOL_SOCKET, SOL_GLOBAL értékei. Egyelőre működni látszik a dolog, ha tényleg beválik akkor lassacskán mindent átmigrálhatunk a 2.x-es socketekre...
Végülis jó lehet így a dolog, kivéve hogy ha a "soc_init"-et az Oracle-connect (vagy más socket-es hívás) után használjuk, akkor hibajelzést kapunk (ami ugyan figyelmen kívül hagyható), ha viszont nem használjuk, de Oracle-connect volt már (és a javítatlan Oracle-t használjuk), akkor a soc_init nélkül semmilyen socket-hívás nem megy.
Ezek alapján javaslatom az inicializálásra: 1. inet_aton("127.0.0.1") - ha sikerül akkor kész(OK), egyébként: 2. soc_init - ha sikerül akkor kész(OK), egyébként: 3. inet_aton("127.0.0.1") - ha sikerül akkor kész(OK), egyébként kész(ERROR)
(legal notice: az itt leírtak természetesen csak az én képzeletemben történtek meg, senkinek sem ajánlom hogy a valóságban is kipróbálja)
Szóval: A $BINDER segítségével piszkáljuk ki az YSOLNK-t az $ORA.ORAPRO.LIB(ORAPRO/L)-ből és a $ORA.ORAMESG.LIB(EXTPROC/L)-ból (START-LLM-UPDATE; REMOVE-MODULE NAME=YSOLNK; SAVE-LLM). Praktikusan ezt egy-egy másolat-könyvtárban végezzük el, és az ORAENV proceduránkban az ORALOAD és BLSLIBxx linkneveket ezekre a másolat-könyvtárakra állítjuk, továbbá egy új BLSLIBxx-et is felveszünk, ami az $.SOCKETS.LIB.013-ra (vagy hasonlóra) mutat (erre azoknak a programoknak van szüksége, akikben nincs benne eleve az YSOLNK, mivel nincs bennük hálozati működés).
Nos, ezzel még nem oldottunk meg semmit :( Ugyanis a PROBIND#, aki betölti (BIND) az ORAPRO-t (illetve a benne lévő PRO2C-t), egy külön context-et hoz létre (ORACLE$USER), és nem rezolválja az YSOLNK-t az alap context-ből (LOCAL#DEFAULT) - legalábbis ha külön nem utasítjuk rá, vagyis mégis berántja duplikálva az YSOLNK-t. Persze ennek a megoldása már csak AID kérdése: /%SET %@(C=PROBIND#.#'138') INTO C=PROBIND#.#'1F0' // 'LOCAL#DEFAULT' címe /%SET 1 INTO C=PROBIND#.#'1AF' // rezolváladó contextek száma
A bajok gyökerét abban látom, hogy az Oracle-nek van egy $ORA.ORAMESG.LIB(EXTPROC/L) eleme, amibe bele van dolgozva az YSOLNK nevű elem, ami egyébként is bele van szerkesztve a programba, a $TSOS.SOCKETS.LIB-ből... tehát máris kettő lesz belőle, ami magyarázhatja a gondokat... következő tervem, hogy kiszedem az EXTPROC-ból az YSOLNK-t és megnézem, mi történik...
Mondjuk ha az 1=Orcale, 2=socket módszert használjuk, akkor a hibaüzenet ellenére minden működik szépen :O Illetve csak akkor, ha a nem dokumentált 'soc_init' függvényt is meghívjuk. Ez ugyan hibát fog jelezni, de utána a többi socket-es hivás már működik!
/start-program (smora21.pha,smora21,a,a),test=aid % CCM0001 ENTER OPTIONS: smora socinit: socket-system initialized 20060405.105921 Connected to oracle as 'scott@test-tcp.world' % CCM0998 CPU TIME USED: 0.3280 SECONDS
/start-program (smora21.pha,smora21,a,a),test=aid % CCM0001 ENTER OPTIONS: orasm 20060405.105929 Connected to oracle as 'scott@test-tcp.world' socinit: socket-system initialized % CCM0998 CPU TIME USED: 0.3169 SECONDS SYSFILE SYSOUT=()
Hát ez tökéletes! Vagy nem? A tesztek szerint ilyenkor a 'connect'-ből sohasem jön vissza.
Tegyük fel hogy össze akarjuk békíteni az Oracle 8.1.5-öt, a Sockets-DE 1.3-as vagy 2.1-es verziójával...
1. próba Oracle-8.1.5 + Sockets-1.3
/start-program (smora13.pha,smora13,a,a),test=aid % CCM0001 ENTER OPTIONS: smora socinit: socket-system initialized ---- ORACLE ERROR ---- on 20060405 at 103031 ---- -12560 *** Error connecting database as 'scott@test-tcp.world' code: -12560 errm: ORA-12560: TNS:protocol adapter error statement: offset: 0 file: $HELIOS.C.MODULE.LIB.CENTRAL[ORACONN.PC] line: 55 ---------------------- % CCM0998 CPU TIME USED: 0.3601 SECONDS
/start-program (smora13.pha,smora13,a,a),test=aid % CCM0001 ENTER OPTIONS: orasm 20060405.103035 Connected to oracle as 'scott@test-tcp.world' *** socinit: there is some error rc=-1 errno=55
Látszik, hogy az első művelet sikerül (legyen bár az Oracle connect vagy socket-es init), a második nem az errno=55 azt jelenti hogy "SCENOBUFS - No buffer space available"
Kiegészítés: a Winsock-nál a sikertelen connect az 'exceptfds'-ben (tehát a harmadik bitvektorban) jelződik, nehogy könnyű legyen hordozható programot csinálni.
Vagy rosszul néztem? Lehet hogy valahogy úgy megy (mármint az új verzióban, a régiben egységesen rossz), hogy ha 'select' után hívom a getsockopt(SO_ERROR) -t, akkor megkapom az ECONNREFUSED-et, de ha csak a saját kútfejem alapján várok egy másodpercet, akkor nem... linux-ban is kipróbáltam, ott nincs különbség a kettő között.
Kipróbáltam egy újabb verzióban is (BCAM 17, Sockets 2.1), a hiba megmaradt. A hibelhárítás lehetséges módja: a 'sikeres' connect után recv (sock,buff,1,MSG_PEEK), ha sikerül vagy EWOULDBLOCK, akkor tényleg létrejött a kapcsolat.