PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL PIOHANDLE Parrot_io_internal_accept(PARROT_INTERP, PIOHANDLE os_handle, ARGOUT(PMC * remote_addr)) { Parrot_Socklen_t addr_len = sizeof (struct sockaddr_storage); struct sockaddr_storage *addr = (struct sockaddr_storage *)Parrot_gc_allocate_memory_chunk(interp, addr_len); Parrot_Sockaddr_attributes *sa_attrs = PARROT_SOCKADDR(remote_addr); PIOSOCKET newsock; newsock = accept((PIOSOCKET)os_handle, (struct sockaddr *)addr, &addr_len); if (newsock == PIO_INVALID_SOCKET) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR, "accept failed: %Ss", Parrot_platform_strerror(interp, PIO_SOCK_ERRNO)); sa_attrs->len = addr_len; sa_attrs->pointer = addr; /* XXX FIXME: Need to do a getsockname and getpeername here to * fill in the sockaddr_in structs for local and peer */ /* Optionally do a gethostbyaddr() to resolve remote IP address. * This should be based on an option set in the master socket */ return (PIOHANDLE)newsock; }
int main(int argc, const char **argv) { PackFile *pf; Interp *interp; const char *file = NULL; int terse = 0; int disas = 0; int convert = 0; int nums_only = 0; int options = PFOPT_UTILS; struct longopt_opt_info opt = LONGOPT_OPT_INFO_INIT; int status; if (argc < 2) help(); interp = Parrot_new(NULL); /* init and set top of stack */ Parrot_init_stacktop(interp, &status); while ((status = longopt_get(interp, argc, argv, opt_options, &opt)) > 0) { switch (opt.opt_id) { #if TRACE_PACKFILE case 'D': options += atoi(opt.opt_arg) << 2; break; #endif case 'h': options += PFOPT_HEADERONLY; break; case 't': terse = 1; break; case 'd': disas = 1; break; case 'o': file = opt.opt_arg; convert = 1; break; case 'n': nums_only = 1; break; case '?': default: help(); break; } } if (status == -1) help(); argc -= opt.opt_index; argv += opt.opt_index; pf = Parrot_pbc_read(interp, *argv, options); if (!pf) { printf("Can't read PBC\n"); return 1; } Parrot_pbc_load(interp, pf); if (convert) { size_t size = PackFile_pack_size(interp, interp->code->base.pf) * sizeof (opcode_t); opcode_t *pack = (opcode_t *)Parrot_gc_allocate_memory_chunk(interp, size); FILE *fp; if (!pack) { printf("out of mem\n"); exit(EXIT_FAILURE); } PackFile_pack(interp, interp->code->base.pf, pack); if (STREQ(file, "-")) fp = stdout; else if ((fp = fopen(file, "wb")) == 0) { printf("Couldn't open %s\n", file); exit(EXIT_FAILURE); } if ((1 != fwrite(pack, size, 1, fp))) { printf("Couldn't write %s\n", file); exit(EXIT_FAILURE); } fclose(fp); Parrot_gc_free_memory_chunk(interp, pack); Parrot_exit(interp, 0); } if (!nums_only) PackFile_header_dump(interp, pf); if (options & PFOPT_HEADERONLY) Parrot_exit(interp, 0); /* install a dumper function */ if (!terse) { pf->PackFuncs[PF_CONST_SEG].dump = const_dump; } if (disas) pf->PackFuncs[PF_BYTEC_SEG].dump = disas_dump; if (nums_only) { int i; for (i = PF_DIR_SEG + 1; i < PF_MAX_SEG; ++i) pf->PackFuncs[i].dump = null_dump; pf->PackFuncs[PF_DIR_SEG].dump = null_dir_dump; pf->PackFuncs[PF_BYTEC_SEG].dump = nums_dump; } /* do a directory dump, which dumps segs then */ PackFile_Segment_dump(interp, &pf->directory.base); Parrot_exit(interp, 0); }
PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL PMC * Parrot_io_internal_getaddrinfo(PARROT_INTERP, ARGIN(STRING *addr), INTVAL port, INTVAL protocol, INTVAL fam, INTVAL passive) { #ifdef PARROT_HAS_IPV6 PMC *array; struct addrinfo hints; struct addrinfo *ai, *walk; /* We need to pass the port as a string (because you could also use a * service specification from /etc/services). The highest port is 65535, * so we need 5 characters + trailing null-byte. */ char portstr[6]; int ret; /* convert Parrot's family to system family */ if (fam < 0 || fam >= PIO_PF_MAX || (fam = pio_pf[fam]) < 0) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR, "unsupported protocol family: %ld", fam); memset(&hints, 0, sizeof (struct addrinfo)); if (passive) hints.ai_flags = AI_PASSIVE; hints.ai_family = fam; hints.ai_protocol = protocol; snprintf(portstr, sizeof (portstr), "%ld", port); { /* Limited scope for the C string to prevent mistakes */ char *s = STRING_IS_NULL(addr) ? (char *) NULL : Parrot_str_to_cstring(interp, addr); ret = getaddrinfo(s, portstr, &hints, &ai); Parrot_str_free_cstring(s); } if (ret != 0) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR, "getaddrinfo failed: %Ss: %Ss", addr, Parrot_platform_strerror(interp, PIO_SOCK_ERRNO)); array = Parrot_pmc_new(interp, enum_class_ResizablePMCArray); for (walk = ai; walk; walk = walk->ai_next) { PMC *sockaddr = Parrot_pmc_new(interp, enum_class_Sockaddr); Parrot_Sockaddr_attributes *sa_attrs = PARROT_SOCKADDR(sockaddr); sa_attrs->family = walk->ai_family; sa_attrs->type = walk->ai_socktype; sa_attrs->protocol = walk->ai_protocol; sa_attrs->len = walk->ai_addrlen; sa_attrs->pointer = Parrot_gc_allocate_memory_chunk(interp, walk->ai_addrlen); memcpy(sa_attrs->pointer, walk->ai_addr, walk->ai_addrlen); VTABLE_push_pmc(interp, array, sockaddr); } freeaddrinfo(ai); return array; #else /* PARROT_HAS_IPV6 */ const char *host; char *cstring; int success; PMC *sockaddr; PMC *array; const size_t addr_len = sizeof (struct sockaddr_in); struct sockaddr_in *sa; Parrot_Sockaddr_attributes *sa_attrs; sa = (struct sockaddr_in *)Parrot_gc_allocate_memory_chunk(interp, addr_len); sockaddr = Parrot_pmc_new(interp, enum_class_Sockaddr); sa_attrs = PARROT_SOCKADDR(sockaddr); sa_attrs->family = PF_INET; sa_attrs->type = 0; sa_attrs->protocol = 0; sa_attrs->len = addr_len; sa_attrs->pointer = sa; if (STRING_IS_NULL(addr)) { cstring = NULL; host = "127.0.0.1"; } else { cstring = Parrot_str_to_cstring(interp, addr); host = cstring; } # ifdef _WIN32 sa->sin_addr.S_un.S_addr = inet_addr(host); success = sa->sin_addr.S_un.S_addr != -1; # else # ifdef PARROT_DEF_INET_ATON success = inet_aton(host, &sa->sin_addr) != 0; # else /* positive retval is success */ success = inet_pton(PF_INET, host, &sa->sin_addr) > 0; # endif # endif if (!success) { /* Maybe it is a hostname, try to lookup */ /* XXX Check PIO option before doing a name lookup, * it may have been toggled off. */ const struct hostent * const he = gethostbyname(host); if (!he) { if (cstring) Parrot_str_free_cstring(cstring); Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR, "getaddrinfo failed: %s", host); } memcpy((char*)&sa->sin_addr, he->h_addr, sizeof (sa->sin_addr)); } if (cstring) Parrot_str_free_cstring(cstring); sa->sin_family = PF_INET; sa->sin_port = htons(port); array = Parrot_pmc_new(interp, enum_class_ResizablePMCArray); VTABLE_push_pmc(interp, array, sockaddr); return array; #endif /* PARROT_HAS_IPV6 */ }