Esempio n. 1
0
procbuf *procbuf::open(const char *command, int mode)
{
    int read_or_write;
    if (is_open())
	return NULL;
    int pipe_fds[2];
    int parent_end, child_end;
    if (::pipe(pipe_fds) < 0)
	return NULL;
    if (mode == ios::in) {
	parent_end = pipe_fds[0];
	child_end = pipe_fds[1];
	read_or_write = _S_NO_WRITES;
    }
    else {
	parent_end = pipe_fds[1];
	child_end = pipe_fds[0];
	read_or_write = _S_NO_READS;
    }
    _pid = FORK();
    if (_pid == 0) {
	::close(parent_end);
	int child_std_end = mode == ios::in ? 1 : 0;
	if (child_end != child_std_end) {
	    ::dup2(child_end, child_std_end);
	    ::close(child_end);
	}
	::execl("/bin/sh", "sh", "-c", command, NULL);
	::_exit(127);
    }
    ::close(child_end);
    if (_pid < 0) {
	::close(parent_end);
	return NULL;
    }
    _fb._fileno = parent_end;
    xsetflags(read_or_write, _S_NO_READS|_S_NO_WRITES);
    return this;
}
Esempio n. 2
0
int gtm_pipe(char *command, pipe_type pt)
{
	int 	pfd[2], child, parent;
	int	dup2_res, rc;
	pid_t	child_pid;

	parent = (int)pt;
	child  = 1 - parent;
	if (0 > pipe(pfd))
	{
		PERROR("pipe : ");
		return -2;
	}
	FORK(child_pid);	/* BYPASSOK: we exit immediately, no FORK_CLEAN needed */
	if (-1 == child_pid)
	{
		PERROR("fork : ");
		return -1;
	} else if (0 == child_pid)
	{	/* child process */
		CLOSEFILE_RESET(pfd[parent], rc);	/* resets "pfd[parent]" to FD_INVALID */
		DUP2(pfd[child], child, dup2_res);
		CLOSEFILE_RESET(pfd[child], rc);	/* resets "pfd[child]" to FD_INVALID */
		/* We should have used exec instead of SYSTEM. Earlier it was followed by exit(EXIT_SUCCESS), which calls
		 * exit_handler.  So both child and parent will do exit handling. This can make ref_cnt < 0, or, it can release
		 * semaphores, which we should not release until parent exists. So we just call _exit(EXIT_SUCCESS).  Add the do
		 * nothing if to keep compiler happy since exiting anyway.
		 */
		rc = SYSTEM(command);
		_exit(EXIT_SUCCESS); /* just exit from here */
	} else
	{	/* parent process */
		pipe_child = child_pid;
		CLOSEFILE_RESET(pfd[child], rc);	/* resets "pfd[child]" to FD_INVALID */
   		return pfd[parent];
	}
}
Esempio n. 3
0
/*
x+y+z = A
xyz = B
xx+yy+zz = C

a=A-x
b=B/x
c=C-xx
=>
yz=b => (a-z)z=b => zz-az+b=0 Solve for z:
 Discriminant "bb-4ac" = aa-4b
 Roots: "-b+-sqrt(d) / 2a" => z = a+-sqrt(d)/2

 Elimination: if x < 0 then equation 2 => y or z < 0. Since A>0 and y and z < 100, x >= -98 :S
 */
int main() {
  int A, B, C, solve[3], ret[3];
  FORCAS {
    ret[0] = ret[1] = ret[2] = 100;
    cin >> A >> B >> C;
    for(int x = -99; x <= 99; ++x) {
      if(x == 0 || B%x != 0)
	continue;
      int a = A-x;
      int b = B/x;
      // Find z:
      int d = a*a-4*b; // bb-4ac
      if(d < 0)
	continue; // no root
      for(int mult = -1; mult <= 1; mult +=2) {
	int z = (a+mult*(int)(0.00000000001+sqrt(d)))/2;
	int y = A-x-z;
	if(x+y+z == A && x*y*z == B && x*x+y*y+z*z == C && x != y && x != z && y != z) {
	  solve[0] = x;
	  solve[1] = y;
	  solve[2] = z;
	  sort(solve, solve+3);
	  if(solve[0] < ret[0] || (solve[0] == ret[0] && solve[1] < ret[1])) {
	    FORK(3)
	      ret[k] = solve[k];
	  }
	}
      } // for mult
    } // for x
    if(ret[0] == 100)
      cout << "No solution." << endl;
    else
      cout << ret[0] << " " << ret[1] << " " << ret[2] << endl;
  } // FORCAS
  return 0;
}
void test1sub(){

Widget labelw_msg;
int status;
pid_t pid2;

	FORK(pid2);
	avs_xt_hier("Tchcksbcls1", "XtCheckSubclass");
	tet_infoline("PREP: Install error message handler");
	XtAppSetErrorMsgHandler(app_ctext, &XtEM_Proc);
        tet_infoline("PREP: Create test label widget");
        labelw_msg = (Widget) CreateLabelWidget("Test", boxw1);
        tet_infoline("PREP: Create windows for widgets and map them");
        XtRealizeWidget(topLevel);
	tet_infoline("TEST: Error message is generated for non-subclass widget");
	XtCheckSubclass(labelw_msg, commandWidgetClass, "ApTest");
	KROF(pid2);
	status = avs_get_event(1);
	if (status != 1) {
		tet_infoline("ERROR: Error message handler was not called");
		tet_result(TET_FAIL);
	}
	tet_result(TET_PASS);
}
BOOL StartWndDescriber(CWnd* p,CWnd* pT, CStringArray* aDescriptions)
{
	COptWinds* pParams=new COptWinds(p,pT,aDescriptions);
	FORK(ShowOptHelp,pParams);
	return TRUE;
}
Esempio n. 6
0
int CALLBACK OptionsDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if(uMsg==WM_INITDIALOG){
		iBegin=0;
		iBegin2=0;
		hDiag=hwndDlg;
		bAutoDelRight=0;
		if(GetKeyState(VK_CONTROL)<0){
			bReplaceMode=1;
		}
		::SetWindowText(GetDlgItem(hwndDlg,IDC_STATUS),CString(" ")+_l("Preparing for search"));
		::SetWindowText(GetDlgItem(hwndDlg,IDC_IMGL_DEL),_l("Delete this image"));
		::SetWindowText(GetDlgItem(hwndDlg,IDC_IMGR_DEL),_l("Delete this image"));
		::SetWindowText(GetDlgItem(hwndDlg,IDC_IMGR_DEL_ALL),_l("Auto"));
		::SetWindowText(GetDlgItem(hwndDlg,IDC_LI_ST),_l("No image, please wait"));
		::SetWindowText(GetDlgItem(hwndDlg,IDC_RI_ST),_l("No image, please wait"));
		if(bReplaceMode){
			::SetWindowText(GetDlgItem(hwndDlg,ID_NEXT),"Stop renamer");
		}else{
			::SetWindowText(GetDlgItem(hwndDlg,ID_NEXT),_l("Stop processing"));
		}
		::SetWindowText(hwndDlg,_l("Search for duplicated images"));
		::EnableWindow(GetDlgItem(hwndDlg,IDC_IMGR_DEL_ALL),FALSE);
		::EnableWindow(GetDlgItem(hwndDlg,IDC_IMGL_DEL),FALSE);
		::EnableWindow(GetDlgItem(hwndDlg,IDC_IMGR_DEL),FALSE);
		SetTaskbarButton(hwndDlg);
		//::EnableWindow(GetDlgItem(hwndDlg,ID_NEXT),FALSE);
	}
	if(uMsg==WM_KEYDOWN){
		if(GetKeyState(VK_CONTROL)<0){
			if(wParam==VK_RETURN){
				uMsg=WM_COMMAND;
				wParam=IDOK;
			}
		}
	}
	if(bStopCheck==0){
		if(uMsg==WM_COMMAND && wParam==WM_USER){
			// Выбираем у кого разрешение ниже...
			CString sPath;
			if(dwPathInRightRes<dwPathInLeftRes){
				uMsg=WM_COMMAND;
				wParam=IDC_IMGR_DEL;
			}else{
				uMsg=WM_COMMAND;
				wParam=IDC_IMGL_DEL;
			}
		}
		if(uMsg==WM_COMMAND && wParam==IDC_IMGL_DEL){
			if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_IMGL_DEL))){
				if(sPathInLeft!=""){
					sListOfImagesToDelete.Add(sPathInLeft);
				}
			}
			sPathInLeft="";
			sPathInRight="";
			uMsg=WM_COMMAND;
			wParam=ID_NEXT;
		}
		if(uMsg==WM_COMMAND && wParam==IDC_IMGR_DEL){
			if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_IMGR_DEL))){
				if(sPathInRight!=""){
					sListOfImagesToDelete.Add(sPathInRight);
				}
			}
			sPathInLeft="";
			sPathInRight="";
			uMsg=WM_COMMAND;
			wParam=ID_NEXT;
		}
		if(uMsg==WM_COMMAND && wParam==IDC_IMGR_DEL_ALL){
			if(bAutoDelRight || AfxMessageBox(_l("Delete duplicated images automatically")+"?",MB_YESNO|MB_ICONQUESTION)==IDYES){
				bAutoDelRight=1-bAutoDelRight;
				if(bAutoDelRight){
					::SetWindowText(GetDlgItem(hwndDlg,IDC_IMGR_DEL_ALL),_l("Stop"));
					PostMessage(hwndDlg,WM_COMMAND,WM_USER,0);
				}else{
					::SetWindowText(GetDlgItem(hwndDlg,IDC_IMGR_DEL_ALL),_l("Auto"));
				}
			}
		}
		if(uMsg==WM_COMMAND && wParam==ID_NEXT){
			if(iMode==0){
				bStopLoad=1;
			}else if(bStopCheck==0){
				iBegin2++;
				::EnableWindow(GetDlgItem(hwndDlg,IDC_IMGL_DEL),FALSE);
				::EnableWindow(GetDlgItem(hwndDlg,IDC_IMGR_DEL),FALSE);
				::EnableWindow(GetDlgItem(hwndDlg,ID_NEXT),FALSE);
				FORK(ContinueCheck,hwndDlg);
			}
		}
	}
	if(uMsg==WM_PAINT){
		PAINTSTRUCT lpPaint;
		memset(&lpPaint,0,sizeof(lpPaint));
		HDC dcH=BeginPaint(hwndDlg,&lpPaint);
		CDC dc;
		dc.Attach(lpPaint.hdc);
		dc.SetStretchBltMode(HALFTONE);
		//DefWindowProc(
		if(sPathInLeft!=""){
			if(btLeft){
				CRect rt,rtw;
				::GetClientRect(GetDlgItem(hwndDlg,IDC_IMGL),&rt);
				::GetWindowRect(GetDlgItem(hwndDlg,IDC_IMGL),&rtw);
				CPoint ptLT(rtw.left,rtw.top);
				ScreenToClient(hwndDlg,&ptLT);
				CDC dc2;
				CDesktopDC dcDesk;
				dc2.CreateCompatibleDC(&dcDesk);
				CBitmap* bmpTmp=dc2.SelectObject(btLeft);
				FitImageToRect(rt,szLeftSize);
				dc.StretchBlt(ptLT.x+rt.left,ptLT.y+rt.top,rt.Width(),rt.Height(),&dc2,0,0,szLeftSize.cx,szLeftSize.cy,SRCCOPY);
				dc2.SelectObject(bmpTmp);
			}
		}
		if(sPathInRight!=""){
			if(btRight){
				CRect rt,rtw;
				::GetClientRect(GetDlgItem(hwndDlg,IDC_IMGR),&rt);
				::GetWindowRect(GetDlgItem(hwndDlg,IDC_IMGR),&rtw);
				CPoint ptLT(rtw.left,rtw.top);
				ScreenToClient(hwndDlg,&ptLT);
				CDC dc2;
				CDesktopDC dcDesk;
				dc2.CreateCompatibleDC(&dcDesk);
				CBitmap* bmpTmp=dc2.SelectObject(btRight);
				FitImageToRect(rt,szLeftSize);
				dc.StretchBlt(ptLT.x+rt.left,ptLT.y+rt.top,rt.Width(),rt.Height(),&dc2,0,0,szRightSize.cx,szRightSize.cy,SRCCOPY);
				dc2.SelectObject(bmpTmp);
			}
		}
		dc.Detach();
		EndPaint(hwndDlg,&lpPaint);
		return TRUE;
	}
	if(uMsg==WM_SYSCOMMAND && wParam==SC_CLOSE){
		uMsg=WM_COMMAND;
		wParam=IDOK;
	}
	if(uMsg==WM_COMMAND && wParam==IDOK){
		bStopCheck=1;
		csCheck.Lock();
		csCheck.Unlock();
		if(sListOfImagesToDelete.GetSize()>0){
			if(dwDeleteOptions){
				if(AfxMessageBox(Format("%s. %s: %i\n%s?",_l("Search for duplicated images: finished"),_l("Image(s) found"),sListOfImagesToDelete.GetSize(),_l("Do you really want to delete image(s)")),MB_YESNO|MB_ICONQUESTION)==IDYES){
					for(int i=0;i<sListOfImagesToDelete.GetSize();i++){
						char szPath[MAX_PATH+2]="";
						memset(&szPath,0,sizeof(szPath));
						strcpy(szPath,sListOfImagesToDelete[i]);
						if(isFileExist(szPath)){
							SHFILEOPSTRUCT str;
							memset(&str,0,sizeof(str));
							str.hwnd=hwndDlg;
							str.wFunc=FO_DELETE;
							str.pFrom=szPath;
							str.pTo=NULL;
							str.fFlags=FOF_ALLOWUNDO|FOF_NOCONFIRMATION|FOF_SILENT;
							SHFileOperation(&str);
							lDeletedFiles++;
						}
					}
				}
			}else{
				lDeletedFiles+=sListOfImagesToDelete.GetSize();
			}
		}
		if(bReplaceMode){
			CString sDump;
			int ik=0;
			for(ik=0;ik<aClosestImage.GetSize();ik++){
				sDump+=Format("%i -> %i, %i %s\n",ik,aClosestImage[ik],aClosestImageTaken[ik],sListOfImages[ik]);
				aClosestImageTaken[ik]=0;
			}
			int iCnt=0;
			int iJumper=-1;
			CStringArray aFrom;
			CStringArray aFromTo;
			while(1){
				if(iJumper==-1){
					// Ищем первую картинку
					for(ik=0;ik<aClosestImage.GetSize();ik++){
						if(aClosestImageTaken[ik]==0){
							iJumper=ik;
							break;
						}
					}
				}
				if(iJumper==-1){
					// Не нашли!!
					break;
				}
				aClosestImageTaken[iJumper]=1;// Чтобы не циклится
				int iNext=aClosestImage[iJumper];
				if(iNext==-1 || aClosestImageTaken[iNext]!=0){
					iJumper=-1;
					continue;
				}
				CString sFrom=sListOfImages[iJumper];
				CString sTo=Format("%s%05i_%s",GetPathPart(sFrom,1,1,0,0),iCnt+1,GetPathPart(sFrom,0,0,1,1));
				aFrom.SetAtGrow(iCnt,sFrom);
				aFromTo.SetAtGrow(iCnt,sTo);
				sDump+=Format("Jumping %i -> %i\n",iJumper,iNext);
				iJumper=iNext;
				iCnt++;
			}
			SaveFile("f:\\rename.txt",sDump);
			for(int i=0;i<aFrom.GetSize();i++)
			{
				if(isFileExist(aFrom[i])){
					SHFILEOPSTRUCT str;
					memset(&str,0,sizeof(str));
					str.hwnd=hwndDlg;
					str.wFunc=FO_RENAME;
					
					char szPath[MAX_PATH+2]="";
					memset(&szPath,0,sizeof(szPath));
					strcpy(szPath,aFrom[i]);
					str.pFrom=szPath;
					
					char szPath2[MAX_PATH+2]="";
					memset(&szPath2,0,sizeof(szPath2));
					strcpy(szPath2,aFromTo[i]);
					str.pTo=szPath2;
					str.fFlags=FOF_NOCONFIRMATION|FOF_SILENT;
					SHFileOperation(&str);
				}
			}

		}
		EndDialog(hwndDlg,0);
		return TRUE;
	}
	if(uMsg==WM_NCDESTROY){
		SetEvent(hStopEvent);
	}
	return FALSE;
}
Esempio n. 7
0
int
tftpd_main (int argc, char **argv)
{
  int result;
  char *address = NULL;		/* address to listen to */
  int port = 69;
  int daemonize = 1;            // brcm (1 == 0);

#if 0 //brcm  
  int on = 1;
  int fd = 0;
  int opt;  
  char directory[256];		/* default directory "/tftpboot/" */
  memset (directory, 0, sizeof (directory));
  strcpy (directory, "/tftpboot/");

  while ((opt = getopt (argc, argv, "sp:a:d:h")) != -1)
    {
      switch (opt)
	{
	case 'p':
	  port = atoi (optarg);
	  break;
	case 'a':
	  address = optarg;
	  break;
	case 's':
	  daemonize = (1 == 1);
	  break;
	case 'd':
	  safe_strncpy (directory, optarg, sizeof (directory));
	  break;
	case 'h':
	  show_usage ();
	  break;
	}
    }
  if (chdir (directory))
    perror_msg_and_die ("Invalid Directory");

  if (ioctl (fd, FIONBIO, &on) < 0)
    perror_msg_and_die ("ioctl(FIONBIO)");
#endif //brcm

  /* daemonize this process */
  if (daemonize)
    {
      pid_t f = FORK ();
      if (f > 0) {
// brcm save the pid in the file for kill.
        FILE *pid_fp;
        if (!(pid_fp = fopen("/var/run/tftpd_pid", "w"))) 
        {
            printf("Error open /var/run/tftpd_pid");
            exit(0);
        }
        fprintf(pid_fp, "%d\n", f);
        fclose(pid_fp);
    	exit (0);
      }
      if (f < 0)
    	perror_msg_and_die ("cannot fork");
#if 0 //brcm
      close (0);
      close (1);
      close (2);
#endif //brcm
    }
  result = tftpd_daemon ("", address, port);
  return (result);
}
Esempio n. 8
0
int
os_daemonize(int argc, char **argv, const char *extra_arg)
{
     pid_t pid;

     /*
      *  The default is to ignore SIGCHLD signals.  However, unless
      *  this call is *explicitly* made, child processes will become
      *  zombies ("defunct") when they exit.
      */
     if (!did_ignore)
     {
	  did_ignore = 1;
	  signal(SIGCHLD, SIG_IGN);
     }

     if ((pid = FORK()) < 0)
	  return(-1);
     else if (pid)
	  /*
	   *  Parent goes bye-bye
	   */
	  _EXIT(0);

     /*
      *  Daemon child continues
      */
#if !defined(__MUST_EXEC)
     return(0);
#else
     {
	  char **argv2;
	  int i, istat;

	  /*
	   *  Need to do an exec*() call
	   */

	  /*
	   *  Build a new argument list which contains an extra argument
	   */
	  argv2 = (char **)malloc(sizeof(char *) * (argc + 2));
	  if (!argv2)
	       return(-1);

	  /*
	   *  Copy the original argument list
	   */
	  for (i = 0; i < argc; i++)
	       argv2[i] = (char *)argv[i];

	  /*
	   *  Add in the extra argument
	   */
	  argv2[argc] = (char *)extra_arg;

	  /*
	   *  And terminate the list
	   */
	  argv2[argc+1] = NULL;

	  /*
	   *  And exec ourself
	   */
	  istat = execve(argv[0], argv2, environ);
	  if (istat != -1)
	       _EXIT(0);

	  /*
	   *  If we're here, there's been an error-o-la
	   */
	  {
	       int save_errno = errno;
	       free(argv2);
	       errno = save_errno;
	       return(-1);
	  }
     }
#endif
}
Esempio n. 9
0
/* Execute LINE as a shell command, returning its status.  */
static int
do_system (const char *line)
{
  int status, save;
  pid_t pid;
  struct sigaction sa;
  sigset_t omask;

  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = SIG_IGN;
  /*sa.sa_flags = 0; - done by memset */
  /*__sigemptyset (&sa.sa_mask); - done by memset */

  DO_LOCK ();
  if (ADD_REF () == 0)
    {
      if (sigaction (SIGINT, &sa, &intr) < 0)
	{
	  SUB_REF ();
	  goto out;
	}
      if (sigaction (SIGQUIT, &sa, &quit) < 0)
	{
	  save = errno;
	  SUB_REF ();
	  goto out_restore_sigint;
	}
    }
  DO_UNLOCK ();

  /* We reuse the bitmap in the 'sa' structure.  */
  __sigaddset (&sa.sa_mask, SIGCHLD);
  save = errno;
  if (sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0)
    {
	{
	  DO_LOCK ();
	  if (SUB_REF () == 0)
	    {
	      save = errno;
	      (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
	    out_restore_sigint:
	      (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL);
	      __set_errno (save);
	    }
	out:
	  DO_UNLOCK ();
	  return -1;
	}
    }

  CLEANUP_HANDLER;

  pid = FORK ();
  if (pid == (pid_t) 0)
    {
      /* Child side.  */
      const char *new_argv[4];
      new_argv[0] = "/bin/sh";
      new_argv[1] = "-c";
      new_argv[2] = line;
      new_argv[3] = NULL;

      /* Restore the signals.  */
      (void) sigaction (SIGINT, &intr, (struct sigaction *) NULL);
      (void) sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
      (void) sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
      INIT_LOCK ();

      /* Exec the shell.  */
      (void) execve ("/bin/sh", (char *const *) new_argv, __environ);
      _exit (127);
    }
  else if (pid < (pid_t) 0)
    /* The fork failed.  */
    status = -1;
  else
    /* Parent side.  */
    {
      /* Note the system() is a cancellation point.  But since we call
	 waitpid() which itself is a cancellation point we do not
	 have to do anything here.  */
      if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
	status = -1;
    }

  CLEANUP_RESET;

  save = errno;
  DO_LOCK ();
  if ((SUB_REF () == 0
       && (sigaction (SIGINT, &intr, (struct sigaction *) NULL)
	   | sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0)
      || sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0)
    {
	status = -1;
    }
  DO_UNLOCK ();

  return status;
}
Esempio n. 10
0
int gtmsource()
{
	int			status, log_init_status, waitpid_res, save_errno;
	char			print_msg[1024], tmpmsg[1024];
	gd_region		*reg, *region_top;
	sgmnt_addrs		*csa, *repl_csa;
	boolean_t		all_files_open, isalive;
	pid_t			pid, ppid, procgp;
	seq_num			read_jnl_seqno, jnl_seqno;
	unix_db_info		*udi;
	gtmsource_local_ptr_t	gtmsource_local;
	boolean_t		this_side_std_null_coll;
	int			null_fd, rc;

	memset((uchar_ptr_t)&jnlpool, 0, SIZEOF(jnlpool_addrs));
	call_on_signal = gtmsource_sigstop;
	ESTABLISH_RET(gtmsource_ch, SS_NORMAL);
	if (-1 == gtmsource_get_opt())
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MUPCLIERR);
	if (gtmsource_options.shut_down)
	{	/* Wait till shutdown time nears even before going to "jnlpool_init". This is because the latter will return
		 * with the ftok semaphore and access semaphore held and we do not want to be holding those locks (while
		 * waiting for the user specified timeout to expire) as that will affect new GTM processes and/or other
		 * MUPIP REPLIC commands that need these locks for their function.
		 */
		if (0 < gtmsource_options.shutdown_time)
		{
			repl_log(stdout, TRUE, TRUE, "Waiting for %d seconds before signalling shutdown\n",
												gtmsource_options.shutdown_time);
			LONG_SLEEP(gtmsource_options.shutdown_time);
		} else
			repl_log(stdout, TRUE, TRUE, "Signalling shutdown immediate\n");
	} else if (gtmsource_options.start)
	{
		repl_log(stdout, TRUE, TRUE, "Initiating START of source server for secondary instance [%s]\n",
			gtmsource_options.secondary_instname);
	}
	if (gtmsource_options.activate && (ROOTPRIMARY_SPECIFIED == gtmsource_options.rootprimary))
	{	/* MUPIP REPLIC -SOURCE -ACTIVATE -UPDOK has been specified. We need to open the gld and db regions now
		 * in case this is a secondary -> primary transition. This is so we can later switch journal files in all
		 * journaled regions when the transition actually happens inside "gtmsource_rootprimary_init". But since
		 * we have not yet done a "jnlpool_init", we dont know if updates are disabled in it or not. Although we
		 * need to do the gld/db open only if updates are currently disabled in the jnlpool, we do this always
		 * because once we do a jnlpool_init, we will come back with the ftok on the jnlpool held and that has
		 * issues with later db open since we will try to hold the db ftok as part of db open and the ftok logic
		 * currently has assumptions that a process holds only one ftok at any point in time.
		 */
		assert(NULL == gd_header);
		gvinit();
		all_files_open = region_init(FALSE);
		if (!all_files_open)
		{
			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOTALLDBOPN);
			gtmsource_exit(ABNORMAL_SHUTDOWN);
		}
	}
	jnlpool_init(GTMSOURCE, gtmsource_options.start, &is_jnlpool_creator);
	/* is_jnlpool_creator == TRUE ==> this process created the journal pool
	 * is_jnlpool_creator == FALSE ==> journal pool already existed and this process simply attached to it.
	 */
	if (gtmsource_options.shut_down)
		gtmsource_exit(gtmsource_shutdown(FALSE, NORMAL_SHUTDOWN) - NORMAL_SHUTDOWN);
	else if (gtmsource_options.activate)
		gtmsource_exit(gtmsource_mode_change(GTMSOURCE_MODE_ACTIVE_REQUESTED) - NORMAL_SHUTDOWN);
	else if (gtmsource_options.deactivate)
		gtmsource_exit(gtmsource_mode_change(GTMSOURCE_MODE_PASSIVE_REQUESTED) - NORMAL_SHUTDOWN);
	else if (gtmsource_options.checkhealth)
		gtmsource_exit(gtmsource_checkhealth() - NORMAL_SHUTDOWN);
	else if (gtmsource_options.changelog)
		 gtmsource_exit(gtmsource_changelog() - NORMAL_SHUTDOWN);
	else if (gtmsource_options.showbacklog)
		gtmsource_exit(gtmsource_showbacklog() - NORMAL_SHUTDOWN);
	else if (gtmsource_options.stopsourcefilter)
		gtmsource_exit(gtmsource_stopfilter() - NORMAL_SHUTDOWN);
	else if (gtmsource_options.jnlpool)
		gtmsource_exit(gtmsource_jnlpool() - NORMAL_SHUTDOWN);
	else if (gtmsource_options.losttncomplete)
		gtmsource_exit(gtmsource_losttncomplete() - NORMAL_SHUTDOWN);
	else if (gtmsource_options.needrestart)
		gtmsource_exit(gtmsource_needrestart() - NORMAL_SHUTDOWN);
	else if (gtmsource_options.showfreeze)
		gtmsource_exit(gtmsource_showfreeze() - NORMAL_SHUTDOWN);
	else if (gtmsource_options.setfreeze)
		gtmsource_exit(gtmsource_setfreeze() - NORMAL_SHUTDOWN);
	else if (!gtmsource_options.start)
	{
		assert(CLI_PRESENT == cli_present("STATSLOG"));
		gtmsource_exit(gtmsource_statslog() - NORMAL_SHUTDOWN);
	}
	assert(gtmsource_options.start);
#	ifndef REPL_DEBUG_NOBACKGROUND
	/* Set "child_server_running" to FALSE before forking off child. Wait for it to be set to TRUE by the child. */
	gtmsource_local = jnlpool.gtmsource_local;
	gtmsource_local->child_server_running = FALSE;
	FORK(pid);
	if (0 > pid)
	{
		save_errno = errno;
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_JNLPOOLSETUP, 0,
			ERR_TEXT, 2, RTS_ERROR_LITERAL("Could not fork source server"), save_errno);
	} else if (0 < pid)
	{	/* Parent. Wait until child sets "child_server_running" to FALSE. That is an indication that the child
		 * source server has completed its initialization phase and is all set so the parent command can return.
		 */
		while (isalive = is_proc_alive(pid, 0))	/* note : intended assignment */
		{
			if (gtmsource_local->child_server_running)
				break;
			/* To take care of reassignment of PIDs, the while condition should be && with the condition
			 * (PPID of pid == process_id)
			 */
			SHORT_SLEEP(GTMSOURCE_WAIT_FOR_SRV_START);
			WAITPID(pid, &status, WNOHANG, waitpid_res); /* Release defunct child if dead */
		}
		if (isalive)
		{	/* Child process is alive and started with no issues */
			if (0 != (save_errno = rel_sem(SOURCE, JNL_POOL_ACCESS_SEM)))
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_JNLPOOLSETUP, 0,
					ERR_TEXT, 2, RTS_ERROR_LITERAL("Error in rel_sem"), save_errno);
			ftok_sem_release(jnlpool.jnlpool_dummy_reg, TRUE, TRUE);
		} else
		{	/* Child source server process errored out at startup and is no longer alive.
			 * If we were the one who created the journal pool, let us clean it up.
			 */
			repl_log(stdout, TRUE, TRUE, "Source server startup failed. See source server log file\n");
			if (is_jnlpool_creator)
				status = gtmsource_shutdown(TRUE, NORMAL_SHUTDOWN);
		}
		/* If the parent is killed (or crashes) between the fork and exit, checkhealth may not detect that startup
		 * is in progress - parent forks and dies, the system will release sem 0 and 1, checkhealth might test the
		 * value of sem 1 before the child grabs sem 1.
		 */
		gtmsource_exit(isalive ? SRV_ALIVE : SRV_ERR);
	}
	/* Point stdin to /dev/null */
	OPENFILE("/dev/null", O_RDONLY, null_fd);
	if (0 > null_fd)
		rts_error_csa(CSA_ARG(NULL) ERR_REPLERR, RTS_ERROR_LITERAL("Failed to open /dev/null for read"), errno, 0);
	FCNTL3(null_fd, F_DUPFD, 0, rc);
	if (0 > rc)
		rts_error_csa(CSA_ARG(NULL) ERR_REPLERR, RTS_ERROR_LITERAL("Failed to set stdin to /dev/null"), errno, 0);
	CLOSEFILE(null_fd, rc);
	if (0 > rc)
		rts_error_csa(CSA_ARG(NULL) ERR_REPLERR, RTS_ERROR_LITERAL("Failed to close /dev/null"), errno, 0);
	/* The parent process (source server startup command) will be holding the ftok semaphore and jnlpool access semaphore
	 * at this point. The variables that indicate this would have been copied over to the child during the fork. This will
	 * make the child think it is actually holding them as well when actually it is not. Reset those variables in the child
	 * to ensure they do not misrepresent the holder of those semaphores.
	 */
	ftok_sem_reg = NULL;
	udi = FILE_INFO(jnlpool.jnlpool_dummy_reg);
	assert(udi->grabbed_ftok_sem);
	udi->grabbed_ftok_sem = FALSE;
	assert(holds_sem[SOURCE][JNL_POOL_ACCESS_SEM]);
	holds_sem[SOURCE][JNL_POOL_ACCESS_SEM] = FALSE;
	assert(!holds_sem[SOURCE][SRC_SERV_COUNT_SEM]);
	/* Start child source server initialization */
	is_src_server = TRUE;
	OPERATOR_LOG_MSG;
	process_id = getpid();
	/* Reinvoke secshr related initialization with the child's pid */
	INVOKE_INIT_SECSHR_ADDRS;
	/* Initialize mutex socket, memory semaphore etc. before any "grab_lock" is done by this process on the journal pool.
	 * Note that the initialization would already have been done by the parent receiver startup command but we need to
	 * redo the initialization with the child process id.
	 */
	assert(mutex_per_process_init_pid && (mutex_per_process_init_pid != process_id));
	mutex_per_process_init();
	START_HEARTBEAT_IF_NEEDED;
	ppid = getppid();
	log_init_status = repl_log_init(REPL_GENERAL_LOG, &gtmsource_log_fd, gtmsource_options.log_file);
	assert(SS_NORMAL == log_init_status);
	repl_log_fd2fp(&gtmsource_log_fp, gtmsource_log_fd);
	if (-1 == (procgp = setsid()))
		send_msg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_JNLPOOLSETUP, 0, ERR_TEXT, 2,
				RTS_ERROR_LITERAL("Source server error in setsid"), errno);
#	endif /* REPL_DEBUG_NOBACKGROUND */
	if (ZLIB_CMPLVL_NONE != gtm_zlib_cmp_level)
		gtm_zlib_init();	/* Open zlib shared library for compression/decompression */
	REPL_DPRINT1("Setting up regions\n");
	gvinit();

	/* We use the same code dse uses to open all regions but we must make sure they are all open before proceeding. */
	all_files_open = region_init(FALSE);
	if (!all_files_open)
	{
		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOTALLDBOPN);
		gtmsource_exit(ABNORMAL_SHUTDOWN);
	}
	/* Determine primary side null subscripts collation order */
	/* Also check whether all regions have same null collation order */
	this_side_std_null_coll = -1;
	for (reg = gd_header->regions, region_top = gd_header->regions + gd_header->n_regions; reg < region_top; reg++)
	{
		csa = &FILE_INFO(reg)->s_addrs;
		if (this_side_std_null_coll != csa->hdr->std_null_coll)
		{
			if (-1 == this_side_std_null_coll)
				this_side_std_null_coll = csa->hdr->std_null_coll;
			else
			{
				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NULLCOLLDIFF);
				gtmsource_exit(ABNORMAL_SHUTDOWN);
			}
		}
		if (!REPL_ALLOWED(csa) && JNL_ALLOWED(csa))
		{
			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_REPLOFFJNLON, 2, DB_LEN_STR(reg));
			gtmsource_exit(ABNORMAL_SHUTDOWN);
		}
		if (reg->read_only && REPL_ALLOWED(csa))
		{
			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_JNLPOOLSETUP, 0, ERR_TEXT, 2,
				   RTS_ERROR_LITERAL("Source Server does not have write permissions to one or "
					             "more database files that are replicated"));
			gtmsource_exit(ABNORMAL_SHUTDOWN);
		}
	}
	/* Initialize source server alive/dead state related fields in "gtmsource_local" before the ftok semaphore is released */
	gtmsource_local->gtmsource_pid = process_id;
	gtmsource_local->gtmsource_state = GTMSOURCE_START;
	if (is_jnlpool_creator)
	{
		DEBUG_ONLY(jnlpool.jnlpool_ctl->jnlpool_creator_pid = process_id);
		gtmsource_seqno_init(this_side_std_null_coll);
		if (ROOTPRIMARY_SPECIFIED == gtmsource_options.rootprimary)
		{	/* Created the journal pool as a root primary. Append a history record to the replication instance file.
			 * Invoke the function "gtmsource_rootprimary_init" to do that.
			 */
			gtmsource_rootprimary_init(jnlpool.jnlpool_ctl->jnl_seqno);
		}
	}
	/* after this point we can no longer have the case where all the regions are unreplicated/non-journaled. */
#	ifndef REPL_DEBUG_NOBACKGROUND
	/* It is necessary for every process that is using the ftok semaphore to increment the counter by 1. This is used
	 * by the last process that shuts down to delete the ftok semaphore when it notices the counter to be 0.
	 * Note that the parent source server startup command would have done an increment of the ftok counter semaphore
	 * for the replication instance file. But the source server process (the child) that comes here would not have done
	 * that. Do that while the parent is still holding on to the ftok semaphore waiting for our okay.
	 */
	if (!ftok_sem_incrcnt(jnlpool.jnlpool_dummy_reg))
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_JNLPOOLSETUP);
	/* Increment the source server count semaphore */
	status = incr_sem(SOURCE, SRC_SERV_COUNT_SEM);
	if (0 != status)
	{
		save_errno = errno;
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_JNLPOOLSETUP, 0, ERR_TEXT, 2,
			RTS_ERROR_LITERAL("Counter semaphore increment failure in child source server"), save_errno);
	}
#	else
	if (0 != (save_errno = rel_sem_immediate(SOURCE, JNL_POOL_ACCESS_SEM)))
	{
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_JNLPOOLSETUP, 0, ERR_TEXT, 2,
			RTS_ERROR_LITERAL("Error in rel_sem_immediate"), save_errno);
	}
#	endif /* REPL_DEBUG_NOBACKGROUND */

	gtmsource_srv_count++;
	gtmsource_local->child_server_running = TRUE;	/* At this point, the parent startup command will stop waiting for child */
	gtm_event_log_init();
	/* Log source server startup command line first */
	SPRINTF(tmpmsg, "%s %s\n", cli_lex_in_ptr->argv[0], cli_lex_in_ptr->in_str);
	repl_log(gtmsource_log_fp, TRUE, TRUE, tmpmsg);

	SPRINTF(tmpmsg, "GTM Replication Source Server with Pid [%d] started for Secondary Instance [%s]",
		process_id, gtmsource_local->secondary_instname);
	sgtm_putmsg(print_msg, VARLSTCNT(4) ERR_REPLINFO, 2, LEN_AND_STR(tmpmsg));
	repl_log(gtmsource_log_fp, TRUE, TRUE, print_msg);
	if (is_jnlpool_creator)
	{
		repl_log(gtmsource_log_fp, TRUE, TRUE, "Created jnlpool with shmid = [%d] and semid = [%d]\n",
			jnlpool.repl_inst_filehdr->jnlpool_shmid, jnlpool.repl_inst_filehdr->jnlpool_semid);
	} else
		repl_log(gtmsource_log_fp, TRUE, TRUE, "Attached to existing jnlpool with shmid = [%d] and semid = [%d]\n",
			jnlpool.repl_inst_filehdr->jnlpool_shmid, jnlpool.repl_inst_filehdr->jnlpool_semid);
	gtm_event_log(GTM_EVENT_LOG_ARGC, "MUPIP", "REPLINFO", print_msg);
#	ifdef GTM_TLS
	if (REPL_TLS_REQUESTED)
	{
		repl_do_tls_init(gtmsource_log_fp);
		assert(REPL_TLS_REQUESTED || PLAINTEXT_FALLBACK);
	}
#	endif
	if (jnlpool.jnlpool_ctl->freeze)
	{
		last_seen_freeze_flag = jnlpool.jnlpool_ctl->freeze;
		sgtm_putmsg(print_msg, VARLSTCNT(3) ERR_REPLINSTFROZEN, 1, jnlpool.repl_inst_filehdr->inst_info.this_instname);
		repl_log(gtmsource_log_fp, TRUE, FALSE, print_msg);
		sgtm_putmsg(print_msg, VARLSTCNT(3) ERR_REPLINSTFREEZECOMMENT, 1, jnlpool.jnlpool_ctl->freeze_comment);
		repl_log(gtmsource_log_fp, TRUE, TRUE, print_msg);
	}
	gtmsource_local->jnlfileonly = gtmsource_options.jnlfileonly;
	do
	{ 	/* If mode is passive, go to sleep. Wakeup every now and then and check to see if I have to become active. */
		gtmsource_state = gtmsource_local->gtmsource_state = GTMSOURCE_START;
		if ((gtmsource_local->mode == GTMSOURCE_MODE_PASSIVE) && (gtmsource_local->shutdown == NO_SHUTDOWN))
		{
			gtmsource_poll_actions(FALSE);
			SHORT_SLEEP(GTMSOURCE_WAIT_FOR_MODE_CHANGE);
			continue;
		}
		if (GTMSOURCE_MODE_PASSIVE == gtmsource_local->mode)
		{	/* Shutdown initiated */
			assert(gtmsource_local->shutdown == SHUTDOWN);
			sgtm_putmsg(print_msg, VARLSTCNT(4) ERR_REPLINFO, 2,
				    RTS_ERROR_LITERAL("GTM Replication Source Server Shutdown signalled"));
			repl_log(gtmsource_log_fp, TRUE, TRUE, print_msg);
			gtm_event_log(GTM_EVENT_LOG_ARGC, "MUPIP", "REPLINFO", print_msg);
			break;
		}
		gtmsource_poll_actions(FALSE);
		if (GTMSOURCE_CHANGING_MODE == gtmsource_state)
			continue;
		if (GTMSOURCE_MODE_ACTIVE_REQUESTED == gtmsource_local->mode)
			gtmsource_local->mode = GTMSOURCE_MODE_ACTIVE;
		SPRINTF(tmpmsg, "GTM Replication Source Server now in ACTIVE mode using port %d", gtmsource_local->secondary_port);
		sgtm_putmsg(print_msg, VARLSTCNT(4) ERR_REPLINFO, 2, LEN_AND_STR(tmpmsg));
		repl_log(gtmsource_log_fp, TRUE, TRUE, print_msg);
		gtm_event_log(GTM_EVENT_LOG_ARGC, "MUPIP", "REPLINFO", print_msg);
		DEBUG_ONLY(repl_csa = &FILE_INFO(jnlpool.jnlpool_dummy_reg)->s_addrs;)
		assert(!repl_csa->hold_onto_crit);	/* so it is ok to invoke "grab_lock" and "rel_lock" unconditionally */
		grab_lock(jnlpool.jnlpool_dummy_reg, TRUE, HANDLE_CONCUR_ONLINE_ROLLBACK);
		if (GTMSOURCE_HANDLE_ONLN_RLBK == gtmsource_state)
		{
			repl_log(gtmsource_log_fp, TRUE, TRUE, "Starting afresh due to ONLINE ROLLBACK\n");
			repl_log(gtmsource_log_fp, TRUE, TRUE, "REPL INFO - Current Jnlpool Seqno : %llu\n",
					jnlpool.jnlpool_ctl->jnl_seqno);
			continue;
		}
		QWASSIGN(gtmsource_local->read_addr, jnlpool.jnlpool_ctl->write_addr);
		gtmsource_local->read = jnlpool.jnlpool_ctl->write;
		gtmsource_local->read_state = gtmsource_local->jnlfileonly ? READ_FILE : READ_POOL;
		read_jnl_seqno = gtmsource_local->read_jnl_seqno;
		assert(read_jnl_seqno <= jnlpool.jnlpool_ctl->jnl_seqno);
		if (read_jnl_seqno < jnlpool.jnlpool_ctl->jnl_seqno)
		{
			gtmsource_local->read_state = READ_FILE;
			QWASSIGN(gtmsource_save_read_jnl_seqno, jnlpool.jnlpool_ctl->jnl_seqno);
			gtmsource_pool2file_transition = TRUE; /* so that we read the latest gener jnl files */
		}
		rel_lock(jnlpool.jnlpool_dummy_reg);
		if (SS_NORMAL != (status = gtmsource_alloc_tcombuff()))
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_REPLCOMM, 0, ERR_TEXT, 2,
				  RTS_ERROR_LITERAL("Error allocating initial tcom buffer space. Malloc error"), status);
		gtmsource_filter = NO_FILTER;
		if ('\0' != gtmsource_local->filter_cmd[0])
		{
			if (SS_NORMAL == (status = repl_filter_init(gtmsource_local->filter_cmd)))
				gtmsource_filter |= EXTERNAL_FILTER;
			else
				gtmsource_exit(ABNORMAL_SHUTDOWN);
		}
		gtmsource_process();
		/* gtmsource_process returns only when mode needs to be changed to PASSIVE */
		assert(gtmsource_state == GTMSOURCE_CHANGING_MODE);
		gtmsource_ctl_close();
		gtmsource_free_msgbuff();
		gtmsource_free_tcombuff();
		gtmsource_free_filter_buff();
		gtmsource_stop_heartbeat();
		if (FD_INVALID != gtmsource_sock_fd)
			repl_close(&gtmsource_sock_fd);
		if (gtmsource_filter & EXTERNAL_FILTER)
			repl_stop_filter();
	} while (TRUE);
Esempio n. 11
0
/**
 * This is the mane entry point of the program
 * 
 * @param   argc  The number of elements in `argv`
 * @parma   argv  Command line arguments, including the command
 * @return        Exit value, zero on success
 */
int main(int argc, char** argv)
{
  struct winsize win;
  struct termios saved_stty;
  struct termios stty;
  size_t i, ndevices = 0;
  pid_t pid = 0;
  char* set = NULL;
  int j, get = 0, help = 0, all = 0, cols = 80;
  char** devices = alloca((size_t)argc * sizeof(char*));
  
  
  if (argc > 1)
    {
      char* arg;
      for (i = 1; i < (size_t)argc; i++)
	{
	  #define T(S)  (!strcmp(arg, S))
	  arg = *(argv + i);
	  if (T("-h") || T("--help"))
	    help = 1;
	  else if (T("-a") || T("--all"))
	    all = 1;
	  else if (T("-c") || T("--copyright") || T("--copying"))
	    {
	      P("\n");
	      P("adjbacklight – Convenient method for adjusting the backlight on your portable computer");
	      P("");
	      P("Copyright © " _YEARS_ "  Mattias Andrée ([email protected])");
	      P("");
	      P("This program is free software: you can redistribute it and/or modify");
	      P("it under the terms of the GNU General Public License as published by");
	      P("the Free Software Foundation, either version 3 of the License, or");
	      P("(at your option) any later version.");
	      P("");
	      P("This program is distributed in the hope that it will be useful,");
	      P("but WITHOUT ANY WARRANTY; without even the implied warranty of");
	      P("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the");
	      P("GNU General Public License for more details.");
	      P("");
	      P("You should have received a copy of the GNU General Public License");
	      P("along with this program.  If not, see <http://www.gnu.org/licenses/>.");
	      P("\n");
	      return 0;
	    }
	  else if (T("-w") || T("--warranty"))
	    {
	      P("\n");
	      P("This program is distributed in the hope that it will be useful,");
	      P("but WITHOUT ANY WARRANTY; without even the implied warranty of");
	      P("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the");
	      P("GNU General Public License for more details.");
	      P("\n");
	      return 0;
	    }
	  else if (T("-s") || T("--set"))
	    {
	      char* tmp;
	      if (i + 1 == (size_t)argc)
		fprintf(stderr, "%s: argument for option %s is missing, ignoring option\n", *argv, arg);
	      else
		if (!isnumerical(tmp = *(argv + ++i)))
		  fprintf(stderr, "%s: argument for option %s is malformated, ignoring option\n", *argv, arg);
		else
		  {
		    set = tmp;
		    get = 0;
		  }
	    }
	  else if (T("-g") || T("--get"))
	    {
	      get = 1;
	      set = NULL;
	    }
	  else if (((*arg == '-') || (*arg == '+') || (*arg == '=')) && isnumerical(arg + 1))
	    {
	      set = arg;
	      get = 0;
	    }
	  else
	    {
	      if (*arg && (*arg != '-'))
		*(devices + ndevices++) = arg;
	      else
		fprintf(stderr, "%s: ignoring unrecognised argument: %s\n", *argv, arg);
	    }
	  #undef T
	}
      fflush(stderr);
      if (help || (((size_t)all + ndevices + (size_t)get == 0) && !set))
	{
	  P("\n");
	  P("adjbacklight - Convenient method for adjusting the backlight on your portable computer");
	  P("");
	  P("USAGE: adjbacklight (-c | -w | [-g | -s LEVEL | LEVEL] [-a | DEVICE...])");
	  P("");
	  P("Run with options to adjust the backlight on your monitors.");
	  P("");
	  P("");
	  P("OPTIONS:");
	  P("");
	  P("-c");
	  P("--copyright");
	  P("--copying       Display copyright information");
	  P("");
	  P("-w");
	  P("--warranty      Display warranty disclaimer");
	  P("");
	  P("-a");
	  P("--all           Run for all devices, including ACPI devices");
	  P("");
	  P("-g");
	  P("--get           Get average brightness on devices");
	  P("");
	  P("-s");
	  P("--set LEVEL[%]  Set brightness on devices");
	  P("");
	  P("+LEVEL          Increase brightness on devices by actual value");
	  P("-LEVEL          Decrease brightness on devices by actual value");
	  P("=LEVEL          Set brightness on devices by actual value");
	  P("");
	  P("+LEVEL%         Increase brightness on devices by percentage-points");
	  P("-LEVEL%         Decrease brightness on devices by percentage-points");
	  P("=LEVEL%         Set brightness on devices by percentage-points");
	  P("");
	  P("+LEVEL%%        Increase brightness on devices by percentage");
	  P("-LEVEL%%        Decrease brightness on devices by percentage");
	  P("=LEVEL%%        Set brightness on devices by percentage");
	  P("");
	  P("");
	  P("KEYBOARD:");
	  P("");
	  P("←");
	  P("↓               Darken the screen");
	  P("");
	  P("→");
	  P("↑               Brighten the screen");
	  P("");
	  P("q");
	  P("enter");
	  P("C-d             Continue to next controller, or if at last, quit");
	  P("");
	  P("");
	  P("");
	  P("Copyright © " _YEARS_ "  Mattias Andrée ([email protected])");
	  P("");
	  P("This program is free software: you can redistribute it and/or modify");
	  P("it under the terms of the GNU General Public License as published by");
	  P("the Free Software Foundation, either version 3 of the License, or");
	  P("(at your option) any later version.");
	  P("");
	  return 0;
	}
    }
  
  
  /* Check permissions */
  if (getuid()) /* Always accept root */
  {
    struct group* video_grp = getgrnam("video");
    if (video_grp) /* Accept everypony if the group ‘video’ does not exist */
      {
	struct passwd* realuser = getpwuid(getuid());
	char** mems;
	char* realname;
	int ok;
	if (!realuser)
	  {
	    P("You do not exist, go away!");
	    return 1;
	  }
	mems = video_grp->gr_mem;
	realname = realuser->pw_name;
	ok = 0;
	for (; *mems; mems++)
	  if (!strcmp(realname, *mems))
	    {
	      ok = 1;
	      break;
	    }
	endgrent();
	if (!ok)
	  {
	    P("Sorry, you need to be in the group 'video'.");
	    return 1;
	  }
      }
    endpwent();
  }
  
  
  if (!get && !set)
    {
      P("\n");
      P("If the program is abnormally aborted the may be some residual");
      P("effects on the terminal. the following commands should reset it:");
      P("");
      P("    stty icanon echo");
      P("    echo -en '\\e[?25h'");
      P("");
      P("\n\n\n");
    }
  
  
  if (!get && !set)
    {
      /* Get the size of the terminal */
      if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == -1)
	perror(*argv);
      else
	cols = win.ws_col;
      
      /* Hide cursor */
      printf("%s", "\033[?25l");
      fflush(stdout);
      
      /* stty -icanon -echo */
      if (tcgetattr(STDIN_FILENO, &stty))
	{
	  perror(*argv);
	  return 1;
	}
      saved_stty = stty;
      stty.c_lflag &= (tcflag_t)~(ICANON | ECHO);
      if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty))
	{
	  perror(*argv);
	  return 1;
	}
    }
  
  
  /* Fork to diminish risk of unclean exit */
  if (!get && !set)
    {
      pid = FORK();
      if (pid == (pid_t)-1)
	{
	  perror(*argv);
	  pid = 0;
	}
    }
  
  if (pid)
    waitpid(pid, NULL, 0);
  else
    {
      float brightness = 0;
      int nbrightness = 0;
      
      if (!get && !set)
	{
	  line = malloc((size_t)cols * 3 * sizeof(char));
	  space = malloc((size_t)cols * sizeof(char));
	  for (i = 0; i < (size_t)cols; i++)
	    {
	      *(line + i * 3 + 0) = (char)(0xE2);
	      *(line + i * 3 + 1) = (char)(0x94);
	      *(line + i * 3 + 2) = (char)(0x80);
	      *(space + i) = ' ';
	    }
	  *(space + cols - 1) = 0;
	  *(line + (cols - 2) * 3) = 0;
	}
      
      if (ndevices)
	{
	  char* device;
	  for (i = 0; i < ndevices; i++)
	    {
	      device = *(devices + i);
	      for (j = 0; *(device + j); j++)
		if (*(device + j) == '/')
		  {
		    device += j + 1;
		    j = -1;
		  }
	      if (get)
		{
		  float value = getbrightness(device);
		  if (value >= 0.f)
		    {
		      brightness += value;
		      nbrightness++;
		    }
		}
	      else if (set)
		setbrightness(device, set);
	      else
		adjust(cols, device);
	    }
	}
      else
	{
	  struct dirent* ent;
	  DIR* dir = opendir(BACKLIGHT_DIR);
	  if (dir)
	    {
	      char* device;
	      while ((ent = readdir(dir)))
		{
		  device = ent->d_name;
		  if (all || (strstr(device, "acpi_video") != device))
		    if (*device && (*device != '.'))
		      {
			if (get)
			  {
			    float value = getbrightness(device);
			    if (value >= 0.f)
			      {
				brightness += value;
				nbrightness++;
			      }
			  }
			else if (set)
			  setbrightness(device, set);
			else
			  adjust(cols, device);
		      }
		}
	      closedir(dir);
	    }
	}
      
      if (!get && !set)
	{
	  free(line);
	  free(space);
	}
      else if (get)
	{
	  if (nbrightness)
	    {
	      brightness *= 100.f;
	      brightness /= (float)nbrightness;
	      printf("%.2f%%\n", (double)brightness);
	      fflush(stdout);
	    }
	  else
	    {
	      printf("%s\n", "100.00%");
	      fflush(stdout);
	    }
	}
    }
  
  
  if (!get && !set)
    {
      /* `stty icanon echo` */
      if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty))
	{
	  perror(*argv);
	  return 1;
	}
      
      /* Show cursor */
      printf("%s", "\033[?25h");
      fflush(stdout);
    }
  
  return 0;
}
int
dbgsysExec(char *cmdLine)
{
    int i;
    int argc;
    pid_t pid_err = (pid_t)(-1); /* this is the error return value */
    pid_t pid;
    char **argv = NULL;
    char *p;
    char *args;

    /* Skip leading whitespace */
    cmdLine = skipWhitespace(cmdLine);

    /*LINTED*/
    args = jvmtiAllocate((jint)strlen(cmdLine)+1);
    if (args == NULL) {
        return SYS_NOMEM;
    }
    (void)strcpy(args, cmdLine);

    p = args;

    argc = 0;
    while (*p != '\0') {
        p = skipNonWhitespace(p);
        argc++;
        if (*p == '\0') {
            break;
        }
        p = skipWhitespace(p);
    }

    /*LINTED*/
    argv = jvmtiAllocate((argc + 1) * (jint)sizeof(char *));
    if (argv == 0) {
        jvmtiDeallocate(args);
        return SYS_NOMEM;
    }

    for (i = 0, p = args; i < argc; i++) {
        argv[i] = p;
        p = skipNonWhitespace(p);
        *p++ = '\0';
        p = skipWhitespace(p);
    }
    argv[i] = NULL;  /* NULL terminate */

    if ((pid = FORK()) == 0) {
        /* Child process */
        int i;
        long max_fd;

        /* close everything */
        max_fd = sysconf(_SC_OPEN_MAX);
        /*LINTED*/
        for (i = 3; i < (int)max_fd; i++) {
            (void)close(i);
        }

        (void)execvp(argv[0], argv);

        exit(-1);
    }
    jvmtiDeallocate(args);
    jvmtiDeallocate(argv);
    if (pid == pid_err) {
        return SYS_ERR;
    } else {
        return SYS_OK;
    }
}
Esempio n. 13
0
os_pid_t
os_spawn_nowait(const char *cmd, os_argv_t *argv, const char *new_env, ...)
{
     int istat;
     size_t len;
     pid_t pid;

     /*
      *  Sanity checks
      */
     if (!argv || !argv->argv[0] || !argv->argv[0][0] || !argv->argc)
     {
	  errno = EFAULT;
	  return((os_pid_t)-1);
     }

     if (!did_ignore)
     {
	  did_ignore = 1;
	  signal(SIGCHLD, SIG_IGN);
     }

     /*
      *  fork()  [fork1() on Solaris]
      */
     pid = FORK();
     if (pid < 0)
	  /*
	   *  Fork failed
	   */
	  return((os_pid_t)-1);
     else if (pid)
	  /*
	   *  We're the happy parent... return to our caller
	   */
	  return((os_pid_t)pid);

     /*
      *  We're the child
      */

     /*
      *  We'll just push the new environment variables into our
      *  copy of the environment
      */
     if (new_env)
     {
	  va_list ap;
	  char buf[4096];
	  size_t len1, len2;
	  const char *nam, *val;

	  va_start(ap, new_env);
	  nam = new_env;
	  while (nam)
	  {
	       val = va_arg(ap, const char *);
	       if (!val)
		    break;
	       len1 = strlen(nam);
	       len2 = strlen(val);
	       if ((len1 + len2 + 2) <= sizeof(buf))
	       {
		    char *p = buf;
		    memcpy(p, nam, len1);
		    p += len1;
		    *p++ = '=';
		    memcpy(p, val, len2+1);
	       }
	       putenv(buf);
	       nam = va_arg(ap, const char *);
	  }
	  va_end(ap);
     }

     /*
      *  Now exec
      */
     execv(argv->argv[0], argv->argv);

     /*
      *  Something bad happened if execution reaches this point
      */
     _EXIT(0);
}
Esempio n. 14
0
/* Execute LINE as a shell command, returning its status.  */
static int
do_system (const char *line)
{
  int status, save;
  pid_t pid;
  struct sigaction sa;
#ifndef _LIBC_REENTRANT
  struct sigaction intr, quit;
#endif
  sigset_t omask;

  sa.sa_handler = SIG_IGN;
  sa.sa_flags = 0;
  __sigemptyset (&sa.sa_mask);

  DO_LOCK ();
  if (ADD_REF () == 0)
    {
      if (__sigaction (SIGINT, &sa, &intr) < 0)
	{
	  (void) SUB_REF ();
	  goto out;
	}
      if (__sigaction (SIGQUIT, &sa, &quit) < 0)
	{
	  save = errno;
	  (void) SUB_REF ();
	  goto out_restore_sigint;
	}
    }
  DO_UNLOCK ();

  /* We reuse the bitmap in the 'sa' structure.  */
  __sigaddset (&sa.sa_mask, SIGCHLD);
  save = errno;
  if (__sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0)
    {
#ifndef _LIBC
      if (errno == ENOSYS)
	__set_errno (save);
      else
#endif
	{
	  DO_LOCK ();
	  if (SUB_REF () == 0)
	    {
	      save = errno;
	      (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
	    out_restore_sigint:
	      (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
	      __set_errno (save);
	    }
	out:
	  DO_UNLOCK ();
	  return -1;
	}
    }

#ifdef CLEANUP_HANDLER
  CLEANUP_HANDLER;
#endif

#ifdef FORK
  pid = FORK ();
#else
  pid = __fork ();
#endif
  if (pid == (pid_t) 0)
    {
      /* Child side.  */
      const char *new_argv[4];
      new_argv[0] = SHELL_NAME;
      new_argv[1] = "-c";
      new_argv[2] = line;
      new_argv[3] = NULL;

      /* Restore the signals.  */
      (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
      (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
      (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
      INIT_LOCK ();

      /* Exec the shell.  */
      (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ);
      _exit (127);
    }
  else if (pid < (pid_t) 0)
    /* The fork failed.  */
    status = -1;
  else
    /* Parent side.  */
    {
      /* Note the system() is a cancellation point.  But since we call
	 waitpid() which itself is a cancellation point we do not
	 have to do anything here.  */
      if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid)
	status = -1;
    }

#ifdef CLEANUP_HANDLER
  CLEANUP_RESET;
#endif

  save = errno;
  DO_LOCK ();
  if ((SUB_REF () == 0
       && (__sigaction (SIGINT, &intr, (struct sigaction *) NULL)
	   | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0)
      || __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0)
    {
#ifndef _LIBC
      /* glibc cannot be used on systems without waitpid.  */
      if (errno == ENOSYS)
	__set_errno (save);
      else
#endif
	status = -1;
    }
  DO_UNLOCK ();

  return status;
}
Esempio n. 15
0
static int
tftpd_daemon (char *directory, char *address, int port)
{
  struct tftphdr *tp;
  struct sockaddr_in from;
  struct sockaddr_in myaddr;
  struct sockaddr_in bindaddr;
  int fd = -1;
  int peer;
  int rv;
  int n;
  pid_t pid;
  int i = 1;

  char buf[TFTP_BLOCKSIZE_DEFAULT + 4];
  struct iovec iov = { buf, sizeof buf };
  struct cmsghdr *cmsg;
  char *ctrl = (char *)xmalloc(MAXCTRLSIZE);
  struct msghdr msg = { (void*)&from, sizeof from, &iov, 1, (void*)ctrl, MAXCTRLSIZE, 0};
  struct in_pktinfo *info = NULL;

   daemon(0,1);
  if ((fd = socket (PF_INET, SOCK_DGRAM, 0)) < 0)
    perror_msg_and_die ("socket");
  memset (&bindaddr, 0, sizeof (bindaddr));
  bindaddr.sin_family = AF_INET;
  bindaddr.sin_addr.s_addr = INADDR_ANY;
  bindaddr.sin_port = htons (port);
  if (address != NULL)
    {
      struct hostent *hostent;
      hostent = xgethostbyname (address);
      if (!hostent || hostent->h_addrtype != AF_INET)
	perror_msg_and_die ("cannot resolve local bind address");
      memcpy (&bindaddr.sin_addr, hostent->h_addr, hostent->h_length);
    }
  // set option for getting the to ip address.
  setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &i, sizeof(i));

  if (bind (fd, (struct sockaddr *) &bindaddr, sizeof (bindaddr)) < 0)
    perror_msg_and_die ("daemon bind failed");
  /* This means we don't want to wait() for children */
  signal (SIGCHLD, SIG_IGN);
  while (1)
    {
      fd_set readset;
      memset(buf,0,TFTP_BLOCKSIZE_DEFAULT + 4);
      memset (&myaddr, 0, sizeof (myaddr));
      FD_ZERO (&readset);
      FD_SET (fd, &readset);
      /* Never time out, we're in standalone mode */
      rv = select (fd + 1, &readset, NULL, NULL, NULL);
      if (rv == -1 && errno == EINTR)
	continue;		/* Signal caught, reloop */
      if (rv == -1)
	perror_msg_and_die ("select loop");
      if (rv == 0)
	{
	  bb_error_msg ("We shouldn't be timeing out!");
	  exit (0);		/* Timeout, return to inetd */
	}

      n = recvmsg (fd, &msg, MSG_WAITALL);
      if (n <= 0)
      {
          printf("*** error recvmsg n=%d\n", n);
          break;
      }
//printf("incoming_ip=%s, n=%d\n", inet_ntoa(from.sin_addr), n);
	for(cmsg=CMSG_FIRSTHDR(&msg); cmsg != NULL;cmsg =CMSG_NXTHDR(&msg,cmsg)) {
		if (cmsg->cmsg_type == IP_PKTINFO){
		    info = (struct in_pktinfo *)CMSG_DATA(cmsg);
//            printf("sepc_dst=%s, ipi_addr=%s\n", inet_ntoa(info->ipi_spec_dst),inet_ntoa(info->ipi_addr));
            break;
		}
    }
    free(ctrl);
  /* Process the request */
  myaddr.sin_family = AF_INET;
  myaddr.sin_port = htons (0);	/* we want a new local port */
  myaddr.sin_addr = getLanIp();

  if (myaddr.sin_addr.s_addr != info->ipi_spec_dst.s_addr)
    memcpy (&myaddr.sin_addr, &bindaddr.sin_addr,sizeof bindaddr.sin_addr);

      /* Now that we have read the request packet from the UDP
         socket, we fork and go back to listening to the socket. */
    pid = FORK ();
    if (pid < 0)
	    perror_msg_and_die ("cannot fork");
    if (pid == 0)
	    break;			/* Child exits the while(1), parent continues to loop */
    }

  /* Close file descriptors we don't need */
  // brcm close (fd);

  /* Get a socket.  This has to be done before the chroot() (/dev goes away) */
  peer = socket (AF_INET, SOCK_DGRAM, 0);
  if (peer < 0)
    perror_msg_and_die ("socket");
  if (chroot ("."))
    perror_msg_and_die ("chroot");
  from.sin_family = AF_INET;

  /* Process the request */
  if (bind (peer, (struct sockaddr *) &myaddr, sizeof myaddr) < 0)
    perror_msg_and_die ("daemon-child bind");

//printf("after bind. my_ip=%s*****\n", inet_ntoa(myaddr.sin_addr));

  if (connect (peer, (struct sockaddr *) &from, sizeof from) < 0)
    perror_msg_and_die ("daemon-child connect");
  tp = (struct tftphdr *) buf;

//printf("after connect \n");

  int accessMode = bcmCheckEnable("tftp", from.sin_addr);
//printf("accessmode = %d\n", accessMode);
  if (accessMode == CLI_ACCESS_DISABLED) 
  {
    close(peer);
    exit(0);
  }
  if (accessMode == CLI_ACCESS_REMOTE) 
  {
    glbIfName[0] = '\0';
    if ((bcmGetIntfNameSocket(peer, glbIfName) != 0) || glbIfName[0] == '\0') 
    {
      printf("Failed to get remote ifc name!\n");
      close(peer);
      exit(0);
    }
  }
//printf("socket ifname = %s\n", glbIfName);
  
  tp->th_opcode = ntohs (tp->th_opcode);

  switch(tp->th_opcode)
  {
  	case RRQ:
	    tftpd_send (peer, tp, n, TFTP_BLOCKSIZE_DEFAULT);
	    break;
	case WRQ:
	    tftpd_receive (peer, tp, n, TFTP_BLOCKSIZE_DEFAULT);
	    break;
  }
  exit (0);
}
Esempio n. 16
0
/* On OSF/1 (Digital Unix), pointers are 64 bits wide; the only exception to this is C programs for which one may
 * specify compiler and link editor options in order to use (and allocate) 32-bit pointers.  However, since C is
 * the only exception and, in particular because the operating system does not support such an exception, the argv
 * array passed to the main program is an array of 64-bit pointers.  Thus the C program needs to declare argv[]
 * as an array of 64-bit pointers and needs to do the same for any pointer it sets to an element of argv[].
 */
void gtcm_init(int argc, char_ptr_t argv[])
{
	char			*ptr;
	struct sigaction 	ignore, act;
	void			get_page_size();
	int		  	pid;
	char			msg[256];
	int			save_errno, maxfds;

	/*  Disassociate from the rest of the universe */
	get_page_size();
	gtm_wcswidth_fnptr = gtm_wcswidth;
#	ifndef GTCM_DEBUG_NOBACKGROUND
	FORK(pid);
	if (0 > pid)
	{
		save_errno = errno;
		SPRINTF(msg, "Unable to detach %s from controlling tty", SRVR_NAME);
		gtcm_rep_err(msg, save_errno);
		EXIT(-1);
	}
	else if (0 < pid)
		EXIT(0);
	(void) setpgrp();
#	endif
	/* Initialize logging */
	omi_pid = getpid();
	/*  Initialize signals */
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	ignore = act;
	ignore.sa_handler = SIG_IGN;
	act.sa_handler = (void (*)()) gtcm_term;
	(void) sigaction(SIGTERM, &act, 0);
	act.sa_handler = (void (*)()) gtcm_dmpstat;
	(void) sigaction(SIGUSR1, &act, 0);

	(void) sigaction(SIGUSR2, &ignore, 0);
	(void) sigaction(SIGALRM, &ignore, 0);
	(void) sigaction(SIGPIPE, &ignore, 0);
	(void) sigaction(SIGINT, &ignore, 0);
#	ifdef GTCM_RC
	act.sa_handler = gtcm_fail;
	act.sa_flags = SA_RESETHAND;
	/* restore signal handler to default action upon receipt
	   of signal */
	(void) sigaction(SIGSEGV, &act, 0);
	(void) sigaction(SIGBUS, &act, 0);
	(void) sigaction(SIGILL, &act, 0);
	(void) sigaction(SIGTRAP, &act, 0);
	(void) sigaction(SIGABRT, &act, 0);
#	ifndef __linux__
	(void) sigaction(SIGEMT, &act, 0);
	(void) sigaction(SIGSYS, &act, 0);
#	endif
#	endif
	/*  Initialize the process flags */
	if (0 != gtcm_prsopt(argc, argv))
		EXIT(-1);
	/* Write down pid into log file */
	 OMI_DBG((omi_debug, "GTCM_SERVER pid : %d\n", omi_pid));
	/* Initialize history mechanism */
	if (history)
	{
		init_hist();
		act.sa_handler = (void (*)())dump_rc_hist;
		act.sa_flags = 0;
		(void) sigaction(SIGUSR2, &act, 0);
	}
	/*  Initialize the DBMS */
	licensed = TRUE;
	getjobnum();
	getzdir();
	if ((maxfds = getmaxfds()) < 0)
	{
		gtcm_rep_err("Unable to get system resource limits", errno);
		EXIT(errno);
	}
	assert(SIZEOF(gtcm_ast_avail) == 2);	/* check that short is size 2 bytes as following code relies on that */
	gtcm_ast_avail = (maxfds > MAXINT2) ? MAXINT2 : maxfds;
	stp_init(STP_INITSIZE);
	rts_stringpool = stringpool;
	curr_pattern = pattern_list = &mumps_pattern;
	pattern_typemask = mumps_pattern.typemask;
	INVOKE_INIT_SECSHR_ADDRS;
	initialize_pattern_table();
	/* Preallocate some timer blocks. */
	prealloc_gt_timers();
	gt_timers_add_safe_hndlrs();
	/* Moved to omi_gvextnam, omi_lkextnam */
	/*    gvinit(); */
	return;
}
Esempio n. 17
0
static int helper_init(upd_helper_entry_ptr_t helper, recvpool_user helper_type)
{
	int			save_errno, save_shutdown;
	char			helper_cmd[UPDHELPER_CMD_MAXLEN];
	int			helper_cmd_len;
	int			status;
	int4			i4status;
	pid_t			helper_pid, waitpid_res;

	save_shutdown = helper->helper_shutdown;
	helper->helper_shutdown = NO_SHUTDOWN;
	if (!gtm_dist_ok_to_use)
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_GTMDISTUNVERIF, 4, STRLEN(gtm_dist), gtm_dist,
				gtmImageNames[image_type].imageNameLen, gtmImageNames[image_type].imageName);
	if (WBTEST_ENABLED(WBTEST_MAXGTMDIST_HELPER_PROCESS))
	{
		memset(gtm_dist, 'a', GTM_PATH_MAX-2);
		gtm_dist[GTM_PATH_MAX-1] = '\0';
	}
	helper_cmd_len = SNPRINTF(helper_cmd, UPDHELPER_CMD_MAXLEN, UPDHELPER_CMD, gtm_dist);
	if ((-1 == helper_cmd_len) || (UPDHELPER_CMD_MAXLEN <= helper_cmd_len))
	{
		helper->helper_shutdown = save_shutdown;
		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_HLPPROC, 0, ERR_TEXT, 2,
			   LEN_AND_LIT("Could not find path of Helper Process. Check value of $gtm_dist"));
		repl_errno = EREPL_UPDSTART_BADPATH;
		return UPDPROC_START_ERR ;
	}
	FORK(helper_pid);
	if (0 > helper_pid)
	{
		save_errno = errno;
		helper->helper_shutdown = save_shutdown;
		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_HLPPROC, 0, ERR_TEXT, 2,
				LEN_AND_LIT("Could not fork Helper process"), save_errno);
		repl_errno = EREPL_UPDSTART_FORK;
		return UPDPROC_START_ERR;
	}
	if (0 == helper_pid)
	{	/* helper */
		getjobnum();
		helper->helper_pid_prev = process_id; /* identify owner of slot */
		if (WBTEST_ENABLED(WBTEST_BADEXEC_HELPER_PROCESS))
			STRCPY(helper_cmd, "ersatz");
		if (-1 == EXECL(helper_cmd, helper_cmd, UPDHELPER_CMD_ARG1, UPDHELPER_CMD_ARG2,
				(UPD_HELPER_READER == helper_type) ? UPDHELPER_READER_CMD_ARG3 : UPDHELPER_WRITER_CMD_ARG3, NULL))
		{
			save_errno = errno;
			helper->helper_shutdown = save_shutdown;
			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(7) ERR_HLPPROC, 0, ERR_TEXT, 2,
				   LEN_AND_LIT("Could not exec Helper Process"), save_errno);
			repl_errno = EREPL_UPDSTART_EXEC;
			UNDERSCORE_EXIT(UPDPROC_START_ERR);
		}
	}
	/* Wait for helper to startup */
	while (helper_pid != helper->helper_pid && is_proc_alive(helper_pid, 0))
	{
		SHORT_SLEEP(GTMRECV_WAIT_FOR_SRV_START);
		UNIX_ONLY(WAITPID(helper_pid, &status, WNOHANG, waitpid_res);) /* Release defunct helper process if dead */
	}
	/* The helper has now gone far enough in the initialization, or died before initialization. Consider startup completed. */
	repl_log(gtmrecv_log_fp, TRUE, TRUE, "Helper %s started. PID %d [0x%X]\n",
			(UPD_HELPER_READER == helper_type) ? "reader" : "writer", helper_pid, helper_pid);
	return UPDPROC_STARTED;
}