lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I''ve converted a C example that uses Linux signals and getaddrinfo_a to LuaJIT.

The example works but I get a double free corruption sometimes. Could
anybody help me identify
where I deviate from LuaJIT best practices ?

The .lj file has the LuaJIT code. The .cdef file has the C definitions.

The attached C example is taken from
http://www.hrozkovi.cz/?p=learning/.git;a=blob;f=getaddrinfo_a/gaia.c

Thanks
jose

Attachment: gaia.lj
Description: Binary data

Attachment: gaia.cdef
Description: Binary data

/*
 * Quick and dirty example of getaddrinfo_a usage
 * 
 * Compile with -lanl
 *
 * Usage ./gaia <space-delimited-list-of-hostnames>
 *
 */
#define _GNU_SOURCE

#include <netdb.h>
#include <stdio.h>
#include <assert.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <arpa/inet.h>


int main(int argc, char **argv)
{
    struct gaicb *host;
    struct gaicb *out;
    struct sigevent ev;
    struct signalfd_siginfo fdsi;
    sigset_t mask;
    int sfd;
    int s;
    int queued, resolved;
    struct sockaddr_in *res;

    if(argc < 2) {
        return 1;
    }

    sigemptyset(&mask);
    sigaddset(&mask, SIGRTMIN);
    sigprocmask(SIG_BLOCK, &mask, NULL);
    sfd = signalfd(-1, &mask, 0);

    for(queued=1; queued<argc; ++queued) {
        host = calloc(1, sizeof(struct gaicb));
        assert(host != NULL);
        host->ar_name = argv[queued];

        ev.sigev_notify = SIGEV_SIGNAL;
        ev.sigev_value.sival_ptr = host;
        ev.sigev_signo = SIGRTMIN;

        getaddrinfo_a(GAI_NOWAIT, &host, 1, &ev);
    }

    --queued;
    resolved = 0;

    /* In real world, we would probably monitor sfd via event loop */
    for(;;) {
        if(resolved == queued) {
            printf("Resolved all hostnames, quit\n");
            break;
        }

        s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
        ++resolved;
        if (s != sizeof(struct signalfd_siginfo)) {
            perror("read");
            return 1;
        }

        if (fdsi.ssi_signo != SIGRTMIN) {
            printf("Got signal %d\n, quitting", fdsi.ssi_signo);
            return 1;
        } 

        out = fdsi.ssi_ptr;
        assert(out != NULL);
        if(out->ar_result == NULL) {
            printf("Cannot resolve %s\n", out->ar_name);
            continue;
        }

        res = (struct sockaddr_in *) out->ar_result->ai_addr;
        printf("host %s has address %s\n", out->ar_name, inet_ntoa(res->sin_addr));
        free(out);

    }

    return 0;
}