Question

I'm not very familiar with C design patterns and searching for the best solution for the following problem. I want to write a little chat client based on libpurple.

While running the program I want to be able to connect and disconnect several instant message accounts. The connect and disconnect calls should be passed over command line, but waiting for input with gets(); is no solution, because the program should run all the time getting new messages from the already connected instant message accounts.

Was it helpful?

Solution

You probably want to use poll (or select) for handling the events. So after establishing the connections, you have the file descriptors, and in addition you have the standard input, which also has a file descriptor from the OS (namely 0), and you can pass all those file descriptors to poll, which notifies you when there is incoming data on any of the file descriptors. Example code:

/* fd1, fd2 are sockets */
while(1) {
    pollfd fds[3];
    int ret;

    fds[0].fd = fd1;
    fds[1].fd = fd2;
    fds[2].fd = STDIN_FILENO;
    fds[0].events = POLLIN;
    fds[1].events = POLLIN;
    fds[2].events = POLLIN;
    ret = poll(fds, 3, -1); /* poll() blocks, but you can set a timeout here */
    if(ret < 0) {
        perror("poll");
    }
    else if(ret == 0) {
        printf("timeout\n");
    }
    else {
        if(fds[0].revents & POLLIN) {
            /* incoming data from fd1 */
        }
        if(fds[0].revents & (POLLERR | POLLNVAL)) {
            /* error on fd1 */
        }
        if(fds[1].revents & POLLIN) {
            /* incoming data from fd2 */
        }
        if(fds[1].revents & (POLLERR | POLLNVAL)) {
            /* error on fd2 */
        }
        if(fds[2].revents & POLLIN) {
            /* incoming data from stdin */
            char buf[1024];
            int bytes_read = read(STDIN_FILENO, buf, 1024);
            /* handle input, which is stored in buf */
        }
    }
}

You didn't mention the OS. This works for POSIX (OS X, Linux, Windows with mingw). If you need to use the Win32 API, it'll look a bit different but the principle is the same.

OTHER TIPS

Check out select(2). I'm not really sure how libpurple works, but if it allows notification via file-descriptor (like a file or socket), then select is your solution.

You could also try creating a seperate thread with pthread_create(3). That way it can block on gets (or whatever) while the rest of your program does it's thing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top