inet_gethost.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 2,324 行 · 第 1/4 页

C
2,324
字号
    case NO_ADDRESS:#endif#endif	return ERRCODE_NO_DATA;#endif    default:	return ERRCODE_NETDB_INTERNAL;    }}static char *errcode_to_string(int errcode){    switch (errcode) {    case ERRCODE_NOTSUP:	return "enotsup";    case ERRCODE_HOST_NOT_FOUND:	/* 	 * I would preffer 	 * return "host_not_found";	 * but have to keep compatibility with the old 	 * inet_gethost's error codes... 	 */	return "notfound";    case ERRCODE_TRY_AGAIN:	return "try_again";    case ERRCODE_NO_RECOVERY:	return "no_recovery";    case ERRCODE_NO_DATA:	return "no_data";    default:	/*case ERRCODE_NETDB_INTERNAL:*/	return "netdb_internal";    }}	static size_t build_error_reply(SerialType serial, int errnum, 				AddrByte **preply,				size_t *preply_size){    char *errstring = errcode_to_string(errnum);    int string_need = strlen(errstring) + 1; /* a '\0' too */    unsigned need;    AddrByte *ptr;    need = PACKET_BYTES + 4 /* Serial */ + 1 /* Unit */ + string_need;    if (*preply_size < need) {	if (*preply_size == 0) {	    *preply = ALLOC((*preply_size = need));	} else {	    *preply = REALLOC(*preply, 			      (*preply_size = need));	}    }    ptr = *preply;    PUT_PACKET_BYTES(ptr,need - PACKET_BYTES);    ptr += PACKET_BYTES;    put_int32(ptr,serial);    ptr +=4;    *ptr++ = (AddrByte) 0; /* 4 or 16 */    strcpy((char*)ptr, errstring);    return need;}    static size_t build_reply(SerialType serial, struct hostent *he, 			  AddrByte **preply, size_t *preply_size){    unsigned need;    int strings_need;    int num_strings;    int num_addresses;    int i;    AddrByte *ptr;    int unit = he->h_length;    for (num_addresses = 0; he->h_addr_list[num_addresses] != NULL; 	 ++num_addresses)	;    strings_need = strlen(he->h_name) + 1; /* 1 for null byte */    num_strings = 1;    if (he->h_aliases) {	for(i=0; he->h_aliases[i] != NULL; ++i) {	    strings_need += strlen(he->h_aliases[i]) + 1;	    ++num_strings;	}    }        need = PACKET_BYTES + 	4 /* Serial */ + 1 /* Unit */ + 4 /* Naddr */ +	(unit * num_addresses) /* Address bytes */ +	4 /* Nnames */ + strings_need /* The name and alias strings */;    if (*preply_size < need) {	if (*preply_size == 0) {	    *preply = ALLOC((*preply_size = need));	} else {	    *preply = REALLOC(*preply, 			      (*preply_size = need));	}    }    ptr = *preply;    PUT_PACKET_BYTES(ptr,need - PACKET_BYTES);    ptr += PACKET_BYTES;    put_int32(ptr,serial);    ptr +=4;    *ptr++ = (AddrByte) unit; /* 4 or 16 */    put_int32(ptr, num_addresses);    ptr += 4;    for (i = 0; i < num_addresses; ++i) {	memcpy(ptr, he->h_addr_list[i], unit);	ptr += unit;    }    put_int32(ptr, num_strings);    ptr += 4;    strcpy((char*)ptr, he->h_name);    ptr += 1 + strlen(he->h_name);    for (i = 0; i < (num_strings - 1); ++i) {	strcpy((char*)ptr, he->h_aliases[i]);	ptr += 1 + strlen(he->h_aliases[i]);    }    return need;}/* * Encode/decode/read/write  */static int get_int32(AddrByte *b) {    int res;    res = (unsigned) b[3];    res |= ((unsigned) b[2]) << 8;    res |= ((unsigned) b[1]) << 16;    res |= ((unsigned) b[0]) << 24;    return res;}static void put_int32(AddrByte *buff, int value){    buff[0] = (((unsigned) value) >> 24) & 0xFF;    buff[1] = (((unsigned) value) >> 16) & 0xFF;    buff[2] = (((unsigned) value) >> 8) & 0xFF;    buff[3] = ((unsigned) value) & 0xFF;}#ifdef WIN32static int read_int32(HANDLE fd, int *res){    AddrByte b[4];    int r;    if ((r = read_exact(fd,b,4)) < 0) {	return -1;    } else if (r == 0) {	return 0;    } else {	*res = (unsigned) b[3];	*res |= ((unsigned) b[2]) << 8;	*res |= ((unsigned) b[1]) << 16;	*res |= ((unsigned) b[0]) << 24;    }    return 4;}static int read_exact(HANDLE fd, void *vbuff, DWORD nbytes){    DWORD ret,got;    BOOL stat;    char *buff = vbuff;    got = 0;    for(;;) {	stat = ReadFile(fd, buff, nbytes - got, &ret, NULL);	if (!stat) {	    if (GetLastError() == ERROR_BROKEN_PIPE) {		DEBUGF(1, ("End of file while reading from pipe."));		return 0;	    } else {		DEBUGF(1, ("Error while reading from pipe,"			   " errno = %d",			   GetLastError()));		return -1;	    }	}	if (ret < nbytes - got) {	    got += ret;	    buff += ret;	} else {	    return nbytes;	}    }}static int write_exact(HANDLE fd, AddrByte *buff, DWORD len) {    DWORD res,stat;    DWORD x = len;    for(;;) {		stat = WriteFile(fd,buff,x,&res,NULL);	if (!stat) {	    if (GetLastError() == ERROR_BROKEN_PIPE) {		return 0;	    } else {		return -1;	    }	} else if (res < x) {	    /* Hmmm, blocking write but not all written, could this happen	       if the other end was closed during the operation? Well, 	       it costs very little to handle anyway... */	    x -= res;	    buff += res;	} else {	    return len;	}    }}DWORD WINAPI reader(void *data) {    MesQ *mq = (MesQ *) data;    QueItem *m;    int siz;    int r;    HANDLE inp = GetStdHandle(STD_INPUT_HANDLE);    for (;;) {	if ((r = READ_PACKET_BYTES(inp,&siz)) != 4) {	    DEBUGF(1,("Erlang has closed (reading)"));	    exit(0);	}	m = ALLOC(sizeof(QueItem) - 1 + siz);	if (read_exact(inp, m->request, siz) != siz) {	    fatal("Unexpected end of file on main input, errno = %d",errno);	}	if (siz < 5) {	    fatal("Unexpected message on main input, message size %d less "		  "than minimum.");	}	m->req_size = siz;	m->next = NULL;	if (!enque_mesq(mq, m)) {	     fatal("Reader could not talk to main thread!");	}    }}	DWORD WINAPI writer(void *data) {    MesQ *mq = (MesQ *) data;    QueItem *m;    HANDLE outp = GetStdHandle(STD_OUTPUT_HANDLE);    AddrByte hdr[PACKET_BYTES];    for (;;) {	WaitForSingleObject(event_mesq(mq),INFINITE);	if (!deque_mesq(mq, &m)) {	    fatal("Writer could not talk to main thread!");	}	PUT_PACKET_BYTES(hdr, m->req_size);	if (write_exact(outp, hdr, 4) != 4) {	    DEBUGF(1,("Erlang has closed (writing)"));	    exit(0);	}	if (write_exact(outp, m->request, m->req_size) != m->req_size) {	    DEBUGF(1,("Erlang has closed (writing)"));	    exit(0);	}	FREE(m);    }}#elsestatic size_t read_int32(int fd, int *res){    AddrByte b[4];    int r;    if ((r = read_exact(fd,b,4)) < 0) {	return -1;    } else if (r == 0) {	return 0;    } else {	*res = (unsigned) b[3];	*res |= ((unsigned) b[2]) << 8;	*res |= ((unsigned) b[1]) << 16;	*res |= ((unsigned) b[0]) << 24;    }    return 4;}static ssize_t read_exact(int fd, void *vbuff, size_t nbytes){    ssize_t ret, got;    char *buff = vbuff;    got = 0;    for(;;) {	ret = read(fd, buff, nbytes - got);	if (ret < 0) {	    if (errno == EINTR) {		continue;	    } else {		DEBUGF(1, ("Error while reading from pipe,"			   " errno = %d",			   errno));		return -1;	    }	} else if (ret == 0) {	    DEBUGF(1, ("End of file while reading from pipe."));	    if (got == 0) {		return 0; /* "Normal" EOF */	    } else {		return -1;	    }	} else if (ret < nbytes - got) {	    got += ret;	    buff += ret;	} else {	    return nbytes;	}    }}static int write_exact(int fd, AddrByte *buff, int len) {    int res;    int x = len;    for(;;) {	if((res = write(fd, buff, x)) == x) {	    break;	}	if (res < 0) {	    if (errno == EINTR) {		continue;	    } else if (errno == EPIPE) {		return 0;	    }#ifdef ENXIO	    else if (errno == ENXIO) {		return 0;	    }#endif	    else {		return -1;	    }	} else {	    /* Hmmm, blocking write but not all written, could this happen	       if the other end was closed during the operation? Well, 	       it costs very little to handle anyway... */	    x -= res;	    buff += res;	}    }    return len;}#endif /* !WIN32 *//* * Debug and memory allocation */static char *format_address(int siz, AddrByte *addr){    static char buff[50];    char tmp[10];    if (siz > 16) {	return "(unknown)";    }    *buff='\0';    if (siz <= 4) {	while(siz--) {	    sprintf(tmp,"%d",(int) *addr++);	    strcat(buff,tmp);	    if(siz) {		strcat(buff,".");	    }	}	return buff;    }     while(siz--) {	sprintf(tmp,"%02x",(int) *addr++);	strcat(buff,tmp);	if(siz) {	    strcat(buff,":");	}    }    return buff;}static void debugf(char *format, ...){    char buff[2048];    char *ptr;    va_list ap;    va_start(ap,format);#ifdef WIN32	sprintf(buff,"%s[%d] (DEBUG):",program_name,(int) GetCurrentThreadId());#else    sprintf(buff,"%s[%d] (DEBUG):",program_name,(int) getpid());#endif    ptr = buff + strlen(buff);    vsprintf(ptr,format,ap);    strcat(ptr,"\r\n");#ifdef WIN32    {	DWORD res;	WriteFile(GetStdHandle(STD_ERROR_HANDLE),buff,strlen(buff),&res,NULL);    }#else    write(2,buff,strlen(buff));#endif    va_end(ap);}static void warning(char *format, ...){    char buff[2048];    char *ptr;    va_list ap;    va_start(ap,format);    sprintf(buff,"%s[%d]: WARNING:",program_name, (int) getpid());    ptr = buff + strlen(buff);    vsprintf(ptr,format,ap);    strcat(ptr,"\r\n");#ifdef WIN32    {	DWORD res;	WriteFile(GetStdHandle(STD_ERROR_HANDLE),buff,strlen(buff),&res,NULL);    }#else    write(2,buff,strlen(buff));#endif    va_end(ap);}static void fatal(char *format, ...){    char buff[2048];    char *ptr;    va_list ap;    va_start(ap,format);    sprintf(buff,"%s[%d]: FATAL ERROR:",program_name, (int) getpid());    ptr = buff + strlen(buff);    vsprintf(ptr,format,ap);    strcat(ptr,"\r\n");#ifdef WIN32    {	DWORD res;	WriteFile(GetStdHandle(STD_ERROR_HANDLE),buff,strlen(buff),&res,NULL);    }#else    write(2,buff,strlen(buff));#endif    va_end(ap);#ifndef WIN32    kill_all_workers();#endif    exit(1);}static void *my_malloc(size_t size){     void *ptr = malloc(size);    if (!ptr) {	fatal("Cannot allocate %d bytes of memory.", (int) size);	return NULL; /* lint... */    }    return ptr;}static void *my_realloc(void *old, size_t size){    void *ptr = realloc(old, size);    if (!ptr) {	fatal("Cannot reallocate %d bytes of memory from 0x%08X.", 	      (int) size, (unsigned) old);	return NULL; /* lint... */    }    return ptr;}#ifdef WIN32BOOL create_mesq(MesQ **q) {    MesQ *tmp = malloc(sizeof(MesQ));    tmp->data_present = CreateEvent(NULL, TRUE, FALSE,NULL);    if (tmp->data_present == NULL) {	free(tmp);	return FALSE;    }    InitializeCriticalSection(&(tmp->crit)); /* Cannot fail */    tmp->shutdown = 0;    tmp->first = NULL;    tmp->last = NULL;    *q = tmp;    return TRUE;}BOOL enque_mesq(MesQ *q, QueItem *m){    EnterCriticalSection(&(q->crit));    if (q->shutdown) {	LeaveCriticalSection(&(q->crit));	return FALSE;    }    if (q->last == NULL) {	q->first = q->last = m;    } else {	q->last->next = m;	q->last = m;    }    m->next = NULL;    if (!SetEvent(q->data_present)) {	fprintf(stderr,"Fatal: Unable to signal event in %s:%d, last error: %d\n",		__FILE__,__LINE__,GetLastError());	exit(1); /* Unable to continue at all */    }    LeaveCriticalSection(&(q->crit));    return TRUE;}BOOL deque_mesq(MesQ *q, QueItem **m){    EnterCriticalSection(&(q->crit));    if (q->first == NULL) { /* Usually shutdown from other end */	ResetEvent(q->data_present); 	LeaveCriticalSection(&(q->crit));	return FALSE;    }    *m = q->first;    q->first = q->first->next;    if (q->first == NULL) {	q->last = NULL;	ResetEvent(q->data_present);    }    (*m)->next = NULL;    LeaveCriticalSection(&(q->crit));    return TRUE;}BOOL close_mesq(MesQ *q){    QueItem *tmp;    EnterCriticalSection(&(q->crit));    if (!q->shutdown) {	q->shutdown = TRUE;	if (!SetEvent(q->data_present)) {	    fprintf(stderr,"Fatal: Unable to signal event in %s:%d, last error: %d\n",		    __FILE__,__LINE__,GetLastError());	    exit(1); /* Unable to continue at all */	}	LeaveCriticalSection(&(q->crit));	return FALSE;    }    /* Noone else is supposed to use this object any more */    LeaveCriticalSection(&(q->crit));    DeleteCriticalSection(&(q->crit));    CloseHandle(q->data_present);    tmp = q->first;    while(tmp) {	q->first = q->first->next;	free(tmp);	tmp = q->first;    }    free(q);    return TRUE;}HANDLE event_mesq(MesQ *q){    return q->data_present;}    #endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?