Esempio n. 1
0
static int process_event(struct input_event *event) {
  if (event->type != EV_KEY)
   return 0;

  if (event->value == KEYHOLD && keystate.hold.num_active && modifiable(event->code))
    return 0;

  add_key_to_queue(event->code, event->value);

  if (!modifiable(event->code)) {
    flush_queue(ACTION_NONE, 0);
    keystate.tap.code = event->code;
    keystate.hold.code = event->code;
    return 0;
  }

  switch (event->value) {
    case KEYDOWN:
      cancel_hold_timeout();
      if (keystate.tap.code == event->code && within_tap_threshold(event)) {
        if (keystate.tap.state == STATE_IDLE) {
          syslog(LOG_WARNING, "Missed tap action due to timeout");
        }
        else {
          tap_action();
          memcpy(&keystate.tap.time, &event->time, sizeof keystate.tap.time);
        }
      }  
      else {
        flush_queue(ACTION_NONE, 0);
        if (keystate.hold.num_active) {
          keystate.hold.code = event->code;
          start_hold_timeout();
        }
        if (keystate.tap.num_active) {
          keystate.tap.code = event->code;
          memcpy(&keystate.tap.time, &event->time, sizeof keystate.tap.time);
          start_tap_timeout();
        }
      }
      break;
    case KEYUP:
      cancel_hold_timeout();
      if (keystate.tap.code != event->code || keystate.tap.state == STATE_IDLE) {
        flush_queue(ACTION_NONE, 0);
        stop_tap();
      }
      break;
    case KEYHOLD:
      if (!keystate.hold.num_active) {
        stop_tap();
        flush_queue(ACTION_NONE, 0);
      }
      break;
    default:
      break;
  }

  return 0;
}
Esempio n. 2
0
struct node *breadth_first_search(struct node *n, int val)
{
	struct queue q = {0};

	queue_push(&q, n);

	while ( (n = queue_shift(&q))) {

#ifdef VERBOSE
		printf("  node: %i (%p), match? %s\n",
				n->val, n, (n->val == val) ? "yes" : "no");
#endif

		if (n->val == val)
			break;

		if (n->left != NULL)
			queue_push(&q, n->left);

		if (n->right != NULL)
			queue_push(&q, n->right);
	}

	flush_queue(&q);

	return n;
}
Esempio n. 3
0
static void
transition_open (CockpitPortal *self)
{
  g_assert (self->state == PORTAL_OPENING);
  self->state = PORTAL_OPEN;
  flush_queue (self);
}
Esempio n. 4
0
void osd_sound(int frq, int ms, int vol, int bgplay) {
  SDL_PauseAudio(0);
  do_beep(frq, ms);
  if (!bgplay) {
    flush_queue();
  }
}
Esempio n. 5
0
static void
transition_failed (CockpitPortal *self)
{
  g_assert (self->state == PORTAL_OPENING);
  g_assert (self->problem != NULL);
  self->state = PORTAL_FAILED;
  flush_queue (self);
}
Esempio n. 6
0
void Conveyor::on_halt(void* argument)
{
    if(argument == nullptr) {
        halted = true;
        flush_queue();
    } else {
        halted = false;
    }
}
Esempio n. 7
0
static int tap_action() {
  struct key_modifier *tap = &keystate.tap;

  if (tap->num_active) {
    if (!tap->circular && (tap->count == tap->num_active))
      return 0;
    send_key(KEY_BACKSPACE, KEYDOWN);
    send_key(KEY_BACKSPACE, KEYUP);
    send_key(keystate.tap.code, KEYUP);
    flush_queue(tap->actions[tap->count], tap->code);
    tap->count = (tap->count + 1) % tap->num_active;
    start_tap_timeout();
  }
  else {
    flush_queue(ACTION_NONE, 0);
  }

  return 0;
}
Esempio n. 8
0
static VOID deleteSFBySfid(struct bcm_mini_adapter *Adapter, UINT uiSearchRuleIndex)
{
	/* deleting all the packet held in the SF */
	flush_queue(Adapter, uiSearchRuleIndex);

	/* Deleting the all classifiers for this SF */
	DeleteAllClassifiersForSF(Adapter, uiSearchRuleIndex);

	/* Resetting only MIBS related entries in the SF */
	memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, sizeof(struct bcm_mibs_table));
}
Esempio n. 9
0
static int hold_action() {
  struct key_modifier *hold = &keystate.hold;

  if (hold->num_active) {
    if (hold->count == hold->num_active) {
      if (!hold->circular)
        return 0;
      hold->count -= hold->num_active;
    }
    send_key(KEY_BACKSPACE, KEYDOWN);
    send_key(KEY_BACKSPACE, KEYUP);
    send_key(keystate.hold.code, KEYUP);
    flush_queue(hold->actions[hold->count], hold->code);
    hold->count++;
    start_hold_timeout();
  }
  else {
    flush_queue(ACTION_NONE, 0);
  }

  return 0;
}
Esempio n. 10
0
static int stop_tap() {
  struct itimerspec value;

  value.it_value.tv_sec = 0;
  value.it_value.tv_nsec = 0;

  timer_settime(tap_timer.timerid, 0, &value, NULL);
  flush_queue(ACTION_NONE, 0);
  keystate.tap.state = STATE_IDLE;
  return 0;
#if 0
  if (keystate.tap.state == STATE_WAITING) {
    keystate.tap.count = 0;
    keystate.tap.code = 0;
    keystate.tap.state = STATE_IDLE;
    timer_settime(tap_timer.timerid, 0, &value, NULL);

    if (keystate.hold.state == STATE_IDLE)
      flush_queue(ACTION_NONE, 0);
  }
#endif
}
Esempio n. 11
0
/* Disconnects 'rc' and frees the underlying storage. */
void
rconn_destroy(struct rconn *rc)
{
    if (rc) {
        size_t i;

        free(rc->name);
        vconn_close(rc->vconn);
        flush_queue(rc);
        queue_destroy(&rc->txq);
        for (i = 0; i < rc->n_monitors; i++) {
            vconn_close(rc->monitors[i]);
        }
        free(rc);
    }
}
Esempio n. 12
0
static int add_key_to_queue(__u16 code, __s32 value) {
  int i;

  if (key_queue[KEYQ_SIZE - 1].code)
    flush_queue(ACTION_NONE, 0);

  for (i=0; i<KEYQ_SIZE; i++) { 
    if (!key_queue[i].code) { 
      key_queue[i].code = code; 
      key_queue[i].value = value; 
      break; 
    } 
  }

  return i;
}
Esempio n. 13
0
void bluefish_exit_request() {

	GList *tmplist;
	
	gboolean tmpb;
	DEBUG_MSG("winefish_exit_request, started\n");
	/* if we have modified documents we have to do something, file_close_all_cb()
	does exactly want we want to do */
	tmplist = return_allwindows_documentlist();
	tmpb = (tmplist && test_docs_modified(tmplist));
	g_list_free(tmplist);
	tmplist = g_list_first(main_v->bfwinlist);
	while (tmplist) {
		/* if there is a project, we anyway want to save & close the project */
		if (BFWIN(tmplist->data)->project) {
			if (!project_save_and_close(BFWIN(tmplist->data))) {
				/* cancelled or error! */
				DEBUG_MSG("winefish_exit_request, project_save_and_close returned FALSE\n");
				return;
			}
		}
		if (tmpb) {
			file_close_all_cb(NULL, BFWIN(tmplist->data));
		}
		tmplist = g_list_next(tmplist);
	}
	/* if we still have modified documents we don't do a thing,
	 if we don't have them we can quit */
	if (tmpb) {
		tmplist = return_allwindows_documentlist();
		tmpb = (tmplist && test_docs_modified(tmplist));
		g_list_free(tmplist);
		if (tmpb) {
			return;
		}
	}
/*	gtk_widget_hide(main_v->main_window);*/
	
	tmplist = g_list_first(gtk_window_list_toplevels());
	gchar *role=NULL;
	while (tmplist) {
		/* BUG#38 */
		if (GTK_IS_WIDGET(tmplist->data)) {
			role = g_strdup(gtk_window_get_role ((GtkWindow*)tmplist->data));
			gtk_widget_hide(GTK_WIDGET(tmplist->data));
			if (role && strncmp(role,"html_dialog",11) ==0) {
				window_destroy(GTK_WIDGET(tmplist->data));
			}
		}
		/* g_print("type = %s, role=%s\n", GTK_OBJECT_TYPE_NAME((GtkObject*) tmplist->data), role); */
		tmplist = g_list_next(tmplist);
	}
	g_free(role);

	flush_queue();

	rcfile_save_all();
	{
		gchar *filename = g_strconcat(g_get_home_dir(), "/.winefish/dir_history", NULL);
		put_stringlist_limited(filename, main_v->recent_directories, main_v->props.max_dir_history);
		g_free(filename);
	}
	
	gtk_main_quit();
}
Esempio n. 14
0
int main(int argc, char *argv[])
{
	gboolean root_override=FALSE, open_in_new_window = FALSE;
	GList *filenames = NULL, *projectfiles=NULL;
	gint linenumber = -1;

	Tbfwin *firstbfwin;
#ifndef NOSPLASH
	GtkWidget *splash_window;
#endif /* #ifndef NOSPLASH */

#ifdef ENABLE_NLS
	setlocale(LC_ALL,"");
	bindtextdomain(PACKAGE,LOCALEDIR);
	DEBUG_MSG("set bindtextdomain for %s to %s\n",PACKAGE,LOCALEDIR);
	bind_textdomain_codeset(PACKAGE, "UTF-8");
	textdomain(PACKAGE);
#endif
#ifdef HAVE_ATLEAST_GNOMEUI_2_6
	gnome_init(PACKAGE, VERSION, argc, argv);
#else
	gtk_init(&argc, &argv);
#endif /* HAVE_ATLEAST_GNOMEUI_2_6
 */
	main_v = g_new0(Tmain, 1);
	main_v->session = g_new0(Tsessionvars,1);
	DEBUG_MSG("main, main_v is at %p\n", main_v);

	rcfile_check_directory();
	rcfile_parse_main();

	parse_commandline(argc, argv, &root_override, &filenames, &projectfiles, &open_in_new_window, &linenumber);
#ifdef WITH_MSG_QUEUE
	if (((filenames || projectfiles) && (main_v->props.view_bars & MODE_REUSE_WINDOW)) || open_in_new_window) {
		msg_queue_start(filenames, projectfiles, linenumber, open_in_new_window);
	}
#endif /* WITH_MSG_QUEUE */
#ifndef NOSPLASH
	/* start splash screen somewhere here */
	splash_window = start_splash_screen();
	splash_screen_set_label(_("parsing highlighting file..."));
#endif /* #ifndef NOSPLASH */

	{
		gchar *filename = g_strconcat(g_get_home_dir(), "/.winefish/dir_history", NULL);
		main_v->recent_directories = get_stringlist(filename, NULL);
		g_free(filename);
	}
	rcfile_parse_global_session();
	rcfile_parse_highlighting();
#ifndef NOSPLASH
	splash_screen_set_label(_("compiling highlighting patterns..."));
#endif /* #ifndef NOSPLASH */
	hl_init();
#ifndef NOSPLASH
	splash_screen_set_label(_("initialize some other things..."));
#endif /* #ifndef NOSPLASH */
	filebrowserconfig_init();
	filebrowser_filters_rebuild();
	autoclosing_init();
#ifndef NOSPLASH
	splash_screen_set_label(_("parsing autotext and words file..."));
#endif /* #ifndef NOSPLASH */
	autotext_init();
	completion_init();
#ifndef NOSPLASH
	splash_screen_set_label(_("parsing custom menu file..."));
#endif /* #ifndef NOSPLASH */
	rcfile_parse_custom_menu(FALSE,FALSE);

#ifdef SNOOPER2
#ifndef NOSPLASH
	splash_screen_set_label(_("parsing keymap and initializing function list..."));
#endif /* #ifndef NOSPLASH */
	funclist_init();
	keymap_init();
#endif /* SNOOPER2 */
	
	main_v->tooltips = gtk_tooltips_new();
	/* initialize the completion window */
	/* main_v->completion.window = NULL; */
	fref_init();
	bmark_init();
#ifdef WITH_MSG_QUEUE
	if (!filenames && !projectfiles && (main_v->props.view_bars & MODE_REUSE_WINDOW)) {
		msg_queue_start(NULL, NULL, -1, open_in_new_window);
	}
#endif /* WITH_MSG_QUEUE */
#ifndef NOSPLASH
	splash_screen_set_label(_("creating main gui..."));
#endif /* #ifndef NOSPLASH */

	/* create the first window */
	firstbfwin = g_new0(Tbfwin,1);
	firstbfwin->session = main_v->session;
	firstbfwin->bookmarkstore = main_v->bookmarkstore;
	main_v->bfwinlist = g_list_append(NULL, firstbfwin);
	gui_create_main(firstbfwin, filenames, linenumber);
	bmark_reload(firstbfwin);
#ifndef NOSPLASH
	splash_screen_set_label(_("showing main gui..."));
#endif /* #ifndef NOSPLASH */

	/* set GTK settings, must be AFTER the menu is created */
	{
		gchar *shortcutfilename;
		GtkSettings* gtksettings = gtk_settings_get_default();
		g_object_set(G_OBJECT(gtksettings), "gtk-can-change-accels", TRUE, NULL); 
		shortcutfilename = g_strconcat(g_get_home_dir(), "/.winefish/menudump_2", NULL);
		gtk_accel_map_load(shortcutfilename);
		g_free(shortcutfilename);
	}

	gui_show_main(firstbfwin);
	/*
	if (main_v->props.view_html_toolbar && main_v->globses.quickbar_items == NULL) {
		info_dialog(firstbfwin->main_window, _("Winefish tip:"), _("This message is shown since you DONOT have any items in the QuickBar.\n\nIf you right-click a button in the Standard toolbars you can add buttons to the Quickbar."));
	}
	*/
	if (projectfiles) {
		GList *tmplist = g_list_first(projectfiles);
		while (tmplist) {
			project_open_from_file(firstbfwin, tmplist->data, linenumber);
			tmplist = g_list_next(tmplist);
		}
	}

#ifndef NOSPLASH
	DEBUG_MSG("destroy splash\n");
	flush_queue();
	{
		static struct timespec const req = { 0, 10000000};
		nanosleep(&req, NULL);
	}
	gtk_widget_destroy(splash_window);
#endif /* #ifndef NOSPLASH */

	/* snooper must be installed after the main gui has shown;
	otherwise the program may be aborted */
#ifndef SNOOPER2
	snooper_install();
#endif /* SNOOPER2 */

	DEBUG_MSG("main, before gtk_main()\n");
	gtk_main();
	DEBUG_MSG("main, after gtk_main()\n");
#ifdef WITH_MSG_QUEUE	
	/* do the cleanup */
	msg_queue_cleanup();
#endif /* WITH_MSG_QUEUE */
	DEBUG_MSG("Winefish: exiting cleanly\n");
	return 0;
}
Esempio n. 15
0
void osd_beep() {
  SDL_PauseAudio(0);
  do_beep(1000, 30);
  do_beep(500, 30);
  flush_queue();
}
Esempio n. 16
0
int     main(int argc, char **argv)
{
    struct stat st;
    char   *slash;
    int     c;
    int     fd;
    int     mode = PQ_MODE_DEFAULT;
    char   *site_to_flush = 0;
    char   *id_to_flush = 0;
    ARGV   *import_env;
    int     bad_site;

    /*
     * Fingerprint executables and core dumps.
     */
    MAIL_VERSION_STAMP_ALLOCATE;

    /*
     * Be consistent with file permissions.
     */
    umask(022);

    /*
     * To minimize confusion, make sure that the standard file descriptors
     * are open before opening anything else. XXX Work around for 44BSD where
     * fstat can return EBADF on an open file descriptor.
     */
    for (fd = 0; fd < 3; fd++)
	if (fstat(fd, &st) == -1
	    && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
	    msg_fatal_status(EX_UNAVAILABLE, "open /dev/null: %m");

    /*
     * Initialize. Set up logging, read the global configuration file and
     * extract configuration information. Set up signal handlers so that we
     * can clean up incomplete output.
     */
    if ((slash = strrchr(argv[0], '/')) != 0 && slash[1])
	argv[0] = slash + 1;
    msg_vstream_init(argv[0], VSTREAM_ERR);
    msg_cleanup(unavailable);
    msg_syslog_init(mail_task("postqueue"), LOG_PID, LOG_FACILITY);
    set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0]));

    /*
     * Check the Postfix library version as soon as we enable logging.
     */
    MAIL_VERSION_CHECK;

    /*
     * Parse JCL. This program is set-gid and must sanitize all command-line
     * parameters. The configuration directory argument is validated by the
     * mail configuration read routine. Don't do complex things until we have
     * completed initializations.
     */
    while ((c = GETOPT(argc, argv, "c:fi:ps:v")) > 0) {
	switch (c) {
	case 'c':				/* non-default configuration */
	    if (setenv(CONF_ENV_PATH, optarg, 1) < 0)
		msg_fatal_status(EX_UNAVAILABLE, "out of memory");
	    break;
	case 'f':				/* flush queue */
	    if (mode != PQ_MODE_DEFAULT)
		usage();
	    mode = PQ_MODE_FLUSH_QUEUE;
	    break;
	case 'i':				/* flush queue file */
	    if (mode != PQ_MODE_DEFAULT)
		usage();
	    mode = PQ_MODE_FLUSH_FILE;
	    id_to_flush = optarg;
	    break;
	case 'p':				/* traditional mailq */
	    if (mode != PQ_MODE_DEFAULT)
		usage();
	    mode = PQ_MODE_MAILQ_LIST;
	    break;
	case 's':				/* flush site */
	    if (mode != PQ_MODE_DEFAULT)
		usage();
	    mode = PQ_MODE_FLUSH_SITE;
	    site_to_flush = optarg;
	    break;
	case 'v':
	    if (geteuid() == 0)
		msg_verbose++;
	    break;
	default:
	    usage();
	}
    }
    if (argc > optind)
	usage();

    /*
     * Further initialization...
     */
    mail_conf_read();
    /* Re-evaluate mail_task() after reading main.cf. */
    msg_syslog_init(mail_task("postqueue"), LOG_PID, LOG_FACILITY);
    mail_dict_init();				/* proxy, sql, ldap */
    get_mail_conf_str_table(str_table);

    /*
     * This program is designed to be set-gid, which makes it a potential
     * target for attack. If not running as root, strip the environment so we
     * don't have to trust the C library. If running as root, don't strip the
     * environment so that showq can receive non-default configuration
     * directory info when the mail system is down.
     */
    if (geteuid() != 0) {
	import_env = mail_parm_split(VAR_IMPORT_ENVIRON, var_import_environ);
	clean_env(import_env->argv);
	argv_free(import_env);
    }
    if (chdir(var_queue_dir))
	msg_fatal_status(EX_UNAVAILABLE, "chdir %s: %m", var_queue_dir);

    signal(SIGPIPE, SIG_IGN);

    /* End of initializations. */

    /*
     * Further input validation.
     */
    if (site_to_flush != 0) {
	bad_site = 0;
	if (*site_to_flush == '[') {
	    bad_site = !valid_mailhost_literal(site_to_flush, DONT_GRIPE);
	} else {
	    bad_site = !valid_hostname(site_to_flush, DONT_GRIPE);
	}
	if (bad_site)
	    msg_fatal_status(EX_USAGE,
	      "Cannot flush mail queue - invalid destination: \"%.100s%s\"",
		   site_to_flush, strlen(site_to_flush) > 100 ? "..." : "");
    }
    if (id_to_flush != 0) {
	if (!mail_queue_id_ok(id_to_flush))
	    msg_fatal_status(EX_USAGE,
		       "Cannot flush queue ID - invalid name: \"%.100s%s\"",
		       id_to_flush, strlen(id_to_flush) > 100 ? "..." : "");
    }

    /*
     * Start processing.
     */
    switch (mode) {
    default:
	msg_panic("unknown operation mode: %d", mode);
	/* NOTREACHED */
    case PQ_MODE_MAILQ_LIST:
	show_queue();
	exit(0);
	break;
    case PQ_MODE_FLUSH_SITE:
	flush_site(site_to_flush);
	exit(0);
	break;
    case PQ_MODE_FLUSH_FILE:
	flush_file(id_to_flush);
	exit(0);
	break;
    case PQ_MODE_FLUSH_QUEUE:
	flush_queue();
	exit(0);
	break;
    case PQ_MODE_DEFAULT:
	usage();
	/* NOTREACHED */
    }
}
Esempio n. 17
0
void osd_clear_sound_queue() {
  flush_queue();
}
Esempio n. 18
0
File: erq.c Progetto: amotzkau/ldmud
/*-------------------------------------------------------------------------*/
int
main(int argc, char *argv[])

/* The main program and -loop of the ERQ.
 */

{
    int num;

    master_pid = getpid();

    /* Print information about this daemon to help debugging */
    {
        fprintf(stderr, "%s XERQ %s: Path '%s', debuglevel %d\n"
                      , time_stamp(), __DATE__, argv[0], ERQ_DEBUG
                );
    }

    /* Quick and dirty commandline parser */
    {
        int is_forked = 0;
        int i;

        for (i = 1; i < argc; i++)
        {
            if (!strcmp(argv[i], "--forked"))
                is_forked = 1;
            else if (!strcmp(argv[i], "--execdir"))
            {
                if (i+1 >= argc)
                {
                    fprintf(stderr, "%s Missing value for --execdir.\n"
                                  , time_stamp());
                    die();
                }
                erq_dir = argv[i+1];
                i++;
            }
            else
            {
                fprintf(stderr, "%s Unknown argument '%s'.\n"
                              , time_stamp(), argv[i]);
                die();
            }
        }
        /* Check if we have been forked off the driver */
        if (is_forked)
        {
            write(1, "1", 1); /* indicate sucessful fork/execl */
            fprintf(stderr, "%s Demon started\n", time_stamp() );
        }
        else
        {
            fprintf(stderr, "%s Dynamic attachment unimplemented\n"
                          , time_stamp());
            die();
        }
    }

    /* Initialize */
    
    in_select = 0;
    pending_sig = 0;

    signal(SIGCLD, sig_child);
    signal(SIGPIPE, SIG_IGN);

    sockets = NULL;
    childs = NULL;
    retries = NULL;
    stdout_queue = NULL;
    
    randomize(time(0));
    seq_number = get_ticket();
    seq_interval = get_ticket() | 1; /* make sure it is odd */

#ifdef DETACH
    /* Detach from console */
    num = open("/dev/tty", O_RDWR);
    if (num >= 0) {
        ioctl(num, TIOCNOTTY, 0);
        close(num);
    }
#endif

    /* The main loop */
    
    while(1)
    {
        fd_set read_fds, write_fds;
        int num_fds;
        child_t *chp;
        retry_t *rtp, **rtpp;
        socket_t *sp;
        struct timeval timeout;

        /* Clean up the list of children (may close some sockets) */
        
        for (chp = childs; chp;)
        {
            child_t *this = chp;

            chp = chp->next;

            /* If there is a pending SIG_CLD for this child, handle it.
             * This is to be expected for CHILD_FORK children.
             */
            if (pending_sig && this->pid == pending_pid)
            {
                if (this->type != CHILD_FORK)
                    fprintf(stderr, "%s Pending SIG_CLD for pid %d delivered.\n"
                                  , time_stamp(), pending_pid);
                this->status = pending_status;
                this->pid = pending_pid;
                pending_sig = 0;
            }

            if (this->status == CHILD_EXITED)
            {
                XPRINTF((stderr, "%s Child %p exited.\n", time_stamp(), this));
                remove_child(this); /* will also unlink it from the list */
            }
        }

        /* look for sockets to select on */

        FD_ZERO(&read_fds);
        FD_ZERO(&write_fds);

        FD_SET(0, &read_fds);
        if (stdout_queue)
            FD_SET(1, &write_fds);

        num_fds = 2;
        for (sp = sockets; sp; sp = sp->next)
        {
            switch(sp->type)
            {
            case SOCKET_WAIT_CONNECT:
            case SOCKET_WAIT_AUTH:
                FD_SET(sp->fd, &write_fds);
                FD_SET(sp->fd, &read_fds);
                if (sp->fd >= num_fds)
                    num_fds=sp->fd+1;
                break;

            default:
                FD_SET(sp->fd, &read_fds);
                if (sp->fd >= num_fds)
                    num_fds=sp->fd+1;
                break;

            case SOCKET_WAIT_ACCEPT:
                /* do nothing */;
                /* Without the ; above, Metrowerks Codewarrior reports
                 * an error :-( */
            }

            if (sp->queue)
                FD_SET(sp->fd, &write_fds);
        } /* for (sockets) */

        /* Scan the list of pending retries for the soonest one.
         * Put the time till then into timeout.
         * (If the list is empty, select() will receive NULL for timeout).
         */
        if (retries)
        {
            time_t t;

            t = retries->time;
            for (rtp = retries; rtp; rtp = rtp->next)
            {
                if (rtp->time < t)
                    t = rtp->time;
            }
            timeout.tv_sec = t - time(NULL);
            timeout.tv_usec = 0;
            XPRINTF((stderr, "%s Soonest retry_t: in %ld seconds.\n"
                           , time_stamp(), (long)timeout.tv_sec));
			   
            if (timeout.tv_sec < 0)
                timeout.tv_sec = 0;
        }

#if ERQ_DEBUG > 1
        fprintf(stderr, "%s select()\n", time_stamp());
#endif
        in_select = 1; /* so sig_child() can write reply directly */
        num = select(num_fds, &read_fds, &write_fds, 0, retries ? &timeout : 0);
        in_select = 0; /* don't want sig_child() writing now */

#if ERQ_DEBUG > 1
        {
            int myerrno = errno;
            fprintf(stderr, "%s select() returns %d, time() %ld\n"
                          , time_stamp(), num, (long)time(NULL));
            errno = myerrno;
        }
#endif

#if ERQ_DEBUG > 0
        if (num < 0)
	/* Give an error now, but don't abort this loop,
	 * because the retries have to be handled first.
	 */
        {
            int myerrno = errno;
            fprintf(stderr, "%s select() errno = %d", time_stamp(), errno);
            errno = myerrno;
            perror(" ");
        }
#endif
	
        /* Is stdout ready to write? Then flush the queue. */
        if (num >= 0 && FD_ISSET(1, &write_fds))
        {
            XPRINTF((stderr, "%s stdout_queue ready for flush.\n", time_stamp()));
            flush_queue(&stdout_queue, 1, 0);
        }

        /* Check for retries */
        for (rtpp = &retries; *rtpp; )
        {
            rtp = *rtpp;
            if (rtp->time <= time(NULL))
            {
                XPRINTF((stderr, "%s Call retry %p (time %ld)\n"
                               , time_stamp(), rtp, (long)rtp->time));
                (*(rtp->func))(rtp->mesg, read_32(rtp->mesg));
                *rtpp = rtp->next;
                free(rtp);
            }
            else
            {
                rtpp = &rtp->next;
            }
        }
	
        /* Error in select */
        if (num < 0)
            continue;

        /* check for input from driver */
        if (FD_ISSET(0, &read_fds))
        {
            XPRINTF((stderr, "%s New command from driver.\n", time_stamp()));
            erq_cmd();
        }

        /* Handle the ready sockets.
         * Remember that read_socket() may close the socket.
         */

        for (sp = sockets; sp; )
        {
            socket_t *this = sp;
            int rc;

            sp = sp->next;

            rc = 0;

            if (FD_ISSET(this->fd, &read_fds))
            {
                XPRINTF((stderr, "%s Socket %p (%d) ready for reading.\n"
                               , time_stamp(), this, this->fd));
                rc = read_socket(this, 0);
            }

            if (!rc && FD_ISSET(this->fd, &write_fds))
            {
                XPRINTF((stderr, "%s Socket %p (%d) ready for writing.\n"
                               , time_stamp(), this, this->fd));
                (void)read_socket(this, 1);
            }
        }
    } /* while(1) */

    /* NOTREACHED */
    
    return 0;
} /* main() */