/* * ------------------------------------------ * Hang the process for a specified time. * * Goes to sleep for a positive value. * Any caught signal will terminate the sleep * following the execution of that signal's catching routine. * * The actual hang duration should be NO LESS than the specified * duration for specified durations greater than .001 seconds. * Certain applications depend on this assumption. * * Arguments: * num - time to sleep * * Return: * none * ------------------------------------------ */ void op_hang(mval* num) { int ms; double tmp; mv_stent *mv_zintcmd; ABS_TIME cur_time, end_time; # ifdef VMS uint4 time[2]; int4 efn_mask, status; # endif DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; ms = 0; MV_FORCE_NUM(num); if (num->mvtype & MV_INT) { if (0 < num->m[1]) { assert(MV_BIAS >= 1000); /* if formats change overflow may need attention */ ms = num->m[1] * (1000 / MV_BIAS); } } else if (0 == num->sgn) /* if sign is not 0 it means num is negative */ { tmp = mval2double(num) * (double)1000; ms = ((double)MAXPOSINT4 >= tmp) ? (int)tmp : (int)MAXPOSINT4; } if (ms) { if (TREF(tpnotacidtime) * 1000 < ms) TPNOTACID_CHECK(HANGSTR); # if defined(DEBUG) && defined(UNIX) if (WBTEST_ENABLED(WBTEST_DEFERRED_TIMERS) && (3 > gtm_white_box_test_case_count) && (123000 == ms)) { DEFER_INTERRUPTS(INTRPT_NO_TIMER_EVENTS); DBGFPF((stderr, "OP_HANG: will sleep for 20 seconds\n")); LONG_SLEEP(20); DBGFPF((stderr, "OP_HANG: done sleeping\n")); ENABLE_INTERRUPTS(INTRPT_NO_TIMER_EVENTS); return; } if (WBTEST_ENABLED(WBTEST_BREAKMPC)&& (0 == gtm_white_box_test_case_count) && (999 == ms)) { frame_pointer->old_frame_pointer->mpc = (unsigned char *)GTM64_ONLY(0xdeadbeef12345678) NON_GTM64_ONLY(0xdead1234); return; } if (WBTEST_ENABLED(WBTEST_UTIL_OUT_BUFFER_PROTECTION) && (0 == gtm_white_box_test_case_count) && (999 == ms)) { /* Upon seeing a .999s hang this white-box test launches a timer that pops with a period of * UTIL_OUT_SYSLOG_INTERVAL and prints a long message via util_out_ptr. */ start_timer((TID)&util_out_syslog_dump, UTIL_OUT_SYSLOG_INTERVAL, util_out_syslog_dump, 0, NULL); return; } # endif sys_get_curr_time(&cur_time); mv_zintcmd = find_mvstent_cmd(ZINTCMD_HANG, restart_pc, restart_ctxt, FALSE); if (!mv_zintcmd) add_int_to_abs_time(&cur_time, ms, &end_time); else { end_time = mv_zintcmd->mv_st_cont.mvs_zintcmd.end_or_remain; cur_time = sub_abs_time(&end_time, &cur_time); /* get remaing time to sleep */ if (0 <= cur_time.at_sec) ms = (int4)(cur_time.at_sec * 1000 + cur_time.at_usec / 1000); else ms = 0; /* all done */ /* restore/pop previous zintcmd_active[ZINTCMD_HANG] hints */ TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last = mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_prior; TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last = mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_ctxt_prior; TAREF1(zintcmd_active, ZINTCMD_HANG).count--; assert(0 <= TAREF1(zintcmd_active, ZINTCMD_HANG).count); if (mv_chain == mv_zintcmd) POP_MV_STENT(); /* just pop if top of stack */ else { /* flag as not active */ mv_zintcmd->mv_st_cont.mvs_zintcmd.command = ZINTCMD_NOOP; mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_check = NULL; } if (0 == ms) return; /* done HANGing */ } # ifdef UNIX if (ms < 10) SLEEP_USEC(ms * 1000, TRUE); /* Finish the sleep if it is less than 10ms. */ else hiber_start(ms); # elif defined(VMS) time[0] = -time_low_ms(ms); time[1] = -time_high_ms(ms) - 1; efn_mask = (1 << efn_outofband | 1 << efn_timer); if (SS$_NORMAL != (status = sys$setimr(efn_timer, &time, NULL, &time, 0))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$setimr"), CALLFROM, status); if (SS$_NORMAL != (status = sys$wflor(efn_outofband, efn_mask))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$wflor"), CALLFROM, status); if (outofband) { if (SS$_WASCLR == (status = sys$readef(efn_timer, &efn_mask))) { if (SS$_NORMAL != (status = sys$cantim(&time, 0))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$cantim"), CALLFROM, status); } else assertpro(SS$_WASSET == status); } # endif } else rel_quant(); if (outofband) { PUSH_MV_STENT(MVST_ZINTCMD); mv_chain->mv_st_cont.mvs_zintcmd.end_or_remain = end_time; mv_chain->mv_st_cont.mvs_zintcmd.restart_ctxt_check = restart_ctxt; mv_chain->mv_st_cont.mvs_zintcmd.restart_pc_check = restart_pc; /* save current information from zintcmd_active */ mv_chain->mv_st_cont.mvs_zintcmd.restart_ctxt_prior = TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last; mv_chain->mv_st_cont.mvs_zintcmd.restart_pc_prior = TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last; TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last = restart_pc; TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last = restart_ctxt; TAREF1(zintcmd_active, ZINTCMD_HANG).count++; mv_chain->mv_st_cont.mvs_zintcmd.command = ZINTCMD_HANG; outofband_action(FALSE); } return; }
int main(int argc, char **argv) { int opt; int num_parms; char equiv_cmd[1024]; char *buff; SOCKET sock; socklen_t fromlen = sizeof(struct sockaddr_in); int default_rcvbuf_sz, cur_size, sz; int num_rcvd; struct sockaddr_in name; struct sockaddr_in src; struct ip_mreq imr; struct timeval tv; int num_sent; float perc_loss; int cur_seq; struct iovec iov; ssize_t iovnr; int iovfd; char strbuffer[1000]; prog_name = argv[0]; if (o_log == 1) { iov.iov_base=strbuffer; iov.iov_len=0; //To be defined latter. iovfd= open ("log.out", O_WRONLY | O_CREAT | O_TRUNC); if (iovfd == -1) { perror ("open error"); exit(1); } } buff = malloc(65536 + 1); /* one extra for trailing null (if needed) */ if (buff == NULL) { fprintf(stderr, "malloc failed\n"); exit(1); } signal(SIGPIPE, SIG_IGN); if((sock = socket(PF_INET,SOCK_DGRAM,0)) == INVALID_SOCKET) { fprintf(stderr, "ERROR: "); perror("socket"); exit(1); } sz = sizeof(default_rcvbuf_sz); if (getsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char *)&default_rcvbuf_sz, (unsigned int *)&sz) == SOCKET_ERROR) { fprintf(stderr, "ERROR: "); perror("getsockopt - SO_RCVBUF"); exit(1); } /* default values for options */ o_quiet_lvl = 0; o_rcvbuf_size = 0x400000; /* 4MB */ o_pause_ms = 0; o_verify = 0; o_stop = 0; o_log = 0; /* default values for optional positional params */ bind_if = NULL; while ((opt = getopt(argc, argv, "hqQ:p:r:vsl")) != EOF) { switch (opt) { case 'h': help(NULL); exit(0); break; case 'q': o_quiet_lvl = 2; break; case 'Q': o_quiet_lvl = atoi(optarg); break; case 'p': o_pause_ms = atoi(optarg); break; case 'r': o_rcvbuf_size = atoi(optarg); if (o_rcvbuf_size == 0) o_rcvbuf_size = default_rcvbuf_sz; break; case 'v': o_verify = 1; break; case 's': o_stop = 1; break; case 'l': o_log = 1; default: usage("unrecognized option"); exit(1); break; } /* switch */ } /* while opt */ num_parms = argc - optind; if (o_log == 1) { iov.iov_base=strbuffer; iov.iov_len=0; //To be defined latter. iovfd= open ("log.out", O_WRONLY | O_CREAT | O_TRUNC); if (iovfd == -1) { perror ("open error"); exit(1); } } /* handle positional parameters */ if (num_parms == 2) { groupaddr = inet_addr(argv[optind]); groupport = (unsigned short)atoi(argv[optind+1]); sprintf(equiv_cmd, "mdump -p%d -Q%d -r%d %s%s%s %s", o_pause_ms, o_quiet_lvl, o_rcvbuf_size, o_verify ? "-v " : "", o_stop ? "-s " : "", argv[optind],argv[optind+1]); printf("Equiv cmd line: %s\n", equiv_cmd); fflush(stdout); fprintf(stderr, "Equiv cmd line: %s\n", equiv_cmd); fflush(stderr); } else if (num_parms == 3) { groupaddr = inet_addr(argv[optind]); groupport = (unsigned short)atoi(argv[optind+1]); bind_if = argv[optind+2]; sprintf(equiv_cmd, "mdump -p%d -Q%d -r%d %s%s %s %s", o_pause_ms, o_quiet_lvl, o_rcvbuf_size, o_verify ? "-v " : "", argv[optind],argv[optind+1],argv[optind+2]); printf("Equiv cmd line: %s\n", equiv_cmd); fflush(stdout); fprintf(stderr, "Equiv cmd line: %s\n", equiv_cmd); fflush(stderr); } else { usage("need 2-3 positional parameters"); exit(1); } if(setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(const char *)&o_rcvbuf_size, sizeof(o_rcvbuf_size)) == SOCKET_ERROR) { printf("WARNING: setsockopt - SO_RCVBUF\n"); fflush(stdout); fprintf(stderr, "WARNING: "); perror("setsockopt - SO_RCVBUF"); fflush(stderr); } sz = sizeof(cur_size); if (getsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char *)&cur_size, (unsigned int *)&sz) == SOCKET_ERROR) { fprintf(stderr, "ERROR: "); perror("getsockopt - SO_RCVBUF"); exit(1); } if (cur_size < o_rcvbuf_size) { printf("WARNING: tried to set SO_RCVBUF to %d, only got %d\n", o_rcvbuf_size, cur_size); fflush(stdout); fprintf(stderr, "WARNING: tried to set SO_RCVBUF to %d, only got %d\n", o_rcvbuf_size, cur_size); fflush(stderr); } memset((char *)&imr,0,sizeof(imr)); imr.imr_multiaddr.s_addr = groupaddr; if (bind_if != NULL) { imr.imr_interface.s_addr = inet_addr(bind_if); } else { imr.imr_interface.s_addr = htonl(INADDR_ANY); } opt = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) == SOCKET_ERROR) { fprintf(stderr, "ERROR: "); perror("setsockopt SO_REUSEADDR"); exit(1); } memset((char *)&name,0,sizeof(name)); name.sin_family = AF_INET; name.sin_addr.s_addr = groupaddr; name.sin_port = htons(groupport); if (bind(sock,(struct sockaddr *)&name,sizeof(name)) == SOCKET_ERROR) { name.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sock,(struct sockaddr *)&name, sizeof(name)) == -1) { fprintf(stderr, "ERROR: "); perror("bind"); exit(1); } } if (setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP, (char *)&imr,sizeof(struct ip_mreq)) == SOCKET_ERROR ) { fprintf(stderr, "ERROR: "); perror("setsockopt - IP_ADD_MEMBERSHIP"); exit(1); } cur_seq = 0; num_rcvd = 0; for (;;) { cur_size = recvfrom(sock,buff,65536,0, (struct sockaddr *)&src,&fromlen); if (cur_size == SOCKET_ERROR) { fprintf(stderr, "ERROR: "); perror("recv"); exit(1); } if (o_log == 1 ) { currenttv(&tv); sprintf(strbuffer, "%s %s.%d %d bytes:\n", format_time(&tv), inet_ntoa(src.sin_addr), ntohs(src.sin_port), cur_size); } if (o_quiet_lvl == 0) { /* non-quiet: print full dump */ currenttv(&tv); printf("%s %s.%d %d bytes:\n", format_time(&tv), inet_ntoa(src.sin_addr), ntohs(src.sin_port), cur_size); dump(buff,cur_size); } if (o_quiet_lvl == 1) { /* semi-quiet: print datagram summary */ currenttv(&tv); printf("%s %s.%d %d bytes\n", /* no colon */ format_time(&tv), inet_ntoa(src.sin_addr), ntohs(src.sin_port), cur_size); fflush(stdout); } if (o_pause_ms > 0) { SLEEP_USEC(o_pause_ms); } if (cur_size > 5 && memcmp(buff, "echo ", 5) == 0) { /* echo command */ buff[cur_size] = '\0'; /* guarantee trailing null */ if (buff[cur_size - 1] == '\n') buff[cur_size - 1] = '\0'; /* strip trailing nl */ printf("%s\n", buff); fflush(stdout); fprintf(stderr, "%s\n", buff); fflush(stderr); } else if (cur_size > 5 && memcmp(buff, "stat ", 5) == 0) { /* when sender tells us to, calc and print stats */ buff[cur_size] = '\0'; /* guarantee trailing null */ /* 'stat' message contains num msgs sent */ num_sent = atoi(&buff[5]); perc_loss = (float)(num_sent - num_rcvd) * 100.0 / (float)num_sent; printf("%d msgs sent, %d received (not including 'stat')\n", num_sent, num_rcvd); printf("%f%% loss\n", perc_loss); fflush(stdout); fprintf(stderr, "%d msgs sent, %d received (not including 'stat')\n", num_sent, num_rcvd); fprintf(stderr, "%f%% loss\n", perc_loss); fflush(stderr); if (o_stop) exit(0); /* reset stats */ num_rcvd = 0; cur_seq = 0; } else { /* not a cmd */ if (o_verify) { buff[cur_size] = '\0'; /* guarantee trailing null */ if (cur_seq != strtol(&buff[8], NULL, 16)) { printf("Expected seq %x (hex), got %s\n", cur_seq, &buff[8]); fflush(stdout); /* resyncronize sequence numbers in case there is loss */ cur_seq = strtol(&buff[8], NULL, 16); } } ++num_rcvd; ++cur_seq; } } /* for ;; */ CLOSESOCKET(sock); exit(0); } /* main */