#include #include #include #include #include #include #include #include #include #include #include "global.h" #include "data_stream.h" #include "line_reader.h" #include "zbuffer.h" #define PORT 57575 #define POLLDELAY (10*1000000) /*struct proc_taskinfo { uint64_t pti_virtual_size; virtual memory size (bytes) uint64_t pti_resident_size; resident memory size (bytes) uint64_t pti_total_user; total time uint64_t pti_total_system; uint64_t pti_threads_user; existing threads only uint64_t pti_threads_system; int32_t pti_policy; default policy for new threads int32_t pti_faults; number of page faults int32_t pti_pageins; number of actual pageins int32_t pti_cow_faults; number of copy-on-write faults int32_t pti_messages_sent; number of messages sent int32_t pti_messages_received; number of messages received int32_t pti_syscalls_mach; number of mach system calls int32_t pti_syscalls_unix; number of unix system calls int32_t pti_csw; number of context switches int32_t pti_threadnum; number of threads in the task int32_t pti_numrunning; number of running threads int32_t pti_priority; task priority };*/ static i64 make_timestamp(void){ struct timeval tv; gettimeofday(&tv,NULL); return tv.tv_sec*(i64)1000000+tv.tv_usec; } static void connection_handler(int sock){ struct data_stream *stream=data_stream_init(sock); struct line_reader *reader=line_reader_init(sock); i64 polldelay=POLLDELAY; i64 timeleft=polldelay; bool do_send_frames=false; bool do_quit=false; while(true){ struct timeval timeout={timeleft/1000000,timeleft%1000000}; i64 before=make_timestamp(); fd_set inset; FD_ZERO(&inset); FD_SET(sock,&inset); int ret=select(sock+1,&inset,NULL,NULL,do_send_frames?&timeout:NULL); if(ret<0){ if(errno==EINTR)continue; perror("select"); break; } if(ret==0||!FD_ISSET(sock,&inset)){ // timeout if(do_send_frames){ if(data_stream_frame(stream)<0){ printf("Error sending data\n"); goto cleanup; } printf("."); fflush(stdout); } timeleft=polldelay; continue; } i64 after=make_timestamp(); if(after\n",line); char *next=strchr(word,' '); if(next!=NULL){ *next='\0'; next++; } if(strcmp(word,"delay")==0){ char *endp; i64 v=strtoll(next,&endp,10); if(*next=='\0'||*endp!='\0'||v<=1000){ free(line); printf("Invalid number in delay\n"); continue; } polldelay=v; printf("polldelay -> %" PRIi64 "\n",polldelay); if(timeleft>polldelay)timeleft=polldelay; } else if(strcmp(word,"start")==0){ do_send_frames=true; printf("Sending enabled\n"); } else if(strcmp(word,"stop")==0){ do_send_frames=false; printf("Sending disabled\n"); } else if(strcmp(word,"flush")==0){ printf("Flushing\n"); if(data_stream_flush(stream)<0){ printf("Error flushing\n"); goto cleanup; } } else if(strcmp(word,"quit")==0){ printf("Quitting by request\n"); do_quit=true; goto cleanup; } else { printf("Read unrecognised line <%s>!\n",line); } free(line); } } cleanup: data_stream_finish_destroy(stream); if(do_quit)exit(0); } int main(void){ int sock=socket(PF_INET,SOCK_STREAM,0); if(sock<0){ perror("socket"); return 1; } int one=1; if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&one,sizeof(int))<0){ perror("setsockopt"); return 1; } struct sockaddr_in sin; sin.sin_family=AF_INET; sin.sin_addr.s_addr=htonl(INADDR_ANY); sin.sin_port=htons(PORT); if(bind(sock,(struct sockaddr*)&sin,sizeof(sin))<0){ close(sock); perror("bind"); return 1; } if(listen(sock,1)<0){ perror("listen"); return 1; } printf("Listening on port %d\n",PORT); while(true){ struct sockaddr_storage client_addr; socklen_t client_addr_sz=sizeof(client_addr); int clientsock=accept(sock,(struct sockaddr*)&client_addr,&client_addr_sz); if(clientsock<0){ perror("accept"); continue; } char str[INET_ADDRSTRLEN]; inet_ntop(client_addr.ss_family,&((struct sockaddr_in*)&client_addr)->sin_addr, str,sizeof(str)); printf("Accept from %s\n",str); connection_handler(clientsock); close(clientsock); } }