Skip to content

Instantly share code, notes, and snippets.

@kubo
Created May 13, 2014 09:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kubo/5e624415ebf07559bf4e to your computer and use it in GitHub Desktop.
Save kubo/5e624415ebf07559bf4e to your computer and use it in GitHub Desktop.
/*
* Test program for https://github.com/kubo/ruby-oci8/issues/55
*
* gcc -o ociconnect32 ociconnect.c -I$ORACLE_HOME/rdbms/public -L$ORACLE_HOME/lib32 -R$ORACLE_HOME/lib32 -lclntsh
* gcc -m64 -o ociconnect64 ociconnect.c -I$ORACLE_HOME/rdbms/public -L$ORACLE_HOME/lib -R$ORACLE_HOME/lib -lclntsh
*/
#include <stdio.h>
#include <unistd.h>
#include <oci.h>
static void checkerr(void *handle, ub4 htype, sword status, const char *func)
{
text errbuf[512];
sb4 errcode = 0;
switch (status) {
case OCI_SUCCESS:
case OCI_SUCCESS_WITH_INFO:
break;
case OCI_NEED_DATA:
printf(" %s => OCI_NEED_DATA\n", func);
break;
case OCI_NO_DATA:
printf(" %s => OCI_NO_DATA\n", func);
break;
case OCI_ERROR:
OCIErrorGet(handle, 1, NULL, &errcode, errbuf, sizeof(errbuf), htype);
printf(" %s => OCI_ERROR\n %.*s\n", func, (int)sizeof(errbuf), errbuf);
break;
case OCI_INVALID_HANDLE:
printf(" %s => OCI_INVALID_HANDLE\n", func);
break;
case OCI_STILL_EXECUTING:
printf(" %s => OCI_STILL_EXECUTE\n", func);
break;
case OCI_CONTINUE:
printf(" %s => OCI_CONTINUE\n", func);
break;
default:
printf(" %s => Unknown %d\n", func, status);
}
}
#define chke(func) do { \
sword status = (func); \
if (status != OCI_SUCCESS) { \
checkerr(envhp, OCI_HTYPE_ENV, status, #func); \
goto cleanup; \
} \
} while (0)
#define chk(func) do { \
sword status = (func); \
if (status != OCI_SUCCESS) { \
checkerr(errhp, OCI_HTYPE_ERROR, status, #func); \
goto cleanup; \
} \
} while (0)
static void connect_test(int id)
{
OCIEnv *envhp = NULL;
OCIError *errhp;
OCISvcCtx *svchp;
OCIServer *srvhp;
OCISession *seshp;
ub4 env_mode;
ub4 server_status;
char *text;
ub4 size;
int attached = 0;
int success = 0;
sword rv;
printf("---------------------\nTEST %d\n", id);
if (id & 1) {
printf(" Don't use OCI_EVNETS\n");
env_mode = OCI_OBJECT | OCI_THREADED;
} else {
printf(" Use OCI_EVENTS\n");
env_mode = OCI_EVENTS | OCI_OBJECT;
}
rv = OCIEnvCreate(&envhp, env_mode, NULL, NULL, NULL, NULL, 0, NULL);
if (rv != 0) {
printf("OCIEnvCreate() => %d\n", rv);
goto cleanup;
}
chke(OCIHandleAlloc(envhp, (void*)&errhp, OCI_HTYPE_ERROR, 0, NULL));
chke(OCIHandleAlloc(envhp, (void*)&srvhp, OCI_HTYPE_SERVER, 0, NULL));
chke(OCIHandleAlloc(envhp, (void*)&svchp, OCI_HTYPE_SVCCTX, 0, NULL));
chke(OCIHandleAlloc(envhp, (void*)&seshp, OCI_HTYPE_SESSION, 0, NULL));
if (id & 2) {
printf(" Detach\n");
chk(OCIAttrGet(srvhp, OCI_HTYPE_SERVER, &server_status, NULL, OCI_ATTR_SERVER_STATUS, errhp));
chk(OCIServerDetach(srvhp, errhp, 0));
} else {
printf(" Don't Detach\n");
}
chk(OCIServerAttach(srvhp, errhp, "XYZ123_SSL_USER", 12, 0));
attached = 1;
chk(OCIAttrGet(srvhp, OCI_HTYPE_SERVER, &text, &size, OCI_ATTR_ACCESS_BANNER, errhp));
chk(OCIAttrSet(svchp, OCI_HTYPE_SVCCTX, srvhp, 0, OCI_ATTR_SERVER, errhp));
if (id & 4) {
printf(" Set username/password\n");
chk(OCIAttrSet(seshp, OCI_HTYPE_SESSION, "", 0, OCI_ATTR_EDITION, errhp));
chk(OCIAttrSet(seshp, OCI_HTYPE_SESSION, "/", 1, OCI_ATTR_USERNAME, errhp));
chk(OCIAttrSet(seshp, OCI_HTYPE_SESSION, "", 0, OCI_ATTR_PASSWORD, errhp));
} else {
printf(" Don't set username/password\n");
}
chk(OCIAttrSet(svchp, OCI_HTYPE_SVCCTX, seshp, 0, OCI_ATTR_SESSION, errhp));
chk(OCIAttrSet(seshp, OCI_HTYPE_SESSION, "OCITEST", 7, OCI_ATTR_DRIVER_NAME, errhp));
chk(OCISessionBegin(svchp, errhp, seshp, OCI_CRED_EXT, 0));
success = 1;
chk(OCISessionEnd(svchp, errhp, seshp, 0));
cleanup:
if (attached) {
OCIServerDetach(srvhp, errhp, 0);
}
if (envhp != NULL) {
OCIHandleFree(envhp, OCI_HTYPE_ENV);
}
if (success) {
printf(" SUCCESS\n");
} else {
printf(" FAILED\n");
}
}
int main(int argc, char *argv)
{
int id;
for (id = 0; id < 8; id++) {
pid_t pid = fork();
int status;
if (pid == 0) {
/* child process */
connect_test(id);
return 0;
}
/* wait child process termination */
waitpid(pid, &status, 0);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment