int jsonrpc_recv(struct jsonrpc *rpc, struct jsonrpc_msg **msgp) { *msgp = NULL; if (rpc->status) { return rpc->status; } while (!rpc->received) { if (byteq_is_empty(&rpc->input)) { size_t chunk; int retval; chunk = byteq_headroom(&rpc->input); retval = stream_recv(rpc->stream, byteq_head(&rpc->input), chunk); if (retval < 0) { if (retval == -EAGAIN) { return EAGAIN; } else { VLOG_WARN_RL(&rl, "%s: receive error: %s", rpc->name, strerror(-retval)); jsonrpc_error(rpc, -retval); return rpc->status; } } else if (retval == 0) { jsonrpc_error(rpc, EOF); return EOF; } byteq_advance_head(&rpc->input, retval); } else { size_t n, used; if (!rpc->parser) { rpc->parser = json_parser_create(0); } n = byteq_tailroom(&rpc->input); used = json_parser_feed(rpc->parser, (char *) byteq_tail(&rpc->input), n); byteq_advance_tail(&rpc->input, used); if (json_parser_is_done(rpc->parser)) { jsonrpc_received(rpc); if (rpc->status) { const struct byteq *q = &rpc->input; if (q->head <= BYTEQ_SIZE) { stream_report_content(q->buffer, q->head, STREAM_JSONRPC, THIS_MODULE, rpc->name); } return rpc->status; } } } } *msgp = rpc->received; rpc->received = NULL; return 0; }
int main() { struct pstream* p_pstream; struct stream* p_stream; const char* pstream_name = "ptcp:1234"; char buffer[50]; uint8_t dscp = 1; int actualrecv = 0; if(pstream_open(pstream_name,&p_pstream,dscp)) printf("pstream open failure!\n"); else { while(1) { while(pstream_accept(p_pstream, &p_stream)) ; printf("\nget one steam connect success!\n"); printf("p_pstream name:%s\n", pstream_get_name(p_pstream)); printf("p_pstream bound_port:%d\n", pstream_get_bound_port(p_pstream)); printf("p_stream name:%s\n", stream_get_name(p_stream)); printf("<remote_ip,remote_port> : <%d,%d>\n", stream_get_remote_ip(p_stream),stream_get_remote_port(p_stream)); printf("<local_ip,local_port> : <%d,%d>\n", stream_get_local_ip(p_stream),stream_get_local_port(p_stream)); actualrecv = stream_recv(p_stream,buffer,sizeof(buffer)); if(actualrecv < 0) printf("pstream receive failure!\n"); else if(actualrecv == 0) printf("pstream receive 0 bytes!\n"); else printf("pstream actual receive %d bytes,buffer:%s\n\n",actualrecv,buffer); } stream_close(p_stream); pstream_close(p_pstream); } return 0; }
/* Connects to a fake_pvconn with vconn_open(), accepts that connection and * reads the hello message from it, then closes the connection and verifies * that vconn_connect() reports 'expected_error'. */ static void test_read_hello(struct ovs_cmdl_context *ctx) { const char *type = ctx->argv[1]; struct fake_pvconn fpv; struct vconn *vconn; struct stream *stream; int error; fpv_create(type, &fpv); CHECK_ERRNO(vconn_open(fpv.vconn_name, 0, DSCP_DEFAULT, &vconn), 0); vconn_run(vconn); stream = fpv_accept(&fpv); fpv_destroy(&fpv); for (;;) { struct ofp_header hello; int retval; retval = stream_recv(stream, &hello, sizeof hello); if (retval == sizeof hello) { enum ofpraw raw; CHECK(hello.version, OFP13_VERSION); CHECK(ofpraw_decode_partial(&raw, &hello, sizeof hello), 0); CHECK(raw, OFPRAW_OFPT_HELLO); CHECK(ntohs(hello.length), sizeof hello); break; } else { CHECK_ERRNO(retval, -EAGAIN); } vconn_run(vconn); CHECK_ERRNO(vconn_connect(vconn), EAGAIN); vconn_run_wait(vconn); vconn_connect_wait(vconn); stream_recv_wait(stream); poll_block(); } stream_close(stream); error = vconn_connect_block(vconn); if (error != ECONNRESET && error != EPIPE) { ovs_fatal(0, "unexpected vconn_connect() return value %d (%s)", error, ovs_strerror(error)); } vconn_close(vconn); }
/* Connects to a fake_pvconn with vconn_open(), accepts that connection and * reads the hello message from it, then closes the connection and verifies * that vconn_connect() reports 'expected_error'. */ static void test_read_hello(int argc OVS_UNUSED, char *argv[]) { const char *type = argv[1]; struct fake_pvconn fpv; struct vconn *vconn; struct stream *stream; fpv_create(type, &fpv); CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn, DSCP_DEFAULT), 0); vconn_run(vconn); stream = fpv_accept(&fpv); fpv_destroy(&fpv); for (;;) { struct ofp_header hello; int retval; retval = stream_recv(stream, &hello, sizeof hello); if (retval == sizeof hello) { CHECK(hello.version, OFP10_VERSION); CHECK(hello.type, OFPT_HELLO); CHECK(ntohs(hello.length), sizeof hello); break; } else { CHECK_ERRNO(retval, -EAGAIN); } vconn_run(vconn); CHECK_ERRNO(vconn_connect(vconn), EAGAIN); vconn_run_wait(vconn); vconn_connect_wait(vconn); stream_recv_wait(stream); poll_block(); } stream_close(stream); CHECK_ERRNO(vconn_connect(vconn), ECONNRESET); vconn_close(vconn); }
// TODO: Tab Completion für builtins static char *my_fgets(char *s, int size, int stream) { pipe_set_flag(STDIN_FILENO, F_ECHO, 0); int cc = 0, i = 0; memset(s, 0, size); size--; while ((i < size) && (cc != '\n')) { fflush(stdout); stream_recv(stream, &cc, 1, O_BLOCKING); if (cc == '\t') { const char *last_space = strrchr(s, ' '); bool complete_cmd = (last_space == NULL); if (complete_cmd) last_space = s; else last_space++; char *path = getenv("PATH"); char dirn[strlen(last_space) + strlen(path) + 2]; char curpart[strlen(last_space) + 1]; char ggt[1024]; ggt[0] = 0; int got_count = 0; char duped_path[strlen(path) + 1]; strcpy(duped_path, path); bool complete_from_path = (complete_cmd && (strchr(last_space, '/') == NULL)); char *path_tok_base = duped_path; char *all_fitting = NULL; size_t all_fitting_sz = 0; bool is_dir = false, is_file = false; do { if (!complete_from_path) strcpy(dirn, last_space); else { char *tok = strtok(path_tok_base, ":"); path_tok_base = NULL; if (tok == NULL) break; sprintf(dirn, "%s/%s", tok, last_space); } char *last_slash = strrchr(dirn, '/'); if (last_slash != NULL) { strcpy(curpart, last_slash + 1); last_slash[1] = 0; } else { if (dirn[0] == '(') continue; strcpy(curpart, dirn); strcpy(dirn, "."); } int dir = create_pipe(dirn, O_RDONLY); if (dir < 0) continue; char buf[pipe_get_flag(dir, F_PRESSURE)]; stream_recv(dir, buf, sizeof(buf), 0); destroy_pipe(dir, 0); size_t j = 0; size_t this_len = strlen(curpart); while (buf[j] && (j < sizeof(buf))) { if (!strncmp(buf + j, curpart, this_len)) { size_t all_fitting_off = all_fitting_sz; all_fitting_sz += strlen(buf + j) + 1; all_fitting = realloc(all_fitting, all_fitting_sz); strcpy(all_fitting + all_fitting_off, buf + j); char full_name[strlen(dirn) + 1 + strlen(buf + j) + 1]; sprintf(full_name, "%s/%s", dirn, buf + j); int fd = create_pipe(full_name, O_JUST_STAT); if (fd >= 0) { if (pipe_implements(fd, I_STATABLE)) { if (S_ISDIR(pipe_get_flag(fd, F_MODE))) is_dir = true; else is_file = true; } else is_dir = is_file = true; destroy_pipe(fd, 0); } else is_dir = is_file = true; if (!got_count++) strcpy(ggt, buf + j + this_len); else { size_t k = 0; do { if (ggt[k] != buf[j + this_len + k]) { ggt[k] = 0; break; } } while (ggt[k++]); } } j += strlen(buf + j) + 1; } } while (complete_from_path); if (ggt[0]) { for (size_t k = 0; ggt[k] && (i < size); k++) { putchar(ggt[k]); s[i++] = ggt[k]; } } if (got_count < 2) { if (is_dir ^ is_file) { char chr = is_dir ? '/' : ' '; if (i < size) { putchar(chr); s[i++] = chr; } } } if ((got_count < 2) || ggt[0]) continue; int j = 0; putchar('\n'); while (j < (int)all_fitting_sz) { printf("%s ", all_fitting + j); j += strlen(all_fitting + j) + 1; } printf("\n%s$ %s", getenv("PWD"), s); free(all_fitting); continue; } else if (cc != '\b') putchar(cc); else { if (i) { printf("\b \b"); while (((s[--i] & 0xC0) == 0x80) && (i > 1)) s[i] = 0; s[i] = 0; } continue; } if (cc != '\n') s[i++] = cc; } pipe_set_flag(STDIN_FILENO, F_ECHO, 1); return s; }
/* Connects to a fake_pvconn with vconn_open(), accepts that connection and * sends the 'out' bytes in 'out_size' to it (presumably an OFPT_HELLO * message), then verifies that vconn_connect() reports * 'expect_connect_error'. */ static void test_send_hello(const char *type, const void *out, size_t out_size, int expect_connect_error) { struct fake_pvconn fpv; struct vconn *vconn; bool read_hello, connected; struct ofpbuf *msg; struct stream *stream; size_t n_sent; fpv_create(type, &fpv); CHECK_ERRNO(vconn_open(fpv.vconn_name, 0, DSCP_DEFAULT, &vconn), 0); vconn_run(vconn); stream = fpv_accept(&fpv); fpv_destroy(&fpv); n_sent = 0; while (n_sent < out_size) { int retval; retval = stream_send(stream, (char *) out + n_sent, out_size - n_sent); if (retval > 0) { n_sent += retval; } else if (retval == -EAGAIN) { stream_run(stream); vconn_run(vconn); stream_recv_wait(stream); vconn_connect_wait(vconn); vconn_run_wait(vconn); poll_block(); } else { ovs_fatal(0, "stream_send returned unexpected value %d", retval); } } read_hello = connected = false; for (;;) { if (!read_hello) { struct ofp_header hello; int retval = stream_recv(stream, &hello, sizeof hello); if (retval == sizeof hello) { enum ofpraw raw; CHECK(hello.version, OFP13_VERSION); CHECK(ofpraw_decode_partial(&raw, &hello, sizeof hello), 0); CHECK(raw, OFPRAW_OFPT_HELLO); CHECK(ntohs(hello.length), sizeof hello); read_hello = true; } else { CHECK_ERRNO(retval, -EAGAIN); } } vconn_run(vconn); if (!connected) { int error = vconn_connect(vconn); if (error == expect_connect_error) { if (!error) { connected = true; } else { stream_close(stream); vconn_close(vconn); return; } } else { CHECK_ERRNO(error, EAGAIN); } } if (read_hello && connected) { break; } vconn_run_wait(vconn); if (!connected) { vconn_connect_wait(vconn); } if (!read_hello) { stream_recv_wait(stream); } poll_block(); } stream_close(stream); CHECK_ERRNO(vconn_recv_block(vconn, &msg), EOF); vconn_close(vconn); }
/* Attempts to receive a message from 'rpc'. * * If successful, stores the received message in '*msgp' and returns 0. The * caller takes ownership of '*msgp' and must eventually destroy it with * jsonrpc_msg_destroy(). * * Otherwise, stores NULL in '*msgp' and returns one of the following: * * - EAGAIN: No message has been received. * * - EOF: The remote end closed the connection gracefully. * * - Otherwise an errno value that represents a JSON-RPC protocol violation * or another error fatal to the connection. 'rpc' will not send or * receive any more messages. */ int jsonrpc_recv(struct jsonrpc *rpc, struct jsonrpc_msg **msgp) { int i; *msgp = NULL; if (rpc->status) { return rpc->status; } for (i = 0; i < 50; i++) { size_t n, used; /* Fill our input buffer if it's empty. */ if (byteq_is_empty(&rpc->input)) { size_t chunk; int retval; chunk = byteq_headroom(&rpc->input); retval = stream_recv(rpc->stream, byteq_head(&rpc->input), chunk); if (retval < 0) { if (retval == -EAGAIN) { return EAGAIN; } else { VLOG_WARN_RL(&rl, "%s: receive error: %s", rpc->name, ovs_strerror(-retval)); jsonrpc_error(rpc, -retval); return rpc->status; } } else if (retval == 0) { jsonrpc_error(rpc, EOF); return EOF; } byteq_advance_head(&rpc->input, retval); } /* We have some input. Feed it into the JSON parser. */ if (!rpc->parser) { rpc->parser = json_parser_create(0); } n = byteq_tailroom(&rpc->input); used = json_parser_feed(rpc->parser, (char *) byteq_tail(&rpc->input), n); byteq_advance_tail(&rpc->input, used); /* If we have complete JSON, attempt to parse it as JSON-RPC. */ if (json_parser_is_done(rpc->parser)) { *msgp = jsonrpc_parse_received_message(rpc); if (*msgp) { return 0; } if (rpc->status) { const struct byteq *q = &rpc->input; if (q->head <= q->size) { stream_report_content(q->buffer, q->head, STREAM_JSONRPC, THIS_MODULE, rpc->name); } return rpc->status; } } } return EAGAIN; }
int main(int argc, char *argv[]) { const char *domain = NULL; const char *dns_ip = NULL; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { fprintf(stderr, "%s: Unknown option '%c'.\n", argv[0], argv[i][0]); return 1; } else { if (argv[i][0] == '@') { if (dns_ip != NULL) { fprintf(stderr, "%s: More than one DNS IP address specified.\n", argv[0]); return 1; } dns_ip = &argv[i][1]; } else if (domain == NULL) domain = argv[i]; else { fprintf(stderr, "%s: Unexpected argument \"%s\".\n", argv[0], argv[i]); return 1; } } } if (domain == NULL) { fprintf(stderr, "%s: Lookup name required.\n", argv[0]); return 1; } uint_fast32_t dns_nip = 0; if (dns_ip != NULL) { char *end = (char *)dns_ip; int ipa[4]; for (int i = 0; i < 4; i++) { ipa[i] = strtol(end, &end, 10); if (ipa[i] & ~0xFF) { fprintf(stderr, "%s: \"%s\" is no valid IP address.\n", argv[0], dns_ip); return 1; } if (((i < 3) && (*end != '.')) || ((i == 3) && *end)) { fprintf(stderr, "%s: \"%s\" is no valid IP address.\n", argv[0], dns_ip); return 1; } dns_nip |= ipa[i] << ((3 - i) * 8); end++; } } char *fname; asprintf(&fname, "(dns)/%s", domain); int fd = create_pipe(fname, O_RDONLY); if (fd < 0) { fprintf(stderr, "%s: Could not open %s: %s\n", argv[0], fname, strerror(errno)); return 1; } free(fname); if (dns_ip != NULL) if (pipe_set_flag(fd, F_DNS_NSIP, dns_nip) < 0) fprintf(stderr, "%s: Error setting namserver IP %s, continuing anyway.\n", argv[0], dns_ip); size_t len = pipe_get_flag(fd, F_PRESSURE); if (!len) { destroy_pipe(fd, 0); fprintf(stderr, "%s: Could not receive IP address.\n", argv[0]); return 1; } char ip[len + 1]; memset(ip, 0, len + 1); stream_recv(fd, ip, len, O_BLOCKING); printf("IP address: %s\n", ip); destroy_pipe(fd, 0); return 0; }