Esempio n. 1
0
static void partial_recv(uint32_t* readoff, uint32_t* writeoff, uint32_t bufsize, char* readbuf, struct message_header* message, int* current_bytes, int target_bytes) {

  while(*current_bytes < target_bytes) {

    if(drain_events(singleton_screen->socketfd) == -1) {
      printf("Socket error draining events\n");
      exit(1);
    }

    int this_recv = recvsome(readoff, writeoff, bufsize, readbuf, 
			 (void*)((char*)message + *current_bytes), 
			     target_bytes - *current_bytes);

    if(this_recv == 0) {
      if(analyse_waits)
	printf("Wait: receive buffer empty\n");
      if(wait_for_rx_not_empty() == -1) {
	printf("Socket error waiting for rx-not-empty\n");
	exit(1);
      }
    }

    discard_ring_bytes(readoff, bufsize, this_recv);
    
    *current_bytes += this_recv;

  }

}
Esempio n. 2
0
int main(int argc, char const *argv[]) {

    int qflag = 0;
    char const *host = 0;
    unsigned short port = 0;

    args = argv;
    /* parse arguments */

    while (argv[1]) {
        if (!strcmp(argv[1], "-q")) {
            if (!argv[2]) {
                usage();
            }
            qflag = atoi(argv[2]);
            if (qflag <= 0) {
                usage();
            }
            ++argv;
            --argc;
        }
        else if (argv[1][0] == '-') {
            usage();
        }
        else {
            if (!host) {
                host = argv[1];
            }
            else if (!port) {
                int i = atoi(argv[1]);
                if (i < 1 || i > 65535) {
                    usage();
                }
                port = (unsigned short)i;
            }
        }
        ++argv;
        --argc;
    }
    if (!host) {
        usage();
    }
    if (!port) {
        usage();
    }

    /* connect to host */
    char buf[8192];
    int r, s = connect_to(host, port);

    /*  do an echo thing */
    while (true) {
        r = read(0, buf, sizeof(buf));
        if (r < 0) {
            perror("read(stdin)");
            exit(1);
        }
        if (r == 0) {
            break;
        }
        int off = 0;
        while (r > off) {
            int q = send(s, &buf[off], r-off, 0);
            if (q < 0) {
                perror("send()");
                exit(1);
            }
            if (q == 0) {
                break;
            }
            off += q;
        }
        r = recvsome(s, buf, sizeof(buf));
        if (r == -2) {  //  closed
            break;
        }
        if (r < 0) {
            perror("recv()");
            exit(1);
        }
        if (r > 0) {
            if (write(1, buf, r) < 0) {
                perror("write()");
                exit(1);
            }
        }
    }
    shutdown(s, SHUT_WR);

    time_t now, then;
    time(&now);
    then = now + qflag;
    r = 1;
    while (now <= then || r > 0) {
        r = recvsome(s, buf, sizeof(buf));
        if (r == -2) {  //  closed
            break;
        }
        if (r < 0) {
            perror("recv()");
            exit(1);
        }
        if (r > 0) {
            if (write(1, buf, r) < 0) {
                perror("write()");
                exit(1);
            }
        }
        time(&now);
    }
    close(s);
    return 0;
}
Esempio n. 3
0
void discard_asynchronous_messages(int block) {

  uint32_t bufsize = ((uint32_t*)singleton_screen->rx_buffer)[0];
  uint32_t* readoff = &(((uint32_t*)singleton_screen->rx_buffer)[1]);
  uint32_t* writeoff = &(((uint32_t*)singleton_screen->rx_buffer)[2]);
  char* readbuf = (char*)&(((uint32_t*)singleton_screen->rx_buffer)[3]);

  if(block) {
    DBG("Discarding async messages (blocking)\n");
  }
  else {
    DBG("Discarding async messages (non-blocking)\n");
  }
  // WARNING HERE: This method assumes that no async failure notification
  // is bigger than the ring. If one were, we would wait fruitlessly until
  // the entire thing were present before deleting it from the ring.

  /* If block is set, we should wait until a synchronous message arrives.
     If block is not set, we should return as soon as we're short of data. */

  int need_more_bytes = 0;

  while(1) {

    struct message_header head;

    if(need_more_bytes) {
      if(block) {
	DBG("Insufficient data, but invoked blocking: sleeping\n");
	wait_for_rx_not_empty();
	need_more_bytes = 0;
	DBG("Woken\n");
      }
      else {
	DBG("Non-blocking discard_async_messages: exiting\n");
	return;
      }
    }

    if(drain_events(singleton_screen->socketfd) == -1) {
      printf("Socket error draining events in discard_async\n");
      return;
    }

    int bytes_peeked = recvsome(readoff, writeoff, bufsize, readbuf, (char*)&head, sizeof(struct message_header));

    if(bytes_peeked < sizeof(struct message_header)) {
      DBG("  Less than a header available (%d bytes); exiting\n", bytes_peeked);
      need_more_bytes = 1;
      continue;
    }

    if(!message_is_asynchronous(head.opcode)) {
      DBG("  Next message (%s) not asynchronous: exiting\n", optotext(head.opcode));
      return;
    }

    int bytes_available = read_avail(readoff, writeoff, bufsize);

    if(bytes_available < head.length) {
      DBG("  Message had length %d but only %d available: exiting\n", head.length, bytes_available);
      need_more_bytes = 1;
      continue;
    }

    char* message_proper = malloc(head.length);
    if(!message_proper) {
      printf("OOM checking for asynchronous failures\n");
      return;
    }

    int bytes_read = recvsome(readoff, writeoff, bufsize, readbuf, message_proper, head.length);

    if(bytes_read < head.length) {
      printf("BUG! read_avail returned %d, yet we could only actually read %d bytes\n", bytes_available, bytes_read);
      free(message_proper);
      return;
    }

    DBG("  Got a message: checking its result\n");

    check_async_result(message_proper, head.opcode);

    free(message_proper);

    discard_ring_bytes(readoff, bufsize, head.length);

  }

}