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 + -
显示快捷键?