Beispiel #1
0
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

}
Beispiel #2
0
void setToBackgroundPriority() {
  setpriority(PRIO_PGRP, 0, 10);
}
Beispiel #3
0
/*
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;

	}
}
Beispiel #4
0
/**
 * \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);
}
Beispiel #5
0
/*
 * 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);
}
Beispiel #6
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;
}
Beispiel #7
0
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);
}
Beispiel #8
0
/* 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;
}
Beispiel #9
0
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
}
Beispiel #10
0
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;
}
Beispiel #11
0
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

}
Beispiel #12
0
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);
}
Beispiel #13
0
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);

///////////////////

}
Beispiel #15
0
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 */

}
Beispiel #17
0
/* 工作进程初始化,
  * 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);
    }
}
Beispiel #19
0
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);
}
Beispiel #20
0
	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));
	}
Beispiel #22
0
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;
}
Beispiel #23
0
/* 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);
} /* }}} */
Beispiel #24
0
Datei: top.c Projekt: AnthraX1/rk
/*
 * 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;
}
Beispiel #25
0
Datei: top.c Projekt: AnthraX1/rk
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);
}
Beispiel #26
0
/// 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;
}
Beispiel #27
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, &param) == -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 ();
}
Beispiel #30
-1
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 ();
}