LINUX.ORG.RU

Firebird/Interbase, сигналы и isc_detach_database

 , , ,


0

1

Вопрос к знатокам.

Есть такой вот код:

#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <ibase.h>

int fb_error(ISC_STATUS_ARRAY status_vector)
{
    if (status_vector[0] == 1 && status_vector[1])
    {
        isc_print_status(status_vector);
        return -1;
    }
    return 0;
}

int fb_open(char* filename, char* user_name, char* user_password, isc_db_handle *handle)
{
    char dpb_buffer[256], *dpb, *p;
    ISC_STATUS_ARRAY status_vector;
    short dpb_length;
    dpb = dpb_buffer;
    *dpb++ = isc_dpb_version1;
    *dpb++ = isc_dpb_user_name;
    *dpb++ = strlen(user_name);
    for (p = user_name; *p;)
    *dpb++ = *p++;
    *dpb++ = isc_dpb_password;
    *dpb++ = strlen(user_password);
    for (p = user_password; *p;)
    *dpb++ = *p++;
    dpb_length = dpb - dpb_buffer;
    isc_attach_database(status_vector, 0, filename, handle, dpb_length, dpb_buffer);
    return !fb_error(status_vector);
}

void fb_close(isc_db_handle *handle)
{
    if (*handle)
    {
        ISC_STATUS_ARRAY status_vector;
        isc_detach_database(status_vector, handle);
        fb_error(status_vector);
    }
}

volatile sig_atomic_t enable = 1;

void stoper(int signum)
{
    enable = 0;
}

int main(void)
{
    isc_db_handle h = 0;

    signal(SIGINT, stoper);

    if (fb_open("filename.fdb", "user", "password", &h))
    {
        printf("Open\n");
        while (enable) sleep(1);
        printf("Interrupt\n");
        fb_close(&h);
        printf("Close\n");
    }

    printf("Stop\n");

    return 0;
}

По идее программа должна нормально завершаться.

То есть последовательно выводить: «Open», «Interrupt», «Close» и «Stop».

Но выводятся только «Open» и «Interrupt», и нет никаких «Close» и «Stop».

Что я делаю не так и как добиться нормального поведения?

и нет никаких «Close» и «Stop».

Программа завершается или нет. Если завершается, то какой код завершения?

mky ★★★★★
()

Варианта примерно два: либо fb_close() по какой-то причине закрывает stdout, либо приводит к завершению/падению.

Deleted
()
Ответ на: комментарий от Deleted

... и strace поможет понять что происходит.

Deleted
()
Ответ на: комментарий от mky

Завершается с кодом 0.

Но я уже знаю в чём там причина.

Оказывается клиентская библиотека Firebird перехватывает exit(), SIGINT и SIGTERM.

Но этим можно управлять и, например, вот тут описано как именно.

user0xff
() автор топика
Ответ на: комментарий от Serik

Бегло просмотрел её исходники.

Похоже оно не обучено блокировать SIGINT и SIGTERM (вызова fb_shutdown_callback нигде не видно).

Можно было бы предположить, что оно ориентированно исключительно на Interbase, но в исходниках можно встретить fb_*, а это относится к Firebird.

Спасибо всем за ответы.

user0xff
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.