Exemple #1
0
void		msh_process_line(t_msh *msh, char *line)
{
	t_list	*atkn[1];
	t_list	*acmd[1];

	*atkn = NULL;
	msh_tokenize(msh, atkn, line);
	if (msh_catch_syntax_errors(msh, *atkn))
	{
		msh_free_structs(msh, atkn, NULL);
		return ;
	}
	*acmd = NULL;
	msh_split_cmd(msh, atkn, acmd);
	process_cmds(msh, acmd);
	msh_free_structs(msh, atkn, acmd);
	return ;
}
void
interactive_shell(void)
{
#define MAX_LINE_LEN 100
#define MAX_CMD_LEN 10
	trie_t trieObj;
	trie_t *trie = &trieObj;
	char cmd[MAX_CMD_LEN] = {0}, arg[MAX_LINE_LEN] = {0};

	trie_init(trie);

	while (1) {
		show_prompt("*Trie");
		if (getInputLine(cmd, arg, MAX_LINE_LEN) == EOF)
			break;

		if (process_cmds(trie, cmd, arg)) {
			/** Done processing at 'quit' command */
			break;
		}
	}
}
Exemple #3
0
int main(int argc, char *argv[], char *environ[])
{
	pid_t pid;
	int masterfd;
	struct winsize terminal_size;
	int i;
	terminal_size.ws_row = 80;
	terminal_size.ws_col = 25;
	terminal_size.ws_xpixel = 0;
	terminal_size.ws_ypixel = 0;

	pid = forkpty(&masterfd, NULL, NULL, &terminal_size);
	if (pid == 0) { /* child */
		char *args[] = {  "/bin/sh",  NULL };
		char *env[] = { NULL };
#if 0
		execve("/bin/bash", args, env);
#endif
#if 1
		process_cmds();
#endif
		_exit(1);
	}
	resync(masterfd);
#if 1
	for (i = 0; i < 10; i++) {
		usleep(100);
		kill(pid, SIGINT);
	}
#endif
#if 0
	usleep(1000);
#endif
	resync(masterfd);
	return 0;
}
Exemple #4
0
int WINAPI
WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)
{
	int success = 0;
	HANDLE helper = NULL;
	HMODULE hookdll = NULL;
	SYSTEM_INFO si;

	set_hooks_proc_t set_hooks_fn;
	remove_hooks_proc_t remove_hooks_fn;
	get_instance_count_proc_t instance_count_fn;

	int check_counter;

	if (strlen(cmdline) == 0) {
		message("No command line specified.");
		return -1;
	}

	if (vchannel_open()) {
		message("Unable to set up the virtual channel.");
		return -1;
	}


	GetSystemInfo(&si);
	switch (si.wProcessorArchitecture) {
	case PROCESSOR_ARCHITECTURE_INTEL:
		hookdll = LoadLibrary("seamlessrdp32.dll");
		break;
	case PROCESSOR_ARCHITECTURE_AMD64:
		hookdll = LoadLibrary("seamlessrdp64.dll");
		break;
	default:
		message("Unsupported processor architecture.");
		break;

	}

	if (!hookdll) {
		message("Could not load hook DLL. Unable to continue.");
		goto close_vchannel;
	}

	set_hooks_fn = (set_hooks_proc_t) GetProcAddress(hookdll, "SetHooks");
	remove_hooks_fn =
		(remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks");
	instance_count_fn =
		(get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount");
	g_move_window_fn =
		(move_window_proc_t) GetProcAddress(hookdll, "SafeMoveWindow");
	g_zchange_fn = (zchange_proc_t) GetProcAddress(hookdll, "SafeZChange");
	g_focus_fn = (focus_proc_t) GetProcAddress(hookdll, "SafeFocus");
	g_set_state_fn = (set_state_proc_t) GetProcAddress(hookdll, "SafeSetState");

	if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn
		|| !g_move_window_fn || !g_zchange_fn || !g_focus_fn
		|| !g_set_state_fn) {
		message
			("Hook DLL doesn't contain the correct functions. Unable to continue.");
		goto close_hookdll;
	}

	/* Check if the DLL is already loaded */
	switch (instance_count_fn()) {
	case 0:
		message("Hook DLL failed to initialize.");
		goto close_hookdll;
		break;
	case 1:
		break;
	default:
		message("Another running instance of Seamless RDP detected.");
		goto close_hookdll;
	}

	helper = launch_helper();

	ProcessIdToSessionId(GetCurrentProcessId(), &g_session_id);

	build_startup_procs();

	g_connected = is_connected();
	g_desktop_hidden = is_desktop_hidden();

	vchannel_write("HELLO", "0x%08x",
		g_desktop_hidden ? SEAMLESS_HELLO_HIDDEN : 0);

	set_hooks_fn();

	/* Since we don't see the entire desktop we must resize windows
	   immediatly. */
	SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);

	/* Disable screen saver since we cannot catch its windows. */
	SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);

	/* We don't want windows denying requests to activate windows. */
	SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, 0);

	if (!launch_app(cmdline)) {
		// CreateProcess failed.
		char msg[256];
		_snprintf(msg, sizeof(msg),
			"Unable to launch the requested application:\n%s", cmdline);
		message(msg);
		goto unhook;
	}

	check_counter = 5;
	while (check_counter-- || !should_terminate()) {
		BOOL connected;
		MSG msg;

		connected = is_connected();
		if (connected && !g_connected) {
			int flags;
			/* These get reset on each reconnect */
			SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
			SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
			SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, 0);

			flags = SEAMLESS_HELLO_RECONNECT;
			if (g_desktop_hidden)
				flags |= SEAMLESS_HELLO_HIDDEN;
			vchannel_write("HELLO", "0x%08x", flags);
		}

		g_connected = connected;

		if (check_counter < 0) {
			BOOL hidden;

			hidden = is_desktop_hidden();
			if (hidden && !g_desktop_hidden)
				vchannel_write("HIDE", "0x%08x", 0);
			else if (!hidden && g_desktop_hidden)
				vchannel_write("UNHIDE", "0x%08x", 0);

			g_desktop_hidden = hidden;

			check_counter = 5;
		}

		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		process_cmds();
		Sleep(100);
	}

	success = 1;

  unhook:
	remove_hooks_fn();

	free_startup_procs();
	if (helper) {
		// Terminate seamlessrdphook32.exe
		kill_15_9(helper, "SeamlessRDPHook", HELPER_TIMEOUT);
	}

  close_hookdll:
	FreeLibrary(hookdll);

  close_vchannel:
	vchannel_close();

	// Logoff the user. This is necessary because the session may
	// have started processes that are not included in Microsofts
	// list of processes to ignore. Typically ieuser.exe.
	// FIXME: Only do this if WTSQuerySessionInformation indicates
	// that we are the initial program. 
	ExitWindows(0, 0);

	if (success)
		return 1;
	else
		return -1;
}
Exemple #5
0
int main() {

	int l_socket_fd = -1;
	int c_socket_fd = -1;
	fd_set fds;

	l_socket_fd = android_get_control_socket(SOCKET_NAME);

	if (l_socket_fd < 0 ){
		ALOGE("Unable to open inputdevinfo_socket (%s)\n", strerror(errno));
		return -1;
	}

	if (make_nonblocking (l_socket_fd)) {
		ALOGE("Unable to modify inputdevinfo_socket flags. (%s)\n", strerror(errno));
	}

	if (listen (l_socket_fd, 0) < 0) {
		ALOGE("Unable to open inputdevinfo_socket (%s)\n", strerror(errno));
		return -1;
	}

	while(1){
		FD_ZERO(&fds);
		FD_SET(l_socket_fd, &fds);

		if (c_socket_fd >= 0 ) {
			// &&  fcntl(c_socket_fd, F_GETFD) >= 0 ? 
			FD_SET(c_socket_fd, &fds);
		}

		int retval = select(get_max(c_socket_fd, l_socket_fd) + 1, &fds, NULL, NULL, NULL);

		if(retval <= 0){
			ALOGI("Error\n");
			// Should I check for EBADR?
			break;
		} 

		if(FD_ISSET(l_socket_fd, &fds)) {
			ALOGI("Connection attempt\n");
			if(c_socket_fd < 0) {
				c_socket_fd = accept(l_socket_fd, NULL, NULL);
			}

			if (make_nonblocking (c_socket_fd)) {
				ALOGE("Unable to modify socket flags. (%s)\n", strerror(errno));
			}
			
		} 

		if(c_socket_fd >= 0 && FD_ISSET(c_socket_fd, &fds)){

			int unread_bytes_count;
			if (ioctl(c_socket_fd, FIONREAD, &unread_bytes_count)){
				ALOGE("Attempt to check if client socket is closed resulted in error.\n");
			} else if(unread_bytes_count == 0) {
				//TODO: Check return code?				
				close(c_socket_fd);
				c_socket_fd = -1;
			} else {
				process_cmds(c_socket_fd, MAX_COMMAND_LENGTH);
				close(c_socket_fd);
				c_socket_fd = -1;
			}
		}

	}

return 0;

}
Exemple #6
0
int main (int argc, char *argv[])

{ time_t timeval ;
  struct tm *tm ;
  char runtime[50] ;
  ioid ttyin,ttyout,outchn ;
  int optlett,printlvl ;
  bool silent,terse,swaperrs,errecho,doversion,dohelp ;
  const char *errmsgpath,*errlogpath,*optpath,*mpspath,*logpath ;

  struct timeval lptime ;
  
  const char *rtnnme = argv[0] ;

/*
  getopt() --- we need explicit declarations under strict ANSI compliance
  mode. This function seems to be quite common, however. Present in GCC.
*/
  int getopt(int argc, char*const *argv, const char *optstring) ;
  extern char *optarg ;
  extern int opterr,optind,optopt ;

  const char *optstring = "e:stp:E:o:m:L:O:hv";

  extern struct tm *localtime(const time_t *clock) ;

  /* mpsio.c */

  extern bool dy_mpsin(const char *mpspath,
  		       consys_struct **consys, double infinity);

  /* dy_basis.c */

  extern void dy_initbasis(int concnt, int factor_freq, double zero_tol),
	      dy_freebasis(void) ;

/*
  Set up some defaults, then process the command line options. This is all very
  specific to Unix and SunOS.
*/
  errmsgpath = DYLP_ERRMSGPATH ;
  errlogpath = NULL ;
  optpath = NULL ;
  mpspath = NULL ;
  outpath = NULL ;
  logpath = NULL ;

  ttyout = IOID_INV ;
  ttyin = IOID_INV ;
  dy_logchn = IOID_INV ;
  outchn = IOID_INV ;

  silent = FALSE ;
  terse = FALSE ;
  dy_gtxecho = TRUE ;
  dy_cmdecho = FALSE ;
  doversion = FALSE ;
  dohelp = FALSE ;

  printlvl = -1 ;

  opterr = 0 ;
  for (optlett = getopt(argc,argv,optstring) ;
       optlett != -1 ;
       optlett = getopt(argc,argv,optstring))
    switch (optlett)
    { case 'e':
      { errmsgpath = optarg ;
	break ; }
      case 'E':
      { errlogpath = optarg ;
	break ; }
      case 'o':
      { optpath = optarg ;
	break ; }
      case 'm':
      { mpspath = optarg ;
	break ; }
      case 'L':
      { logpath = optarg ;
	break ; }
      case 'O':
      { outpath = optarg ;
	break ; }
      case 's':
      { silent = TRUE ;
	dy_gtxecho = FALSE ;
	break ; }
      case 't':
      { terse = TRUE ;
	dy_gtxecho = FALSE ;
	break ; }
      case 'p':
      { printlvl = atoi(optarg) ;
	break ; }
      case 'v':
      { doversion = TRUE ;
	break ; }
      case 'h':
      { dohelp = TRUE ;
	break ; }
      case '?':
      { errinit(errmsgpath,errlogpath,TRUE) ;
	dyio_ioinit() ;
	errmsg(3,rtnnme,"command line option",optopt) ;
	exit (1) ; } }
/*
  If there's still a parameter left, it must be the mps file, specified without
  using the -m option. There should not be more than one parameter remaining.
*/
  if (optind < argc)
  { mpspath = argv[optind] ;
    optind++ ; }
  if (optind < argc)
  { dohelp = TRUE ; } 
/*
  What's our output level? If the user has specified a print level, go with it.
  Otherwise, take a cue from any -s or -t flags. Default to print level 2.
*/
  if (printlvl < 0)
  { if (silent == TRUE)
      printlvl = 0 ;
    else
    if (terse == TRUE)
      printlvl = 1 ;
    else
      printlvl = 2 ; }
/*
  Output file name: if the user hasn't specified one, and we're not running
  silent, default to stdout.
*/
  if (outpath == NULL && silent == FALSE) outpath = "stdout" ;
/*
  Grab the time and format it nicely.
*/
  if (time(&timeval) == (time_t)(-1))
  { warn(19,rtnnme) ;
    osidylp_time = "n/a" ; }
  else
  { tm = localtime(&timeval) ;
    if (tm != NULL)
    { strftime(runtime,sizeof(runtime),"%A, %B %d, %Y,  %I:%M:%S %p",tm) ;
      osidylp_time = runtime ; }
    else
    { osidylp_time = "n/a" ; } }
/*
  Figure out the appropriate settings for silent and terse.
  silent is set to (silent || terse), and is passed to process_cmds so that
	 it can properly handle dy_cmdecho and dy_gtxecho.
  terse	 is set for ease of controlling the output specifically mentioned in
	 conjunction with terse mode (which is controlled from this routine).
	 The proper value is (terse || !silent).
  The cryptic little if statement below accomplishes this (try a decision tree
  to convince yourself).
*/
  if (terse == TRUE)
  { if (silent == TRUE)
      terse = FALSE ;
    else
      silent = TRUE ; }
  else
  { if (silent == FALSE) terse = TRUE ; }
/*
  Execute initialization routines for the i/o and error reporting packages.
*/
  if (silent == TRUE)
    errecho = FALSE ;
  else
    errecho = TRUE ;
  errinit(errmsgpath,errlogpath,errecho) ;
  if (dyio_ioinit() != TRUE)
  { errmsg(1,rtnnme,__LINE__) ;
    exit (2) ; }
/*
  Connect ttyout to the standard output. Initialize ttyin, setting the mode to
  line-oriented. Serious internal confusion if we can't manage these. Set the
  initial command input channel to stdin.
*/
  ttyout = dyio_openfile("stdout","w") ;
  if (ttyout == IOID_INV)
  { errmsg(1,rtnnme,__LINE__) ;
    exit(3) ; }
  ttyin = dyio_openfile("stdin","r") ;
  if (ttyin == IOID_INV)
  { errmsg(1,rtnnme,__LINE__) ;
    exit(4) ; }
  (void) dyio_setmode(ttyin,'l') ;
  dy_cmdchn = ttyin ;
/*
  Initialize logging.
*/
  if (logpath != NULL)
  { dy_logchn = dyio_openfile(logpath,"w") ;
    if (dy_logchn == IOID_INV)
    { warn(201,rtnnme,logpath) ;
      dy_logchn = IOID_NOSTRM ; } }
  else
  { dy_logchn = IOID_NOSTRM ; }
/*
  Are we supposed to merge the error messages with the log stream? (Note that
  errors will be echoed to stderr unless we're running silent. If the user's
  turned off logging too, well, it's their business.) swaperrs just tells the
  code that it should reset the error logging channel if it ever resets the
  main logging channel.
*/
  if (errlogpath == NULL && dy_logchn != IOID_NOSTRM)
  { swaperrs = TRUE ;
    errlogpath = logpath ;
    if (dyio_chgerrlog(errlogpath,errecho) == FALSE)
    { warn(18,rtnnme,"<null>",errlogpath) ; } }
/*
  Ok, after all that work, check if we've been asked for the version or usage
  messages. If so, do it and head for the exit. Version preempts help.
*/
  if (doversion == TRUE)
  { print_version(dy_logchn,dy_gtxecho,argv[0],rtnnme,osidylp_version) ;
    goto NOOUTFILE_CLEANUP ; }
  if (dohelp == TRUE)
  { print_help(dy_logchn,dy_gtxecho,argv[0]) ;
    goto NOOUTFILE_CLEANUP ; }
/*
  We're up! Banners to the appropriate places.
*/
  dyio_outfmt(dy_logchn,terse,"\n\t\t    %s\tV %s\n",rtnnme,osidylp_version) ;
  dyio_outfmt(dy_logchn,terse,"\n\t\t%s",runtime) ;
  dyio_outfmt(dy_logchn,terse,"\n\n") ;
  if (outpath != NULL && strcmp(outpath,"stdout") != 0)
  { outchn = dyio_pathtoid(outpath,NULL) ;
    if (outchn == IOID_INV) outchn = dyio_openfile(outpath,"w") ;
    if (outchn == IOID_INV)
    { warn(10,rtnnme,outpath,"w") ; }
    else
    { dyio_outfmt(outchn,FALSE,"\n\t\t    %s\tV %s\n",rtnnme,osidylp_version) ;
      dyio_outfmt(outchn,FALSE,"\n\t\t%s",runtime) ;
      dyio_outfmt(outchn,FALSE,"\n\n") ; } }
/*
  Time to set up the lp options. Establish a set of defaults, then read the
  options file to see what the user has in mind. Because this is a standalone
  shell, doing a one-time solution for an LP, set up a default of cold start
  using the full system and a logical basis. This can be overridden in a .spc
  file if desired.

  For reasons that escape me at the moment, the parser fails on Windows. This
  may get fixed eventually. For now, disabled by the simple expedient of
  forcing optpath to NULL.
*/
  dy_defaults(&main_lpopts,&main_lptols) ;
  main_lpopts->forcecold = TRUE ;
  main_lpopts->fullsys = TRUE ;
  main_lpopts->coldbasis = ibLOGICAL ;
# if defined(_MSC_VER) || defined(__MSVCRT__)
  optpath = NULL ;
# endif
  if (optpath != NULL)
  { dy_cmdchn = dyio_openfile(optpath,"r") ;
    if (dy_cmdchn == IOID_INV) exit (1) ;
    (void) dyio_setmode(dy_cmdchn,'l') ;
    switch (process_cmds(silent))
    { case cmdOK:
      { break ; }
      case cmdHALTERROR:
      { exit (1) ; }
      case cmdHALTNOERROR:
      { exit (0) ; }
      default:
      { exit (1) ; } }
    if (dy_cmdchn != ttyin)
    { (void) dyio_closefile(dy_cmdchn) ;
      dy_cmdchn = IOID_INV ; } }
/*
  Make an attempt to read the mps input file.
*/
  if (dy_mpsin(mpspath,&main_sys,main_lptols->inf) == FALSE)
  { exit (10) ;}
/*
  Check over the option settings, now that we know how big the constraint
  system will be.
*/
  dy_checkdefaults(main_sys,main_lpopts,main_lptols) ;
/*
  Initialise the basis maintenance package. The second parameter controls how
  many basis updates the basis can hold before it requires refactoring.
  Adding 5 to dylp's refactor interval should give a safety margin.
*/
  dy_initbasis(2*main_sys->concnt,main_lpopts->factor+5,0.0) ;
/*
  Run the lp.
*/
  if (do_lp(&lptime,printlvl) == FALSE)
  { errmsg(443,rtnnme,main_sys->nme,dy_prtlpphase(main_lp->phase,TRUE),
	   main_lp->iters) ; }
/*
  Should we produce any output? Print to a file, if requested.
*/
  if (outchn != IOID_INV && outchn != ttyout)
  { dy_dumpcompact(outchn,FALSE,main_lp,FALSE) ; }
/*
  Any final terminal output we should do?
*/
  if (printlvl >= 1)
  { if (printlvl >= 2)
    { dy_dumpcompact(dy_logchn,
		     (dy_logchn == IOID_INV)?TRUE:FALSE,main_lp,FALSE) ; }
    dyio_outfmt(dy_logchn,TRUE,"\nReturn code %s",dy_prtlpret(main_lp->lpret)) ;
    if (main_lp->phase == dyDONE)
      dyio_outfmt(dy_logchn,TRUE," after %d pivots",main_lp->iters) ;
    if (main_lp->lpret == lpOPTIMAL)
    { dyio_outfmt(dy_logchn,TRUE,"; objective %.8g",main_lp->obj) ; }
    dyio_outfmt(dy_logchn,TRUE,
		" (%.2f sec.)",lptime.tv_sec+lptime.tv_usec/1e6) ;
    dyio_outfmt(dy_logchn,TRUE,".\n") ;
    dyio_flushio(dy_logchn,dy_gtxecho) ; }
/*
  Final cleanup. Free space used by the remaining main_* structures.
*/
  dy_freebasis() ;

  if (main_lp != NULL)
  { dy_freesoln(main_lp) ;
    if (main_lp->consys != NULL) consys_free(main_lp->consys) ;
    FREE(main_lp) ; }
  if (main_lpopts != NULL) FREE(main_lpopts) ;
  if (main_lptols != NULL) FREE(main_lptols) ;
/*
  Leap to here for shutdown when we opened the output file but didn't solve
  an LP.
*/
  if (outchn != IOID_INV && outchn != ttyout)
  { (void) dyio_closefile(outchn) ; }
/*
  Leap to here for shutdown in cases where we never get as far as opening
  an output file. We still need to close the log file and shut down the i/o
  subsystem.
*/
  NOOUTFILE_CLEANUP:
  if (dy_logchn != IOID_INV && dy_logchn != IOID_NOSTRM)
  { (void) dyio_closefile(dy_logchn) ; }
  dyio_ioterm() ;
  errterm() ;

  exit(0) ;
  
/*
  Just to suppress the silly warning from the compiler, which isn't satisfied
  with the immediately preceding `exit'.
*/

  return (0) ; }
static void* ril_state_thread(void* arg)
{
    int         started    = 0;
    RilState*   rilState   = (RilState*) arg;
    int         ril_fd     = rilState->fd;
    int         control_fd = rilState->control[1];

    D("RIL LCSAPI thread running");
    ril_lcsapi_init(rilState);

    for (;;)
    {
        struct      pollfd pfd[2];
        int         nfds;
        int         nevents;
        unsigned int ne;
        int timeoutms = -1;

        memset(pfd, 0, sizeof(pfd));

        timeout_action_update_timeouts(ta_conn_retry, _SIZE(ta_conn_retry));

        if (rilState->fd < 0)
        {
            // Waiting a constant time isn't the best solution because
            // 1. In the case where LCS socket is matching, less waiting is better.
            //    The booting time is smaller.
            // 2. In the case where LCS socket is mismatching due to integration failure,
            //    it causes unexpected flood of warnings.
            D("ril_state_thread, fd < 0, calling timeout_action_add");
            timeout_action_add(ta_conn_retry, _SIZE(ta_conn_retry), 0,
                               wait_time_get(), connect_init_cb, rilState);
        }
        else
        {
            D("ril_state_thread, fd = %d", rilState->fd);
            nfds = poll_register_in(pfd, _SIZE(pfd), rilState->fd);
            // Resets the LCS socket waiting time so next connection loss won't wait for long.
            wait_time_reset();
        }

        if (timeout_action_any_inuse(ta_conn_retry, _SIZE(ta_conn_retry)))
        {
            timeoutms = 1000;
        }

        // register control file descriptors for polling
        nfds = poll_register_in(pfd, _SIZE(pfd), control_fd );

        nevents = poll(pfd, nfds, timeoutms);

        if (nevents < 0)
        {
            if (errno != EINTR)
            {
                LOGE("poll unexpected error: %s", strerror(errno));
            }

            continue;
        }

        D("ril thread received %d events", nevents);

        if (nevents == 0)
        {
            continue;
        }

        for (ne=0; ne<_SIZE(pfd); ne++)
        {
            if ((pfd[ne].fd == rilState->fd) && (pfd[ne].revents & (POLLERR | POLLHUP)) != 0)
            {
                LOGE("EPOLLERR or EPOLLHUP after poll() !?");
                ril_state_done(rilState);
                continue;
            }

            if (pfd[ne].revents & POLLIN)
            {
                int  fd = pfd[ne].fd;

                if (fd == control_fd)
                {
                    struct ril_cmds cmd;
                    int   ret;
                    D("ril control fd event");

                    do
                    {
                        ret = read( fd, &cmd, sizeof(cmd));
                    }
                    while (ret < 0 && errno == EINTR);

                    if (ret == sizeof(cmd))
                    {
                        if (cmd.id == CMD_DEINIT)
                        {
                            goto Exit;
                        }
                        else
                        {
                            process_cmds(rilState, &cmd);
                        }
                    }
                    else if (ret < 0)
                    {
                        D("Error reading command %d", errno);
                    }
                    else
                    {
                        D("Not proper size");
                    }
                }
                else if (fd == rilState->fd)
                {
                    D("gps fd event");
                    BrcmLbs_processMessages(rilState->lbs, BRCMLBS_RX);
                }
                else
                {
                    LOGE("poll() returned unkown fd %d ?", fd);
                }
            }
        }
    }

Exit:
    D("Exiting ril thread");
    ril_state_done(rilState);
    return NULL;
}