void *fdserver(void *data) { int fd; EMsg *msg; int id = (int)data; fd_set rfds; fd = e_msgport_fd(server_port); while (1) { int count = 0; printf("server %d: waiting on fd %d\n", id, fd); FD_ZERO(&rfds); FD_SET(fd, &rfds); select(fd+1, &rfds, NULL, NULL, NULL); printf("server %d: Got async notification, checking for messages\n", id); while ((msg = e_msgport_get(server_port))) { printf("server %d: got message\n", id); g_usleep(1000000); printf("server %d: replying\n", id); e_msgport_reply(msg); count++; } printf("server %d: got %d messages\n", id, count); } }
static void * cs_getnameinfo(void *data) { struct _addrinfo_msg *msg = data; /* there doens't appear to be a return code which says host or serv buffers are too short, lengthen them */ msg->result = getnameinfo(msg->addr, msg->addrlen, msg->host, msg->hostlen, msg->serv, msg->servlen, msg->flags); if (msg->cancelled) cs_freeinfo(msg); else e_msgport_reply((EMsg *)msg); return NULL; }
static void * cs_getaddrinfo(void *data) { struct _addrinfo_msg *info = data; info->result = getaddrinfo(info->name, info->service, info->hints, info->res); if (info->cancelled) { cs_freeinfo(info); } else { e_msgport_reply((EMsg *)info); } return NULL; }
static void * cs_getnameinfo(void *data) { struct _addrinfo_msg *msg = data; int herr; struct hostent h; struct sockaddr_in *sin = (struct sockaddr_in *)msg->addr; /* FIXME: error code */ if (msg->addr->sa_family != AF_INET) { msg->result = -1; return NULL; } /* FIXME: honour getnameinfo flags: do we care, not really */ while ((msg->result = camel_gethostbyaddr_r((const char *)&sin->sin_addr, sizeof(sin->sin_addr), AF_INET, &h, msg->hostbufmem, msg->hostbuflen, &herr)) == ERANGE) { pthread_testcancel (); msg->hostbuflen *= 2; msg->hostbufmem = g_realloc(msg->hostbufmem, msg->hostbuflen); } if (msg->cancelled) goto cancel; if (msg->host) { g_free(msg->host); if (msg->result == 0 && h.h_name && h.h_name[0]) { msg->host = g_strdup(h.h_name); } else { unsigned char *in = (unsigned char *)&sin->sin_addr; /* sin_addr is always network order which is big-endian */ msg->host = g_strdup_printf("%u.%u.%u.%u", in[0], in[1], in[2], in[3]); } } /* we never actually use this anyway */ if (msg->serv) sprintf(msg->serv, "%d", sin->sin_port); e_msgport_reply((EMsg *)msg); return NULL; cancel: cs_freeinfo(msg); return NULL; }
static void * cs_getaddrinfo(void *data) { struct _addrinfo_msg *info = data; if (!info->name) g_warning ("Memory problem in cs_getaddrinfo\n"); info->result = getaddrinfo(info->name, info->service, info->hints, info->res); if (info->cancelled) { /* g_free(info); */ cs_freeinfo(info); } else { e_msgport_reply((EMsg *)info); } return NULL; }
void *server(void *data) { EMsg *msg; int id = (int)data; while (1) { printf("server %d: waiting\n", id); msg = e_msgport_wait(server_port); if (msg) { printf("server %d: got message\n", id); g_usleep(1000000); printf("server %d: replying\n", id); e_msgport_reply(msg); } else { printf("server %d: didn't get message\n", id); } } return NULL; }
static void * cs_getaddrinfo(void *data) { struct _addrinfo_msg *msg = data; int herr; struct hostent h; struct addrinfo *res, *last = NULL; struct sockaddr_in *sin; in_port_t port = 0; int i; /* This is a pretty simplistic emulation of getaddrinfo */ while ((msg->result = camel_gethostbyname_r(msg->name, &h, msg->hostbufmem, msg->hostbuflen, &herr)) == ERANGE) { pthread_testcancel(); msg->hostbuflen *= 2; msg->hostbufmem = g_realloc(msg->hostbufmem, msg->hostbuflen); } /* If we got cancelled, dont reply, just free it */ if (msg->cancelled) goto cancel; /* FIXME: map error numbers across */ if (msg->result != 0) goto reply; /* check hints matched */ if (msg->hints && msg->hints->ai_family && msg->hints->ai_family != h.h_addrtype) { msg->result = EAI_FAMILY; goto reply; } /* we only support ipv4 for this interface, even if it could supply ipv6 */ if (h.h_addrtype != AF_INET) { msg->result = EAI_FAMILY; goto reply; } /* check service mapping */ if (msg->service) { const char *p = msg->service; while (*p) { if (*p < '0' || *p > '9') break; p++; } if (*p) { const char *socktype = NULL; struct servent *serv; if (msg->hints && msg->hints->ai_socktype) { if (msg->hints->ai_socktype == SOCK_STREAM) socktype = "tcp"; else if (msg->hints->ai_socktype == SOCK_DGRAM) socktype = "udp"; } serv = getservbyname(msg->service, socktype); if (serv == NULL) { msg->result = EAI_NONAME; goto reply; } port = serv->s_port; } else { port = htons(strtoul(msg->service, NULL, 10)); } } for (i=0;h.h_addr_list[i];i++) { res = g_malloc0(sizeof(*res)); if (msg->hints) { res->ai_flags = msg->hints->ai_flags; if (msg->hints->ai_flags & AI_CANONNAME) res->ai_canonname = g_strdup(h.h_name); res->ai_socktype = msg->hints->ai_socktype; res->ai_protocol = msg->hints->ai_protocol; } else { res->ai_flags = 0; res->ai_socktype = SOCK_STREAM; /* fudge */ res->ai_protocol = 0; /* fudge */ } res->ai_family = AF_INET; res->ai_addrlen = sizeof(*sin); res->ai_addr = g_malloc(sizeof(*sin)); sin = (struct sockaddr_in *)res->ai_addr; sin->sin_family = AF_INET; sin->sin_port = port; memcpy(&sin->sin_addr, h.h_addr_list[i], sizeof(sin->sin_addr)); if (last == NULL) { *msg->res = last = res; } else { last->ai_next = res; last = res; } } reply: e_msgport_reply((EMsg *)msg); return NULL; cancel: cs_freeinfo(msg); return NULL; }