int main(int argc, char** argv) { init_signals(); setpriority(PRIO_PROCESS, 0, 0); int IsSilence = 0; int svcEnable = 0; int cnt=0; int activePortCnt=0; if( GetSampleRate() == 16000 ) { audioOutputBitrate = 128000; audioSamplingFrequency = 16000; }else{ audioOutputBitrate = 64000; audioSamplingFrequency = 8000; } // Begin by setting up our usage environment: TaskScheduler* scheduler = BasicTaskScheduler::createNew(); UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler); int msg_type, video_type; APPROInput* MjpegInputDevice = NULL; APPROInput* H264InputDevice = NULL; APPROInput* Mpeg4InputDevice = NULL; static pid_t child[4] = { -1,-1,-1,-1 }; StreamingMode streamingMode = STREAMING_UNICAST; netAddressBits multicastAddress = 0;//our_inet_addr("224.1.4.6"); portNumBits videoRTPPortNum = 0; portNumBits audioRTPPortNum = 0; IsSilence = 0; svcEnable = 0; audioType = AUDIO_G711; streamingMode = STREAMING_UNICAST; for( cnt = 1; cnt < argc ;cnt++ ) { if( strcmp( argv[cnt],"-m" )== 0 ) { streamingMode = STREAMING_MULTICAST_SSM; } if( strcmp( argv[cnt],"-s" )== 0 ) { IsSilence = 1; } if( strcmp( argv[cnt],"-a" )== 0 ) { audioType = AUDIO_AAC; } if( strcmp( argv[cnt],"-v" )== 0 ) { svcEnable = 1; } } #if 0 printf("###########IsSilence = %d ################\n",IsSilence); printf("###########streamingMode = %d ################\n",streamingMode); printf("###########audioType = %d ################\n",audioType); printf("###########svcEnable = %d ################\n",svcEnable); #endif child[0] = fork(); if( child[0] != 0 ) { child[1] = fork(); } if( child[0] != 0 && child[1] != 0 ) { child[2] = fork(); } if( child[0] != 0 && child[1] != 0 && child[2] != 0 ) { child[3] = fork(); } if(svcEnable) { if( child[0] != 0 && child[1] != 0 && child[2] != 0 && child[3] != 0) { child[4] = fork(); } if( child[0] != 0 && child[1] != 0 && child[2] != 0 && child[3] != 0 && child[4] != 0) { child[5] = fork(); } if( child[0] != 0 && child[1] != 0 && child[2] != 0 && child[3] != 0 && child[4] != 0 && child[5] != 0) { child[6] = fork(); } if( child[0] != 0 && child[1] != 0 && child[2] != 0 && child[3] != 0 && child[4] != 0 && child[5] != 0 && child[6] != 0) { child[7] = fork(); } } if( child[0] == 0 ) { /* parent, success */ msg_type = LIVE_MSG_TYPE4; video_type = VIDEO_TYPE_H264_CIF; rtspServerPortNum = 8556; H264VideoBitrate = 12000000; videoRTPPortNum = 6012; audioRTPPortNum = 6014; } if( child[1] == 0 ) { /* parent, success */ msg_type = LIVE_MSG_TYPE3; video_type = VIDEO_TYPE_MJPEG; rtspServerPortNum = 8555; MjpegVideoBitrate = 12000000; videoRTPPortNum = 6008; audioRTPPortNum = 6010; } if( child[2] == 0 ) { /* parent, success */ msg_type = LIVE_MSG_TYPE; video_type = VIDEO_TYPE_MPEG4; rtspServerPortNum = 8553; Mpeg4VideoBitrate = 12000000; videoRTPPortNum = 6000; audioRTPPortNum = 6002; } if( child[3] == 0 ) { /* parent, success */ msg_type = LIVE_MSG_TYPE2; video_type = VIDEO_TYPE_MPEG4_CIF; rtspServerPortNum = 8554; Mpeg4VideoBitrate = 12000000; videoRTPPortNum = 6004; audioRTPPortNum = 6006; } if(svcEnable) { if( child[4] == 0 ) { /* parent, success */ msg_type = LIVE_MSG_TYPE5; video_type = VIDEO_TYPE_H264_SVC_30FPS; rtspServerPortNum = 8601; H264VideoBitrate = 12000000; videoRTPPortNum = 6016; audioRTPPortNum = 6018; } if( child[5] == 0 ) { /* parent, success */ msg_type = LIVE_MSG_TYPE6; video_type = VIDEO_TYPE_H264_SVC_15FPS; rtspServerPortNum = 8602; H264VideoBitrate = 12000000; videoRTPPortNum = 6020; audioRTPPortNum = 6022; } if( child[6] == 0 ) { /* parent, success */ msg_type = LIVE_MSG_TYPE7; video_type = VIDEO_TYPE_H264_SVC_7FPS; rtspServerPortNum = 8603; H264VideoBitrate = 12000000; videoRTPPortNum = 6024; audioRTPPortNum = 6026; } if( child[7] == 0 ) { /* parent, success */ msg_type = LIVE_MSG_TYPE8; video_type = VIDEO_TYPE_H264_SVC_3FPS; rtspServerPortNum = 8604; H264VideoBitrate = 12000000; videoRTPPortNum = 6028; audioRTPPortNum = 6030; } if( child[0] != 0 && child[1] != 0 && child[2] != 0 && child[3] != 0 && child[4] != 0 && child[5] != 0 && child[6] != 0 && child[7] != 0) { /* parent, success */ msg_type = LIVE_MSG_TYPE9; video_type = VIDEO_TYPE_H264; rtspServerPortNum = 8557; H264VideoBitrate = 12000000; videoRTPPortNum = 6032; audioRTPPortNum = 6034; } } else { if( child[0] != 0 && child[1] != 0 && child[2] != 0 && child[3] != 0) { /* parent, success */ msg_type = LIVE_MSG_TYPE5; video_type = VIDEO_TYPE_H264; rtspServerPortNum = 8557; H264VideoBitrate = 12000000; videoRTPPortNum = 6032; audioRTPPortNum = 6034; } } videoType = video_type; // Objects used for multicast streaming: static Groupsock* rtpGroupsockAudio = NULL; static Groupsock* rtcpGroupsockAudio = NULL; static Groupsock* rtpGroupsockVideo = NULL; static Groupsock* rtcpGroupsockVideo = NULL; static FramedSource* sourceAudio = NULL; static RTPSink* sinkAudio = NULL; static RTCPInstance* rtcpAudio = NULL; static FramedSource* sourceVideo = NULL; static RTPSink* sinkVideo = NULL; static RTCPInstance* rtcpVideo = NULL; share_memory_init(msg_type); //init_signals(); *env << "Initializing...\n"; // Initialize the WIS input device: if( video_type == VIDEO_TYPE_MJPEG) { MjpegInputDevice = APPROInput::createNew(*env, VIDEO_TYPE_MJPEG); if (MjpegInputDevice == NULL) { err(*env) << "Failed to create MJPEG input device\n"; exit(1); } } if( video_type == VIDEO_TYPE_H264 || video_type == VIDEO_TYPE_H264_CIF || video_type == VIDEO_TYPE_H264_SVC_30FPS || video_type == VIDEO_TYPE_H264_SVC_15FPS || video_type == VIDEO_TYPE_H264_SVC_7FPS || video_type == VIDEO_TYPE_H264_SVC_3FPS) { H264InputDevice = APPROInput::createNew(*env, video_type); if (H264InputDevice == NULL) { err(*env) << "Failed to create MJPEG input device\n"; exit(1); } } if( video_type == VIDEO_TYPE_MPEG4 || video_type == VIDEO_TYPE_MPEG4_CIF ) { Mpeg4InputDevice = APPROInput::createNew(*env, video_type); if (Mpeg4InputDevice == NULL) { err(*env) << "Failed to create MPEG4 input device\n"; exit(1); } } // Create the RTSP server: RTSPServer* rtspServer = NULL; // Normal case: Streaming from a built-in RTSP server: rtspServer = RTSPServer::createNew(*env, rtspServerPortNum, NULL); if (rtspServer == NULL) { *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n"; exit(1); } *env << "...done initializing\n"; if( streamingMode == STREAMING_UNICAST ) { if( video_type == VIDEO_TYPE_MJPEG) { ServerMediaSession* sms = ServerMediaSession::createNew(*env, MjpegStreamName, MjpegStreamName, streamDescription,streamingMode == STREAMING_MULTICAST_SSM); sms->addSubsession(WISJPEGVideoServerMediaSubsession ::createNew(sms->envir(), *MjpegInputDevice, MjpegVideoBitrate)); if( IsSilence == 0) { sms->addSubsession(WISPCMAudioServerMediaSubsession::createNew(sms->envir(), *MjpegInputDevice)); } rtspServer->addServerMediaSession(sms); char *url = rtspServer->rtspURL(sms); *env << "Play this stream using the URL:\n\t" << url << "\n"; delete[] url; } if( video_type == VIDEO_TYPE_H264 || video_type == VIDEO_TYPE_H264_CIF || video_type == VIDEO_TYPE_H264_SVC_30FPS || video_type == VIDEO_TYPE_H264_SVC_15FPS || video_type == VIDEO_TYPE_H264_SVC_7FPS || video_type ==VIDEO_TYPE_H264_SVC_3FPS) { ServerMediaSession* sms; sms = ServerMediaSession::createNew(*env, H264StreamName, H264StreamName, streamDescription,streamingMode == STREAMING_MULTICAST_SSM); sms->addSubsession(WISH264VideoServerMediaSubsession ::createNew(sms->envir(), *H264InputDevice, H264VideoBitrate)); if( IsSilence == 0) { sms->addSubsession(WISPCMAudioServerMediaSubsession::createNew(sms->envir(), *H264InputDevice)); } rtspServer->addServerMediaSession(sms); char *url = rtspServer->rtspURL(sms); *env << "Play this stream using the URL:\n\t" << url << "\n"; delete[] url; } // Create a record describing the media to be streamed: if( video_type == VIDEO_TYPE_MPEG4 || video_type == VIDEO_TYPE_MPEG4_CIF ) { ServerMediaSession* sms = ServerMediaSession::createNew(*env, Mpeg4StreamName, Mpeg4StreamName, streamDescription,streamingMode == STREAMING_MULTICAST_SSM); sms->addSubsession(WISMPEG4VideoServerMediaSubsession ::createNew(sms->envir(), *Mpeg4InputDevice, Mpeg4VideoBitrate)); if( IsSilence == 0) { sms->addSubsession(WISPCMAudioServerMediaSubsession::createNew(sms->envir(), *Mpeg4InputDevice)); } rtspServer->addServerMediaSession(sms); char *url = rtspServer->rtspURL(sms); *env << "Play this stream using the URL:\n\t" << url << "\n"; delete[] url; } }else{ if (streamingMode == STREAMING_MULTICAST_SSM) { if (multicastAddress == 0) multicastAddress = chooseRandomIPv4SSMAddress(*env); } else if (multicastAddress != 0) { streamingMode = STREAMING_MULTICAST_ASM; } struct in_addr dest; dest.s_addr = multicastAddress; const unsigned char ttl = 255; // For RTCP: const unsigned maxCNAMElen = 100; unsigned char CNAME[maxCNAMElen + 1]; gethostname((char *) CNAME, maxCNAMElen); CNAME[maxCNAMElen] = '\0'; // just in case ServerMediaSession* sms=NULL; if( video_type == VIDEO_TYPE_MJPEG) { sms = ServerMediaSession::createNew(*env, MjpegStreamName, MjpegStreamName, streamDescription,streamingMode == STREAMING_MULTICAST_SSM); sourceAudio = MjpegInputDevice->audioSource(); sourceVideo = WISJPEGStreamSource::createNew(MjpegInputDevice->videoSource()); // Create 'groupsocks' for RTP and RTCP: const Port rtpPortVideo(videoRTPPortNum); const Port rtcpPortVideo(videoRTPPortNum+1); rtpGroupsockVideo = new Groupsock(*env, dest, rtpPortVideo, ttl); rtcpGroupsockVideo = new Groupsock(*env, dest, rtcpPortVideo, ttl); if (streamingMode == STREAMING_MULTICAST_SSM) { rtpGroupsockVideo->multicastSendOnly(); rtcpGroupsockVideo->multicastSendOnly(); } setVideoRTPSinkBufferSize(); sinkVideo = JPEGVideoRTPSink::createNew(*env, rtpGroupsockVideo); } if( video_type == VIDEO_TYPE_H264 || video_type == VIDEO_TYPE_H264_CIF || video_type == VIDEO_TYPE_H264_SVC_30FPS || video_type == VIDEO_TYPE_H264_SVC_15FPS || video_type == VIDEO_TYPE_H264_SVC_7FPS || video_type == VIDEO_TYPE_H264_SVC_3FPS) { sms = ServerMediaSession::createNew(*env, H264StreamName, H264StreamName, streamDescription,streamingMode == STREAMING_MULTICAST_SSM); sourceAudio = H264InputDevice->audioSource(); sourceVideo = H264VideoStreamFramer::createNew(*env, H264InputDevice->videoSource()); // Create 'groupsocks' for RTP and RTCP: const Port rtpPortVideo(videoRTPPortNum); const Port rtcpPortVideo(videoRTPPortNum+1); rtpGroupsockVideo = new Groupsock(*env, dest, rtpPortVideo, ttl); rtcpGroupsockVideo = new Groupsock(*env, dest, rtcpPortVideo, ttl); if (streamingMode == STREAMING_MULTICAST_SSM) { rtpGroupsockVideo->multicastSendOnly(); rtcpGroupsockVideo->multicastSendOnly(); } setVideoRTPSinkBufferSize(); { char BuffStr[200]; extern int GetSprop(void *pBuff, char vType); GetSprop(BuffStr,video_type); sinkVideo = H264VideoRTPSink::createNew(*env, rtpGroupsockVideo,96, 0x64001F,BuffStr); } } // Create a record describing the media to be streamed: if( video_type == VIDEO_TYPE_MPEG4 || video_type == VIDEO_TYPE_MPEG4_CIF ) { sms = ServerMediaSession::createNew(*env, Mpeg4StreamName, Mpeg4StreamName, streamDescription,streamingMode == STREAMING_MULTICAST_SSM); sourceAudio = Mpeg4InputDevice->audioSource(); sourceVideo = MPEG4VideoStreamDiscreteFramer::createNew(*env, Mpeg4InputDevice->videoSource()); // Create 'groupsocks' for RTP and RTCP: const Port rtpPortVideo(videoRTPPortNum); const Port rtcpPortVideo(videoRTPPortNum+1); rtpGroupsockVideo = new Groupsock(*env, dest, rtpPortVideo, ttl); rtcpGroupsockVideo = new Groupsock(*env, dest, rtcpPortVideo, ttl); if (streamingMode == STREAMING_MULTICAST_SSM) { rtpGroupsockVideo->multicastSendOnly(); rtcpGroupsockVideo->multicastSendOnly(); } setVideoRTPSinkBufferSize(); sinkVideo = MPEG4ESVideoRTPSink::createNew(*env, rtpGroupsockVideo,97); } /* VIDEO Channel initial */ if(1) { // Create (and start) a 'RTCP instance' for this RTP sink: unsigned totalSessionBandwidthVideo = (Mpeg4VideoBitrate+500)/1000; // in kbps; for RTCP b/w share rtcpVideo = RTCPInstance::createNew(*env, rtcpGroupsockVideo, totalSessionBandwidthVideo, CNAME, sinkVideo, NULL /* we're a server */ , streamingMode == STREAMING_MULTICAST_SSM); // Note: This starts RTCP running automatically sms->addSubsession(PassiveServerMediaSubsession::createNew(*sinkVideo, rtcpVideo)); // Start streaming: sinkVideo->startPlaying(*sourceVideo, NULL, NULL); } /* AUDIO Channel initial */ if( IsSilence == 0) { // there's a separate RTP stream for audio // Create 'groupsocks' for RTP and RTCP: const Port rtpPortAudio(audioRTPPortNum); const Port rtcpPortAudio(audioRTPPortNum+1); rtpGroupsockAudio = new Groupsock(*env, dest, rtpPortAudio, ttl); rtcpGroupsockAudio = new Groupsock(*env, dest, rtcpPortAudio, ttl); if (streamingMode == STREAMING_MULTICAST_SSM) { rtpGroupsockAudio->multicastSendOnly(); rtcpGroupsockAudio->multicastSendOnly(); } if( audioSamplingFrequency == 16000 ) { if( audioType == AUDIO_G711) { sinkAudio = SimpleRTPSink::createNew(*env, rtpGroupsockAudio, 96, audioSamplingFrequency, "audio", "PCMU", 1); } else { char const* encoderConfigStr = "1408";// (2<<3)|(8>>1) = 0x14 ; ((8<<7)&0xFF)|(1<<3)=0x08 ; sinkAudio = MPEG4GenericRTPSink::createNew(*env, rtpGroupsockAudio, 96, audioSamplingFrequency, "audio", "AAC-hbr", encoderConfigStr, audioNumChannels); } } else{ if(audioType == AUDIO_G711) { sinkAudio = SimpleRTPSink::createNew(*env, rtpGroupsockAudio, 0, audioSamplingFrequency, "audio", "PCMU", 1); } else{ char const* encoderConfigStr = "1588";// (2<<3)|(11>>1) = 0x15 ; ((11<<7)&0xFF)|(1<<3)=0x88 ; sinkAudio = MPEG4GenericRTPSink::createNew(*env, rtpGroupsockAudio, 96, audioSamplingFrequency, "audio", "AAC-hbr", encoderConfigStr, audioNumChannels); } } // Create (and start) a 'RTCP instance' for this RTP sink: unsigned totalSessionBandwidthAudio = (audioOutputBitrate+500)/1000; // in kbps; for RTCP b/w share rtcpAudio = RTCPInstance::createNew(*env, rtcpGroupsockAudio, totalSessionBandwidthAudio, CNAME, sinkAudio, NULL /* we're a server */, streamingMode == STREAMING_MULTICAST_SSM); // Note: This starts RTCP running automatically sms->addSubsession(PassiveServerMediaSubsession::createNew(*sinkAudio, rtcpAudio)); // Start streaming: sinkAudio->startPlaying(*sourceAudio, NULL, NULL); } rtspServer->addServerMediaSession(sms); { struct in_addr dest; dest.s_addr = multicastAddress; char *url = rtspServer->rtspURL(sms); //char *url2 = inet_ntoa(dest); *env << "Mulicast Play this stream using the URL:\n\t" << url << "\n"; //*env << "2 Mulicast addr:\n\t" << url2 << "\n"; delete[] url; } } // Begin the LIVE555 event loop: env->taskScheduler().doEventLoop(&watchVariable); // does not return if( streamingMode!= STREAMING_UNICAST ) { Medium::close(rtcpAudio); Medium::close(sinkAudio); Medium::close(sourceAudio); delete rtpGroupsockAudio; delete rtcpGroupsockAudio; Medium::close(rtcpVideo); Medium::close(sinkVideo); Medium::close(sourceVideo); delete rtpGroupsockVideo; delete rtcpGroupsockVideo; } Medium::close(rtspServer); // will also reclaim "sms" and its "ServerMediaSubsession"s if( MjpegInputDevice != NULL ) { Medium::close(MjpegInputDevice); } if( H264InputDevice != NULL ) { Medium::close(H264InputDevice); } if( Mpeg4InputDevice != NULL ) { Medium::close(Mpeg4InputDevice); } env->reclaim(); delete scheduler; ApproInterfaceExit(); return 0; // only to prevent compiler warning }
void setToBackgroundPriority() { setpriority(PRIO_PGRP, 0, 10); }
/* CHANGED in 2.0.7: wsgi_req is useless ! */ char *uwsgi_spool_request(struct wsgi_request *wsgi_req, char *buf, size_t len, char *body, size_t body_len) { struct timeval tv; static uint64_t internal_counter = 0; int fd = -1; struct spooler_req sr; if (len > 0xffff) { uwsgi_log("[uwsgi-spooler] args buffer is limited to 64k, use the 'body' for bigger values\n"); return NULL; } // parse the request buffer memset(&sr, 0, sizeof(struct spooler_req)); uwsgi_hooked_parse(buf, len, spooler_req_parser_hook, &sr); struct uwsgi_spooler *uspool = uwsgi.spoolers; if (!uspool) { uwsgi_log("[uwsgi-spooler] no spooler available\n"); return NULL; } // if it is a number, get the spooler by id instead of by name if (sr.spooler && sr.spooler_len) { uspool = uwsgi_get_spooler_by_name(sr.spooler, sr.spooler_len); if (!uspool) { uwsgi_log("[uwsgi-spooler] unable to find spooler \"%.*s\"\n", sr.spooler_len, sr.spooler); return NULL; } } // this lock is for threads, the pid value in filename will avoid multiprocess races uwsgi_lock(uspool->lock); // we increase it even if the request fails internal_counter++; gettimeofday(&tv, NULL); char *filename = NULL; size_t filename_len = 0; if (sr.priority && sr.priority_len) { filename_len = strlen(uspool->dir) + sr.priority_len + strlen(uwsgi.hostname) + 256; filename = uwsgi_malloc(filename_len); int ret = snprintf(filename, filename_len, "%s/%.*s", uspool->dir, (int) sr.priority_len, sr.priority); if (ret <= 0 || ret >= (int) filename_len) { uwsgi_log("[uwsgi-spooler] error generating spooler filename\n"); free(filename); uwsgi_unlock(uspool->lock); return NULL; } // no need to check for errors... (void) mkdir(filename, 0777); ret = snprintf(filename, filename_len, "%s/%.*s/uwsgi_spoolfile_on_%s_%d_%llu_%d_%llu_%llu", uspool->dir, (int)sr.priority_len, sr.priority, uwsgi.hostname, (int) getpid(), (unsigned long long) internal_counter, rand(), (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec); if (ret <= 0 || ret >=(int) filename_len) { uwsgi_log("[uwsgi-spooler] error generating spooler filename\n"); free(filename); uwsgi_unlock(uspool->lock); return NULL; } } else { filename_len = strlen(uspool->dir) + strlen(uwsgi.hostname) + 256; filename = uwsgi_malloc(filename_len); int ret = snprintf(filename, filename_len, "%s/uwsgi_spoolfile_on_%s_%d_%llu_%d_%llu_%llu", uspool->dir, uwsgi.hostname, (int) getpid(), (unsigned long long) internal_counter, rand(), (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec); if (ret <= 0 || ret >= (int) filename_len) { uwsgi_log("[uwsgi-spooler] error generating spooler filename\n"); free(filename); uwsgi_unlock(uspool->lock); return NULL; } } fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR); if (fd < 0) { uwsgi_error_open(filename); free(filename); uwsgi_unlock(uspool->lock); return NULL; } // now lock the file, it will no be runnable, until the lock is not removed // a race could come if the spooler take the file before fcntl is called // in such case the spooler will detect a zeroed file and will retry later if (uwsgi_fcntl_lock(fd)) { close(fd); free(filename); uwsgi_unlock(uspool->lock); return NULL; } struct uwsgi_header uh; uh.modifier1 = 17; uh.modifier2 = 0; uh._pktsize = (uint16_t) len; #ifdef __BIG_ENDIAN__ uh._pktsize = uwsgi_swap16(uh._pktsize); #endif if (write(fd, &uh, 4) != 4) { uwsgi_log("[spooler] unable to write header for %s\n", filename); goto clear; } if (write(fd, buf, len) != (ssize_t) len) { uwsgi_log("[spooler] unable to write args for %s\n", filename); goto clear; } if (body && body_len > 0) { if ((size_t) write(fd, body, body_len) != body_len) { uwsgi_log("[spooler] unable to write body for %s\n", filename); goto clear; } } if (sr.at > 0) { #ifdef __UCLIBC__ struct timespec ts[2]; ts[0].tv_sec = sr.at; ts[0].tv_nsec = 0; ts[1].tv_sec = sr.at; ts[1].tv_nsec = 0; if (futimens(fd, ts)) { uwsgi_error("uwsgi_spooler_request()/futimens()"); } #else struct timeval tv[2]; tv[0].tv_sec = sr.at; tv[0].tv_usec = 0; tv[1].tv_sec = sr.at; tv[1].tv_usec = 0; #ifdef __sun__ if (futimesat(fd, NULL, tv)) { #else if (futimes(fd, tv)) { #endif uwsgi_error("uwsgi_spooler_request()/futimes()"); } #endif } // here the file will be unlocked too close(fd); if (!uwsgi.spooler_quiet) uwsgi_log("[spooler] written %lu bytes to file %s\n", (unsigned long) len + body_len + 4, filename); // and here waiting threads can continue uwsgi_unlock(uspool->lock); /* wake up the spoolers attached to the specified dir ... (HACKY) no need to fear races, as USR1 is harmless an all of the uWSGI processes... it could be a problem if a new process takes the old pid, but modern systems should avoid that */ struct uwsgi_spooler *spoolers = uwsgi.spoolers; while (spoolers) { if (!strcmp(spoolers->dir, uspool->dir)) { if (spoolers->pid > 0 && spoolers->running == 0) { (void) kill(spoolers->pid, SIGUSR1); } } spoolers = spoolers->next; } return filename; clear: uwsgi_unlock(uspool->lock); uwsgi_error("uwsgi_spool_request()/write()"); if (unlink(filename)) { uwsgi_error("uwsgi_spool_request()/unlink()"); } free(filename); // unlock the file too close(fd); return NULL; } void spooler(struct uwsgi_spooler *uspool) { // prevent process blindly reading stdin to make mess int nullfd; // asked by Marco Beri #ifdef __HAIKU__ #ifdef UWSGI_DEBUG uwsgi_log("lowering spooler priority to %d\n", B_LOW_PRIORITY); #endif set_thread_priority(find_thread(NULL), B_LOW_PRIORITY); #else #ifdef UWSGI_DEBUG uwsgi_log("lowering spooler priority to %d\n", PRIO_MAX); #endif setpriority(PRIO_PROCESS, getpid(), PRIO_MAX); #endif nullfd = open("/dev/null", O_RDONLY); if (nullfd < 0) { uwsgi_error_open("/dev/null"); exit(1); } if (nullfd != 0) { dup2(nullfd, 0); close(nullfd); } int spooler_event_queue = event_queue_init(); int interesting_fd = -1; if (uwsgi.master_process) { event_queue_add_fd_read(spooler_event_queue, uwsgi.shared->spooler_signal_pipe[1]); } // reset the tasks counter uspool->tasks = 0; time_t last_task_managed = 0; for (;;) { if (chdir(uspool->dir)) { uwsgi_error("chdir()"); exit(1); } if (uwsgi.spooler_ordered) { spooler_scandir(uspool, NULL); } else { spooler_readdir(uspool, NULL); } // here we check (if in cheap mode), if the spooler has done its job if (uwsgi.spooler_cheap) { if (last_task_managed == uspool->last_task_managed) { uwsgi_log_verbose("cheaping spooler %s ...\n", uspool->dir); exit(0); } last_task_managed = uspool->last_task_managed; } int timeout = uwsgi.shared->spooler_frequency ? uwsgi.shared->spooler_frequency : uwsgi.spooler_frequency; if (wakeup > 0) { timeout = 0; } if (event_queue_wait(spooler_event_queue, timeout, &interesting_fd) > 0) { if (uwsgi.master_process) { if (interesting_fd == uwsgi.shared->spooler_signal_pipe[1]) { if (uwsgi_receive_signal(NULL, interesting_fd, "spooler", (int) getpid())) { if (uwsgi.spooler_signal_as_task) { uspool->tasks++; if (uwsgi.spooler_max_tasks > 0 && uspool->tasks >= (uint64_t) uwsgi.spooler_max_tasks) { uwsgi_log("[spooler %s pid: %d] maximum number of tasks reached (%d) recycling ...\n", uspool->dir, (int) uwsgi.mypid, uwsgi.spooler_max_tasks); end_me(0); } } } } } } // avoid races uint64_t tmp_wakeup = wakeup; if (tmp_wakeup > 0) { tmp_wakeup--; } wakeup = tmp_wakeup; } }
/** * \brief This function interprets APIVSXML for the passed Test Suite * * \param[in] pTS - A Specific Test Suite to interpret * \return STATUS_PASS - Test conformance (PASS) * STATUS_FAIL - Test nonconformance (FAIL) */ int16_t interpretTS(P_TS *pTS) { char msg[OUTPUT_STRING_MAX]; int16_t status; P_TC *pTC; // Interpret Test Suite // Start the Output XML Generator outputXmlAttrAddCommon(LEVEL_SUMMARY, &pTS->common, A_NAME); outputXmlTagOpen(LEVEL_SUMMARY, P_TESTSUITE, outputXmlAttrGet()); if (strcmp(configFileGetFPUILBDEV(), "NULL") && (0 != vt100_start(configFileGetFPUILBDEV(), configFileGetSH(), configFileGetSW()))) { // vt100_start failed sprintf(msg, "interpretTS(): VT100 Virtual Display error starting device [%s]", configFileGetFPUILBDEV()); OUTPUT_ERR(pTS->common.lineNumber, msg, vt100_get_errorText(), NULL); return(STATUS_FAIL); } if (strcmp(configFileGetFIOLBDEV(), "NULL") && (EMFIO_OK != emfio_start(configFileGetFIOLBDEV()))) { // emfio_start failed sprintf(msg, "interpretTS(): FIO Emulator start error starting device [%s]", configFileGetFIOLBDEV()); OUTPUT_ERR(pTS->common.lineNumber, msg, emfio_getErrorText(), NULL); return(STATUS_FAIL); } // Lower relative priority after thread startup errno = 0; int prio = getpriority(PRIO_PROCESS, 0); if (errno == 0) { setpriority(PRIO_PROCESS, 0, prio+1); } if (STATUS_PASS == (status = interpretSetUp(pTS->pSU))) { pTC = pTS->pTC; // First TC while (NULL != pTC) { outputXmlNewLine(LEVEL_SUMMARY); status = interpretTC(pTC); outputXmlNewLine(LEVEL_SUMMARY); if (STATUS_FAIL == status) { break; } pTC = pTC->pTC; // Next Test Case } if (STATUS_PASS == status) { status = interpretTearDown(pTS->pTD); } } if (strcmp(configFileGetFPUILBDEV(), "NULL") && configFileGetFPUILBDEV()) { vt100_end(); } if (strcmp(configFileGetFIOLBDEV(), "NULL") && configFileGetFIOLBDEV()) { emfio_end(); } // Output final closing element tag outputXmlTagClose(LEVEL_SUMMARY, P_TESTSUITE); return(status); }
/* * Enact a scenario by looping through the four test cases for the scenario, * spawning off pairs of processes with the desired credentials, and * reporting results to stdout. */ static int enact_scenario(int scenario) { pid_t pid1, pid2; char *name, *tracefile; int error, desirederror, loop; for (loop = 0; loop < LOOP_MAX+1; loop++) { /* * Spawn the first child, target of the operation. */ pid1 = fork(); switch (pid1) { case -1: return (-1); case 0: /* child */ error = cred_set(scenarios[scenario].sc_cred2); if (error) { perror("cred_set"); return (error); } /* 200 seconds should be plenty of time. */ sleep(200); exit(0); default: /* parent */ break; } /* * XXX * This really isn't ideal -- give proc 1 a chance to set * its credentials, or we may get spurious errors. Really, * some for of IPC should be used to allow the parent to * wait for the first child to be ready before spawning * the second child. */ sleep(1); /* * Spawn the second child, source of the operation. */ pid2 = fork(); switch (pid2) { case -1: return (-1); case 0: /* child */ error = cred_set(scenarios[scenario].sc_cred1); if (error) { perror("cred_set"); return (error); } /* * Initialize errno to zero so as to catch any * generated errors. In each case, perform the * operation. Preserve the error number for later * use so it doesn't get stomped on by any I/O. * Determine the desired error for the given case * by extracting it from the scenario table. * Initialize a function name string for output * prettiness. */ errno = 0; switch (loop) { case LOOP_PTRACE: error = ptrace(PT_ATTACH, pid1, NULL, 0); error = errno; name = "ptrace"; desirederror = scenarios[scenario].sc_canptrace_errno; break; case LOOP_KTRACE: tracefile = mktemp("/tmp/testuid_ktrace.XXXXXX"); if (tracefile == NULL) { error = errno; perror("mktemp"); break; } error = ktrace(tracefile, KTROP_SET, KTRFAC_SYSCALL, pid1); error = errno; name = "ktrace"; desirederror = scenarios[scenario].sc_canktrace_errno; unlink(tracefile); break; case LOOP_SIGHUP: error = kill(pid1, SIGHUP); error = errno; name = "sighup"; desirederror = scenarios[scenario].sc_cansighup_errno; break; case LOOP_SIGSEGV: error = kill(pid1, SIGSEGV); error = errno; name = "sigsegv"; desirederror = scenarios[scenario].sc_cansigsegv_errno; break; case LOOP_SEE: getpriority(PRIO_PROCESS, pid1); error = errno; name = "see"; desirederror = scenarios[scenario].sc_cansee_errno; break; case LOOP_SCHED: error = setpriority(PRIO_PROCESS, pid1, 0); error = errno; name = "sched"; desirederror = scenarios[scenario].sc_cansched_errno; break; default: name = "broken"; } if (error != desirederror) { fprintf(stdout, "[%s].%s: expected %s, got %s\n ", scenarios[scenario].sc_name, name, errno_to_string(desirederror), errno_to_string(error)); cred_print(stdout, scenarios[scenario].sc_cred1); cred_print(stdout, scenarios[scenario].sc_cred2); fprintf(stdout, "\n"); } exit(0); default: /* parent */ break; } error = waitpid(pid2, NULL, 0); /* * Once pid2 has died, it's safe to kill pid1, if it's still * alive. Mask signal failure in case the test actually * killed pid1 (not unlikely: can occur in both signal and * ptrace cases). */ kill(pid1, SIGKILL); error = waitpid(pid2, NULL, 0); } return (0); }
int renice_main(int argc UNUSED_PARAM, char **argv) { static const char Xetpriority_msg[] ALIGN1 = "%cetpriority"; int retval = EXIT_SUCCESS; int which = PRIO_PROCESS; /* Default 'which' value. */ int use_relative = 0; int adjustment, new_priority; unsigned who; char *arg; /* Yes, they are not #defines in glibc 2.4! #if won't work */ if (PRIO_PROCESS < CHAR_MIN || PRIO_PROCESS > CHAR_MAX) BUG_bad_PRIO_PROCESS(); if (PRIO_PGRP < CHAR_MIN || PRIO_PGRP > CHAR_MAX) BUG_bad_PRIO_PGRP(); if (PRIO_USER < CHAR_MIN || PRIO_USER > CHAR_MAX) BUG_bad_PRIO_USER(); arg = *++argv; /* Check if we are using a relative adjustment. */ if (arg && arg[0] == '-' && arg[1] == 'n') { use_relative = 1; if (!arg[2]) arg = *++argv; else arg += 2; } if (!arg) { /* No args? Then show usage. */ bb_show_usage(); } /* Get the priority adjustment (absolute or relative). */ adjustment = xatoi_range(arg, INT_MIN/2, INT_MAX/2); while ((arg = *++argv) != NULL) { /* Check for a mode switch. */ if (arg[0] == '-' && arg[1]) { static const char opts[] ALIGN1 = { 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER }; const char *p = strchr(opts, arg[1]); if (p) { which = p[4]; if (!arg[2]) continue; arg += 2; } } /* Process an ID arg. */ if (which == PRIO_USER) { struct passwd *p; p = getpwnam(arg); if (!p) { bb_error_msg("unknown user %s", arg); goto HAD_ERROR; } who = p->pw_uid; } else { who = bb_strtou(arg, NULL, 10); if (errno) { bb_error_msg("invalid number '%s'", arg); goto HAD_ERROR; } } /* Get priority to use, and set it. */ if (use_relative) { int old_priority; errno = 0; /* Needed for getpriority error detection. */ old_priority = getpriority(which, who); if (errno) { bb_perror_msg(Xetpriority_msg, 'g'); goto HAD_ERROR; } new_priority = old_priority + adjustment; } else { new_priority = adjustment; } if (setpriority(which, who, new_priority) == 0) { continue; } bb_perror_msg(Xetpriority_msg, 's'); HAD_ERROR: retval = EXIT_FAILURE; } /* No need to check for errors outputing to stderr since, if it * was used, the HAD_ERROR label was reached and retval was set. */ return retval; }
static void action_launch_child(svc_action_t *op) { int lpc; /* SIGPIPE is ignored (which is different from signal blocking) by the gnutls library. * Depending on the libqb version in use, libqb may set SIGPIPE to be ignored as well. * We do not want this to be inherited by the child process. By resetting this the signal * to the default behavior, we avoid some potential odd problems that occur during OCF * scripts when SIGPIPE is ignored by the environment. */ signal(SIGPIPE, SIG_DFL); #if defined(HAVE_SCHED_SETSCHEDULER) if (sched_getscheduler(0) != SCHED_OTHER) { struct sched_param sp; memset(&sp, 0, sizeof(sp)); sp.sched_priority = 0; if (sched_setscheduler(0, SCHED_OTHER, &sp) == -1) { crm_perror(LOG_ERR, "Could not reset scheduling policy to SCHED_OTHER for %s", op->id); } } #endif if (setpriority(PRIO_PROCESS, 0, 0) == -1) { crm_perror(LOG_ERR, "Could not reset process priority to 0 for %s", op->id); } /* Man: The call setpgrp() is equivalent to setpgid(0,0) * _and_ compiles on BSD variants too * need to investigate if it works the same too. */ setpgid(0, 0); /* close all descriptors except stdin/out/err and channels to logd */ for (lpc = getdtablesize() - 1; lpc > STDERR_FILENO; lpc--) { close(lpc); } #if SUPPORT_CIBSECRETS if (replace_secret_params(op->rsc, op->params) < 0) { /* replacing secrets failed! */ if (safe_str_eq(op->action,"stop")) { /* don't fail on stop! */ crm_info("proceeding with the stop operation for %s", op->rsc); } else { crm_err("failed to get secrets for %s, " "considering resource not configured", op->rsc); _exit(PCMK_OCF_NOT_CONFIGURED); } } #endif /* Setup environment correctly */ add_OCF_env_vars(op); /* execute the RA */ execvp(op->opaque->exec, op->opaque->args); /* Most cases should have been already handled by stat() */ services_handle_exec_error(op, errno); _exit(op->rc); }
/* Link remote and local file descriptors */ int linkfd(struct vtun_host *host) { struct sigaction sa, sa_oldterm, sa_oldint, sa_oldhup; int old_prio; lfd_host = host; old_prio=getpriority(PRIO_PROCESS,0); setpriority(PRIO_PROCESS,0,LINKFD_PRIO); /* Build modules stack */ if(host->flags & VTUN_ZLIB) lfd_add_mod(&lfd_zlib); if(host->flags & VTUN_LZO) lfd_add_mod(&lfd_lzo); if(host->flags & VTUN_ENCRYPT) if(host->cipher == VTUN_LEGACY_ENCRYPT) { lfd_add_mod(&lfd_legacy_encrypt); } else { lfd_add_mod(&lfd_encrypt); } if(host->flags & VTUN_SHAPE) lfd_add_mod(&lfd_shaper); if(lfd_alloc_mod(host)) return 0; memset(&sa, 0, sizeof(sa)); sa.sa_handler=sig_term; sigaction(SIGTERM,&sa,&sa_oldterm); sigaction(SIGINT,&sa,&sa_oldint); sa.sa_handler=sig_hup; sigaction(SIGHUP,&sa,&sa_oldhup); /* Initialize keep-alive timer */ if( host->flags & (VTUN_STAT|VTUN_KEEP_ALIVE) ){ sa.sa_handler=sig_alarm; sigaction(SIGALRM,&sa,NULL); alarm( (host->ka_interval < VTUN_STAT_IVAL) ? host->ka_interval : VTUN_STAT_IVAL ); } /* Initialize statstic dumps */ if( host->flags & VTUN_STAT ){ char file[40]; sa.sa_handler=sig_alarm; sigaction(SIGALRM,&sa,NULL); sa.sa_handler=sig_usr1; sigaction(SIGUSR1,&sa,NULL); sprintf(file,"%s/%.20s", VTUN_STAT_DIR, host->host); if( (host->stat.file=fopen(file, "a")) ){ setvbuf(host->stat.file, NULL, _IOLBF, 0); } else vtun_syslog(LOG_ERR, "Can't open stats file %s", file); } io_init(); lfd_linker(); if( host->flags & (VTUN_STAT|VTUN_KEEP_ALIVE) ){ alarm(0); if (host->stat.file) fclose(host->stat.file); } lfd_free_mod(); sigaction(SIGTERM,&sa_oldterm,NULL); sigaction(SIGINT,&sa_oldint,NULL); sigaction(SIGHUP,&sa_oldhup,NULL); setpriority(PRIO_PROCESS,0,old_prio); return linker_term; }
bool KProcess::start(RunMode runmode, Communication comm) { if (runs) { kdDebug(175) << "Attempted to start an already running process" << endl; return false; } uint n = arguments.count(); if (n == 0) { kdDebug(175) << "Attempted to start a process without arguments" << endl; return false; } #ifdef Q_OS_UNIX char **arglist; QCString shellCmd; if (d->useShell) { if (d->shell.isEmpty()) { kdDebug(175) << "Invalid shell specified" << endl; return false; } for (uint i = 0; i < n; i++) { shellCmd += arguments[i]; shellCmd += " "; // CC: to separate the arguments } arglist = static_cast<char **>(malloc( 4 * sizeof(char *))); arglist[0] = d->shell.data(); arglist[1] = (char *) "-c"; arglist[2] = shellCmd.data(); arglist[3] = 0; } else { arglist = static_cast<char **>(malloc( (n + 1) * sizeof(char *))); for (uint i = 0; i < n; i++) arglist[i] = arguments[i].data(); arglist[n] = 0; } run_mode = runmode; if (!setupCommunication(comm)) { kdDebug(175) << "Could not setup Communication!" << endl; free(arglist); return false; } // We do this in the parent because if we do it in the child process // gdb gets confused when the application runs from gdb. #ifdef HAVE_INITGROUPS struct passwd *pw = geteuid() ? 0 : getpwuid(getuid()); #endif int fd[2]; if (pipe(fd)) fd[0] = fd[1] = -1; // Pipe failed.. continue // we don't use vfork() because // - it has unclear semantics and is not standardized // - we do way too much magic in the child pid_ = fork(); if (pid_ == 0) { // The child process close(fd[0]); // Closing of fd[1] indicates that the execvp() succeeded! fcntl(fd[1], F_SETFD, FD_CLOEXEC); if (!commSetupDoneC()) kdDebug(175) << "Could not finish comm setup in child!" << endl; // reset all signal handlers struct sigaction act; sigemptyset(&act.sa_mask); act.sa_handler = SIG_DFL; act.sa_flags = 0; for (int sig = 1; sig < NSIG; sig++) sigaction(sig, &act, 0L); if (d->priority) setpriority(PRIO_PROCESS, 0, d->priority); if (!runPrivileged()) { setgid(getgid()); #ifdef HAVE_INITGROUPS if (pw) initgroups(pw->pw_name, pw->pw_gid); #endif if (geteuid() != getuid()) setuid(getuid()); if (geteuid() != getuid()) _exit(1); } setupEnvironment(); if (runmode == DontCare || runmode == OwnGroup) setsid(); const char *executable = arglist[0]; if (!d->executable.isEmpty()) executable = d->executable.data(); execvp(executable, arglist); char resultByte = 1; write(fd[1], &resultByte, 1); _exit(-1); } else if (pid_ == -1) { // forking failed // commAbort(); pid_ = 0; free(arglist); return false; } // the parent continues here free(arglist); if (!commSetupDoneP()) kdDebug(175) << "Could not finish comm setup in parent!" << endl; // Check whether client could be started. close(fd[1]); for(;;) { char resultByte; int n = ::read(fd[0], &resultByte, 1); if (n == 1) { // exec() failed close(fd[0]); waitpid(pid_, 0, 0); pid_ = 0; commClose(); return false; } if (n == -1) { if (errno == EINTR) continue; // Ignore } break; // success } close(fd[0]); runs = true; switch (runmode) { case Block: for (;;) { commClose(); // drain only, unless obsolete reimplementation if (!runs) { // commClose detected data on the process exit notifification pipe KProcessController::theKProcessController->unscheduleCheck(); if (waitpid(pid_, &status, WNOHANG) != 0) // error finishes, too { commClose(); // this time for real (runs is false) KProcessController::theKProcessController->rescheduleCheck(); break; } runs = true; // for next commClose() iteration } else { // commClose is an obsolete reimplementation and waited until // all output channels were closed (or it was interrupted). // there is a chance that it never gets here ... waitpid(pid_, &status, 0); runs = false; break; } } // why do we do this? i think this signal should be emitted _only_ // after the process has successfully run _asynchronously_ --ossi emit processExited(this); break; default: // NotifyOnExit & OwnGroup input_data = 0; // Discard any data for stdin that might still be there break; } return true; #else //TODO return false; #endif }
int main(int argc, char **argv) { // // Machine d'état // // int state // -1: erreur // 0: non initialisé // 1: initialisé, pret rotation // 2: rotation, pret décollage // 3: décollage // 4: vol normal // 5: atterissage // state = 0; printf("\n"); printf("\n================================================"); printf("\n===== XMicroDrone - Controlleur V1.1 ====="); printf("\n================================================"); printf("\n"); // // Récupérons les numéros de devices séries (paramétre optionnel) // int premierDevice = 0; // La valeur par défaut, qu'on utilisera s'il n'y a pas d'arguments if (argc >= 2) { int arg = atoi(argv[1]); if (arg >= 0 && arg <= 2) { premierDevice = arg; } else { printf("Argument devices hors de portée.\n"); } } //--------------------------------------------------------------------------- // // // INITIALISATION DU PROGRAMME // // //--------------------------------------------------------------------------- // // Rend le fgets sur stdin non bloquant; FONCTIONNE ! // int flags = fcntl(0, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(0, F_SETFL, flags); printf("Initialisation des différents modules..."); fflush(stdout); Misc_Initialise(); // Ne dépend de rien d'autre // Pas de blabla Maths_Initialise(); // Ne dépend de rien d'autre // Pas de blabla Params_Initialise(); // Après Maths_Initialise(); (peut utiliser des maths) // Pas de blabla Asservissement_Initialise(); // Après Params_Initialise(); //Pilote_Initialise(); // Après Params, // Pas de blabla printf(" OK\n"); printf("Fermeture des serveurs port séries..."); fflush(stdout); //system("pkill -9 xuartctl"); // kill tous les process utilisant xuartctl TS7500 //usleep(100 * 1000); printf(" OK... - A priori, A voir si on en a besoin - Pour l'instant ne fait rien\n"); // La fonction suivante émet son propre blabla I2C_Initialise(); Controlleur_Initialise(0); // Aprés Params_Initialise() et I2C_initialise; // Argument: 1 pour allumer les moteurs successivement //int grnLedOn = 0; //int redLedOn = 0; //Misc_SetRedLed(0); //TS7500 //Misc_SetGrnLed(0); if (0) { CommWiFi_Initialise(); // Emet son propre blabla } // On se donne temporairement la priorité -15 pour que les xuart l'aient // // -15 pour les xuartctl (Port séries) et ts7500ctl (I2C) // -10 pour nous et ts7500ctl // -5 pour les trucs systemes importants // 0 pour le reste // Plage: -20 (haute priorité) é +20 (faible priorité) int usePrio = 0; if (usePrio && setpriority(PRIO_PROCESS, getpid(), -15)) { printf("ERREUR: setpriority\n"); } Centrale_Initialise(premierDevice); // Argument: le dev par défaut, -1 pour laisser l'utilisateur choisir Sonar_Initialise(premierDevice + 1); // Argument: le dev par défaut, -1 pour laisser l'utilisateur choisir // On se replace a -10 if (usePrio && setpriority(PRIO_PROCESS, getpid(), -10)) { printf("ERREUR: setpriority !\n"); } printf("Merci de vérifier les numéros de devices ci-dessus\n"); if (usePrio) { printf("ET de vous assurer que la priorité du process ts5700ctl est strictement négative !\n"); } if (0) { Misc_WaitEnter(); } float tempsSCum = 0; int dispType = 1; // ---------------------------------- int attenteSonar = 0; int attenteCentrale = 0; int appelsCentrale = 0; int appelsSonar = 0; int dernierTestSonar = 0; int dispUneFois = 0; int toursAvantVerInputConsole = VERIFICATION_INPUT_CONSOLE_TOUT_LES - 1; // Initialisé ainsi pour vérifier une commande // dés le 1er tour de boucle int dispFreqOnce = 0; // // Liste des commandes // int MAX_COMMAND_LENGTH = 7 + 2; // Prendre la longueur réelle + 2 pour le \n et un cran de sécurité !!! char chSETPR[] = "set ep"; // Pas d'estimation //---Réglages des gains char chSETLP[] = "set lp"; // Régler le gain lacet proportionnel char chSETLI[] = "set li"; // Régler le gain lacet intégral char chSETLD[] = "set ld"; // Régler le gain lacet dérivé char chSETRP[] = "set rp"; // Régler le gain roulis proportionnel char chSETRI[] = "set ri"; // Régler le gain roulis intégral char chSETRD[] = "set rd"; // Régler le gain roulis dérivé char chSETTP[] = "set tp"; // Régler le gain tangage proportionnel char chSETTI[] = "set ti"; // Régler le gain tangage intégral char chSETTD[] = "set td"; // Régler le gain tangage dérivé char chSETAP[] = "set ap"; // Régler le gain altitude proportionnel char chSETAI[] = "set ai"; // Régler le gain altitude intégral char chSETAD[] = "set ad"; // Régler le gain altitude dérivé //videBufferSonar(); TODO Attention ici il faudra décommenter //--------------------------------------------------------------------------- // // // FONCTIONNEMENT NORMAL: BOUCLE INFINIE // // //--------------------------------------------------------------------------- printf("Initialisation terminée !\n"); fflush(stdout); Misc_ResetElapsedUs(); for (;;) { // La boucle infinie du programme // // Vérification de la liaison // if (state > 1 && modeI2C > 0) { attenteSignal++; if (attenteSignal == 300) { // 5 sec avant warning printf("\nATTENTION: communication inactive, merci d'appuyer sur entrée !\n"); fflush(stdout); } else if (attenteSignal == 500) { // 10 sec avant désactivation if (state == 3 || state == 4) { state = 5; // Lance un atterissage si en vol printf("\nERREUR: Aucun signal wifi, atterissage d'urgence !\n"); } else { state = -1; // Arret d'urgence sinon printf("\nERREUR: Aucun signal wifi, arret d'urgence !\n"); } fflush(stdout); } } ////////////////////////////////////////////////////////////////// // // Regardons si une commande a été tapé dans la console // ////////////////////////////////////////////////////////////////// toursAvantVerInputConsole++; if (toursAvantVerInputConsole >= VERIFICATION_INPUT_CONSOLE_TOUT_LES) { toursAvantVerInputConsole = 0; if (1 || Misc_HasData(0)) { // Misc_HasData(0) fonctionne bien en ethernet char *cptr; char buffer[MAX_COMMAND_LENGTH]; // Ex 256 au lieu de MAX_COMMAND_LENGTH cptr = fgets(buffer, MAX_COMMAND_LENGTH, stdin); // Ex 256 au lieu de MAX_COMMAND_LENGTH if (cptr != NULL) { attenteSignal = 0; // Watchdog: la communication est active ! // // Convertissons le char* en char[] pour pouvoir le comparer a l'aide de strncmp // char dst[MAX_COMMAND_LENGTH]; strncpy(dst, cptr, MAX_COMMAND_LENGTH - 1); dst[MAX_COMMAND_LENGTH - 1] = '\0'; if (dispType > 0) { printf("\n"); // Le dispCommande affiche une ligne puis l'enleve en permanence } // // Comparons le a la liste des commandes implémentés // //------------------------------------------------ //--------------- TOUCHE "ENTREE" ---------------- //------------------------------------------------ if ((int)dst[0] == 10) { dispUneFois = 1; // Nous poursuivons l'éxécution tranquillement } //---------------- Traitons en premier les commandes longues ------------- //------------------------------------------------ //-------------- COMMANDES "SET **" -------------- //------------------------------------------------ else if (strncmp(chSETLP, dst, sizeof chSETLP - 1) == 0) { GAINS_PRO[0] = askFloatValue("Gain proportionnel lacet"); } else if (strncmp(chSETLI, dst, sizeof chSETLI - 1) == 0) { GAINS_INT[0] = askFloatValue("Gain intégral lacet"); } else if (strncmp(chSETLD, dst, sizeof chSETLD - 1) == 0) { GAINS_DER[0] = askFloatValue("Gain dérivé lacet"); } else if (strncmp(chSETRP, dst, sizeof chSETRP - 1) == 0) { GAINS_PRO[1] = askFloatValue("Gain proportionnel roulis"); } else if (strncmp(chSETRI, dst, sizeof chSETRI - 1) == 0) { GAINS_INT[1] = askFloatValue("Gain intégral roulis"); } else if (strncmp(chSETRD, dst, sizeof chSETRD - 1) == 0) { GAINS_DER[1] = askFloatValue("Gain dérivé roulis"); } else if (strncmp(chSETTP, dst, sizeof chSETTP - 1) == 0) { GAINS_PRO[2] = askFloatValue("Gain proportionnel tangage"); } else if (strncmp(chSETTI, dst, sizeof chSETTI - 1) == 0) { GAINS_INT[2] = askFloatValue("Gain intégral tangage"); } else if (strncmp(chSETTD, dst, sizeof chSETTD - 1) == 0) { GAINS_DER[2] = askFloatValue("gain dérivé tangage"); } else if (strncmp(chSETAP, dst, sizeof chSETAP - 1) == 0) { GAINS_PRO[3] = askFloatValue("GAIN proportionnel altitude"); } else if (strncmp(chSETAI, dst, sizeof chSETAI - 1) == 0) { GAINS_INT[3] = askFloatValue("GAIN intégral altitude"); } else if (strncmp(chSETAD, dst, sizeof chSETAD - 1) == 0) { GAINS_DER[3] = askFloatValue("GAIN dérivé altitude"); } //------------------------------------------------ //--------------- COMMANDE "SET PR" ----------------- //------------------------------------------------ else if (strncmp(chSETPR, dst, sizeof chSETPR - 1) == 0) { if (state == 0 || state == 1) { printf( "\nTemps d'anticipation actuel de l'estimateur: %i\n", ESTIMATEUR_TEMPS_DE_REACTION); int value = askIntValue("TDR"); if (value >= 1 && value <= 5) { printf("Nouvelle valeur acceptée !"); ESTIMATEUR_TEMPS_DE_REACTION = value; Asservissement_Initialise(); } else { printf("ERREUR: Nouvelle valeure refusée !\n"); fflush(stdout); } } else { printf("Commande inaccessible dans cet état !\n"); fflush(stdout); } } //---------------- Traitons en second les commandes courtes ------------- //------------------------------------------------ //-------------- COMMANDE NAVIG. ----------------- //------------------------------------------------ else if (dst[0] == 'a') { ConsLRTA[0] += PAS_L; } else if (dst[0] == 'e') { ConsLRTA[0] -= PAS_L; } else if (dst[0] == 'q') { ConsLRTA[1] += PAS_RT; } else if (dst[0] == 'd') { ConsLRTA[1] -= PAS_RT; } else if (dst[0] == 'z') { ConsLRTA[2] -= PAS_RT; } else if (dst[0] == 's') { ConsLRTA[2] += PAS_RT; } else if (dst[0] == 'r') { ConsLRTA[3] += PAS_A; } else if (dst[0] == 'f') { ConsLRTA[3] -= PAS_A; } //------------------------------------------------ //------------- COMMANDES VEQ -------------------- //------------------------------------------------ else if (dst[0] == 'p') { VEqui += 50.0F; printf("Nouvelle vitesse d'équilibre: %f\n", VEqui); fflush(stdout); if (state == 4) { Vactu = VEqui; } } else if (dst[0] == 'm') { VEqui -= 50.0F; printf("Nouvelle vitesse d'équilibre: %f\n", VEqui); fflush(stdout); if (state == 4) { Vactu = VEqui; } } //------------------------------------------------ //------------- COMMANDES A_VOL -------------------- //------------------------------------------------ else if (dst[0] == '$') { ALTITUDE_FIN_DECOLLAGE += 0.05F; if(ALTITUDE_FIN_DECOLLAGE > 0.8F) { ALTITUDE_FIN_DECOLLAGE = 0.8F; } printf("Nouvelle altitude cible au décollage: %icm\n", (int)(100.0F * ALTITUDE_FIN_DECOLLAGE)); fflush(stdout); } else if (dst[0] == '*') { ALTITUDE_FIN_DECOLLAGE -= 0.05F; if(ALTITUDE_FIN_DECOLLAGE < 0.3F) { ALTITUDE_FIN_DECOLLAGE = 0.3F; } printf("Nouvelle altitude cible au décollage: %icm\n", (int)(100.0F * ALTITUDE_FIN_DECOLLAGE)); fflush(stdout); } //------------------------------------- MACHINE ETAT ------------------------------- //------------------------------------------------ //--------------- COMMANDE "w" ----------------- //------------------------------------------------ else if (dst[0] == 'w') { if (state == -1) { printf("Erreur ignoré !\n"); state = 0; } else { printf("ERREUR: La commande ne peut étre appliqué dans ce contexte.\n"); } fflush(stdout); } //------------------------------------------------ //--------------- COMMANDE "x" ----------------- //------------------------------------------------ else if (dst[0] == 'x') { if (state == -1 || state == 0 || state == 1) { printf("Initialisation... OK\n"); //--RAZ attitude et position Centrale_RAZAttitude(); //Centrale_RAZPosition(); videBufferSonar(); //--RAZ des consignes ConsLRTA[0] = 0.0F; // 0 en lacet ConsLRTA[3] = 0.0F; // 0 en altitude if (ConsLRTA[1] != 0.0F || ConsLRTA[2] != 0) { printf("\n\nWARNING: Initialisé avec consignes RT non nulles !!\n\n"); } if (state == -1) { printf("Il faut encore faire 'clr'\n"); } else { printf("Pret pour mise en rotation\n"); state = 1; } fflush(stdout); } else { printf("ERREUR: La commande ne peut étre appliqué dans ce contexte.\n"); } fflush(stdout); } //------------------------------------------------ //--------------- COMMANDE "c" ----------------- //------------------------------------------------ else if (dst[0] == 'c') { if (state == 1) { printf("Mise en rotation...\n"); state = 2; } else { printf("ERREUR: La commande ne peut étre appliqué dans ce contexte.\n"); } fflush(stdout); } //------------------------------------------------ //--------------- COMMANDE "v" ----------------- //------------------------------------------------ else if (dst[0] == 'v') { if (state == 2) { printf("Décollage...\n"); Vactu = 0.0F; state = 3; } else { printf("ERREUR: La commande ne peut étre appliqué dans ce contexte.\n"); } fflush(stdout); } //------------------------------------------------ //--------------- COMMANDE "b" ----------------- //------------------------------------------------ else if (dst[0] == 'b') { if (state == 4 || state == 3) { printf("Atterissage...\n"); state = 5; } else { printf("ERREUR: La commande ne peut étre appliqué dans ce contexte.\n"); } fflush(stdout); } //------------------------------------------------ //--------------- COMMANDE "STOP" ---------------- //------------------------------------------------ else if (dst[0] == ' ') { state = -1; printf("\n !! ARRET D'URGENCE !! \n"); fflush(stdout); } //------------------------------------- Divers --------------- //------------------------------------------------ //--------------- COMMANDE "k" ---------------- //------------------------------------------------ else if (dst[0] == 'k') { printf("Arret du programme...\n"); fflush(stdout); break; // Termine la boucle et entraine la fermeture du programme } //------------------------------------------------ //--------------- COMMANDE "n" ----------------- //------------------------------------------------ else if (dst[0] == 'n') { dispType++; if (dispType == 3) { dispType = 0; } printf("Mode d'affichage changé. (mode actuel: %i)\n", dispType); fflush(stdout); } //------------------------------------------------ //--------------- COMMANDE "j" ----------------- //------------------------------------------------ else if (dst[0] == 'j') { modeI2C++; if (modeI2C == 2) { modeI2C = 0; } printf( "Mode de controle I2C changé. (mode actuel: %i)\n", modeI2C); fflush(stdout); } //------------------------------------------------ //--------------- COMMANDE "u" ----------------- //------------------------------------------------ else if (dst[0] == 'u') { BUF_CTR++; if (BUF_CTR == 3) { BUF_CTR = 1; } printf( "Buffer centrale changé. (facteur actuel: %i)\n", BUF_CTR); fflush(stdout); } //------------------------------------------------ //--------------- COMMANDE "y" ----------------- //------------------------------------------------ else if (dst[0] == 'y') { if (readSonar == 1) { readSonar = 0; printf("Lecture sonar désactivée !\n"); } else { readSonar = 1; printf("Lecture sonar activée !\n"); } fflush(stdout); } //------------------------------------------------ //--------------- COMMANDE "i" ---------------- //------------------------------------------------ else if (dst[0] == 'i') { dispFreqOnce = 1; } //------------------------------------------------ //-------------- COMMANDE "l" --------------- //------------------------------------------------ else if (dst[0] == 'l') { // Listons les réglages PID actuels printf("\n Proportionnel Intégral Dérivé\n"); printf("Lacet : %15f %15f %15f\n", GAINS_PRO[0], GAINS_INT[0], GAINS_DER[0]); printf("Roulis : %15f %15f %15f\n", GAINS_PRO[1], GAINS_INT[1], GAINS_DER[1]); printf("Tangage : %15f %15f %15f\n", GAINS_PRO[2], GAINS_INT[2], GAINS_DER[2]); printf("Altitude : %15f %15f %15f\n", GAINS_PRO[3], GAINS_INT[3], GAINS_DER[3]); printf("Vequi : %15f", VEqui); fflush(stdout); } //------------------------------------------------ //---------------- COMMANDE "HELP" --------------- //------------------------------------------------ else if (dst[0] == 'h') { Misc_PrintHelp(); fflush(stdout); } //------------------------------------------------ //------------- COMMANDE NON RECONNUE ------------ //------------------------------------------------ else { printf("\nCommande non reconnue: %s", cptr); // Pas de \n car cptr en contient un ! printf("\nAppuyez sur 'h' pour obtenir de l'aide.\n"); fflush(stdout); } } } } ////////////////////////////////////////////////////////////////// // // Récupération de l'état du systéme // ////////////////////////////////////////////////////////////////// if (state != -1) { // // On attend une nouvelle trame centrale // attenteCentrale = 0; for (;;) { appelsCentrale++; Centrale_CheckData(1); if (NouvelleTrameCentrale) { NouvelleTrameCentrale = 0; break; //--La trame a été récupéré et analysé, nous avons alors la nouvelle attitude du drone // La variable trameRate a été mise a 1 si on a raté une trame entre temps ! } else { attenteCentrale++; if (attenteCentrale > 1000 * 100) { // La valeur de 100 convient parfaitement en lecture bloquante printf("\nERREUR: Pas de données centrale !\n"); fflush(stdout); state = -1; break; } } } } dernierTestSonar++; if (readSonar && state != -1 && dernierTestSonar >= TEST_SONAR_TOUT_LES && !trameRate) { dernierTestSonar = 0; // // On regarde si on a une trame sonar // appelsSonar++; Sonar_CheckData(1); if (NouvelleTrameSonar) { NouvelleTrameSonar = 0; attenteSonar = 0; //--Tant mieux, l'altitude a été mis-é-jour if (SonarTropBas) { if (state == 4) { printf("\nDANGER: Trop bas"); fflush(stdout); } } else if (SonarTropHaut) { if (state == 4) { printf("\nDANGER: Trop haut, baisse consigne"); fflush(stdout); ConsLRTA[3] -= 0.005F; // 0.5cm 20 fois par seconde => 10cm / s } } else { // On est dans la plage du sonar ! } } else { //--Tant pis, nous avons toujours l'ancienne valeur attenteSonar++; if (attenteSonar > ATTENTE_SONAR_MAXI) { printf("\nERREUR: Pas de données sonar !\n"); fflush(stdout); state = -1; } } } ////////////////////////////////////////////////////////////////// // // Calcul de l'intervalle de temps // ////////////////////////////////////////////////////////////////// // // Important: // // A ce stade de la boucle, nous avons récupéré une trame centrale, et en avons extrait l'information // temporelle qui nous a permis de calculer l'intervalle de temps réel entre les deux trames. // Cette intervalle est stocké dans "IntervalleTemps" et est utilisé par Asservissement_Controle() // et puis par Pilote_CalculConsignes(); // // // Calcul de l'intervalle de temps avec les trames centrale // tempsSCum += IntervalleTemps; float TOUT_LES = 0.25F; if (tempsSCum >= TOUT_LES) { tempsSCum -= TOUT_LES; dispUneFois = 1; } /*if (0) { // Clignottement LED verte: TS7500 if (tempsSCum > 0.5F && !grnLedOn) { grnLedOn = 1; Misc_SetGrnLed(grnLedOn); } else if (tempsSCum < 0.5F && grnLedOn) { grnLedOn = 0; Misc_SetGrnLed(grnLedOn); } } */ ////////////////////////////////////////////////////////////////// // // Transitions d'état automatiques et sécurités // ////////////////////////////////////////////////////////////////// // 3 -> 4 (Fin du décollage) if (state == 3) { if (Vactu < VEqui) { // Premiere phase du décollage: amener Vactu a VEqui Vactu += RAMPE_ROTATION * IntervalleTemps; if (Vactu >= VEqui) { Vactu = VEqui; printf("\nPuissance de vol atteinte ! Ascension verticale...\n"); fflush(stdout); } } else { // Seconde phase: ascension verticale ConsLRTA[3] += RAMPE_ASCENSION * IntervalleTemps; if (ConsLRTA[3] >= ALTITUDE_FIN_DECOLLAGE) { ConsLRTA[3] = ALTITUDE_FIN_DECOLLAGE; state = 4; printf("\nDécollage terminé ! Vol de croisiére.\n"); fflush(stdout); } } } // 5 -> 1 (Fin de l'atterissage) if (state == 5) { if (ConsLRTA[3] > 0.0F) { // Premiere phase: Descente verticale ConsLRTA[3] -= RAMPE_DESCENTE * IntervalleTemps; if (ConsLRTA[3] <= 0.0F) { ConsLRTA[3] = 0.0F; printf("\nDescente terminée !\n"); fflush(stdout); } } else { // Seconde phase: extinction des moteurs Vactu -= RAMPE_ROTATION * IntervalleTemps; if (Vactu <= 0.0F) { // Sera limité par la valeur minimale de toute faéon Vactu = 0.0F; state = 1; printf("\nAtterissage terminé !\n"); fflush(stdout); } } } // // Vérification des plages de fonctionnement // if (state >= 1) { // Initialisé ou en vol //--Angle de lacet if (Misc_Abs(ConsLRTA[0] - PosLRTA[0]) > ECART_MAXI_L) { printf( "\nERREUR: Angle de lacet hors de porté (Cons=%5fé, Pos=%5fé)!\n", 57 * ConsLRTA[0], 57 * PosLRTA[0]); fflush(stdout); state = -1; } //--Angle de roulis if (Misc_Abs(ConsLRTA[1] - PosLRTA[1]) > ECART_MAXI_RT) { printf( "\nERREUR: Angle de roulis hors de porté (Cons=%5fé, Pos=%5fé)!\n", 57 * ConsLRTA[1], 57 * PosLRTA[1]); fflush(stdout); state = -1; } //--Angle de tangage if (Misc_Abs(ConsLRTA[2] - PosLRTA[2]) > ECART_MAXI_RT) { printf( "\nERREUR: Angle de tangage hors de porté (Cons=%5fé, Pos=%5fé)!\n", 57 * ConsLRTA[2], 57 * PosLRTA[2]); fflush(stdout); state = -1; } //--Altitude if (Misc_Abs(ConsLRTA[3] - PosLRTA[3]) > ECART_MAXI_A) { printf( "\nERREUR: Altitude hors de porté (Cons=%5fcm, Pos=%5fcm)!\n", 100 * ConsLRTA[3], 100 * PosLRTA[3]); fflush(stdout); state = -1; } } ////////////////////////////////////////////////////////////////// // // Calcul et envoi de la commande // ////////////////////////////////////////////////////////////////// if (state == -1 || state == 0 || state == 1) { // Aucune rotation Controlleur_Envoi(0); } else if (state == 2) { // Rotation lente Controlleur_Envoi(1); } else if (state == 3 || state == 4 || state == 5) { //Pilote_CalculConsignes(); Asservissement_Controle(); Controlleur_Envoi(2); } ////////////////////////////////////////////////////////////////// // // Affichage de quelques infos // ////////////////////////////////////////////////////////////////// if (dispUneFois) { dispUneFois = 0; // // Mise a jour LED rouge TS7500 // /*if (state == -1 && !redLedOn) { redLedOn = 1; Misc_SetRedLed(redLedOn); } else if (state >= 0 && redLedOn) { redLedOn = 0; Misc_SetRedLed(redLedOn); } */ // // dispType : // 0 : aucun affichage régulier // 1 : affichage ligne d'état // 2 : affichage ligne d'état + freqs if (dispType > 0) { // // Mode I2C // printf("\n[M=%i]", modeI2C); // // Etat // if (state == -1) { printf("[ERR]"); } else if (state == 0) { printf("[N.I]"); } else if (state == 1) { printf("[PRT]"); } else if (state == 2) { printf("[ROT]"); } else if (state == 3) { printf("[DEC]"); } else if (state == 4) { printf("[VOL]"); } else if (state == 5) { printf("[ATT]"); } // // Vmoyen et equi // printf("[%i/%i/%i]", Controlleur_VMoyen(), (int)(VEqui), Ass_CorAlti()); // // Sonar // printf("A: "); if (SonarTropBas) { printf("T.BAS"); } else if (SonarTropHaut) { printf("T.HAUT"); } else { printf("%3i", (int)(100 * PosLRTA[3])); } printf("/%3icm", (int)(100 * ConsLRTA[3])); // // Lacet, roulis, tangage // printf(" L: %3i/%3ié R: %2i/%2ié T: %2i/%2ié", (int)(57 * PosLRTA[0]), (int)(57 * ConsLRTA[0]), (int)(57 * PosLRTA[1]), (int)(57 * ConsLRTA[1]), (int)(57 * PosLRTA[2]), (int)(57 * ConsLRTA[2])); // // Commande // // if (dispType == 3) { // Controlleur_PrintCmd(); // } if (dispType == 2 || dispFreqOnce) { printf( "\nCENTRALE: Ap: %5i Tr: %4i Er: %4i Re: %4i Ef: %4i", appelsCentrale, freqCentrale, erreursCentrale, recherchesCentrale, tramesEffacees); printf( "\nSONAR : Ap: %5i Tr: %4i Er: %4i Re: %4i Ef: %4i", appelsSonar, freqSonar, erreursSonar, recherchesSonar, 0); dispFreqOnce = 0; } fflush(stdout); } freqSonar = 0; appelsSonar = 0; erreursSonar = 0; recherchesSonar = 0; freqCentrale = 0; appelsCentrale = 0; erreursCentrale = 0; recherchesCentrale = 0; tramesEffacees = 0; } ////////////////////////////////////////////////////////////////// // // Fin de la boucle, temporisation si nécessaire // ////////////////////////////////////////////////////////////////// if (state == -1) { usleep(10*1000); } } // Fin de la boucle infinie //--------------------------------------------------------------------------- // // // FERMETURE DU PROGRAMME: LIBERATION MEMOIRE // // //--------------------------------------------------------------------------- //--Envoi d'une consigne zero Controlleur_Envoi(0); printf("Fermeture du programme...\n"); fflush(stdout); Sonar_Termine(); Centrale_Termine(); Controlleur_Termine(); Pilote_Termine(); CommWiFi_Termine(); //Misc_SetGrnLed(0); TS7500 //Misc_SetRedLed(0); printf("Programme terminé !\n"); fflush(stdout); return 1; }
int main(int argc, char *argv[]) { int ret = ERROR_OK; int err_count = 0; int rcv_err_count = 0; bool msg_received = false; char* device; /* Para parsear el los mensajes se recorre el arreglo con un puntero * a enteros de dos bytes. */ int16_t *ch_buff; //char str[128]; // dbg // check input arguments if(argc<2) { err_log(HOW_TO); return -1; } else device = argv[1]; struct timeval tv_in; struct timeval tv_end; struct timeval tv_diff; #if DEBUG_TIMING_SBUSD struct timeval tv_last; #endif //#if DEBUG_TIMING_SBUSD #if !PC_TEST fd = open_port(device); if (fd == -1) { return -1; } configure_port(fd); ret = custom_baud(fd); if (ret < 0) { err_log_stderr("custom_baud() failed!"); return ret; } #endif /** * Inherit priority from main.c for correct IPC. */ if(setpriority(PRIO_PROCESS, 0, -18) == -1) //requires being superuser { err_log_num("setpriority() failed!",errno); return -1; } // Catch signals prctl(PR_SET_PDEATHSIG, SIGHUP); signal(SIGHUP, uquad_sig_handler); signal(SIGINT, uquad_sig_handler); signal(SIGQUIT, uquad_sig_handler); #if PC_TEST futaba_sbus_begin(); //para tiempo de start #endif //PC_TEST // Lleva a cero todos los canales y el mensaje sbus futaba_sbus_set_channel(ROLL_CHANNEL, 1500); //init roll en cero futaba_sbus_set_channel(PITCH_CHANNEL, 1500); //init pitch en cero futaba_sbus_set_channel(YAW_CHANNEL, 1500); //init yaw en cero futaba_sbus_set_channel(THROTTLE_CHANNEL, 950); //init throttle en minimo futaba_sbus_set_channel(FLIGHTMODE_CHANNEL, 1500); //inint flight mode 2 futaba_sbus_update_msg(); sleep_ms(500); //Para ponerme a tiro con main bool main_ready = false; // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // Loop // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- for(;;) { gettimeofday(&tv_in,NULL); //printf("errores: %d\n",err_count);//dbg #if !PC_TEST if (err_count > MAX_ERR_SBUSD) { err_log("error count exceded"); //err_count = 0; quit(); } #endif ret = uquad_read(&rbuf); if(ret == ERROR_OK) { if(!main_ready) main_ready = true; //err_log("read ok!"); msg_received = true; // Parse message. 2 bytes per channel. ch_buff = (int16_t *)rbuf.mtext; // send ack ret = uquad_send_ack(); if(ret != ERROR_OK) { err_log("Failed to send ack!"); } if (rcv_err_count > 0) rcv_err_count = 0; } else { //err_log("Failed to read msg!"); msg_received = false; rcv_err_count++; if (main_ready && rcv_err_count > 3) { err_count++; rcv_err_count = 0; } } if(msg_received) { futaba_sbus_set_channel(ROLL_CHANNEL, ch_buff[ROLL_CH_INDEX]); futaba_sbus_set_channel(PITCH_CHANNEL, ch_buff[PITCH_CH_INDEX]); futaba_sbus_set_channel(YAW_CHANNEL, ch_buff[YAW_CH_INDEX]); futaba_sbus_set_channel(THROTTLE_CHANNEL, ch_buff[THROTTLE_CH_INDEX]); //futaba_sbus_set_channel(7, ch_buff[FLIGHTMODE_CH_INDEX]); // flight mode no se modifica // Comando para activar failsafe if ( (ch_buff[FAILSAFE_CH_INDEX] == ACTIVATE_FAILSAFE) && (futaba_sbus_get_failsafe() == SBUS_SIGNAL_OK) ) futaba_sbus_set_failsafe(SBUS_SIGNAL_FAILSAFE); // Comando para desactivar failsafe if ( (ch_buff[FAILSAFE_CH_INDEX] == DEACTIVATE_FAILSAFE) && (futaba_sbus_get_failsafe() == SBUS_SIGNAL_FAILSAFE) ) futaba_sbus_set_failsafe(SBUS_SIGNAL_OK); futaba_sbus_update_msg(); msg_received = false; //print_sbus_data(); // dbg } #if !PC_TEST ret = futaba_sbus_write_msg(fd); if (ret < 0) { err_count++; // si fallo al enviar el mensaje se apagan los motores!! } else { /// This loop was fine if(err_count > 0) err_count--; } sleep_ms(5); //TODO revisar si hay que hacerlo siempre!! #else sleep_ms(5); //TODO revisar si hay que hacerlo siempre!! #endif // Escribe el mensaje a stdout - dbg //convert_sbus_data(str); //printf("%s",str); /// Control de tiempo gettimeofday(&tv_end,NULL); ret = uquad_timeval_substract(&tv_diff, tv_end, tv_in); if(ret > 0) { if(tv_diff.tv_usec < LOOP_T_US) usleep(LOOP_T_US - (unsigned long)tv_diff.tv_usec); #if DEBUG_TIMING_SBUSD gettimeofday(&tv_end,NULL); uquad_timeval_substract(&tv_diff, tv_end, tv_in); printf("duracion loop sbusd (14ms): %lu\n",(unsigned long)tv_diff.tv_usec); #endif } else { err_log("WARN: Absurd timing!"); err_count++; // si no cumplo el tiempo de loop falla la comunicacion sbus } //printf("rcv_err_count: %d\n", rcv_err_count); //printf("err_count: %d\n", err_count); } //for(;;) return 0; //never gets here }
int main(int argc, char **argv) { int c; int cnt; char *childArgv[10]; char *buff; int childArgc = 0; int retcode; char *pwdbuf = NULL; struct passwd *pwd = NULL, _pwd; struct login_context cxt = { .tty_mode = TTY_MODE, /* tty chmod() */ .pid = getpid(), /* PID */ .conv = { misc_conv, NULL } /* PAM conversation function */ }; timeout = (unsigned int)getlogindefs_num("LOGIN_TIMEOUT", LOGIN_TIMEOUT); signal(SIGALRM, timedout); siginterrupt(SIGALRM, 1); /* we have to interrupt syscalls like ioclt() */ alarm(timeout); signal(SIGQUIT, SIG_IGN); signal(SIGINT, SIG_IGN); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); setpriority(PRIO_PROCESS, 0, 0); initproctitle(argc, argv); /* * -p is used by getty to tell login not to destroy the environment * -f is used to skip a second login authentication * -h is used by other servers to pass the name of the remote * host to login so that it may be placed in utmp and wtmp */ while ((c = getopt(argc, argv, "fHh:pV")) != -1) switch (c) { case 'f': cxt.noauth = 1; break; case 'H': cxt.nohost = 1; break; case 'h': if (getuid()) { fprintf(stderr, _("login: -h for super-user only.\n")); exit(EXIT_FAILURE); } init_remote_info(&cxt, optarg); break; case 'p': cxt.keep_env = 1; break; case 'V': printf(UTIL_LINUX_VERSION); return EXIT_SUCCESS; case '?': default: fprintf(stderr, _("usage: login [ -p ] [ -h host ] [ -H ] [ -f username | username ]\n")); exit(EXIT_FAILURE); } argc -= optind; argv += optind; if (*argv) { char *p = *argv; cxt.username = xstrdup(p); /* wipe name - some people mistype their password here */ /* (of course we are too late, but perhaps this helps a little ..) */ while (*p) *p++ = ' '; } for (cnt = get_fd_tabsize() - 1; cnt > 2; cnt--) close(cnt); setpgrp(); /* set pgid to pid this means that setsid() will fail */ openlog("login", LOG_ODELAY, LOG_AUTHPRIV); init_tty(&cxt); init_loginpam(&cxt); /* login -f, then the user has already been authenticated */ cxt.noauth = cxt.noauth && getuid() == 0 ? 1 : 0; if (!cxt.noauth) loginpam_auth(&cxt); /* * Authentication may be skipped (for example, during krlogin, rlogin, * etc...), but it doesn't mean that we can skip other account checks. * The account could be disabled or password expired (although * kerberos ticket is valid). -- [email protected] (22-Feb-2006) */ loginpam_acct(&cxt); if (!(cxt.pwd = get_passwd_entry(cxt.username, &pwdbuf, &_pwd))) { warnx(_("\nSession setup problem, abort.")); syslog(LOG_ERR, _("Invalid user name \"%s\" in %s:%d. Abort."), cxt.username, __FUNCTION__, __LINE__); pam_end(cxt.pamh, PAM_SYSTEM_ERR); sleepexit(EXIT_FAILURE); } pwd = cxt.pwd; cxt.username = pwd->pw_name; /* * Initialize the supplementary group list. This should be done before * pam_setcred because the PAM modules might add groups during * pam_setcred. * * For root we don't call initgroups, instead we call setgroups with * group 0. This avoids the need to step through the whole group file, * which can cause problems if NIS, NIS+, LDAP or something similar * is used and the machine has network problems. */ retcode = pwd->pw_uid ? initgroups(cxt.username, pwd->pw_gid) : /* user */ setgroups(0, NULL); /* root */ if (retcode < 0) { syslog(LOG_ERR, _("groups initialization failed: %m")); warnx(_("\nSession setup problem, abort.")); pam_end(cxt.pamh, PAM_SYSTEM_ERR); sleepexit(EXIT_FAILURE); } /* * Open PAM session (after successful authentication and account check) */ loginpam_session(&cxt); /* committed to login -- turn off timeout */ alarm((unsigned int)0); endpwent(); cxt.quiet = get_hushlogin_status(pwd); log_utmp(&cxt); log_audit(&cxt, 1); log_lastlog(&cxt); chown_tty(&cxt); if (setgid(pwd->pw_gid) < 0 && pwd->pw_gid) { syslog(LOG_ALERT, _("setgid() failed")); exit(EXIT_FAILURE); } if (pwd->pw_shell == NULL || *pwd->pw_shell == '\0') pwd->pw_shell = _PATH_BSHELL; init_environ(&cxt); /* init $HOME, $TERM ... */ setproctitle("login", cxt.username); log_syslog(&cxt); if (!cxt.quiet) { motd(); #ifdef LOGIN_STAT_MAIL /* * This turns out to be a bad idea: when the mail spool * is NFS mounted, and the NFS connection hangs, the * login hangs, even root cannot login. * Checking for mail should be done from the shell. */ { struct stat st; char *mail; mail = getenv("MAIL"); if (mail && stat(mail, &st) == 0 && st.st_size != 0) { if (st.st_mtime > st.st_atime) printf(_("You have new mail.\n")); else printf(_("You have mail.\n")); } } #endif } /* * Detach the controlling terminal, fork() and create, new session * and reinilizalize syslog stuff. */ fork_session(&cxt); /* discard permissions last so can't get killed and drop core */ if (setuid(pwd->pw_uid) < 0 && pwd->pw_uid) { syslog(LOG_ALERT, _("setuid() failed")); exit(EXIT_FAILURE); } /* wait until here to change directory! */ if (chdir(pwd->pw_dir) < 0) { warn(_("%s: change directory failed"), pwd->pw_dir); if (!getlogindefs_bool("DEFAULT_HOME", 1)) exit(0); if (chdir("/")) exit(EXIT_FAILURE); pwd->pw_dir = "/"; printf(_("Logging in with home = \"/\".\n")); } /* if the shell field has a space: treat it like a shell script */ if (strchr(pwd->pw_shell, ' ')) { buff = xmalloc(strlen(pwd->pw_shell) + 6); strcpy(buff, "exec "); strcat(buff, pwd->pw_shell); childArgv[childArgc++] = "/bin/sh"; childArgv[childArgc++] = "-sh"; childArgv[childArgc++] = "-c"; childArgv[childArgc++] = buff; } else { char tbuf[PATH_MAX + 2], *p; tbuf[0] = '-'; xstrncpy(tbuf + 1, ((p = strrchr(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell), sizeof(tbuf) - 1); childArgv[childArgc++] = pwd->pw_shell; childArgv[childArgc++] = xstrdup(tbuf); } childArgv[childArgc++] = NULL; execvp(childArgv[0], childArgv + 1); if (!strcmp(childArgv[0], "/bin/sh")) warn(_("couldn't exec shell script")); else warn(_("no shell")); exit(EXIT_SUCCESS); }
void *SpeechVMRecorder::DumpVMRecordDataThread(void *arg) { // Adjust thread priority prctl(PR_SET_NAME, (unsigned long)__FUNCTION__, 0, 0, 0); setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO); ALOGD("%s(), pid: %d, tid: %d", __FUNCTION__, getpid(), gettid()); SpeechVMRecorder *pSpeechVMRecorder = (SpeechVMRecorder *)arg; RingBuf &ring_buf = pSpeechVMRecorder->mRingBuf; // open file if (pSpeechVMRecorder->OpenFile() != NO_ERROR) { pSpeechVMRecorder->mEnable = false; pthread_exit(NULL); return 0; } // open modem record function SpeechDriverInterface *pSpeechDriver = SpeechDriverFactory::GetInstance()->GetSpeechDriver(); status_t retval = pSpeechDriver->VoiceMemoRecordOn(); if (retval != NO_ERROR) { ALOGE("%s(), VoiceMemoRecordOn() fail!! Return.", __FUNCTION__); pSpeechDriver->VoiceMemoRecordOff(); pSpeechVMRecorder->mEnable = false; pthread_exit(NULL); return 0; } // Internal Input Buffer Initialization pSpeechVMRecorder->mRingBuf.pBufBase = new char[kReadBufferSize]; pSpeechVMRecorder->mRingBuf.bufLen = kReadBufferSize; pSpeechVMRecorder->mRingBuf.pRead = pSpeechVMRecorder->mRingBuf.pBufBase; pSpeechVMRecorder->mRingBuf.pWrite = pSpeechVMRecorder->mRingBuf.pBufBase; ASSERT(pSpeechVMRecorder->mRingBuf.pBufBase != NULL); memset(pSpeechVMRecorder->mRingBuf.pBufBase, 0, pSpeechVMRecorder->mRingBuf.bufLen); pSpeechVMRecorder->mStarting = true; while (1) { // lock & wait data pthread_mutex_lock(&pSpeechVMRecorder->mMutex); int ret = pthread_cond_timeout_np(&pSpeechVMRecorder->mExitCond, &pSpeechVMRecorder->mMutex, kCondWaitTimeoutMsec); if (ret != 0) { ALOGW("%s(), pthread_cond_timeout_np return %d. ", __FUNCTION__, ret); } // make sure VM is still recording after conditional wait if (pSpeechVMRecorder->mEnable == false) { // close file if (pSpeechVMRecorder->mDumpFile != NULL) { fflush(pSpeechVMRecorder->mDumpFile); fclose(pSpeechVMRecorder->mDumpFile); pSpeechVMRecorder->mDumpFile = NULL; } // release local ring buffer if (pSpeechVMRecorder->mRingBuf.pBufBase != NULL) { delete []pSpeechVMRecorder->mRingBuf.pBufBase; pSpeechVMRecorder->mRingBuf.pBufBase = NULL; pSpeechVMRecorder->mRingBuf.pRead = NULL; pSpeechVMRecorder->mRingBuf.pWrite = NULL; pSpeechVMRecorder->mRingBuf.bufLen = 0; } ALOGD("%s(), pid: %d, tid: %d, mEnable == false, break.", __FUNCTION__, getpid(), gettid()); pthread_mutex_unlock(&pSpeechVMRecorder->mMutex); break; } // write data to sd card const uint16_t data_count = RingBuf_getDataCount(&ring_buf); uint16_t write_bytes = 0; if (data_count > 0) { const char *end = ring_buf.pBufBase + ring_buf.bufLen; if (ring_buf.pRead <= ring_buf.pWrite) { write_bytes += fwrite((void *)ring_buf.pRead, sizeof(char), data_count, pSpeechVMRecorder->mDumpFile); } else { int r2e = end - ring_buf.pRead; write_bytes += fwrite((void *)ring_buf.pRead, sizeof(char), r2e, pSpeechVMRecorder->mDumpFile); write_bytes += fwrite((void *)ring_buf.pBufBase, sizeof(char), data_count - r2e, pSpeechVMRecorder->mDumpFile); } ring_buf.pRead += write_bytes; if (ring_buf.pRead >= end) { ring_buf.pRead -= ring_buf.bufLen; } SLOGV("data_count: %u, write_bytes: %u", data_count, write_bytes); } if (write_bytes != data_count) { ALOGE("%s(), write_bytes(%d) != data_count(%d), SD Card might be full!!", __FUNCTION__, write_bytes, data_count); } // unlock pthread_mutex_unlock(&pSpeechVMRecorder->mMutex); } pthread_exit(NULL); return 0; }
void dockingportGSP::init() { /////////////////// Set process priorities int prior; int dummy1; /// set process priority of ueye usb daemon to highest possible value char reniceCmd[100]; string processIDofUeyeDeamonStr; int processIDofUeyeDeamon; char pidOfCmd[100]; sprintf(pidOfCmd, "pidof ueyeusbd"); processIDofUeyeDeamonStr = this->execAndReturnSystemOutput(pidOfCmd); processIDofUeyeDeamon = atoi(processIDofUeyeDeamonStr.c_str()); sprintf(reniceCmd, "sudo renice -20 %d", processIDofUeyeDeamon); dummy1 = system(reniceCmd); prior = getpriority(PRIO_PROCESS, processIDofUeyeDeamon); printf("\n ueyeusbd process priority set to: %d\n",prior); /// set process priority of TestProject process to a value slightly lower than ueye usb daemon setpriority(PRIO_PROCESS,0,-15); usleep(10000); prior = getpriority(PRIO_PROCESS,0); printf(" TestProject process priority set to: %d\n",prior); this->useBackgroundTask = false; prevImageTimeStamp = 0; /////////////////// Path Initializations sprintf(this->calibParamDir, "/opt/GogglesOptics/Calib_Params/%s", this->calibParamSetName); //set the parameter directory to be what we enter in command line /////////////////// /////////////////// Camera Initialization section GSPretVal = camera.initOneCamera(); // Errors handled within functions if (GSPretVal != 0) { printf("Camera could not be initialized!\n"); return exit(1); } // Start camera GSPretVal = camera.startOneCamera(); // Errors handled within functions if (GSPretVal != 0) { printf("Camera could not be started!\n"); return exit(1); } ////////////////// UDP PIC INITIALIZATION if (useUDP_PIC) this->connectToPIC(); /////////////////// /////////////////// Image Rectification Initialization GSPretVal = rectifier.calcRectificationMaps(camera.getImageWidth(), camera.getImageHeight(), this->calibParamDir); if (GSPretVal != 0) { cout << "Rectification maps could not be processed!" << endl; } /////////////////// /////////////////// Data Storage Initialization datastorage.initDataStorage(this->dockportName, this->camera_ID, this->runPath, this->camera.getImageWidth(), this->camera.getImageHeight()); if (datastorage.autoImageStorage) { // create image-datastorage thread GSPretVal = pthread_create(&ImageStorageThread, NULL, this->imageStorage_thread_Helper, this); if (GSPretVal != 0) { printf("pthread_create ImageStorageThread failed\n"); return exit(1); } } /////////////////// /////////////////// Initialization of OpenCV Mats with correct Size (depending on the parameter/boolean camera.reduceImageSizeTo320x240) singleImage.create(camera.getImageHeight(), camera.getImageWidth(), CV_8UC3); /////////////////// }
int main(int argc, char *argv[]) { int exitcode = EXIT_FAILURE; struct sigaction sa; char *device = NULL, *snoop = NULL; int device_fd; struct epoll_event device_event; int dd, opt, detach = 1; while ((opt=getopt_long(argc, argv, "d:s:nh", options, NULL)) != EOF) { switch(opt) { case 'd': device = strdup(optarg); break; case 's': snoop = strdup(optarg); break; case 'n': detach = 0; break; case 'h': usage(); exit(0); default: usage(); exit(1); } } argc -= optind; argv += optind; optind = 0; if (argc < 1) { usage(); exit(1); } if (getbdaddrbyname(argv[0], &vdev.bdaddr) < 0) exit(1); if (detach) { if (daemon(0, 0)) { perror("Can't start daemon"); exit(1); } } /* Start logging to syslog and stderr */ openlog("hciemu", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); syslog(LOG_INFO, "HCI emulation daemon ver %s started", VERSION); memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sa.sa_handler = sig_term; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); if (!device) device = strdup(VHCI_DEV); /* Open and create virtual HCI device */ device_fd = open(device, O_RDWR); if (device_fd < 0) { syslog(LOG_ERR, "Can't open device %s: %s (%d)", device, strerror(errno), errno); free(device); return exitcode; } free(device); /* Create snoop file */ if (snoop) { dd = create_snoop(snoop); if (dd < 0) syslog(LOG_ERR, "Can't create snoop file %s: %s (%d)", snoop, strerror(errno), errno); free(snoop); } else dd = -1; /* Create event loop */ epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (epoll_fd < 0) { perror("Failed to create epoll descriptor"); goto close_device; } reset_vdev(); vdev.dev_fd = device_fd; vdev.dd = dd; memset(&device_event, 0, sizeof(device_event)); device_event.events = EPOLLIN; device_event.data.fd = device_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, device_fd, &device_event) < 0) { perror("Failed to setup device event watch"); goto close_device; } setpriority(PRIO_PROCESS, 0, -19); /* Start event processor */ for (;;) { struct epoll_event events[MAX_EPOLL_EVENTS]; int n, nfds; if (__io_canceled) break; nfds = epoll_wait(epoll_fd, events, MAX_EPOLL_EVENTS, -1); if (nfds < 0) continue; for (n = 0; n < nfds; n++) { if (events[n].data.fd == vdev.dev_fd) io_hci_data(); else if (events[n].data.fd == vdev.scan_fd) io_conn_ind(); } } exitcode = EXIT_SUCCESS; epoll_ctl(epoll_fd, EPOLL_CTL_DEL, device_fd, NULL); close_device: close(device_fd); if (dd >= 0) close(dd); close(epoll_fd); syslog(LOG_INFO, "Exit"); return exitcode; }
void vegas_rawdisk_thread(void *_args) { /* Set cpu affinity */ cpu_set_t cpuset, cpuset_orig; sched_getaffinity(0, sizeof(cpu_set_t), &cpuset_orig); CPU_ZERO(&cpuset); CPU_SET(1, &cpuset); int rv = sched_setaffinity(0, sizeof(cpu_set_t), &cpuset); if (rv<0) { vegas_error("vegas_rawdisk_thread", "Error setting cpu affinity."); perror("sched_setaffinity"); } /* Get args */ struct vegas_thread_args *args = (struct vegas_thread_args *)_args; /* get instance_id */ int instance_id = args->instance_id; /* Set priority */ rv = setpriority(PRIO_PROCESS, 0, 0); if (rv<0) { vegas_error("vegas_rawdisk_thread", "Error setting priority level."); perror("set_priority"); } /* Attach to status shared mem area */ struct vegas_status st; rv = vegas_status_attach(instance_id, &st); if (rv!=VEGAS_OK) { vegas_error("vegas_rawdisk_thread", "Error attaching to status shared memory."); pthread_exit(NULL); } pthread_cleanup_push((void *)vegas_status_detach, &st); pthread_cleanup_push((void *)set_exit_status, &st); /* Init status */ vegas_status_lock_safe(&st); hputs(st.buf, STATUS_KEY, "init"); vegas_status_unlock_safe(&st); /* Read in general parameters */ struct vegas_params gp; struct sdfits sf; pthread_cleanup_push((void *)vegas_free_sdfits, &sf); /* Attach to databuf shared mem */ struct vegas_databuf *db; db = vegas_databuf_attach(instance_id, args->input_buffer); if (db==NULL) { vegas_error("vegas_rawdisk_thread", "Error attaching to databuf shared memory."); pthread_exit(NULL); } pthread_cleanup_push((void *)vegas_databuf_detach, db); /* Init output file */ FILE *fraw = NULL; pthread_cleanup_push((void *)safe_fclose, fraw); /* Loop */ int blocksize=0; int curblock=0, dataset; int block_count=0, blocks_per_file=128, filenum=0; int first=1; char *ptr; float *data_array; struct databuf_index* db_index; signal(SIGINT,cc); while (run) { /* Note waiting status */ vegas_status_lock_safe(&st); hputs(st.buf, STATUS_KEY, "waiting"); vegas_status_unlock_safe(&st); /* Wait for buf to have data */ rv = vegas_databuf_wait_filled(db, curblock); if (rv!=0) continue; /* Read param struct and index for this block */ ptr = vegas_databuf_header(db, curblock); db_index = (struct databuf_index*)(vegas_databuf_index(db, curblock)); /* If first time running */ if (first==1) { first = 0; vegas_read_obs_params(ptr, &gp, &sf); char fname[256]; sprintf(fname, "%s_%4d.raw", sf.basefilename, filenum); fprintf(stderr, "Opening raw file '%s'\n", fname); // TODO: check for file exist. fraw = fopen(fname, "wb"); if (fraw==NULL) { vegas_error("vegas_rawdisk_thread", "Error opening file."); pthread_exit(NULL); } } else vegas_read_subint_params(ptr, &gp, &sf); /* See if we need to open next file */ if (block_count >= blocks_per_file) { fclose(fraw); filenum++; char fname[256]; sprintf(fname, "%s_%4d.raw", sf.basefilename, filenum); fprintf(stderr, "Opening raw file '%s'\n", fname); fraw = fopen(fname, "wb"); if (fraw==NULL) { vegas_error("vegas_rawdisk_thread", "Error opening file."); pthread_exit(NULL); } block_count=0; } /* Get full data block size */ hgeti4(ptr, "BLOCSIZE", &blocksize); /* Note writing status and current block */ vegas_status_lock_safe(&st); hputi4(st.buf, "DSKBLKIN", curblock); hputs(st.buf, STATUS_KEY, "writing"); vegas_status_unlock_safe(&st); /* Write all data arrays to disk */ for(dataset = 0; dataset < db_index->num_datasets; dataset++) { data_array = (float*)(vegas_databuf_data(db, curblock) + db_index->disk_buf[dataset].array_offset); rv = fwrite(data_array, 4, (size_t)(db_index->array_size/4), fraw); if (rv != db_index->array_size/4) { vegas_error("vegas_rawdisk_thread", "Error writing data."); } } /* Increment block counter */ block_count++; /* flush output */ fflush(fraw); /* Mark as free */ vegas_databuf_set_free(db, curblock); /* Go to next block */ curblock = (curblock + 1) % db->n_block; /* Check for cancel */ pthread_testcancel(); } pthread_exit(NULL); pthread_cleanup_pop(0); /* Closes fclose */ pthread_cleanup_pop(0); /* Closes vegas_databuf_detach */ pthread_cleanup_pop(0); /* Closes vegas_free_psrfits */ pthread_cleanup_pop(0); /* Closes set_exit_status */ pthread_cleanup_pop(0); /* Closes vegas_status_detach */ }
/* 工作进程初始化, * worker表示创建的是第几个进程 */ static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker) { sigset_t set; uint64_t cpu_affinity; ngx_int_t n; ngx_uint_t i; struct rlimit rlmt; ngx_core_conf_t *ccf; ngx_listening_t *ls; if (ngx_set_environment(cycle, NULL) == NULL) { /* fatal */ exit(2); } ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (worker >= 0 && ccf->priority != 0) { /* 设置进程的优先级 */ if (setpriority(PRIO_PROCESS, 0, ccf->priority) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setpriority(%d) failed", ccf->priority); } } if (ccf->rlimit_nofile != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile; rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile; if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_NOFILE, %i) failed", ccf->rlimit_nofile); } } if (ccf->rlimit_core != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_core; rlmt.rlim_max = (rlim_t) ccf->rlimit_core; if (setrlimit(RLIMIT_CORE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_CORE, %O) failed", ccf->rlimit_core); } } if (geteuid() == 0) { if (setgid(ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setgid(%d) failed", ccf->group); /* fatal */ exit(2); } if (initgroups(ccf->username, ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "initgroups(%s, %d) failed", ccf->username, ccf->group); } if (setuid(ccf->user) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setuid(%d) failed", ccf->user); /* fatal */ exit(2); } } if (worker >= 0) { cpu_affinity = ngx_get_cpu_affinity(worker); if (cpu_affinity) { ngx_setaffinity(cpu_affinity, cycle->log); } } #if (NGX_HAVE_PR_SET_DUMPABLE) /* allow coredump after setuid() in Linux 2.4.x */ if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "prctl(PR_SET_DUMPABLE) failed"); } #endif if (ccf->working_directory.len) { if (chdir((char *) ccf->working_directory.data) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "chdir(\"%s\") failed", ccf->working_directory.data); /* fatal */ exit(2); } } sigemptyset(&set); if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigprocmask() failed"); } srandom((ngx_pid << 16) ^ ngx_time()); /* * disable deleting previous events for the listening sockets because * in the worker processes there are no events at all at this point */ ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { ls[i].previous = NULL; } /* 在worker进程初始化的时候,会调用相应模块的进程初始化回调 * 注意模块数组也是每个进程都保有一份的 */ for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->init_process) { if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { /* fatal */ exit(2); } } } /* 扫描所有的进程,在后续创建的子进程要通知 * 之前创建的子进程通信的socket文件描述符 */ for (n = 0; n < ngx_last_process; n++) { /* 判断进程是否存活 */ if (ngx_processes[n].pid == -1) { continue; } /* 如果是当前子进程的索引 */ if (n == ngx_process_slot) { continue; } if (ngx_processes[n].channel[1] == -1) { continue; } /* 将其他子进程的1通道关闭 */ if (close(ngx_processes[n].channel[1]) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "close() channel failed"); } } /* 把自己的0通道给关闭,所以其他子进程和当前进程通信的时候 * 就是和当前进程的1通道通信 */ if (close(ngx_processes[ngx_process_slot].channel[0]) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "close() channel failed"); } #if 0 ngx_last_process = 0; #endif /* 监听子进程的1通道,看是否有其他进程给自己发送消息 */ if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT, ngx_channel_handler) == NGX_ERROR) { /* fatal */ exit(2); } }
static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority) { sigset_t set; ngx_int_t n; ngx_uint_t i; struct rlimit rlmt; ngx_core_conf_t *ccf; ngx_listening_t *ls; if (ngx_set_environment(cycle, NULL) == NULL) { /* fatal */ exit(2); } ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (priority && ccf->priority != 0) { if (setpriority(PRIO_PROCESS, 0, ccf->priority) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setpriority(%d) failed", ccf->priority); } } if (ccf->rlimit_nofile != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile; rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile; if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_NOFILE, %i) failed", ccf->rlimit_nofile); } } if (ccf->rlimit_core != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_core; rlmt.rlim_max = (rlim_t) ccf->rlimit_core; if (setrlimit(RLIMIT_CORE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_CORE, %O) failed", ccf->rlimit_core); } } #ifdef RLIMIT_SIGPENDING if (ccf->rlimit_sigpending != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_sigpending; rlmt.rlim_max = (rlim_t) ccf->rlimit_sigpending; if (setrlimit(RLIMIT_SIGPENDING, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_SIGPENDING, %i) failed", ccf->rlimit_sigpending); } } #endif if (geteuid() == 0) { if (setgid(ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setgid(%d) failed", ccf->group); /* fatal */ exit(2); } if (initgroups(ccf->username, ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "initgroups(%s, %d) failed", ccf->username, ccf->group); } if (setuid(ccf->user) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setuid(%d) failed", ccf->user); /* fatal */ exit(2); } } #if (NGX_HAVE_SCHED_SETAFFINITY) if (cpu_affinity) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "sched_setaffinity(0x%08Xl)", cpu_affinity); if (sched_setaffinity(0, 32, (cpu_set_t *) &cpu_affinity) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sched_setaffinity(0x%08Xl) failed", cpu_affinity); } } #endif #if (NGX_HAVE_PR_SET_DUMPABLE) /* allow coredump after setuid() in Linux 2.4.x */ if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "prctl(PR_SET_DUMPABLE) failed"); } #endif if (ccf->working_directory.len) { if (chdir((char *) ccf->working_directory.data) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "chdir(\"%s\") failed", ccf->working_directory.data); /* fatal */ exit(2); } } sigemptyset(&set); if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigprocmask() failed"); } /* * disable deleting previous events for the listening sockets because * in the worker processes there are no events at all at this point */ ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { ls[i].previous = NULL; } for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->init_process) { if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { /* fatal */ exit(2); } } } for (n = 0; n < ngx_last_process; n++) { if (ngx_processes[n].pid == -1) { continue; } if (n == ngx_process_slot) { continue; } if (ngx_processes[n].channel[1] == -1) { continue; } if (close(ngx_processes[n].channel[1]) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "close() channel failed"); } } if (close(ngx_processes[ngx_process_slot].channel[0]) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "close() channel failed"); } #if 0 ngx_last_process = 0; #endif if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT, ngx_channel_handler) == NGX_ERROR) { /* fatal */ exit(2); } }
static void logger_thread(void *arg) { int bytes_read; UNREFERENCED(arg); /* Set root mode in order to set priority */ SETMODE(ROOT); /* Set device thread priority; ignore any errors */ if(setpriority(PRIO_PROCESS, 0, sysblk.devprio)) WRMSG(HHC00136, "W", "setpriority()", strerror(errno)); /* Back to user mode */ SETMODE(USER); #if !defined( _MSVC_ ) /* Redirect stdout to the logger */ if(dup2(logger_syslogfd[LOG_WRITE],STDOUT_FILENO) == -1) { if(logger_hrdcpy) fprintf(logger_hrdcpy, MSG(HHC02102, "E", "dup2()", strerror(errno))); exit(1); } #endif /* !defined( _MSVC_ ) */ setvbuf (stdout, NULL, _IONBF, 0); obtain_lock(&logger_lock); logger_active = 1; /* Signal initialization complete */ signal_condition(&logger_cond); release_lock(&logger_lock); /* ZZ FIXME: We must empty the read pipe before we terminate */ /* (Couldn't we just loop waiting for a 'select(,&readset,,,timeout)' to return zero?? Or use the 'poll' function similarly?? - Fish) */ while(logger_active) { bytes_read = read_pipe(logger_syslogfd[LOG_READ],logger_buffer + logger_currmsg, ((logger_bufsize - logger_currmsg) > LOG_DEFSIZE ? LOG_DEFSIZE : logger_bufsize - logger_currmsg)); if(bytes_read == -1) { int read_pipe_errno = HSO_errno; // (ignore any/all errors at shutdown) if (sysblk.shutdown) continue; if (HSO_EINTR == read_pipe_errno) continue; obtain_lock(&logger_lock); if(logger_hrdcpy) { fprintf(logger_hrdcpy, MSG(HHC02102, "E", "read_pipe()", strerror(read_pipe_errno))); } release_lock(&logger_lock); bytes_read = 0; } /* If Hercules is not running in daemon mode and panel initialization is not yet complete, write message to stderr so the user can see it on the terminal */ if (!sysblk.daemon_mode) { if (!sysblk.panel_init) { char* pLeft2 = logger_buffer + logger_currmsg; int nLeft2 = bytes_read; #if defined( OPTION_MSGCLR ) /* Remove "<pnl,..." color string if it exists */ if (1 && nLeft2 > 5 && strncasecmp( pLeft2, "<pnl", 4 ) == 0 && (pLeft2 = memchr( pLeft2+4, '>', nLeft2-4 )) != NULL ) { pLeft2++; nLeft2 -= (int)(pLeft2 - (logger_buffer + logger_currmsg)); } #endif // defined( OPTION_MSGCLR ) /* (ignore any errors; we did the best we could) */ if (nLeft2) fwrite( pLeft2, nLeft2, 1, stderr ); } } obtain_lock(&logger_lock); /* Write log data to hardcopy file */ if (logger_hrdcpy) #if !defined( OPTION_TIMESTAMP_LOGFILE ) { char* pLeft2 = logger_buffer + logger_currmsg; int nLeft2 = bytes_read; #if defined( OPTION_MSGCLR ) /* Remove "<pnl,..." color string if it exists */ if (1 && nLeft2 > 5 && strncasecmp( pLeft2, "<pnl", 4 ) == 0 && (pLeft2 = memchr( pLeft2+4, '>', nLeft2-4 )) != NULL ) { pLeft2++; nLeft2 -= (pLeft2 - (logger_buffer + logger_currmsg)); } else { pLeft2 = logger_buffer + logger_currmsg; nLeft2 = bytes_read; } #endif // defined( OPTION_MSGCLR ) if (nLeft2) { logger_logfile_write( pLeft2, nLeft2 ); } } #else // defined( OPTION_TIMESTAMP_LOGFILE ) { /* Need to prefix each line with a timestamp. */ static int needstamp = 1; char* pLeft = logger_buffer + logger_currmsg; int nLeft = bytes_read; char* pRight = NULL; int nRight = 0; char* pNL = NULL; /* (pointer to NEWLINE character) */ if (needstamp) { if (!sysblk.logoptnotime) logger_logfile_timestamp(); needstamp = 0; } while ( (pNL = memchr( pLeft, '\n', nLeft )) != NULL ) { pRight = pNL + 1; nRight = nLeft - (int)(pRight - pLeft); nLeft -= nRight; #if defined( OPTION_MSGCLR ) /* Remove "<pnl...>" color string if it exists */ { char* pLeft2 = pLeft; int nLeft2 = nLeft; if (1 && nLeft > 5 && strncasecmp( pLeft, "<pnl", 4 ) == 0 && (pLeft2 = memchr( pLeft+4, '>', nLeft-4 )) != NULL ) { pLeft2++; nLeft2 -= (int)(pLeft2 - pLeft); } else { pLeft2 = pLeft; nLeft2 = nLeft; } if (nLeft2) logger_logfile_write( pLeft2, nLeft2 ); } #else // !defined( OPTION_MSGCLR ) if (nLeft) logger_logfile_write( pLeft, nLeft ); #endif // defined( OPTION_MSGCLR ) pLeft = pRight; nLeft = nRight; if (!nLeft) { needstamp = 1; break; } if (!sysblk.logoptnotime) logger_logfile_timestamp(); } if (nLeft) logger_logfile_write( pLeft, nLeft ); } #endif // !defined( OPTION_TIMESTAMP_LOGFILE ) release_lock(&logger_lock); /* Increment buffer index to next available position */ logger_currmsg += bytes_read; if(logger_currmsg >= logger_bufsize) { logger_currmsg = 0; logger_wrapped = 1; } /* Notify all interested parties new log data is available */ obtain_lock(&logger_lock); broadcast_condition(&logger_cond); release_lock(&logger_lock); } logger_tid = 0; /* Logger is now terminating */ obtain_lock(&logger_lock); /* Write final message to hardcopy file */ if (logger_hrdcpy) { char* term_msg = MSG(HHC02103, "I"); size_t term_msg_len = strlen(term_msg); #ifdef OPTION_TIMESTAMP_LOGFILE if (!sysblk.logoptnotime) logger_logfile_timestamp(); #endif logger_logfile_write( term_msg, term_msg_len ); } /* Redirect all msgs to stderr */ logger_syslog[LOG_WRITE] = stderr; logger_syslogfd[LOG_WRITE] = STDERR_FILENO; fflush(stderr); /* Signal any waiting tasks */ broadcast_condition(&logger_cond); release_lock(&logger_lock); }
void cThread::SetPriority(int Priority) { if (setpriority(PRIO_PROCESS, 0, Priority) < 0) LOG_ERROR; }
int start_stop_daemon(int argc, char **argv) { int devnull_fd = -1; #ifdef TIOCNOTTY int tty_fd = -1; #endif #ifdef HAVE_PAM pam_handle_t *pamh = NULL; int pamr; const char *const *pamenv = NULL; #endif int opt; bool start = false; bool stop = false; bool oknodo = false; bool test = false; bool quiet; bool verbose = false; char *exec = NULL; char *startas = NULL; char *name = NULL; char *pidfile = NULL; char *retry = NULL; int sig = -1; int nicelevel = 0, ionicec = -1, ioniced = 0; bool background = false; bool makepidfile = false; bool interpreted = false; bool progress = false; uid_t uid = 0; gid_t gid = 0; char *home = NULL; int tid = 0; char *redirect_stderr = NULL; char *redirect_stdout = NULL; int stdout_fd; int stderr_fd; pid_t pid, spid; int i; char *svcname = getenv("RC_SVCNAME"); RC_STRINGLIST *env_list; RC_STRING *env; char *tmp, *newpath, *np; char *p; char *token; char exec_file[PATH_MAX]; struct passwd *pw; struct group *gr; char line[130]; FILE *fp; size_t len; mode_t numask = 022; char **margv; unsigned int start_wait = 0; TAILQ_INIT(&schedule); #ifdef DEBUG_MEMORY atexit(cleanup); #endif signal_setup(SIGINT, handle_signal); signal_setup(SIGQUIT, handle_signal); signal_setup(SIGTERM, handle_signal); if ((tmp = getenv("SSD_NICELEVEL"))) if (sscanf(tmp, "%d", &nicelevel) != 1) eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)", applet, tmp); /* Get our user name and initial dir */ p = getenv("USER"); home = getenv("HOME"); if (home == NULL || p == NULL) { pw = getpwuid(getuid()); if (pw != NULL) { if (p == NULL) setenv("USER", pw->pw_name, 1); if (home == NULL) { setenv("HOME", pw->pw_dir, 1); home = pw->pw_dir; } } } while ((opt = getopt_long(argc, argv, getoptstring, longopts, (int *) 0)) != -1) switch (opt) { case 'I': /* --ionice */ if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0) eerrorx("%s: invalid ionice `%s'", applet, optarg); if (ionicec == 0) ioniced = 0; else if (ionicec == 3) ioniced = 7; ionicec <<= 13; /* class shift */ break; case 'K': /* --stop */ stop = true; break; case 'N': /* --nice */ if (sscanf(optarg, "%d", &nicelevel) != 1) eerrorx("%s: invalid nice level `%s'", applet, optarg); break; case 'P': /* --progress */ progress = true; break; case 'R': /* --retry <schedule>|<timeout> */ retry = optarg; break; case 'S': /* --start */ start = true; break; case 'b': /* --background */ background = true; break; case 'u': /* --user <username>|<uid> */ case 'c': /* --chuid <username>|<uid> */ { p = optarg; tmp = strsep(&p, ":"); changeuser = xstrdup(tmp); if (sscanf(tmp, "%d", &tid) != 1) pw = getpwnam(tmp); else pw = getpwuid((uid_t)tid); if (pw == NULL) eerrorx("%s: user `%s' not found", applet, tmp); uid = pw->pw_uid; home = pw->pw_dir; unsetenv("HOME"); if (pw->pw_dir) setenv("HOME", pw->pw_dir, 1); unsetenv("USER"); if (pw->pw_name) setenv("USER", pw->pw_name, 1); if (gid == 0) gid = pw->pw_gid; if (p) { tmp = strsep (&p, ":"); if (sscanf(tmp, "%d", &tid) != 1) gr = getgrnam(tmp); else gr = getgrgid((gid_t) tid); if (gr == NULL) eerrorx("%s: group `%s'" " not found", applet, tmp); gid = gr->gr_gid; } } break; case 'd': /* --chdir /new/dir */ ch_dir = optarg; break; case 'e': /* --env */ putenv(optarg); break; case 'g': /* --group <group>|<gid> */ if (sscanf(optarg, "%d", &tid) != 1) gr = getgrnam(optarg); else gr = getgrgid((gid_t)tid); if (gr == NULL) eerrorx("%s: group `%s' not found", applet, optarg); gid = gr->gr_gid; break; case 'i': /* --interpreted */ interpreted = true; break; case 'k': if (parse_mode(&numask, optarg)) eerrorx("%s: invalid mode `%s'", applet, optarg); break; case 'm': /* --make-pidfile */ makepidfile = true; break; case 'n': /* --name <process-name> */ name = optarg; break; case 'o': /* --oknodo */ oknodo = true; break; case 'p': /* --pidfile <pid-file> */ pidfile = optarg; break; case 's': /* --signal <signal> */ sig = parse_signal(optarg); break; case 't': /* --test */ test = true; break; case 'r': /* --chroot /new/root */ ch_root = optarg; break; case 'a': /* --startas <name> */ startas = optarg; break; case 'w': if (sscanf(optarg, "%d", &start_wait) != 1) eerrorx("%s: `%s' not a number", applet, optarg); break; case 'x': /* --exec <executable> */ exec = optarg; break; case '1': /* --stdout /path/to/stdout.lgfile */ redirect_stdout = optarg; break; case '2': /* --stderr /path/to/stderr.logfile */ redirect_stderr = optarg; break; case_RC_COMMON_GETOPT } endpwent(); argc -= optind; argv += optind; quiet = rc_yesno(getenv("EINFO_QUIET")); verbose = rc_yesno(getenv("EINFO_VERBOSE")); /* Allow start-stop-daemon --signal HUP --exec /usr/sbin/dnsmasq * instead of forcing --stop --oknodo as well */ if (!start && !stop && sig != SIGINT && sig != SIGTERM && sig != SIGQUIT && sig != SIGKILL) oknodo = true; if (!exec) exec = startas; else if (!name) name = startas; if (!exec) { exec = *argv; if (!exec) exec = name; if (name && start) *argv = name; } else if (name) *--argv = name; else if (exec) *--argv = exec; if (stop || sig != -1) { if (sig == -1) sig = SIGTERM; if (!*argv && !pidfile && !name && !uid) eerrorx("%s: --stop needs --exec, --pidfile," " --name or --user", applet); if (background) eerrorx("%s: --background is only relevant with" " --start", applet); if (makepidfile) eerrorx("%s: --make-pidfile is only relevant with" " --start", applet); if (redirect_stdout || redirect_stderr) eerrorx("%s: --stdout and --stderr are only relevant" " with --start", applet); } else { if (!exec) eerrorx("%s: nothing to start", applet); if (makepidfile && !pidfile) eerrorx("%s: --make-pidfile is only relevant with" " --pidfile", applet); if ((redirect_stdout || redirect_stderr) && !background) eerrorx("%s: --stdout and --stderr are only relevant" " with --background", applet); } /* Expand ~ */ if (ch_dir && *ch_dir == '~') ch_dir = expand_home(home, ch_dir); if (ch_root && *ch_root == '~') ch_root = expand_home(home, ch_root); if (exec) { if (*exec == '~') exec = expand_home(home, exec); /* Validate that the binary exists if we are starting */ if (*exec == '/' || *exec == '.') { /* Full or relative path */ if (ch_root) snprintf(exec_file, sizeof(exec_file), "%s/%s", ch_root, exec); else snprintf(exec_file, sizeof(exec_file), "%s", exec); } else { /* Something in $PATH */ p = tmp = xstrdup(getenv("PATH")); *exec_file = '\0'; while ((token = strsep(&p, ":"))) { if (ch_root) snprintf(exec_file, sizeof(exec_file), "%s/%s/%s", ch_root, token, exec); else snprintf(exec_file, sizeof(exec_file), "%s/%s", token, exec); if (exists(exec_file)) break; *exec_file = '\0'; } free(tmp); } } if (start && !exists(exec_file)) { eerror("%s: %s does not exist", applet, *exec_file ? exec_file : exec); exit(EXIT_FAILURE); } /* If we don't have a pidfile we should check if it's interpreted * or not. If it we, we need to pass the interpreter through * to our daemon calls to find it correctly. */ if (interpreted && !pidfile) { fp = fopen(exec_file, "r"); if (fp) { p = fgets(line, sizeof(line), fp); fclose(fp); if (p != NULL && line[0] == '#' && line[1] == '!') { p = line + 2; /* Strip leading spaces */ while (*p == ' ' || *p == '\t') p++; /* Remove the trailing newline */ len = strlen(p) - 1; if (p[len] == '\n') p[len] = '\0'; token = strsep(&p, " "); strncpy(exec_file, token, sizeof(exec_file)); opt = 0; for (nav = argv; *nav; nav++) opt++; nav = xmalloc(sizeof(char *) * (opt + 3)); nav[0] = exec_file; len = 1; if (p) nav[len++] = p; for (i = 0; i < opt; i++) nav[i + len] = argv[i]; nav[i + len] = '\0'; } } } margv = nav ? nav : argv; if (stop || sig != -1) { if (sig == -1) sig = SIGTERM; if (!stop) oknodo = true; if (retry) parse_schedule(retry, sig); else if (test || oknodo) parse_schedule("0", sig); else parse_schedule(NULL, sig); i = run_stop_schedule(exec, (const char *const *)margv, pidfile, uid, quiet, verbose, test, progress); if (i < 0) /* We failed to stop something */ exit(EXIT_FAILURE); if (test || oknodo) return i > 0 ? EXIT_SUCCESS : EXIT_FAILURE; /* Even if we have not actually killed anything, we should * remove information about it as it may have unexpectedly * crashed out. We should also return success as the end * result would be the same. */ if (pidfile && exists(pidfile)) unlink(pidfile); if (svcname) rc_service_daemon_set(svcname, exec, (const char *const *)argv, pidfile, false); exit(EXIT_SUCCESS); } if (pidfile) pid = get_pid(pidfile, true); else pid = 0; if (do_stop(exec, (const char * const *)margv, pid, uid, 0, true, false, true) > 0) eerrorx("%s: %s is already running", applet, exec); if (test) { if (quiet) exit (EXIT_SUCCESS); einfon("Would start"); while (argc-- >= 0) printf(" %s", *argv++); printf("\n"); eindent(); if (uid != 0) einfo("as user id %d", uid); if (gid != 0) einfo("as group id %d", gid); if (ch_root) einfo("in root `%s'", ch_root); if (ch_dir) einfo("in dir `%s'", ch_dir); if (nicelevel != 0) einfo("with a priority of %d", nicelevel); if (name) einfo ("with a process name of %s", name); eoutdent(); exit(EXIT_SUCCESS); } if (verbose) { ebegin("Detaching to start `%s'", exec); eindent(); } /* Remove existing pidfile */ if (pidfile) unlink(pidfile); if (background) signal_setup(SIGCHLD, handle_signal); if ((pid = fork()) == -1) eerrorx("%s: fork: %s", applet, strerror(errno)); /* Child process - lets go! */ if (pid == 0) { pid_t mypid = getpid(); umask(numask); #ifdef TIOCNOTTY tty_fd = open("/dev/tty", O_RDWR); #endif devnull_fd = open("/dev/null", O_RDWR); if (nicelevel) { if (setpriority(PRIO_PROCESS, mypid, nicelevel) == -1) eerrorx("%s: setpritory %d: %s", applet, nicelevel, strerror(errno)); } /* Only linux suports setting an IO priority */ #ifdef __linux__ if (ionicec != -1 && ioprio_set(1, mypid, ionicec | ioniced) == -1) eerrorx("%s: ioprio_set %d %d: %s", applet, ionicec, ioniced, strerror(errno)); #endif if (ch_root && chroot(ch_root) < 0) eerrorx("%s: chroot `%s': %s", applet, ch_root, strerror(errno)); if (ch_dir && chdir(ch_dir) < 0) eerrorx("%s: chdir `%s': %s", applet, ch_dir, strerror(errno)); if (makepidfile && pidfile) { fp = fopen(pidfile, "w"); if (! fp) eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno)); fprintf(fp, "%d\n", mypid); fclose(fp); } #ifdef HAVE_PAM if (changeuser != NULL) pamr = pam_start("start-stop-daemon", changeuser, &conv, &pamh); else pamr = pam_start("start-stop-daemon", "nobody", &conv, &pamh); if (pamr == PAM_SUCCESS) pamr = pam_authenticate(pamh, PAM_SILENT); if (pamr == PAM_SUCCESS) pamr = pam_acct_mgmt(pamh, PAM_SILENT); if (pamr == PAM_SUCCESS) pamr = pam_open_session(pamh, PAM_SILENT); if (pamr != PAM_SUCCESS) eerrorx("%s: pam error: %s", applet, pam_strerror(pamh, pamr)); #endif if (gid && setgid(gid)) eerrorx("%s: unable to set groupid to %d", applet, gid); if (changeuser && initgroups(changeuser, gid)) eerrorx("%s: initgroups (%s, %d)", applet, changeuser, gid); if (uid && setuid(uid)) eerrorx ("%s: unable to set userid to %d", applet, uid); /* Close any fd's to the passwd database */ endpwent(); #ifdef TIOCNOTTY ioctl(tty_fd, TIOCNOTTY, 0); close(tty_fd); #endif /* Clean the environment of any RC_ variables */ env_list = rc_stringlist_new(); i = 0; while(environ[i]) rc_stringlist_add(env_list, environ[i++]); #ifdef HAVE_PAM pamenv = (const char *const *)pam_getenvlist(pamh); if (pamenv) { while (*pamenv) { /* Don't add strings unless they set a var */ if (strchr(*pamenv, '=')) putenv(xstrdup(*pamenv)); else unsetenv(*pamenv); pamenv++; } } #endif TAILQ_FOREACH(env, env_list, entries) { if ((strncmp(env->value, "RC_", 3) == 0 && strncmp(env->value, "RC_SERVICE=", 10) != 0 && strncmp(env->value, "RC_SVCNAME=", 10) != 0) || strncmp(env->value, "SSD_NICELEVEL=", 14) == 0) { p = strchr(env->value, '='); *p = '\0'; unsetenv(env->value); continue; } } rc_stringlist_free(env_list); /* For the path, remove the rcscript bin dir from it */ if ((token = getenv("PATH"))) { len = strlen(token); newpath = np = xmalloc(len + 1); while (token && *token) { p = strchr(token, ':'); if (p) { *p++ = '\0'; while (*p == ':') p++; } if (strcmp(token, RC_LIBEXECDIR "/bin") != 0 && strcmp(token, RC_LIBEXECDIR "/sbin") != 0) { len = strlen(token); if (np != newpath) *np++ = ':'; memcpy(np, token, len); np += len; } token = p; } *np = '\0'; unsetenv("PATH"); setenv("PATH", newpath, 1); } stdout_fd = devnull_fd; stderr_fd = devnull_fd; if (redirect_stdout) { if ((stdout_fd = open(redirect_stdout, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR)) == -1) eerrorx("%s: unable to open the logfile" " for stdout `%s': %s", applet, redirect_stdout, strerror(errno)); } if (redirect_stderr) { if ((stderr_fd = open(redirect_stderr, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR)) == -1) eerrorx("%s: unable to open the logfile" " for stderr `%s': %s", applet, redirect_stderr, strerror(errno)); } /* We don't redirect stdin as some daemons may need it */ if (background || quiet || redirect_stdout) dup2(stdout_fd, STDOUT_FILENO); if (background || quiet || redirect_stderr) dup2(stderr_fd, STDERR_FILENO); for (i = getdtablesize() - 1; i >= 3; --i) close(i); setsid(); execvp(exec, argv); #ifdef HAVE_PAM if (pamr == PAM_SUCCESS) pam_close_session(pamh, PAM_SILENT); #endif eerrorx("%s: failed to exec `%s': %s", applet, exec,strerror(errno)); }
int main(int argc, char *argv[]) { char path[PATH_MAX + 128], buf[PATH_MAX]; FILE *log; int fd; const char *log_file_dir = NULL; const char *hostname_str = NULL; #ifdef HAVE_SYS_RESOURCE_H setpriority(PRIO_PROCESS, 0, 19); #elif _WIN32 SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); #endif if (!eina_init()) return 1; efreetd_mp_stat = eina_mempool_add("chained_mempool", "struct stat", NULL, sizeof(struct stat), 10); if (!efreetd_mp_stat) return 1; if (!ecore_init()) goto ecore_error; ecore_app_args_set(argc, (const char **)argv); if (!ecore_file_init()) goto ecore_file_error; if (!ipc_init()) goto ipc_error; if (!cache_init()) goto cache_error; log_file_dir = eina_environment_tmp_get(); if (gethostname(buf, sizeof(buf)) < 0) hostname_str = ""; else hostname_str = buf; snprintf(path, sizeof(path), "%s/efreetd_%s_XXXXXX.log", log_file_dir, hostname_str); fd = eina_file_mkstemp(path, NULL); if (fd < 0) { ERR("Can't create log file '%s'\b", path); goto tmp_error; } log = fdopen(fd, "wb"); if (!log) goto tmp_error; eina_log_print_cb_set(eina_log_print_cb_file, log); efreetd_log_dom = eina_log_domain_register("efreetd", EFREETD_DEFAULT_LOG_COLOR); if (efreetd_log_dom < 0) { EINA_LOG_ERR("Efreet: Could not create a log domain for efreetd."); goto tmp_error; } ecore_main_loop_begin(); eina_mempool_del(efreetd_mp_stat); cache_shutdown(); ipc_shutdown(); ecore_file_shutdown(); ecore_shutdown(); eina_log_domain_unregister(efreetd_log_dom); efreetd_log_dom = -1; eina_shutdown(); return 0; tmp_error: cache_shutdown(); cache_error: ipc_shutdown(); ipc_error: ecore_file_shutdown(); ecore_file_error: ecore_shutdown(); ecore_error: if (efreetd_log_dom >= 0) eina_log_domain_unregister(efreetd_log_dom); efreetd_log_dom = -1; eina_shutdown(); return 1; }
/* Function int main(int argc, char **argv) {{{ */ int main(int argc, char **argv) { /* libcfg+ parsing context */ CFG_CONTEXT con; /* Parsing return code */ register int ret; /* Option variables */ int help, verbose, nice; char *cfg_file; char **command; /* Option set */ struct cfg_option options[] = { {"help", 'h', NULL, CFG_BOOL, (void *) &help, 0}, {"nice", 'n', "nice", CFG_INT, (void *) &nice, 0}, {"verbose", 'v', "verbose", CFG_BOOL+CFG_MULTI,(void *) &verbose, 0}, {NULL, 'f', NULL, CFG_STR, (void *) &cfg_file, 0}, {NULL, '\0', "command", CFG_STR+CFG_MULTI_SEPARATED+CFG_LEFTOVER_ARGS, (void *) &command, 0}, CFG_END_OF_LIST }; /* Creating context */ con = cfg_get_context(options); if (con == NULL) { puts("Not enough memory"); return 1; } /* Parse command line from second argument to end (NULL) */ cfg_set_cmdline_context(con, 1, -1, argv); /* Clearing option variables */ help = 0; verbose = 0; nice = 0; cfg_file = NULL; command = NULL; /* Parsing command line */ ret = cfg_parse(con); if (ret != CFG_OK) { printf("error parsing command line: "); cfg_fprint_error(con, stdout); putchar('\n'); return ret < 0 ? -ret : ret; } /* Help screen */ if (help) { printf("libcfg+ example program / compiled %s %s\n", __DATE__, __TIME__); puts(" Developed by Ondrej Jombik, http://nepto.sk/"); puts(" Copyright (c) 2001-2002 Platon SDG, http://platon.sk/"); puts("Usage:"); printf(" %s [options] command\n", argv[0]); puts("Options:"); puts(" -h, --help print this help screen"); puts(" -v, --verbose verbose (more -v means more verbose)"); puts(" -n, --nice process run priority (from 20 to -20)"); puts(" -f configuration file load"); return 1; } /* Config file testing */ if (cfg_file != NULL) { /* Parse configuration file from the first line to end of file */ cfg_set_cfgfile_context(con, 0, -1, cfg_file); /* Parsing config line */ ret = cfg_parse(con); if (ret != CFG_OK) { printf("error parsing config file: "); cfg_fprint_error(con, stdout); putchar('\n'); return ret < 0 ? -ret : ret; } } /* Testing if command to run was specified */ if (command == NULL) { puts("error: you must specify program to run"); return 1; } /* Nice parameter */ if (nice != 0) { if (verbose) printf("info: setting priority (nice) to %d\n", nice); if (setpriority(PRIO_PROCESS, PRIO_PROCESS, nice) == -1) printf("warning: unable to set priority (nice) to %d\n", nice); } /* Verbose running info */ if (verbose) { register int i; printf("info: running"); for (i = 0; command[i] != NULL; i++) printf(" %s", command[i]); putchar('\n'); } execvp(command[0], command); perror("error running program"); return errno == 0 ? 255 : (errno < 0 ? -errno : errno); } /* }}} */
/* * Process keyboard input during the main loop */ void do_key(char c) { int numinput, i; char rcfile[MAXNAMELEN]; FILE *fp; /* * First the commands which don't require a terminal mode switch. */ if (c == 'q') end(); else if (c == 12) { clear_screen(); return; } /* * Switch the terminal to normal mode. (Will the original * attributes always be normal? Does it matter? I suppose the * shell will be set up the way the user wants it.) */ ioctl(0, TCSETA, &Savetty); /* * Handle the rest of the commands. */ switch (c) { case '?': case 'h': PUTP(cl); PUTP(ho); putchar('\n'); PUTP(mr); printf("Proc-Top Revision 1.01"); PUTP(me); putchar('\n'); printf("Secure mode "); PUTP(md); fputs(Secure ? "on" : "off", stdout); PUTP(me); fputs("; cumulative mode ", stdout); PUTP(md); fputs(Cumulative ? "on" : "off", stdout); PUTP(me); fputs("; noidle mode ", stdout); PUTP(md); fputs(Noidle ? "on" : "off", stdout); PUTP(me); fputs("\n\n", stdout); printf("%s\n\nPress any key to continue\n", Secure ? SECURE_HELP_SCREEN : HELP_SCREEN); ioctl(0, TCSETA, &Rawtty); (void) getchar(); break; case 'i': Noidle = !Noidle; SHOWMESSAGE(("No-idle mode %s", Noidle ? "on" : "off")); break; case 'k': if (Secure) SHOWMESSAGE(("\aCan't kill in secure mode")); else { int pid, signal; PUTP(md); SHOWMESSAGE(("PID to kill: ")); pid = getint(); if (pid == -1) break; PUTP(top_clrtoeol); SHOWMESSAGE(("Kill PID %d with signal [15]: ", pid)); PUTP(me); signal = getsig(); if (signal == -1) signal = SIGTERM; if (kill(pid, signal)) SHOWMESSAGE(("\aKill of PID %d with %d failed: %s", pid, signal, strerror(errno))); } break; case 'l': SHOWMESSAGE(("Display load average %s", !show_loadav ? "on" : "off")); if (show_loadav) { show_loadav = 0; header_lines--; } else { show_loadav = 1; header_lines++; } Numfields = make_header(); break; case 'm': SHOWMESSAGE(("Display memory information %s", !show_memory ? "on" : "off")); if (show_memory) { show_memory = 0; header_lines -= 2; } else { show_memory = 1; header_lines += 2; } Numfields = make_header(); break; case 'M': SHOWMESSAGE(("Sort by memory usage")); sort_type = S_MEM; reset_sort_options(); register_sort_function(-1, (cmp_t)mem_sort); break; case 'n': case '#': printf("Processes to display (0 for unlimited): "); numinput = getint(); if (numinput != -1) { Display_procs = numinput; window_size(); } break; case 'r': if (Secure) SHOWMESSAGE(("\aCan't renice in secure mode")); else { int pid, val; printf("PID to renice: "); pid = getint(); if (pid == -1) break; PUTP(tgoto(cm, 0, header_lines - 2)); PUTP(top_clrtoeol); printf("Renice PID %d to value: ", pid); val = getint(); if (val == -1) val = 10; if (setpriority(PRIO_PROCESS, pid, val)) SHOWMESSAGE(("\aRenice of PID %d to %d failed: %s", pid, val, strerror(errno))); } break; case 'P': SHOWMESSAGE(("Sort by CPU usage")); sort_type = S_PCPU; reset_sort_options(); register_sort_function(-1, (cmp_t)pcpu_sort); break; case 'c': show_cmd = !show_cmd; SHOWMESSAGE(("Show %s", show_cmd ? "command names" : "command line")); break; case 'S': Cumulative = !Cumulative; SHOWMESSAGE(("Cumulative mode %s", Cumulative ? "on" : "off")); if (Cumulative) headers[22][1] = 'C'; else headers[22][1] = ' '; Numfields = make_header(); break; case 's': if (Secure) SHOWMESSAGE(("\aCan't change delay in secure mode")); else { double tmp; printf("Delay between updates: "); tmp = getfloat(); if (!(tmp < 0)) Sleeptime = tmp; } break; case 't': SHOWMESSAGE(("Display summary information %s", !show_stats ? "on" : "off")); if (show_stats) { show_stats = 0; header_lines -= 2; } else { show_stats = 1; header_lines += 2; } Numfields = make_header(); break; case 'T': SHOWMESSAGE(("Sort by %s time", Cumulative ? "cumulative" : "")); sort_type = S_TIME; reset_sort_options(); register_sort_function( -1, (cmp_t)time_sort); break; case 'f': case 'F': change_fields(); break; case 'o': case 'O': change_order(); break; case 'W': if (getenv("HOME")) { strcpy(rcfile, getenv("HOME")); strcat(rcfile, "/"); strcat(rcfile, RCFILE); fp = fopen(rcfile, "w"); if (fp != NULL) { fprintf(fp, "%s\n", Fields); i = (int) Sleeptime; if (i < 2) i = 2; if (i > 9) i = 9; fprintf(fp, "%d", i); if (Secure) fprintf(fp, "%c", 's'); if (Cumulative) fprintf(fp, "%c", 'S'); if (show_cmd) fprintf(fp, "%c", 'c'); if (Noidle) fprintf(fp, "%c", 'i'); if (!show_memory) fprintf(fp, "%c", 'm'); if (!show_loadav) fprintf(fp, "%c", 'l'); if (!show_stats) fprintf(fp, "%c", 't'); fprintf(fp, "\n"); fclose(fp); SHOWMESSAGE(("Wrote configuration to %s", rcfile)); } else { SHOWMESSAGE(("Couldn't open %s", rcfile)); } } else { SHOWMESSAGE(("Couldn't get $HOME -- not saving")); } break; default: SHOWMESSAGE(("\aUnknown command `%c' -- hit `h' for help", c)); } /* * Return to raw mode. */ ioctl(0, TCSETA, &Rawtty); return; }
int main(int argc, char **argv) { /* For select(2). */ struct timeval tv; fd_set in; /* For parsing arguments. */ char *cp; /* The key read in. */ char c; get_options(); /* * Parse arguments. */ argv++; while (*argv) { cp = *argv++; while (*cp) { switch (*cp) { case 'd': if (cp[1]) { if (sscanf(++cp, "%f", &Sleeptime) != 1) { fprintf(stderr, PROGNAME ": Bad delay time `%s'\n", cp); exit(1); } goto breakargv; } else if (*argv) { /* last char in an argv, use next as arg */ if (sscanf(cp = *argv++, "%f", &Sleeptime) != 1) { fprintf(stderr, PROGNAME ": Bad delay time `%s'\n", cp); exit(1); } goto breakargv; } else { fprintf(stderr, "-d requires an argument\n"); exit(1); } break; case 'q': if (!getuid()) /* set priority to -10 in order to stay above kswapd */ if (setpriority(PRIO_PROCESS, getpid(), -10)) { /* We check this just for paranoia. It's not fatal, and shouldn't happen. */ perror(PROGNAME ": setpriority() failed"); } Sleeptime = 0; break; case 'c': show_cmd = !show_cmd; break; case 'S': Cumulative = 1; break; case 'i': Noidle = 1; break; case 's': Secure = 1; break; case '-': break; /* Just ignore it */ #if defined (SHOWFLAG) case '/': showall++; #endif default: fprintf(stderr, PROGNAME ": Unknown argument `%c'\n", *cp); exit(1); } cp++; } breakargv: } /* set to PCPU sorting */ register_sort_function( -1, (cmp_t)pcpu_sort); /* for correct handling of some fields, we have to do distinguish * between kernel versions */ set_linux_version(); /* get kernel symbol table, if needed */ if (!CL_wchan_nout) { if (open_psdb()) { CL_wchan_nout = 1; } else { psdbsucc = 1; } } setup_terminal(); window_size(); /* * calculate header size, length of cmdline field ... */ Numfields = make_header(); /* * Set up signal handlers. */ signal(SIGHUP, (void *) (int) end); signal(SIGINT, (void *) (int) end); signal(SIGQUIT, (void *) (int) end); signal(SIGTSTP, (void *) (int) stop); signal(SIGWINCH, (void *) (int) window_size); /* loop, collecting process info and sleeping */ while (1) { if (setjmp(redraw_jmp)) clear_screen(); /* display the tasks */ show_procs(); /* sleep & wait for keyboard input */ tv.tv_sec = Sleeptime; tv.tv_usec = (Sleeptime - (int) Sleeptime) * 1000000; FD_ZERO(&in); FD_SET(0, &in); if (select(16, &in, 0, 0, &tv) > 0 && read(0, &c, 1) == 1) do_key(c); } } /*####################################################################### *#### Signal handled routines: error_end, end, stop, window_size ### *#### Small utilities: make_header, getstr, getint, getfloat, getsig ### *####################################################################### */ /* * end when exiting with an error. */ void error_end(int rno) { if (psdbsucc) close_psdb(); ioctl(0, TCSETAF, &Savetty); PUTP(tgoto(cm, 0, Lines - 1)); fputs("\r\n", stdout); exit(rno); } /* * Normal end of execution. */ void end(void) { if (psdbsucc) close_psdb(); ioctl(0, TCSETAF, &Savetty); PUTP(tgoto(cm, 0, Lines - 1)); fputs("\r\n", stdout); exit(0); } /* * SIGTSTP catcher. */ void stop(void) { /* Reset terminal. */ if (psdbsucc) close_psdb(); ioctl(0, TCSETAF, &Savetty); PUTP(tgoto(cm, 0, Lines - 3)); fflush(stdout); raise(SIGTSTP); /* Later... */ ioctl(0, TCSETAF, &Rawtty); signal(SIGTSTP, (void *) (int) stop); longjmp(redraw_jmp, 1); } /* * Reads the window size and clear the window. This is called on setup, * and also catches SIGWINCHs, and adjusts Maxlines. Basically, this is * the central place for window size stuff. */ void window_size(void) { struct winsize ws; if (ioctl(1, TIOCGWINSZ, &ws) != -1) { Cols = ws.ws_col; Lines = ws.ws_row; } else { Cols = tgetnum("co"); Lines = tgetnum("li"); } clear_screen(); } /* * this adjusts the lines needed for the header to the current value */ int make_header(void) { int i, j; j = 0; for (i = 0; i < strlen(Fields); i++) { if (isupper(Fields[i])) { pflags[j++] = Fields[i] - 'A'; } } strcpy(Header, ""); for (i = 0; i < j; i++) strcat(Header, headers[pflags[i]]); /* readjust window size ... */ Maxcmd = Cols - strlen(Header) + 7; Maxlines = Display_procs ? Display_procs : Lines - header_lines; if (Maxlines > Lines - header_lines) Maxlines = Lines - header_lines; return (j); }
/// Launch the auth server extern int main(int argc, char** argv) { // Command line parsing to get the configuration file name char const* configFile = _TRINITY_REALM_CONFIG; int count = 1; while (count < argc) { if (strcmp(argv[count], "-c") == 0) { if (++count >= argc) { printf("Runtime-Error: -c option requires an input argument\n"); usage(argv[0]); return 1; } else configFile = argv[count]; } ++count; } if (!sConfigMgr->LoadInitial(configFile)) { printf("Invalid or missing configuration file : %s\n", configFile); printf("Verify that the file exists and has \'[authserver]\' written in the top of the file!\n"); return 1; } TC_LOG_INFO("server.authserver", "RageFire (authserver)", _FULLVERSION); TC_LOG_INFO("server.authserver", "RageFire 3.3.5a Emulator Authserver"); TC_LOG_INFO("server.authserver", "Using configuration file %s.", configFile); TC_LOG_WARN("server.authserver", "%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif TC_LOG_DEBUG("server.authserver", "RageFire: Max allowed open files is %d", ACE::max_handles()); // authserver PID file creation std::string pidFile = sConfigMgr->GetStringDefault("PidFile", ""); if (!pidFile.empty()) { if (uint32 pid = CreatePIDFile(pidFile)) TC_LOG_INFO("server.authserver", "RageFire: Daemon PID: %u\n", pid); else { TC_LOG_ERROR("server.authserver", "RageFire: Cannot create PID file %s.\n", pidFile.c_str()); return 1; } } // Initialize the database connection if (!StartDB()) return 1; // Get the list of realms for the server sRealmList->Initialize(sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList->size() == 0) { TC_LOG_ERROR("server.authserver", "RageFire: No valid realms specified."); return 1; } // Launch the listening network socket RealmAcceptor acceptor; int32 rmport = sConfigMgr->GetIntDefault("RealmServerPort", 3724); if (rmport < 0 || rmport > 0xFFFF) { TC_LOG_ERROR("server.authserver", "RageFire: Specified port out of allowed range (1-65535)"); return 1; } std::string bind_ip = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(uint16(rmport), bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { TC_LOG_ERROR("server.authserver", "RageFire: Auth server can not bind to %s:%d", bind_ip.c_str(), rmport); return 1; } // Initialize the signal handlers AuthServerSignalHandler SignalINT, SignalTERM; // Register authservers's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); ///- Handle affinity for multiple processors and process priority uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0); bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false); #ifdef _WIN32 // Windows { HANDLE hProcess = GetCurrentProcess(); if (affinity > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR currentAffinity = affinity & appAff; // remove non accessible processors if (!currentAffinity) TC_LOG_ERROR("server.authserver", "RageFire: Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff); else if (SetProcessAffinityMask(hProcess, currentAffinity)) TC_LOG_INFO("server.authserver", "RageFire: Using processors (bitmask, hex): %x", currentAffinity); else TC_LOG_ERROR("server.authserver", "RageFire: Can't set used processors (hex): %x", currentAffinity); } } if (highPriority) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) TC_LOG_INFO("server.authserver", "RageFire: authserver process priority class set to HIGH"); else TC_LOG_ERROR("server.authserver", "RageFire: Can't set authserver process priority class."); } } #elif __linux__ // Linux if (affinity > 0) { cpu_set_t mask; CPU_ZERO(&mask); for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i) if (affinity & (1 << i)) CPU_SET(i, &mask); if (sched_setaffinity(0, sizeof(mask), &mask)) TC_LOG_ERROR("server.authserver", "RageFire: Can't set used processors (hex): %x, error: %s", affinity, strerror(errno)); else { CPU_ZERO(&mask); sched_getaffinity(0, sizeof(mask), &mask); TC_LOG_INFO("server.authserver", "RageFire: Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask)); } } if (highPriority) { if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY)) TC_LOG_ERROR("server.authserver", "RageFire: Can't set authserver process priority class, error: %s", strerror(errno)); else TC_LOG_INFO("server.authserver", "RageFire: authserver process priority class set to %i", getpriority(PRIO_PROCESS, 0)); } #endif // maximum counter for next ping uint32 numLoops = (sConfigMgr->GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ((++loopCounter) == numLoops) { loopCounter = 0; TC_LOG_INFO("server.authserver", "RageFire: Ping MySQL to keep connection alive"); LoginDatabase.KeepAlive(); } } // Close the Database Pool and library StopDB(); TC_LOG_INFO("server.authserver", "RageFire: Halting process..."); return 0; }
int main(int argc, char* argv[]) { struct item *list; int workingset_size = 1024; int i, j; struct list_head head; struct list_head *pos; struct timespec start, end; uint64_t nsdiff; double avglat; uint64_t readsum = 0; int serial = 0; int repeat = DEFAULT_ITER; int cpuid = 0; struct sched_param param; cpu_set_t cmask; int num_processors; int opt, prio; /* * get command line options */ while ((opt = getopt(argc, argv, "m:sc:i:p:h")) != -1) { switch (opt) { case 'm': /* set memory size */ g_mem_size = 1024 * strtol(optarg, NULL, 0); break; case 's': /* set access type */ serial = 1; break; case 'c': /* set CPU affinity */ cpuid = strtol(optarg, NULL, 0); num_processors = sysconf(_SC_NPROCESSORS_CONF); CPU_ZERO(&cmask); CPU_SET(cpuid % num_processors, &cmask); if (sched_setaffinity(0, num_processors, &cmask) < 0) perror("error"); else fprintf(stderr, "assigned to cpu %d\n", cpuid); break; case 'p': /* set priority */ prio = strtol(optarg, NULL, 0); if (setpriority(PRIO_PROCESS, 0, prio) < 0) perror("error"); else fprintf(stderr, "assigned priority %d\n", prio); break; case 'i': /* iterations */ repeat = strtol(optarg, NULL, 0); fprintf(stderr, "repeat=%d\n", repeat); break; case 'h': usage(argc, argv); break; } } workingset_size = g_mem_size / CACHE_LINE_SIZE; srand(0); #if 0 param.sched_priority = 1; /* 1(low) - 99(high) for SCHED_FIFO or SCHED_RR 0 for SCHED_OTHER or SCHED_BATCH */ if(sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) { perror("sched_setscheduler failed"); } #endif INIT_LIST_HEAD(&head); /* allocate */ list = (struct item *)malloc(sizeof(struct item) * workingset_size + CACHE_LINE_SIZE); for (i = 0; i < workingset_size; i++) { list[i].data = i; list[i].in_use = 0; INIT_LIST_HEAD(&list[i].list); // printf("%d 0x%x\n", list[i].data, &list[i].data); } printf("allocated: wokingsetsize=%d entries\n", workingset_size); /* initialize */ int *perm = (int *)malloc(workingset_size * sizeof(int)); for (i = 0; i < workingset_size; i++) perm[i] = i; if (!serial) { for (i = 0; i < workingset_size; i++) { int tmp = perm[i]; int next = rand() % workingset_size; perm[i] = perm[next]; perm[next] = tmp; } } for (i = 0; i < workingset_size; i++) { list_add(&list[perm[i]].list, &head); // printf("%d\n", perm[i]); } fprintf(stderr, "initialized.\n"); /* actual access */ clock_gettime(CLOCK_REALTIME, &start); for (j = 0; j < repeat; j++) { pos = (&head)->next; for (i = 0; i < workingset_size; i++) { struct item *tmp = list_entry(pos, struct item, list); readsum += tmp->data; // READ pos = pos->next; // printf("%d ", tmp->data, &tmp->data); } } clock_gettime(CLOCK_REALTIME, &end); nsdiff = get_elapsed(&start, &end); avglat = (double)nsdiff/workingset_size/repeat; printf("duration %.0f us\naverage %.2f ns | ", (double)nsdiff/1000, avglat); printf("bandwidth %.2f MB (%.2f MiB)/s\n", (double)64*1000/avglat, (double)64*1000000000/avglat/1024/1024); printf("readsum %lld\n", (unsigned long long)readsum); }
// worker进程,cachemanager进程和cacheloader进程的初始化函数 static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker) { sigset_t set; uint64_t cpu_affinity; ngx_int_t n; ngx_uint_t i; struct rlimit rlmt; ngx_core_conf_t *ccf; ngx_listening_t *ls; if (ngx_set_environment(cycle, NULL) == NULL) { /* fatal */ exit(2); } ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); // 设置worker进程的nice值,cachemanager cacheloader进程不会设置 if (worker >= 0 && ccf->priority != 0) { if (setpriority(PRIO_PROCESS, 0, ccf->priority) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setpriority(%d) failed", ccf->priority); } } // 设置进程最多可以打开的fd数量 if (ccf->rlimit_nofile != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile; rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile; if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_NOFILE, %i) failed", ccf->rlimit_nofile); } } // 设置这个进程独立于系统的coredump属性 if (ccf->rlimit_core != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_core; rlmt.rlim_max = (rlim_t) ccf->rlimit_core; if (setrlimit(RLIMIT_CORE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_CORE, %O) failed", ccf->rlimit_core); } } #ifdef RLIMIT_SIGPENDING if (ccf->rlimit_sigpending != NGX_CONF_UNSET) { rlmt.rlim_cur = (rlim_t) ccf->rlimit_sigpending; rlmt.rlim_max = (rlim_t) ccf->rlimit_sigpending; if (setrlimit(RLIMIT_SIGPENDING, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "setrlimit(RLIMIT_SIGPENDING, %i) failed", ccf->rlimit_sigpending); } } #endif // 如果设置了user指令,而且使用root权限启动会在这里改变进程所属的用户和组 if (geteuid() == 0) { if (setgid(ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setgid(%d) failed", ccf->group); /* fatal */ exit(2); } if (initgroups(ccf->username, ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "initgroups(%s, %d) failed", ccf->username, ccf->group); } if (setuid(ccf->user) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setuid(%d) failed", ccf->user); /* fatal */ exit(2); } } if (worker >= 0) { // 获取这个worker对应的CPU号 cpu_affinity = ngx_get_cpu_affinity(worker); // 绑定这个worker对应的CPU。 if (cpu_affinity) { ngx_setaffinity(cpu_affinity, cycle->log); } } #if (NGX_HAVE_PR_SET_DUMPABLE) /* allow coredump after setuid() in Linux 2.4.x */ if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "prctl(PR_SET_DUMPABLE) failed"); } #endif // 设置工作目录 if (ccf->working_directory.len) { if (chdir((char *) ccf->working_directory.data) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "chdir(\"%s\") failed", ccf->working_directory.data); /* fatal */ exit(2); } } sigemptyset(&set); // 把父进程设置为阻塞的信号重新设置为可接收状态。 if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigprocmask() failed"); } // 设置随机数种子。 srandom((ngx_pid << 16) ^ ngx_time()); /* * disable deleting previous events for the listening sockets because * in the worker processes there are no events at all at this point */ ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { ls[i].previous = NULL; } // 调用每个模块的init_process函数 for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->init_process) { if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { /* fatal */ exit(2); } } } // 关闭其他子进程与maser进程通信的unix套接字 for (n = 0; n < ngx_last_process; n++) { if (ngx_processes[n].pid == -1) { continue; } if (n == ngx_process_slot) { continue; } if (ngx_processes[n].channel[1] == -1) { continue; } if (close(ngx_processes[n].channel[1]) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "close() channel failed"); } } // 关闭unix套接字对的父进程端套接字 if (close(ngx_processes[ngx_process_slot].channel[0]) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "close() channel failed"); } #if 0 ngx_last_process = 0; #endif // 将这个进程接收父进程消息套接字的接收事件放到事件模型中, // 并将回调函数设置为ngx_channel_handler if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT, ngx_channel_handler) == NGX_ERROR) { /* fatal */ exit(2); } }
static void server (int fd, const char* prio) { int ret; char buffer[MAX_BUF + 1]; gnutls_session_t session; gnutls_certificate_credentials_t x509_cred; const char* err; struct timespec start, stop; static unsigned long measurement; setpriority(PRIO_PROCESS, getpid(), -15); /* this must be called once in the program */ global_init (); memset(buffer, 0, sizeof(buffer)); #ifdef DEBUG gnutls_global_set_log_function (server_log_func); gnutls_global_set_log_level (6); #endif gnutls_certificate_allocate_credentials (&x509_cred); ret = gnutls_certificate_set_x509_key_mem (x509_cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "Could not set certificate\n"); return; } #ifdef REHANDSHAKE restart: #endif gnutls_init (&session, GNUTLS_SERVER); /* avoid calling all the priority functions, since the defaults * are adequate. */ if ((ret=gnutls_priority_set_direct (session, prio, &err)) < 0) { fprintf(stderr, "Error in priority string %s: %s\n", gnutls_strerror(ret), err); return; } gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd); do { ret = gnutls_handshake (session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { #ifdef GNUTLS_E_PREMATURE_TERMINATION if (ret != GNUTLS_E_PREMATURE_TERMINATION && ret != GNUTLS_E_UNEXPECTED_PACKET_LENGTH) #else if (ret != GNUTLS_E_UNEXPECTED_PACKET_LENGTH) #endif { fprintf( stderr, "server: Handshake has failed (%s)\n\n", gnutls_strerror (ret)); } goto finish; } #ifndef REHANDSHAKE restart: #endif clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); do { ret = gnutls_record_recv (session, buffer, sizeof (buffer)); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop); if (ret == GNUTLS_E_DECRYPTION_FAILED) { gnutls_session_force_valid(session); measurement = timespec_sub_ns(&stop, &start); do { ret = gnutls_record_send(session, &measurement, sizeof(measurement)); /* GNUTLS_AL_FATAL, GNUTLS_A_BAD_RECORD_MAC); */ } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); #ifdef REHANDSHAKE gnutls_deinit(session); #endif if (ret >= 0) goto restart; } else if (ret < 0) fprintf(stderr, "err: %s\n", gnutls_strerror(ret)); /* do not wait for the peer to close the connection. */ gnutls_bye (session, GNUTLS_SHUT_WR); finish: close (fd); gnutls_deinit (session); gnutls_certificate_free_credentials (x509_cred); gnutls_global_deinit (); }
static void client (int fd, const char* prio, unsigned int text_size, struct test_st *test) { int ret; char buffer[MAX_BUF + 1]; char text[text_size]; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; struct timespec start, stop; static unsigned long taken = 0; static unsigned long measurement; const char* err; global_init (); setpriority(PRIO_PROCESS, getpid(), -15); memset(text, 0, text_size); #ifdef DEBUG gnutls_global_set_log_function (client_log_func); gnutls_global_set_log_level (6); #endif gnutls_certificate_allocate_credentials (&x509_cred); #ifdef REHANDSHAKE restart: #endif /* Initialize TLS session */ gnutls_init (&session, GNUTLS_CLIENT); gnutls_session_set_ptr(session, test); cli_session = session; /* Use default priorities */ if ((ret=gnutls_priority_set_direct (session, prio, &err)) < 0) { fprintf(stderr, "Error in priority string %s: %s\n", gnutls_strerror(ret), err); exit(1); } /* put the anonymous credentials to the current session */ gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd); /* Perform the TLS handshake */ do { ret = gnutls_handshake (session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { fprintf (stderr, "client: Handshake failed\n"); gnutls_perror (ret); exit(1); } ret = gnutls_protocol_get_version(session); if (ret < GNUTLS_TLS1_1) { fprintf (stderr, "client: Handshake didn't negotiate TLS 1.1 (or later)\n"); exit(1); } gnutls_transport_set_push_function (session, push_crippled); #ifndef REHANDSHAKE restart: #endif do { ret = gnutls_record_send (session, text, sizeof(text)); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); /* measure peer's processing time */ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); #define TLS_RECV #ifdef TLS_RECV do { ret = gnutls_record_recv(session, buffer, sizeof(buffer)); } while(ret < 0 && (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)); #else do { ret = recv(fd, buffer, sizeof(buffer), 0); } while(ret == -1 && errno == EAGAIN); #endif if (taken < MAX_MEASUREMENTS(test->npoints) && ret > 0) { clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop); taken++; measurement = timespec_sub_ns(&stop, &start); prev_point_ptr->measurements[prev_point_ptr->midx] = measurement; /*fprintf(stderr, "(%u,%u): %lu\n", (unsigned) prev_point_ptr->byte1, (unsigned) prev_point_ptr->byte2, measurements[taken]);*/ memcpy(&measurement, buffer, sizeof(measurement)); prev_point_ptr->smeasurements[prev_point_ptr->midx] = measurement; prev_point_ptr->midx++; /* read server's measurement */ #ifdef REHANDSHAKE gnutls_deinit(session); #endif goto restart; } #ifndef TLS_RECV else if (ret < 0) { fprintf(stderr, "Error in recv()\n"); exit(1); } #endif gnutls_transport_set_push_function (session, push); gnutls_bye (session, GNUTLS_SHUT_WR); { double avg2, med, savg, smed; unsigned i; FILE* fp = NULL; if (test->file) fp = fopen(test->file, "w"); if (fp) /* point, avg, median */ fprintf(fp, "Delta,TimeAvg,TimeMedian,ServerAvg,ServerMedian\n"); for (i=0;i<test->npoints;i++) { qsort( test->points[i].measurements, test->points[i].midx, sizeof(test->points[i].measurements[0]), compar); qsort( test->points[i].smeasurements, test->points[i].midx, sizeof(test->points[i].smeasurements[0]), compar); avg2 = calc_avg( test->points[i].measurements, test->points[i].midx); /*var = calc_var( test->points[i].measurements, test->points[i].midx, avg2);*/ med = calc_median( test->points[i].measurements, test->points[i].midx); savg = calc_avg( test->points[i].smeasurements, test->points[i].midx); /*var = calc_var( test->points[i].measurements, test->points[i].midx, avg2);*/ smed = calc_median( test->points[i].smeasurements, test->points[i].midx); /*min = calc_min( test->points[i].measurements, test->points[i].midx);*/ if (fp) /* point, avg, median */ fprintf(fp, "%u,%.2lf,%.2lf,%.2lf,%.2lf\n", (unsigned)test->points[i].byte1, avg2,med,savg, smed); /*printf("(%u) Avg: %.3f nanosec, Median: %.3f, Variance: %.3f\n", (unsigned)test->points[i].byte1, avg2, med, var);*/ } if (fp) fclose(fp); } if (test->desc) fprintf(stderr, "Description: %s\n", test->desc); close (fd); gnutls_deinit (session); gnutls_certificate_free_credentials (x509_cred); gnutls_global_deinit (); }