libcacard: teach vscclient to use GMainLoop for portability
This version handles non-blocking sending and receiving from the socket. Signed-off-by: Marc-André Lureau <mlureau@redhat.com> Reviewed-by: Alon Levy <alevy@redhat.com>
This commit is contained in:
		
							parent
							
								
									930c8ad472
								
							
						
					
					
						commit
						c9495ee9eb
					
				@ -10,7 +10,10 @@
 | 
				
			|||||||
 * See the COPYING.LIB file in the top-level directory.
 | 
					 * See the COPYING.LIB file in the top-level directory.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _WIN32
 | 
				
			||||||
#include <netdb.h>
 | 
					#include <netdb.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#include <glib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "qemu-common.h"
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "qemu/thread.h"
 | 
					#include "qemu/thread.h"
 | 
				
			||||||
@ -22,9 +25,7 @@
 | 
				
			|||||||
#include "vcard_emul.h"
 | 
					#include "vcard_emul.h"
 | 
				
			||||||
#include "vevent.h"
 | 
					#include "vevent.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int verbose;
 | 
					static int verbose;
 | 
				
			||||||
 | 
					 | 
				
			||||||
int sock;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
print_byte_array(
 | 
					print_byte_array(
 | 
				
			||||||
@ -51,7 +52,47 @@ print_usage(void) {
 | 
				
			|||||||
    vcard_emul_usage();
 | 
					    vcard_emul_usage();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static QemuMutex write_lock;
 | 
					static GIOChannel *channel_socket;
 | 
				
			||||||
 | 
					static GByteArray *socket_to_send;
 | 
				
			||||||
 | 
					static QemuMutex socket_to_send_lock;
 | 
				
			||||||
 | 
					static guint socket_tag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					update_socket_watch(gboolean out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					do_socket_send(GIOChannel *source,
 | 
				
			||||||
 | 
					               GIOCondition condition,
 | 
				
			||||||
 | 
					               gpointer data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gsize bw;
 | 
				
			||||||
 | 
					    GError *err = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail(socket_to_send->len != 0, FALSE);
 | 
				
			||||||
 | 
					    g_return_val_if_fail(condition & G_IO_OUT, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_io_channel_write_chars(channel_socket,
 | 
				
			||||||
 | 
					        (gchar *)socket_to_send->data, socket_to_send->len, &bw, &err);
 | 
				
			||||||
 | 
					    if (err != NULL) {
 | 
				
			||||||
 | 
					        g_error("Error while sending socket %s", err->message);
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    g_byte_array_remove_range(socket_to_send, 0, bw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (socket_to_send->len == 0) {
 | 
				
			||||||
 | 
					        update_socket_watch(FALSE);
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					socket_prepare_sending(gpointer user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    update_socket_watch(TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
send_msg(
 | 
					send_msg(
 | 
				
			||||||
@ -60,10 +101,9 @@ send_msg(
 | 
				
			|||||||
    const void *msg,
 | 
					    const void *msg,
 | 
				
			||||||
    unsigned int length
 | 
					    unsigned int length
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    int rv;
 | 
					 | 
				
			||||||
    VSCMsgHeader mhHeader;
 | 
					    VSCMsgHeader mhHeader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_mutex_lock(&write_lock);
 | 
					    qemu_mutex_lock(&socket_to_send_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (verbose > 10) {
 | 
					    if (verbose > 10) {
 | 
				
			||||||
        printf("sending type=%d id=%u, len =%u (0x%x)\n",
 | 
					        printf("sending type=%d id=%u, len =%u (0x%x)\n",
 | 
				
			||||||
@ -73,23 +113,11 @@ send_msg(
 | 
				
			|||||||
    mhHeader.type = htonl(type);
 | 
					    mhHeader.type = htonl(type);
 | 
				
			||||||
    mhHeader.reader_id = 0;
 | 
					    mhHeader.reader_id = 0;
 | 
				
			||||||
    mhHeader.length = htonl(length);
 | 
					    mhHeader.length = htonl(length);
 | 
				
			||||||
    rv = write(sock, &mhHeader, sizeof(mhHeader));
 | 
					    g_byte_array_append(socket_to_send, (guint8 *)&mhHeader, sizeof(mhHeader));
 | 
				
			||||||
    if (rv < 0) {
 | 
					    g_byte_array_append(socket_to_send, (guint8 *)msg, length);
 | 
				
			||||||
        /* Error */
 | 
					    g_idle_add(socket_prepare_sending, NULL);
 | 
				
			||||||
        fprintf(stderr, "write header error\n");
 | 
					
 | 
				
			||||||
        close(sock);
 | 
					    qemu_mutex_unlock(&socket_to_send_lock);
 | 
				
			||||||
        qemu_mutex_unlock(&write_lock);
 | 
					 | 
				
			||||||
        return 16;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    rv = write(sock, msg, length);
 | 
					 | 
				
			||||||
    if (rv < 0) {
 | 
					 | 
				
			||||||
        /* Error */
 | 
					 | 
				
			||||||
        fprintf(stderr, "write error\n");
 | 
					 | 
				
			||||||
        close(sock);
 | 
					 | 
				
			||||||
        qemu_mutex_unlock(&write_lock);
 | 
					 | 
				
			||||||
        return 16;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    qemu_mutex_unlock(&write_lock);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -245,31 +273,52 @@ on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    STATE_HEADER,
 | 
				
			||||||
 | 
					    STATE_MESSAGE,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define APDUBufSize 270
 | 
					#define APDUBufSize 270
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static gboolean
 | 
				
			||||||
do_socket_read(void)
 | 
					do_socket_read(GIOChannel *source,
 | 
				
			||||||
 | 
					               GIOCondition condition,
 | 
				
			||||||
 | 
					               gpointer data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int rv;
 | 
					    int rv;
 | 
				
			||||||
    int dwSendLength;
 | 
					    int dwSendLength;
 | 
				
			||||||
    int dwRecvLength;
 | 
					    int dwRecvLength;
 | 
				
			||||||
    uint8_t pbRecvBuffer[APDUBufSize];
 | 
					    uint8_t pbRecvBuffer[APDUBufSize];
 | 
				
			||||||
    uint8_t pbSendBuffer[APDUBufSize];
 | 
					    static uint8_t pbSendBuffer[APDUBufSize];
 | 
				
			||||||
    VReaderStatus reader_status;
 | 
					    VReaderStatus reader_status;
 | 
				
			||||||
    VReader *reader = NULL;
 | 
					    VReader *reader = NULL;
 | 
				
			||||||
    VSCMsgHeader mhHeader;
 | 
					    static VSCMsgHeader mhHeader;
 | 
				
			||||||
    VSCMsgError *error_msg;
 | 
					    VSCMsgError *error_msg;
 | 
				
			||||||
 | 
					    GError *err = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rv = read(sock, &mhHeader, sizeof(mhHeader));
 | 
					    static gchar *buf;
 | 
				
			||||||
    if (rv < sizeof(mhHeader)) {
 | 
					    static gsize br, to_read;
 | 
				
			||||||
        /* Error */
 | 
					    static int state = STATE_HEADER;
 | 
				
			||||||
        if (rv < 0) {
 | 
					
 | 
				
			||||||
            perror("header read error\n");
 | 
					    if (state == STATE_HEADER && to_read == 0) {
 | 
				
			||||||
        } else {
 | 
					        buf = (gchar *)&mhHeader;
 | 
				
			||||||
            fprintf(stderr, "header short read %d\n", rv);
 | 
					        to_read = sizeof(mhHeader);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        return -1;
 | 
					
 | 
				
			||||||
 | 
					    if (to_read > 0) {
 | 
				
			||||||
 | 
					        g_io_channel_read_chars(source, (gchar *)buf, to_read, &br, &err);
 | 
				
			||||||
 | 
					        if (err != NULL) {
 | 
				
			||||||
 | 
					            g_error("error while reading: %s", err->message);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        buf += br;
 | 
				
			||||||
 | 
					        to_read -= br;
 | 
				
			||||||
 | 
					        if (to_read != 0) {
 | 
				
			||||||
 | 
					            return TRUE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (state == STATE_HEADER) {
 | 
				
			||||||
        mhHeader.type = ntohl(mhHeader.type);
 | 
					        mhHeader.type = ntohl(mhHeader.type);
 | 
				
			||||||
        mhHeader.reader_id = ntohl(mhHeader.reader_id);
 | 
					        mhHeader.reader_id = ntohl(mhHeader.reader_id);
 | 
				
			||||||
        mhHeader.length = ntohl(mhHeader.length);
 | 
					        mhHeader.length = ntohl(mhHeader.length);
 | 
				
			||||||
@ -283,20 +332,19 @@ do_socket_read(void)
 | 
				
			|||||||
        case VSC_Flush:
 | 
					        case VSC_Flush:
 | 
				
			||||||
        case VSC_Error:
 | 
					        case VSC_Error:
 | 
				
			||||||
        case VSC_Init:
 | 
					        case VSC_Init:
 | 
				
			||||||
        rv = read(sock, pbSendBuffer, mhHeader.length);
 | 
					            buf = (gchar *)pbSendBuffer;
 | 
				
			||||||
        break;
 | 
					            to_read = mhHeader.length;
 | 
				
			||||||
 | 
					            state = STATE_MESSAGE;
 | 
				
			||||||
 | 
					            return TRUE;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.type);
 | 
					            fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.type);
 | 
				
			||||||
        return -1;
 | 
					            return FALSE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (state == STATE_MESSAGE) {
 | 
				
			||||||
        switch (mhHeader.type) {
 | 
					        switch (mhHeader.type) {
 | 
				
			||||||
        case VSC_APDU:
 | 
					        case VSC_APDU:
 | 
				
			||||||
        if (rv < 0) {
 | 
					 | 
				
			||||||
            /* Error */
 | 
					 | 
				
			||||||
            fprintf(stderr, "read error\n");
 | 
					 | 
				
			||||||
            close(sock);
 | 
					 | 
				
			||||||
            return -1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
            if (verbose) {
 | 
					            if (verbose) {
 | 
				
			||||||
                printf(" recv APDU: ");
 | 
					                printf(" recv APDU: ");
 | 
				
			||||||
                print_byte_array(pbSendBuffer, mhHeader.length);
 | 
					                print_byte_array(pbSendBuffer, mhHeader.length);
 | 
				
			||||||
@ -355,29 +403,73 @@ do_socket_read(void)
 | 
				
			|||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case VSC_Init:
 | 
					        case VSC_Init:
 | 
				
			||||||
            if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) {
 | 
					            if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) {
 | 
				
			||||||
            return -1;
 | 
					                return FALSE;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
        printf("Default\n");
 | 
					            g_warn_if_reached();
 | 
				
			||||||
        return -1;
 | 
					            return FALSE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					        state = STATE_HEADER;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					do_socket(GIOChannel *source,
 | 
				
			||||||
 | 
					          GIOCondition condition,
 | 
				
			||||||
 | 
					          gpointer data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* not sure if two watches work well with a single win32 sources */
 | 
				
			||||||
 | 
					    if (condition & G_IO_OUT) {
 | 
				
			||||||
 | 
					        if (!do_socket_send(source, condition, data)) {
 | 
				
			||||||
 | 
					            return FALSE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (condition & G_IO_IN) {
 | 
				
			||||||
 | 
					        if (!do_socket_read(source, condition, data)) {
 | 
				
			||||||
 | 
					            return FALSE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
do_command(void)
 | 
					update_socket_watch(gboolean out)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (socket_tag != 0) {
 | 
				
			||||||
 | 
					        g_source_remove(socket_tag);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    socket_tag = g_io_add_watch(channel_socket,
 | 
				
			||||||
 | 
					        G_IO_IN | (out ? G_IO_OUT : 0), do_socket, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					do_command(GIOChannel *source,
 | 
				
			||||||
 | 
					           GIOCondition condition,
 | 
				
			||||||
 | 
					           gpointer data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char inbuf[255];
 | 
					 | 
				
			||||||
    char *string;
 | 
					    char *string;
 | 
				
			||||||
    VCardEmulError error;
 | 
					    VCardEmulError error;
 | 
				
			||||||
    static unsigned int default_reader_id;
 | 
					    static unsigned int default_reader_id;
 | 
				
			||||||
    unsigned int reader_id;
 | 
					    unsigned int reader_id;
 | 
				
			||||||
    VReader *reader = NULL;
 | 
					    VReader *reader = NULL;
 | 
				
			||||||
 | 
					    GError *err = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_assert(condition & G_IO_IN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reader_id = default_reader_id;
 | 
					    reader_id = default_reader_id;
 | 
				
			||||||
    string = fgets(inbuf, sizeof(inbuf), stdin);
 | 
					    g_io_channel_read_line(source, &string, NULL, NULL, &err);
 | 
				
			||||||
 | 
					    if (err != NULL) {
 | 
				
			||||||
 | 
					        g_error("Error while reading command: %s", err->message);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (string != NULL) {
 | 
					    if (string != NULL) {
 | 
				
			||||||
        if (strncmp(string, "exit", 4) == 0) {
 | 
					        if (strncmp(string, "exit", 4) == 0) {
 | 
				
			||||||
            /* remove all the readers */
 | 
					            /* remove all the readers */
 | 
				
			||||||
@ -491,6 +583,8 @@ do_command(void)
 | 
				
			|||||||
    vreader_free(reader);
 | 
					    vreader_free(reader);
 | 
				
			||||||
    printf("> ");
 | 
					    printf("> ");
 | 
				
			||||||
    fflush(stdout);
 | 
					    fflush(stdout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -504,7 +598,7 @@ connect_to_qemu(
 | 
				
			|||||||
) {
 | 
					) {
 | 
				
			||||||
    struct addrinfo hints;
 | 
					    struct addrinfo hints;
 | 
				
			||||||
    struct addrinfo *server;
 | 
					    struct addrinfo *server;
 | 
				
			||||||
    int ret;
 | 
					    int ret, sock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sock = qemu_socket(AF_INET, SOCK_STREAM, 0);
 | 
					    sock = qemu_socket(AF_INET, SOCK_STREAM, 0);
 | 
				
			||||||
    if (sock < 0) {
 | 
					    if (sock < 0) {
 | 
				
			||||||
@ -543,6 +637,8 @@ main(
 | 
				
			|||||||
    int argc,
 | 
					    int argc,
 | 
				
			||||||
    char *argv[]
 | 
					    char *argv[]
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
 | 
					    GMainLoop *loop;
 | 
				
			||||||
 | 
					    GIOChannel *channel_stdin;
 | 
				
			||||||
    char *qemu_host;
 | 
					    char *qemu_host;
 | 
				
			||||||
    char *qemu_port;
 | 
					    char *qemu_port;
 | 
				
			||||||
    VSCMsgHeader mhHeader;
 | 
					    VSCMsgHeader mhHeader;
 | 
				
			||||||
@ -552,7 +648,10 @@ main(
 | 
				
			|||||||
    char *cert_names[MAX_CERTS];
 | 
					    char *cert_names[MAX_CERTS];
 | 
				
			||||||
    char *emul_args = NULL;
 | 
					    char *emul_args = NULL;
 | 
				
			||||||
    int cert_count = 0;
 | 
					    int cert_count = 0;
 | 
				
			||||||
    int c, rv;
 | 
					    int c, sock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (socket_init() != 0)
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while ((c = getopt(argc, argv, "c:e:pd:")) != -1) {
 | 
					    while ((c = getopt(argc, argv, "c:e:pd:")) != -1) {
 | 
				
			||||||
        switch (c) {
 | 
					        switch (c) {
 | 
				
			||||||
@ -618,15 +717,33 @@ main(
 | 
				
			|||||||
        exit(5);
 | 
					        exit(5);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_mutex_init(&write_lock);
 | 
					    socket_to_send = g_byte_array_new();
 | 
				
			||||||
 | 
					    qemu_mutex_init(&socket_to_send_lock);
 | 
				
			||||||
    qemu_mutex_init(&pending_reader_lock);
 | 
					    qemu_mutex_init(&pending_reader_lock);
 | 
				
			||||||
    qemu_cond_init(&pending_reader_condition);
 | 
					    qemu_cond_init(&pending_reader_condition);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vcard_emul_init(command_line_options);
 | 
					    vcard_emul_init(command_line_options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    loop = g_main_loop_new(NULL, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("> ");
 | 
					    printf("> ");
 | 
				
			||||||
    fflush(stdout);
 | 
					    fflush(stdout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					    channel_stdin = g_io_channel_win32_new_fd(STDIN_FILENO);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    channel_stdin = g_io_channel_unix_new(STDIN_FILENO);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    g_io_add_watch(channel_stdin, G_IO_IN, do_command, NULL);
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					    channel_socket = g_io_channel_win32_new_socket(sock);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    channel_socket = g_io_channel_unix_new(sock);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    g_io_channel_set_encoding(channel_socket, NULL, NULL);
 | 
				
			||||||
 | 
					    /* we buffer ourself for thread safety reasons */
 | 
				
			||||||
 | 
					    g_io_channel_set_buffered(channel_socket, FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Send init message, Host responds (and then we send reader attachments) */
 | 
					    /* Send init message, Host responds (and then we send reader attachments) */
 | 
				
			||||||
    VSCMsgInit init = {
 | 
					    VSCMsgInit init = {
 | 
				
			||||||
        .version = htonl(VSCARD_VERSION),
 | 
					        .version = htonl(VSCARD_VERSION),
 | 
				
			||||||
@ -635,28 +752,12 @@ main(
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
    send_msg(VSC_Init, mhHeader.reader_id, &init, sizeof(init));
 | 
					    send_msg(VSC_Init, mhHeader.reader_id, &init, sizeof(init));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    do {
 | 
					    g_main_loop_run(loop);
 | 
				
			||||||
        fd_set fds;
 | 
					    g_main_loop_unref(loop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        FD_ZERO(&fds);
 | 
					    g_io_channel_unref(channel_stdin);
 | 
				
			||||||
        FD_SET(1, &fds);
 | 
					    g_io_channel_unref(channel_socket);
 | 
				
			||||||
        FD_SET(sock, &fds);
 | 
					    g_byte_array_unref(socket_to_send);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* waiting on input from the socket */
 | 
					 | 
				
			||||||
        rv = select(sock+1, &fds, NULL, NULL, NULL);
 | 
					 | 
				
			||||||
        if (rv < 0) {
 | 
					 | 
				
			||||||
            /* handle error */
 | 
					 | 
				
			||||||
            perror("select");
 | 
					 | 
				
			||||||
            return 7;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (FD_ISSET(1, &fds)) {
 | 
					 | 
				
			||||||
            do_command();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (!FD_ISSET(sock, &fds)) {
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        rv = do_socket_read();
 | 
					 | 
				
			||||||
    } while (rv >= 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user