int recv_msg(int ctlSocket, int* type, void* msg, int* len) { unsigned char buff[3]; int length; assert(type); assert(msg); assert(len); if (readn(ctlSocket, buff, 3) != 3) { return -1; } *type = buff[0]; length = buff[1]; length = (length << 8) + buff[2]; assert(length <= (*len)); if (length > (*len)) { log_println(3, "recv_msg: length [%d] > *len [%d]", length, *len); return -2; } *len = length; if (readn(ctlSocket, msg, length) != length) { return -3; } log_println(8, "<<< recv_msg: type=%d, len=%d", *type, *len); return 0; }
/** * Reads value from JSON object represented by jsontext using specific key * * @param jsontext string representing JSON object * @param key by which value should be obtained from JSON map */ char* json_read_map_value(const char *jsontext, const char *key) { json_t *root; json_error_t error; json_t *data; root = json_loads(jsontext, 0, &error); if(!root) { log_println(0, "Error while reading value from JSON string: %s", error.text); return NULL; } if(!json_is_object(root)) { log_println(0, "Error while reading value from JSON string: root is not an object"); json_decref(root); return NULL; } data = json_object_get(root, key); if(data != NULL) { char *value = (char *)json_string_value(data); return value; } else return NULL; }
void throttler_enable(bool enable) { enabled = enable; if (enable) log_println(LEVEL_INFO, TAG, "Throttler is now enabled"); else log_println(LEVEL_INFO, TAG, "Throttler is now disabled"); }
/** * Receive the protocol message from the control socket. * @param ctl control Connection * @param type target place for type of the message * @param msg target place for the message body * @param len target place for the length of the message * @returns 0 on success, error code otherwise. * Error codes: * -1 : Error reading from socket * -2 : No of bytes received were lesser than expected byte count * -3 : No of bytes received did not match expected byte count */ int recv_msg_any(Connection* ctl, int* type, void* msg, int* len) { unsigned char buff[3]; int length; char *msgtemp = (char*) msg; assert(type); assert(msg); assert(len); // if 3 bytes are not explicitly read, signal error if (readn_any(ctl, buff, 3) != 3) { return -1; } // get msg type, and calculate length as sum of the next 2 bytes *type = buff[0]; length = buff[1]; length = (length << 8) + buff[2]; // if received buffer size < length as conveyed by buffer contents, then error assert(length <= (*len)); if (length > (*len)) { log_println(3, "recv_msg: length [%d] > *len [%d]", length, *len); return -2; } *len = length; if (readn_any(ctl, msg, length) != length) { return -3; } log_println(8, "<<< recv_msg: type=%d, len=%d", *type, *len); protolog_rcvprintln(*type, msgtemp, *len, getpid(), ctl->socket); return 0; }
void catch_s2c_alrm(int signo) { if (signo == SIGALRM) { log_println(1, "SIGALRM was caught"); return; } log_println(0, "Unknown (%d) signal was caught", signo); }
int _ptrace(const char *file, int line, int request, pid_t pid, caddr_t address, int data) { int result; const char *requestName; char unknownRequestNameBuf[100]; if (log_TELE) { requestName = requestToString(request, unknownRequestNameBuf, sizeof(unknownRequestNameBuf)); log_print("%s:%d ptrace(%s, %d, %p, %d)", file, line, requestName, pid, address, data); } errno = 0; result = ptrace(request, pid, address, data); int error = errno; if (log_TELE) { if (request == PT_READ_D || request == PT_READ_I || request == PT_READ_U) { log_println(" = %p", result); } else { log_print_newline(); } } if (error != 0) { requestName = requestToString(request, unknownRequestNameBuf, sizeof(unknownRequestNameBuf)); log_println("%s:%d ptrace(%s, %d, %p, %d) caused error %d [%s]", file, line, requestName, pid, address, data, error, strerror(error)); } return result; }
int writen(int fd, void* buf, int amount) { int sent, n; char* ptr = buf; sent = 0; assert(amount >= 0); while (sent < amount) { n = write(fd, ptr+sent, amount - sent); if (n == -1) { if (errno == EINTR) continue; if (errno != EAGAIN) { log_println(6, "writen() Error! write(%d) failed with err='%s(%d) pic=%d'", fd, strerror(errno), errno, getpid()); return -1; } } assert(n != 0); if (n != -1) { sent += n; } } return sent; }
/* Generic virtual space allocator. * If the address parameters is specified, allocate at the specified address and fail if it cannot be allocated. * Use MAP_NORESERVE if reserveSwap is false * Use PROT_NONE if protNone is true, otherwise set all protection (i.e., allow any type of access). */ Address virtualMemory_allocatePrivateAnon(Address address, Size size, jboolean reserveSwap, jboolean protNone, int type) { int flags = MAP_PRIVATE | MAP_ANON; #if os_LINUX /* For some reason, subsequent calls to mmap to allocate out of the space * reserved here only work if the reserved space is in 32-bit space. */ // flags |= MAP_32BIT; #endif int prot = protNone == JNI_TRUE ? PROT_NONE : PROT; if (reserveSwap == JNI_FALSE) { flags |= MAP_NORESERVE; } if (address != 0) { flags |= MAP_FIXED; } void * result = mmap((void*) address, (size_t) size, prot, flags, -1, 0); #if log_LOADER log_println("virtualMemory_allocatePrivateAnon(address=%p, size=%p, swap=%s, prot=%s) allocated at %p", address, size, reserveSwap==JNI_TRUE ? "true" : "false", protNone==JNI_TRUE ? "none" : "all", result); #endif return check_mmap_result(result); }
/** * Receive an initialization message, but the message may not be an NDT * message, and instead it may be the beginning of the websocket handshake. In * that case, set up the websocket handshake and then receive the message. */ int recv_msg_plus_websocket(Connection* ctl, TestOptions* test_options, int* msg_type, char* msg_value, int* msg_len) { char header[3] = {0}; int64_t err; int received_length; if (readn_any(ctl, header, sizeof(header)) != sizeof(header)) { log_println(3, "Failed to read %d bytes", sizeof(header)); return EIO; } if (strncmp(header, "GET", 3) == 0) { // GET starts HTTP stuff, so try and perform the websocket handshake err = initialize_websocket_connection(ctl, sizeof(header), "ndt"); if (err) return err; test_options->connection_flags |= WEBSOCKET_SUPPORT; err = recv_websocket_ndt_msg(ctl, msg_type, msg_value, msg_len); return (err < 0) ? -err : 0; } else { // It didn't start with GET so it's not a websocket connection test_options->connection_flags &= ~WEBSOCKET_SUPPORT; *msg_type = header[0]; received_length = (header[1] << 8) + header[2]; if (received_length > *msg_len) return EMSGSIZE; *msg_len = received_length; if (readn_any(ctl, msg_value, *msg_len) != *msg_len) return EIO; return 0; } }
/* * ccreader_set_protocol Set protocol of the camera control reader. * * protocol: protocol name * return: 0 on success; -1 if protocol not found */ static int ccreader_set_protocol(struct ccreader *rdr, const char *protocol) { if(strcasecmp(protocol, "joystick") == 0) { rdr->do_read = joystick_do_read; ccreader_set_timeout(rdr, JOYSTICK_TIMEOUT); } else if(strcasecmp(protocol, "manchester") == 0) { rdr->do_read = manchester_do_read; ccreader_set_timeout(rdr, MANCHESTER_TIMEOUT); } else if(strcasecmp(protocol, "pelco_d") == 0) { rdr->do_read = pelco_d_do_read; ccreader_set_timeout(rdr, PELCO_D_TIMEOUT); } else if(strcasecmp(protocol, "pelco_p") == 0) { rdr->do_read = pelco_p_do_read; ccreader_set_timeout(rdr, PELCO_D_TIMEOUT); } else if(strcasecmp(protocol, "pelco_p7") == 0) { rdr->do_read = pelco_p_do_read; rdr->flags = PT_DEADZONE; ccreader_set_timeout(rdr, PELCO_P_TIMEOUT); } else if(strcasecmp(protocol, "vicon") == 0) { rdr->do_read = vicon_do_read; ccreader_set_timeout(rdr, VICON_TIMEOUT); } else { log_println(rdr->log, "Unknown protocol: %s", protocol); return -1; } return 0; }
/** * Write the given amount of data to the Connection. * @param conn the Connection * @param buf buffer with data to write * @param amount the size of the data * @return The amount of bytes written to the Connection */ int writen_any(Connection* conn, const void* buf, int amount) { int sent, n; const char* ptr = buf; sent = 0; assert(amount >= 0); while (sent < amount) { if (conn->ssl == NULL) { n = write(conn->socket, ptr + sent, amount - sent); } else { n = SSL_write(conn->ssl, ptr + sent, amount - sent); } if (n == -1) { if (errno == EINTR) // interrupted, retry writing again continue; if (errno != EAGAIN) { // some genuine socket write error log_println(6, "writen() Error! write(%d) failed with err='%s(%d) pid=%d'", conn->socket, strerror(errno), errno, getpid()); return -1; } } assert(n != 0); if (n != -1) { // success writing "n" bytes. Increment total bytes written sent += n; } } return sent; }
char* mrange_next(char* port, size_t port_strlen) { int val; Range* ptr; assert(port); if (check_rint(port, &val, 0, MAX_TCP_PORT)) { // check if valid log_println(0, "WARNING: invalid port number"); snprintf(port, port_strlen, RESERVED_PORT); return port; } val++; while (val <= MAX_TCP_PORT) { // Maximum port number not exceeded ptr = mrange_root; while (ptr != NULL) { // While there is some data if ((val >= ptr->min) && (val <= ptr->max)) { // check range // and return port if valid snprintf(port, port_strlen, "%d", val); return port; } ptr = ptr->next; } val++; } snprintf(port, port_strlen, RESERVED_PORT); return port; }
Address memory_allocate(Size size) { Address mem = (Address) calloc(1, (size_t) size); if (mem % sizeof(void *)) { log_println("MEMORY ALLOCATED NOT WORD-ALIGNED (size:%d at address:%x, void* size: %d)", size, mem, sizeof(void *)); } return mem; }
size_t readn_ssl(SSL *ssl, void *buf, size_t amount) { const char *error_file; int error_line; size_t received = 0; char error_string[120] = {0}; int ssl_err; char *ptr = buf; // To read from OpenSSL, just read. SSL_read has its own timeout. received = SSL_read(ssl, ptr, amount); if (received <= 0) { ssl_err = ERR_get_error_line(&error_file, &error_line); ERR_error_string_n(ssl_err, error_string, sizeof(error_string)); log_println(2, "SSL failed due to %s (%d)\n", error_string, ssl_err); log_println(2, "File: %s line: %d\n", error_file, error_line); } return received; }
static bool uart_init() { int ptm; struct termios tattr; for (int i = 0; i < NUMOFCHANNELS; i++) { log_println(LEVEL_INFO, TAG, "Opening PTY for channel %d", i); ptm = posix_openpt(O_RDWR | O_NOCTTY); if (ptm == -1) { log_println(LEVEL_INFO, TAG, "failed opening PTY!"); return false; } else { if (grantpt(ptm) < 0) { log_println(LEVEL_INFO, TAG, "failed granting PTY!"); return false; } if (unlockpt(ptm) < 0) { log_println(LEVEL_INFO, TAG, "failed unlocking PTY!"); return false; } log_println(LEVEL_INFO, TAG, "Channel %d pts is %s", i, ptsname(ptm)); channels[i].ptm = ptm; tcgetattr(ptm, &tattr); cfmakeraw(&tattr); tcsetattr(ptm, 0, &tattr); int flags = fcntl(ptm, F_GETFL); if (!(flags & O_NONBLOCK)) { fcntl(ptm, F_SETFL, flags | O_NONBLOCK); } } channels[i].txfifo = g_async_queue_new(); channels[i].rxfifo = g_async_queue_new(); uart_reset_channel(&(channels[i])); pollfds[i].fd = channels[i].ptm; pollfds[i].events = POLL_IN; } return true; }
/** * web100clt currently (as of 2015-12-21) requires that its output queue be * drained at the end of the c2s test and hangs if it is not. We don't want to * break it, but that extra second or so should not be part of our measured * transmitted data, because the spec says that it's a 10 second upload from * client to server, not a "10 seconds or a little bit more depending on when * the client starts counting" upload. Therefore, here we read from the * sockets for just a little longer, but ignore the resulting data, so that old * clients don't hang, but newer clients are not penalized for quitting after * 10 seconds, just like the spec says they can. * * TODO: Fix web100clt to eliminate the need for this function. * TODO: Make this function happen in a separate thread (but not a forked * subprocess due to SSL issues). That way old clients being dumb doesn't * slow down new clients' tests. Currently it wastes 1 second per test, * which at 150k tests per day is a waste of 40+ hours of peoples' lives * every day. * * @param c2s_conns The connections to drain * @param streamsNum The number of connections * @param buff The buffer into which we should read data * @param buff_size The size of said buffer */ void drain_old_clients(Connection* c2s_conns, int streamsNum, char* buff, size_t buff_size) { int activeStreams; double trash = 0; // A byte count we ignore. fd_set rfd; int max_fd; double start_time; int msgretvalue, read_error; struct timeval sel_tv; start_time = secs(); activeStreams = connections_to_fd_set(c2s_conns, streamsNum, &rfd, &max_fd); while (activeStreams > 0 && (secs() - start_time) < DRAIN_TIME) { sel_tv.tv_sec = DRAIN_TIME; sel_tv.tv_usec = 0; msgretvalue = select(max_fd + 1, &rfd, NULL, NULL, &sel_tv); if (msgretvalue == -1) { if (errno == EINTR) { // select interrupted. Continue waiting for activity on socket continue; } else { log_println(5, "Socket error while draining the client's send queue: %s. This is likely ok.", strerror(errno)); return; } } else if (msgretvalue == 0) { log_println(5, "Done draining the client's send queue."); return; } else if (msgretvalue > 0) { read_error = read_ready_streams(&rfd, c2s_conns, streamsNum, buff, buff_size, &trash); if (read_error != 0 && read_error != EINTR) { // EINTR is expected, but all other errors are actually errors log_println(5, "Error while trying to drain client's send queue: %s. This is likely ok.", strerror(read_error)); return; } } else { // This should never happen. select() returns -1, 0, or a positive number says POSIX. log_println(0, "Unhandled return value from select: %d.", msgretvalue); return; } // Set up the FD_SET and activeStreams for the next select. activeStreams = connections_to_fd_set(c2s_conns, streamsNum, &rfd, &max_fd); } }
static void soundcard_dump_config(int channel, bool latched) { if (channel == 0) { masterchannel* chan = &(channels[channel].master); log_println(LEVEL_DEBUG, TAG, "master channel, config 0x%04x, volume left %d right %d", chan->config, VOLLEFT(chan->volume), VOLRIGHT(chan->volume)); } else { audiochannel* chan = latched ? &(channelslatched[channel].audio) : &(channels[channel].audio); log_println(LEVEL_DEBUG, TAG, "channel %d, config 0x%04x, pointer 0x%04x, len 0x%04x, pos 0x%04x, volume left %d right %d", channel - 1, chan->config, chan->samplepointer, chan->samplelength, chan->samplepos, VOLLEFT(chan->volume), VOLRIGHT(chan->volume)); } }
int mrange_parse(char* text) { char tmp[300]; char* ptr, *sptr; Range* mr_ptr = NULL; assert(text); memset(tmp, 0, 300); if (strlen(text) > 299) { return 1; } // strcpy(tmp, text); strlcpy(tmp, text, sizeof(tmp)); // tokenize based on a "," character. // An example of the string : 2003:3000,4000:5000 ptr = strtok(tmp, ","); while (ptr != NULL) { // tokens found if ((sptr = strchr(ptr, ':')) != NULL) { // also found a ":" character, // with sptr pointing to its location *sptr++ = 0; if (strchr(sptr, ':') != NULL) { // should not find any more range return 1; } } else { sptr = ptr; } if ((mr_ptr = malloc(sizeof(Range))) == NULL) { log_println(0, "FATAL: cannot allocate memory"); return 1; } if (*ptr == 0) { ptr = "1"; } // Check if the input string is within range and store // result as "minimum" // For ex: Is 2003 in a string like "2003:4000" within integer range ? // If not, free the memory allocated to store the range and return if (check_rint(ptr, &mr_ptr->min, 1, MAX_TCP_PORT)) { free(mr_ptr); return 1; } if (*sptr == 0) { sptr = MAX_TCP_PORT_STR; } // now validate if "maximum" is within range and store // result as "maximum" if (check_rint(sptr, &mr_ptr->max, 1, MAX_TCP_PORT)) { free(mr_ptr); return 1; // if invalid range, free allocated memory and return } mr_ptr->next = mrange_root; mrange_root = mr_ptr; // ready to point to next member ptr = strtok(NULL, ","); } free(mr_ptr); return 0; }
int check_msg_type(char* prefix, int expected, int received, char* buff, int len) { // check if expected and received messages are the same if (expected != received) { if (prefix) { // Add prefix to log message log_print(0, "%s: ", prefix); } if (received == MSG_ERROR) { // if Error message was actually received, // then its not an unexpected message exchange buff[len] = 0; // terminate string log_println(0, "ERROR MSG: %s", buff); } else { // certainly an unexpected message log_println(0, "ERROR: received message type %d (expected %d)", received, expected); } return 1; } // everything is well, return 0 return 0; }
/** * Open and set up an SSL connection from a socket connection. * @param conn the Connection to set up. Should already have its socket set to * a valid socketfd * @param ctx the SSL context to use for the setup * @return 0 or an error code */ int setup_SSL_connection(Connection *conn, SSL_CTX *ctx) { char ssl_error[255]; unsigned long ssl_err; conn->ssl = SSL_new(ctx); if (conn->ssl == NULL) { log_println(4, "SSL_new failed"); return ENOMEM; } if (SSL_set_fd(conn->ssl, conn->socket) == 0) { log_println(4, "SSL_set_fd failed"); return EIO; } if ((ssl_err = SSL_accept(conn->ssl)) != 1) { if (ssl_err == 0) { ssl_err = SSL_get_error(conn->ssl, ssl_err); } ERR_error_string_n(ssl_err, ssl_error, sizeof(ssl_error)); log_println(4, "SSL_accept failed (%s)", ssl_error); return EIO; } return 0; }
static bool soundcard_init() { sampleram = malloc(SAMPLETOTAL); if (sampleram == NULL) { log_println(LEVEL_DEBUG, TAG, "sample ram malloc failed"); return false; } audiobuffer = ringbuffer_new(BUFFER); channelregisterbase = utils_nextpow(SAMPLETOTAL); log_println(LEVEL_DEBUG, TAG, "registers start at 0x%08x", channelregisterbase); soundcard_channelbases(channelbases, channelregisterbase); for (int i = 1; i < TOTALCHANNELS; i++) { log_println(LEVEL_INFO, TAG, "Channel %d is at 0x%08x", i - 1, channelbases[i]); } SDL_AudioSpec fmt; fmt.freq = RATE; fmt.format = AUDIO_S16SYS; // BE samples will get converted to the local format fmt.channels = OUTPUTCHANNELS; fmt.samples = 512; fmt.callback = soundcard_sdlcallback; fmt.userdata = audiobuffer; if (SDL_OpenAudio(&fmt, NULL) == 0) { if (!disabled) { SDL_PauseAudio(0); log_println(LEVEL_DEBUG, TAG, "SDL output is now active"); active = true; } } else log_println(LEVEL_INFO, TAG, "Failed to open sound"); return true; }
int send_msg(int ctlSocket, int type, const void* msg, int len) { unsigned char buff[3]; int rc, i; assert(msg); assert(len >= 0); /* memset(0, buff, 3); */ // set message type and length into message itself buff[0] = type; buff[1] = len >> 8; buff[2] = len; // retry sending data 5 times for (i = 0; i < 5; i++) { // Write initial data about length and type to socket rc = writen(ctlSocket, buff, 3); if (rc == 3) // write completed break; if (rc == 0) // nothing written yet, continue; if (rc == -1) // error writing to socket..cannot continue return -1; } // Exceeded retries, return as "failed trying to write" if (i == 5) return -3; // Now write the actual message for (i = 0; i < 5; i++) { rc = writen(ctlSocket, msg, len); // all the data has been written successfully if (rc == len) break; // data writing not complete, continue if (rc == 0) continue; if (rc == -1) // error writing to socket, cannot continue writing data return -2; } if (i == 5) return -3; log_println(8, ">>> send_msg: type=%d, len=%d, msg=%s, pid=%d", type, len, msg, getpid()); protolog_sendprintln(type, msg, len, getpid(), ctlSocket); return 0; }
/** * Initialize the Host Porting Interface (HPI) socket library. */ int HPI::initialize_socket_library() { // Resolve the socket library interface. int result = (*_get_interface)((void**) (uintptr_t) &_socket, "Socket", 1); if (result != 0) { if (opt_TraceHPI) log_println("HPI::initialize_socket_library: Can't find HPI_SocketInterface"); return JNI_ERR; } return JNI_OK; }
ThreadState_t toThreadState(char taskState, pid_t tid) { ThreadState_t threadState; switch (taskState) { case 'W': case 'D': case 'S': threadState = TS_SLEEPING; break; case 'R': threadState = TS_RUNNING; break; case 'T': threadState = TS_SUSPENDED; break; case 'Z': threadState = TS_DEAD; break; default: log_println("Unknown task state '%c' for task %d interpreted as thread state TS_DEAD", taskState, tid); threadState = TS_DEAD; break; } return threadState; }
void renderer_init() { SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE); SDL_CreateWindowAndRenderer(VIDEO_WIDTH, VIDEO_HEIGHT, 0, &window, &renderer); screen = SDL_CreateRGBSurface(0, VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_PIXELFORMAT, 0, 0, 0, 0); if (screen == NULL) log_println(LEVEL_WARNING, TAG, "Failed to create surface"); sdlTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, VIDEO_WIDTH, VIDEO_HEIGHT); //SDL_WM_SetCaption(WINDOWTITLE, WINDOWTITLE, NULL); //screen = SDL_SetVideoMode(VIDEO_WIDTH, VIDEO_HEIGHT, 0, SDL_HWSURFACE); // //log_println(LEVEL_INFO, TAG, "Created surface; %d x %d pixels @ %dBPP", screen->w, screen->h, // screen->format->BitsPerPixel); }
void statistics_print_gc_memory_usage(void) { static int64_t count = 0; int64_t max; int64_t size; int64_t free; int64_t used; int64_t total; count++; max = gc_get_max_heap_size(); size = gc_get_heap_size(); free = gc_get_free_bytes(); used = size - free; total = gc_get_total_bytes(); if (opt_ProfileMemoryUsageGNUPlot) { if (count == 1) fprintf(opt_ProfileMemoryUsageGNUPlot, "plot \"profile.dat\" using 1:2 with lines title \"max. Java heap size\", \"profile.dat\" using 1:3 with lines title \"Java heap size\", \"profile.dat\" using 1:4 with lines title \"used\", \"profile.dat\" using 1:5 with lines title \"free\"\n"); fprintf(opt_ProfileMemoryUsageGNUPlot, "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 "\n", count, max, size, used, free); fflush(opt_ProfileMemoryUsageGNUPlot); } else { log_println("GC memory usage -------------------"); log_println(""); log_println("max. Java heap size: %10lld", max); log_println(""); log_println("Java heap size: %10lld", size); log_println("used: %10lld", used); log_println("free: %10lld", free); log_println("totally used: %10lld", total); log_println(""); } }
/** * Kick off old clients. Send the special code which causes old clients to * disconnect. * @param ctl Control socket Connection */ int kick_off_old_clients(Connection* ctl) { int retcode; int i; for (i = 0; i < RETRY_COUNT; i++) { // the specially crafted data that kicks off the old clients retcode = writen_any(ctl, "123456 654321", 13); if ((retcode == -1) && (errno == EINTR)) // interrupted, retry continue; if (retcode == 13) // 13 bytes correctly written, exit successfully return KICK_SUCCESS; if (retcode == -1) { // socket error hindering further retries break; } } log_println(1, "Initial contact with client failed errno=%d", errno); return KICK_FAILURE; }
/** Starts the web100srv process. Either args must be NULL or the last element * of **args must be NULL. */ pid_t start_server(int port, char **extra_args) { int extra_args_index = 0; char *arg; pid_t server_pid; siginfo_t server_status; char port_string[6]; // 32767 is the max port, so must hold 5 digits + \0 int rv; char *args_for_exec[256] = {"./web100srv", "--snaplog", "--tcpdump", "--cputime", "--log_dir", "/tmp", "-l", LOGFILE_TEMPLATE, "--port", NULL}; int exec_args_index = 0; // set exec_args_index to the first index of args_for_exec that is NULL while (args_for_exec[exec_args_index] != NULL) { // along the way, fill in the template for the test logs if (strcmp(args_for_exec[exec_args_index], LOGFILE_TEMPLATE) == 0) { mkstemp(args_for_exec[exec_args_index]); } exec_args_index++; } log_println(1, "Starting the server"); if ((server_pid = fork()) == 0) { sprintf(port_string, "%d", port); args_for_exec[exec_args_index++] = port_string; while (extra_args != NULL && extra_args[extra_args_index] != NULL) { CHECK((args_for_exec[exec_args_index++] = strdup(extra_args[extra_args_index++])) != NULL); } args_for_exec[exec_args_index++] = NULL; execv("./web100srv", args_for_exec); perror("SERVER START ERROR: SHOULD NEVER HAPPEN"); FAIL("The server should never return - it should only be killed."); exit(1); } // Wait until the server port (hopefully) becomes available. The server PID is // available immediately, but we need to make sure to lose the race condition // with the server startup process, so that the NDT port is open and ready to // receive traffic and we won't begin the test before the server's startup // routines are complete. sleep(1); // Double-check that the server didn't crash on startup. server_status.si_pid = 0; rv = waitid(P_PID, server_pid, &server_status, WEXITED | WSTOPPED | WNOHANG); ASSERT(rv == 0 && server_status.si_pid == 0, "The server did not start successfully (exit code %d)", rv); return server_pid; }
int readn(int fd, void* buf, int amount) { int received = 0, n, rc; char* ptr = buf; struct timeval sel_tv; fd_set rfd; assert(amount >= 0); FD_ZERO(&rfd); // initialize with zeroes FD_SET(fd, &rfd); sel_tv.tv_sec = 600; sel_tv.tv_usec = 0; /* modified readn() routine 11/26/09 - RAC * addedd in select() call, to timeout if no read occurs after 10 seconds of waiting. * This should fix a bug where the server hangs at it looks like it's in this read * state. The select() should check to see if there is anything to read on this socket. * if not, and the 3 second timer goes off, exit out and clean up. */ while (received < amount) { // check if fd+1 socket is ready to be read rc = select(fd + 1, &rfd, NULL, NULL, &sel_tv); if (rc == 0) { /* A timeout occurred, nothing to read from socket after 3 seconds */ log_println(6, "readn() routine timeout occurred, return error signal " "and kill off child"); return received; } if ((rc == -1) && (errno == EINTR)) /* a signal was processed, ignore it */ continue; n = read(fd, ptr + received, amount - received); if (n == -1) { // error if (errno == EINTR) // interrupted , try reading again continue; if (errno != EAGAIN) // genuine socket read error, return return -errno; } if (n != -1) { // if no errors reading, increment data byte count received += n; } if (n == 0) return 0; } return received; }
JNIEXPORT void JNICALL Java_com_sun_max_tele_debug_linux_LinuxNativeTeleChannelProtocol_nativeGatherThreads(JNIEnv *env, jclass c, jlong pid, jobject linuxTeleProcess, jobject threads, long tlaList) { pid_t *tasks; const int nTasks = scan_process_tasks(pid, &tasks); if (nTasks < 0) { log_println("Error scanning /proc/%d/task directory: %s", pid, strerror(errno)); return; } int n = 0; while (n < nTasks) { pid_t tid = tasks[n]; gatherThread(env, pid, tid, linuxTeleProcess, threads, tlaList); n++; } free(tasks); }