コード例 #1
0
ファイル: signals.c プロジェクト: junjiemars/rlwrap
static void
child_died(int unused)
{
    int saved_errno;
    DEBUG_RANDOM_SLEEP;
    zero_select_timeout();
    saved_errno = errno;
    DPRINTF0(DEBUG_SIGNALS, "Caught SIGCHLD");

    if(command_pid && waitpid(command_pid, &commands_exit_status, WNOHANG)) {
        DPRINTF2(DEBUG_SIGNALS, "child (pid %d) has died, exit status: %x", command_pid, commands_exit_status);
        command_is_dead = TRUE;
        command_pid = 0;            /* thus we know that there is no child anymore to pass signals to */
    } else if (filter_pid && waitpid(filter_pid, &filters_exit_status, WNOHANG)) {
        DPRINTF2(DEBUG_SIGNALS, "filter (pid %d) has died, exit status: %x", filter_pid, filters_exit_status);
        filter_is_dead = TRUE;
        filter_pid = 0;
    } else  {
        DPRINTF0(DEBUG_ALL, "Whoa, got a SIGCHLD, but not from slave command or filter! I must have children I don't know about (blush...)!");
        /* ignore */
    }

    errno = saved_errno;
    return;   /* allow remaining output from child to be processed in main loop */
    /* (so that we will see childs good-bye talk)                     */
    /* this will then clean up and terminate                          */

}
コード例 #2
0
ファイル: f_format.c プロジェクト: apprisi/illumos-gate
int32_t
_m_media_format_track(rmedia_handle_t *handle, void *ip)
{

	/* Check for valid handle */
	if (handle == NULL) {
		DPRINTF("Null Handle\n");
		errno = EINVAL;
		return (-1);
	}
	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
		DPRINTF("Invalid signature in handle.\n");
		DPRINTF2(
			"Signature expected=0x%x, found=0x%x\n",
				LIBSMEDIA_SIGNATURE, handle->sm_signature);
		errno = EINVAL;
		return (-1);
	}
	if (handle->sm_fd < 0) {
		DPRINTF("Invalid file handle.\n");
		errno = EINVAL;
		return (-1);
	}
#ifdef DEBUG
	if (ip != NULL) {
		struct format_track *ft = (struct format_track *)ip;
		DPRINTF2("Format track %d head %d\n", ft->track_no, ft->head);
	}
#endif /* DEBUG */
	return (format_floppy(handle->sm_fd, ip));
}
コード例 #3
0
void
move_cursor_to_start_of_prompt(int erase)
{
  int termwidth = winsize.ws_col;
  int promptlen_on_screen, number_of_lines_in_prompt, curpos, count;
  int cooked = (saved_rl_state.cooked_prompt != NULL);
  
  DPRINTF2(DEBUG_READLINE,"prompt_is_still_uncooked: %d, impatient_prompt: %d", prompt_is_still_uncooked, impatient_prompt);
  if (prompt_is_still_uncooked && ! impatient_prompt)
    return; /* @@@ is this necessary ?*/

	
  promptlen_on_screen =  colourless_strlen_unmarked(saved_rl_state.cooked_prompt ? saved_rl_state.cooked_prompt : saved_rl_state.raw_prompt, termwidth);
  curpos = (within_line_edit ? 1 : 0); /* if the user has pressed a key the cursor will be 1 past the current prompt */
  assert(termwidth > 0); 
  number_of_lines_in_prompt = 1 +  ((promptlen_on_screen + curpos -1) / termwidth); /* integer arithmetic! (e.g. 171/80 = 2) */
  cr(); 
  for (count = 0; count < number_of_lines_in_prompt -1; count++) {
    if (erase)
      clear_line();
    curs_up();
  } 
  clear_line();
  DPRINTF4(DEBUG_READLINE,"moved cursor up %d lines (erase = %d, len=%d, cooked=%d)", number_of_lines_in_prompt - 1, erase, promptlen_on_screen, cooked); 
}       
コード例 #4
0
ファイル: signals.c プロジェクト: junjiemars/rlwrap
/* After a resize, clear all the lines that were occupied by prompt + line buffer before the resize */
static
void wipe_textarea(struct winsize *old_winsize)
{
    int point, lineheight, linelength, cursor_height, i, promptlength;
    if (!prompt_is_single_line()) {       /* Don't need to do anything in horizontal_scroll_mode  */
        promptlength = colourless_strlen((saved_rl_state.cooked_prompt ? saved_rl_state.cooked_prompt:  saved_rl_state.raw_prompt), NULL, old_winsize -> ws_col);
        linelength = (within_line_edit ? strlen(rl_line_buffer) : 0) + promptlength;
        point = (within_line_edit ? rl_point : 0) + promptlength;
        assert(old_winsize -> ws_col > 0);
        lineheight = (linelength == 0 ? 0 : (1 + (max(point, (linelength - 1)) / old_winsize -> ws_col)));
        if (lineheight > 1 && term_cursor_up != NULL && term_cursor_down != NULL) {
            /* i.e. if we have multiple rows displayed, and we can clean them up first */
            cr();
            cursor_height = point / old_winsize -> ws_col;    /* cursor is still on old line */
            DPRINTF2(DEBUG_SIGNALS, "lineheight: %d, cursor_height: %d", lineheight, cursor_height);
            for (i = 1 + cursor_height; i < lineheight; i++)
                curs_down();    /* ...move it down to last line */
            for (i = lineheight; i > 1; i--) {        /* go up again, erasing every line */
                clear_line();
                curs_up();
            }
        }
        clear_line();
        cr();
    }
}
コード例 #5
0
ファイル: l_misc.c プロジェクト: apprisi/illumos-gate
int32_t
call_function(rmedia_handle_t *handle, void *ip, char *func_name)
{

	int32_t ret_val;
	int32_t (*fcn_ptr)(rmedia_handle_t *handle, void *ip);
	void *lib_handle;

	if (handle == NULL) {
		DPRINTF("Handle is NULL\n");
		errno = EINVAL;
		return (-1);
	}
	lib_handle = handle->sm_lib_handle;
	if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
		DPRINTF2("call_function:signature expected=0x%x, found=0x%x\n",
		    LIBSMEDIA_SIGNATURE, handle->sm_signature);
		errno = EINVAL;
		return (-1);
	}

	fcn_ptr = (int32_t (*)(rmedia_handle_t *, void*))
	    dlsym(lib_handle, func_name);
	if (fcn_ptr == NULL) {
		DPRINTF1("Could not find %s\n", func_name);
		errno = ENOTSUP;
		return (-1);
	}
	ret_val = (*fcn_ptr)(handle, ip);
	return (ret_val);
}
コード例 #6
0
ファイル: f_generic.c プロジェクト: andreiw/polaris
/* ARGSUSED */
int32_t
_m_eject(rmedia_handle_t *handle, void *ip)
{

	/* Check for valid handle */
	if (handle == NULL) {
		DPRINTF("Null Handle\n");
		errno = EINVAL;
		return (-1);
	}
	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
		DPRINTF("Invalid signature in handle.\n");
		DPRINTF2(
		"Signature expected=0x%x found=0x%x\n",
			LIBSMEDIA_SIGNATURE, handle->sm_signature);
		errno = EINVAL;
		return (-1);
	}
	if (handle->sm_fd < 0) {
		DPRINTF("Invalid file handle.\n");
		errno = EINVAL;
		return (-1);
	}
#ifdef sparc
	return (ioctl(handle->sm_fd, FDEJECT));
#else
	errno = ENOTSUP;
	return (-1);
#endif
}
コード例 #7
0
ファイル: f_generic.c プロジェクト: andreiw/polaris
/* ARGSUSED0 */
int32_t
_m_get_device_info(rmedia_handle_t *handle, void *ip)
{
	smdevice_info_t *dev_info = (smdevice_info_t *)ip;
	char *vendor_name, *product_name, *fw_version;

	/* Check for valid handle */
	if (handle == NULL) {
		DPRINTF("Null Handle\n");
		errno = EINVAL;
		return (-1);
	}
	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
		DPRINTF("Invalid signature in handle.\n");
		DPRINTF2(
			"Signature expected=0x%x found=0x%x\n",
				LIBSMEDIA_SIGNATURE,
				handle->sm_signature);
		errno = EINVAL;
		return (-1);
	}
	if (handle->sm_fd < 0) {
		DPRINTF("Invalid file handle.\n");
		errno = EINVAL;
		return (-1);
	}
	vendor_name = (char *)malloc(1);
	if (vendor_name == NULL) {
		if (!errno)
			errno = ENOMEM;
		return (-1);
	}
	product_name = (char *)malloc(1);
	if (product_name == NULL) {
		free(vendor_name);
		if (!errno)
			errno = ENOMEM;
		return (-1);
	}

	fw_version = (char *)malloc(1);
	if (fw_version == NULL) {
		free(vendor_name);
		free(product_name);
		if (!errno)
			errno = ENOMEM;
		return (-1);
	}

	vendor_name[0] = 0;
	product_name[0] = 0;
	fw_version[0] = 0;

	dev_info->sm_interface_type = IF_FLOPPY;
	dev_info->sm_vendor_name = vendor_name;
	dev_info->sm_product_name = product_name;
	dev_info->sm_firmware_version = fw_version;

	return (0);
}
コード例 #8
0
ファイル: f_format.c プロジェクト: apprisi/illumos-gate
int32_t
_m_media_format(rmedia_handle_t *handle, void *ip) {
	struct format_track ft;

	/* Check for valid handle */
	if (handle == NULL) {
		DPRINTF("Null Handle\n");
		errno = EINVAL;
		return (-1);
	}
	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
		DPRINTF("Invalid signature in handle.\n");
		DPRINTF2(
			"Signature expected=0x%x, found=0x%x\n",
				LIBSMEDIA_SIGNATURE, handle->sm_signature);
		errno = EINVAL;
		return (-1);
	}
	if (handle->sm_fd < 0) {
		DPRINTF("Invalid file handle.\n");
		errno = EINVAL;
		return (-1);
	}
	DPRINTF("Format floppy called \n");
	ft.track_no = (-1);
	ft.head = (-1);
	ft.flag = ((struct format_flags *)ip)->flavor;
	return (format_floppy(handle->sm_fd, &ft));

}
コード例 #9
0
ファイル: string_utils.c プロジェクト: bak724/rlwrap
char *
search_and_replace(char *patt, char *repl, const char *string, int cursorpos,
                   int *line, int *col)
{
  int i, j, k;
  int pattlen = strlen(patt);
  int replen = strlen(repl);
  int stringlen = strlen(string);
  int cursor_found = FALSE;
  int current_line = 1;
  int current_column = 0;
  size_t scratchsize;
  char *scratchpad, *result;

  assert(patt && repl && string);
  DPRINTF2(DEBUG_READLINE, "string=%s, cursorpos=%d",
           mangle_string_for_debug_log(string, 40), cursorpos);
  scratchsize = max(stringlen, (stringlen * replen) / pattlen) + 1;     /* worst case : repleng > pattlen and string consists of only <patt> */
  DPRINTF1(DEBUG_READLINE, "Allocating %d bytes for scratchpad", (int) scratchsize);
  scratchpad = mymalloc(scratchsize);


  for (i = j = 0; i < stringlen;  ) {
    if (line && col &&                           /* if col and line are BOTH non-NULL, and .. */
        i >= cursorpos && !cursor_found) {       /*  ... for the first time, i >= cursorpos: */
      cursor_found = TRUE;                       /* flag that we're done here */                              
      *line = current_line;                      /* update *line */ 
      *col = current_column;                     /* update *column */
    }
    if (strncmp(patt, string + i, pattlen) == 0) { /* found match */
      i += pattlen;                                /* update i ("jump over" patt (and, maybe, cursorpos)) */  
      for (k = 0; k < replen; k++)                 /* append repl to scratchpad */
        scratchpad[j++] = repl[k];
      current_line++;                              /* update line # (assuming that repl = "\n") */
      current_column = 0;                          /* reset column */
    } else {
      scratchpad[j++] = string[i++];               /* or else just copy things */
      current_column++;
    }
  }
  if (line && col)
    DPRINTF2(DEBUG_READLINE, "line=%d, col=%d", *line, *col);
  scratchpad[j] = '\0';
  result = mysavestring(scratchpad);
  free(scratchpad);
  return (result);
}
コード例 #10
0
ファイル: pxping_win.c プロジェクト: bayasist/vbox
static void
pxping_icmp6_callback(struct pong6 *pong)
{
    DWORD nreplies;
    ICMPV6_ECHO_REPLY *reply;
    struct pbuf *p;
    struct icmp6_echo_hdr *icmph;
    size_t icmplen;
    ip6_addr_t src;
    int mapped;

    nreplies = Icmp6ParseReplies(pong->buf, (DWORD)pong->bufsize);
    if (nreplies == 0) {
        DWORD error = GetLastError();
        if (error == IP_REQ_TIMED_OUT) {
            DPRINTF2(("pong6: %p timed out\n", (void *)pong));
        }
        else {
            DPRINTF(("pong6: %p: Icmp6ParseReplies: error %d\n",
                     (void *)pong, error));
        }
        return;
    }

    reply = (ICMPV6_ECHO_REPLY *)pong->buf;

    mapped = pxremap_inbound_ip6(&src, (ip6_addr_t *)reply->Address.sin6_addr);
    if (mapped == PXREMAP_FAILED) {
        return;
    }

    /*
     * Reply data follows ICMPV6_ECHO_REPLY structure in memory, but
     * it doesn't tell us its size.  Assume it's equal the size of the
     * request.
     */
    icmplen = sizeof(*icmph) + pong->reqsize;
    p = pbuf_alloc(PBUF_IP, (u16_t)icmplen, PBUF_RAM);
    if (RT_UNLIKELY(p == NULL)) {
        return;
    }

    icmph = (struct icmp6_echo_hdr *)p->payload;
    icmph->type = ICMP6_TYPE_EREP;
    icmph->code = 0;
    icmph->chksum = 0;
    icmph->id = pong->reqicmph.id;
    icmph->seqno = pong->reqicmph.seqno;

    memcpy((u8_t *)p->payload + sizeof(*icmph),
           pong->buf + sizeof(*reply), pong->reqsize);

    icmph->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len,
                                      &src, &pong->reqsrc);
    ip6_output_if(p, /* :src */ &src, /* :dst */ &pong->reqsrc,
                  LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6,
                  pong->netif);
    pbuf_free(p);
}
コード例 #11
0
ファイル: pxdns.c プロジェクト: bayasist/vbox
/**
 * Forward request to the req::residx resolver in the pxdns::resolvers
 * array of upstream resolvers.
 *
 * Returns 1 on success, 0 on failure.
 */
static int
pxdns_forward_outbound(struct pxdns *pxdns, struct request *req)
{
    union sockaddr_inet *resolver;
    ssize_t nsent;

    DPRINTF2(("%s: req %p: sending to resolver #%lu\n",
              __func__, (void *)req, (unsigned long)req->residx));

    LWIP_ASSERT1(req->generation == pxdns->generation);
    LWIP_ASSERT1(req->residx < pxdns->nresolvers);
    resolver = &pxdns->resolvers[req->residx];

    if (resolver->sa.sa_family == AF_INET) {
        nsent = sendto(pxdns->sock4, req->data, req->size, 0,
                       &resolver->sa, sizeof(resolver->sin));
        
    }
    else if (resolver->sa.sa_family == AF_INET6) {
        if (pxdns->sock6 != INVALID_SOCKET) {
            nsent = sendto(pxdns->sock6, req->data, req->size, 0,
                           &resolver->sa, sizeof(resolver->sin6));
        }
        else {
            /* shouldn't happen, we should have weeded out IPv6 resolvers */
            return 0;
        }
    }
    else {
        /* shouldn't happen, we should have weeded out unsupported families */
        return 0;
    }

    if ((size_t)nsent == req->size) {
        return 1; /* sent */
    }

    if (nsent < 0) {
        DPRINTF2(("%s: send: %R[sockerr]\n", __func__, SOCKERRNO()));
    }
    else {
        DPRINTF2(("%s: sent only %lu of %lu\n",
                  __func__, (unsigned long)nsent, (unsigned long)req->size));
    }
    return 0; /* not sent, caller will retry as necessary */
}
コード例 #12
0
ファイル: pxdns.c プロジェクト: bayasist/vbox
static void
pxdns_query(struct pxdns *pxdns, struct udp_pcb *pcb, struct pbuf *p,
            ipX_addr_t *addr, u16_t port)
{
    struct request *req;
    int sent;

    if (pxdns->nresolvers == 0) {
        /* nothing we can do */
        pbuf_free(p);
        return;
    }

    req = calloc(1, sizeof(struct request) - 1 + p->tot_len);
    if (req == NULL) {
        pbuf_free(p);
        return;
    }

    /* copy request data */
    req->size = p->tot_len;
    pbuf_copy_partial(p, req->data, p->tot_len, 0);

    /* save client identity and client's request id */
    req->pcb = pcb;
    ipX_addr_copy(PCB_ISIPV6(pcb), req->client_addr, *addr);
    req->client_port = port;
    memcpy(&req->client_id, req->data, sizeof(req->client_id));

    /* slap our request id onto it */
    req->id = pxdns->id++;
    memcpy(req->data, &req->id, sizeof(u16_t));

    /* resolver to forward to */
    req->generation = pxdns->generation;
    req->residx = 0;

    /* prepare for relaying the reply back to guest */
    req->msg_reply.type = TCPIP_MSG_CALLBACK_STATIC;
    req->msg_reply.sem = NULL;
    req->msg_reply.msg.cb.function = pxdns_pcb_reply;
    req->msg_reply.msg.cb.ctx = (void *)req;

    DPRINTF2(("%s: req=%p: client id %d -> id %d\n",
              __func__, (void *)req, req->client_id, req->id));

    pxdns_request_register(pxdns, req);

    sent = pxdns_forward_outbound(pxdns, req);
    if (!sent) {
        sent = pxdns_rexmit(pxdns, req);
    }
    if (!sent) {
        pxdns_request_deregister(pxdns, req);
        pxdns_request_free(req);
    }
}
コード例 #13
0
ファイル: signals.c プロジェクト: junjiemars/rlwrap
static void
handle_sigTSTP(int signo)
{
    sigset_t all_signals;
    int error, saved_errno = errno;

    DEBUG_RANDOM_SLEEP;
    sigfillset(&all_signals);

    DPRINTF2(DEBUG_SIGNALS, "got %s, sending it to pgid %d", signal_name(signo), command_pid);
    zero_select_timeout();
    /* Hand the SIGTSTP down to command and its process group */
    if (command_pid && (error = kill(-command_pid, SIGTSTP))) {
        myerror(FATAL|USE_ERRNO, "Failed to deliver SIGTSTP");
    }

    if (within_line_edit)
        save_rl_state();


    mysignal(SIGTSTP, SIG_DFL);   /* reset disposition to default (i.e. suspend) */
    sigprocmask(SIG_UNBLOCK, &all_signals, NULL); /* respond to sleep- and wake-up signals  */
    kill(getpid(), SIGTSTP); /* suspend */
    /* keyboard gathers dust, kingdoms crumble,.... */

    /* .... */

    /* Beautiful princess types "fg", (or her father tries to kill us...) and we wake up HERE: */
    sigprocmask(SIG_BLOCK, &all_signals, NULL);
    mysignal(SIGTSTP, &handle_sigTSTP);
    DPRINTF0(DEBUG_SIGNALS, "woken up");

    /* On most systems, command's process group will have been woken up by the handler of
       the signal that woke us up. This doesn't seem to happen for SIGCONT on QNX, so here goes: */

#ifdef __QNX__
    if (command_pid && (error = kill(-command_pid, SIGCONT))) {
        myerror(FATAL|USE_ERRNO, "Failed to deliver SIGCONT");
    }
#endif

    if (within_line_edit) {
        restore_rl_state();
    } else {
        set_echo(FALSE);
        cr();
        if (skip_rlwrap())
            return;
        move_cursor_to_start_of_prompt(ERASE);
        cook_prompt_if_necessary();
        my_putstr(saved_rl_state.cooked_prompt);
    }
    adapt_tty_winsize(STDIN_FILENO, master_pty_fd);       /* just in case */
    errno = saved_errno;
    sigprocmask(SIG_UNBLOCK, &all_signals, NULL);
}
コード例 #14
0
void
pollmgr_del_slot(int slot)
{
    LWIP_ASSERT1(slot >= POLLMGR_SLOT_FIRST_DYNAMIC);

    DPRINTF2(("%s(%d): fd %d ! DELETED\n",
              __func__, slot, pollmgr.fds[slot].fd));

    pollmgr.fds[slot].fd = INVALID_SOCKET; /* see poll loop */
}
コード例 #15
0
ファイル: filter.c プロジェクト: rubicks/rlwrap
char *pass_through_filter(int tag, const char *buffer) {
    char *filtered;
    DPRINTF3(DEBUG_FILTERING, "to filter (%s, %d bytes) %s", tag2description(tag), (int) strlen(buffer), mangle_string_for_debug_log(buffer, MANGLE_LENGTH));
    if (filter_pid ==0)
        return mysavestring(buffer);
    write_to_filter((expected_tag = tag), buffer);
    filtered = read_from_filter(tag);
    DPRINTF2(DEBUG_FILTERING, "from filter (%d bytes) %s", (int) strlen(filtered), mangle_string_for_debug_log(filtered, MANGLE_LENGTH));
    return filtered;
}
コード例 #16
0
ファイル: string_utils.c プロジェクト: bak724/rlwrap
void remove_padding_and_terminate(char *buf, int length) {
  char *readptr, *copyptr;

  for (readptr = copyptr = buf; readptr < buf + length; readptr++) {
    if (*readptr != '\0')
      *copyptr++ = *readptr;
  }
  *copyptr = '\0';
  if (debug && strlen(buf) != length)
    DPRINTF2(DEBUG_TERMIO, "removed %d zero bytes (padding?) from %s", length - (int) strlen(buf), mangle_string_for_debug_log(buf, MANGLE_LENGTH));
}       
コード例 #17
0
/*
 * Must be called from pollmgr loop (via callbacks), so no locking.
 */
int
pollmgr_add(struct pollmgr_handler *handler, SOCKET fd, int events)
{
    int slot;

    DPRINTF2(("%s: new fd %d\n", __func__, fd));

    if (pollmgr.nfds == pollmgr.capacity) {
        struct pollfd *newfds;
        struct pollmgr_handler **newhdls;
        nfds_t newcap;
	nfds_t i;

        newcap = pollmgr.capacity * 2;

        newfds = (struct pollfd *)
            realloc(pollmgr.fds, newcap * sizeof(*pollmgr.fds));
        if (newfds == NULL) {
            perror("realloc");
            handler->slot = -1;
            return -1;
        }

        pollmgr.fds = newfds; /* don't crash/leak if realloc(handlers) fails */
        /* but don't update capacity yet! */

        newhdls = (struct pollmgr_handler **)
            realloc(pollmgr.handlers, newcap * sizeof(*pollmgr.handlers));
        if (newhdls == NULL) {
            perror("realloc");
            /* if we failed to realloc here, then fds points to the
             * new array, but we pretend we still has old capacity */
            handler->slot = -1;
            return -1;
        }

        pollmgr.handlers = newhdls;
        pollmgr.capacity = newcap;

        for (i = pollmgr.nfds; i < newcap; ++i) {
            newfds[i].fd = -1;
            newfds[i].events = 0;
            newfds[i].revents = 0;
            newhdls[i] = NULL;
        }
    }

    slot = pollmgr.nfds;
    ++pollmgr.nfds;

    pollmgr_add_at(slot, handler, fd, events);
    return slot;
}
コード例 #18
0
ファイル: pxudp.c プロジェクト: gvsurenderreddy/virtualbox
/**
 * Proxy udp_pcbs are expired by timer, which is signaled by passing
 * NULL pbuf to the udp_recv() callback.  At that point the pcb is
 * removed from the list of proxy udp pcbs so no new datagrams will be
 * delivered.
 */
static void
pxudp_pcb_expired(struct pxudp *pxudp)
{
    struct udp_pcb *pcb;

    DPRINTF2(("%s: pxudp %p, pcb %p, sock %d: expired\n",
              __func__, (void *)pxudp, (void *)pxudp->pcb, pxudp->sock));

    pcb = pxudp_pcb_dissociate(pxudp);
    if (pcb != NULL) {
        udp_remove(pcb);
    }

    pxudp_chan_send_weak(POLLMGR_CHAN_PXUDP_DEL, pxudp);
}
コード例 #19
0
ファイル: task.c プロジェクト: chunhualiu/OpenNT
UINT WINAPI mmTaskCreate(LPTASKCALLBACK lpfn, HTASK FAR * lph, DWORD dwInst)
{
    MMTaskStruct     TaskStruct;
    char             szName[20];
    UINT             wRes;
    HTASK            hTask;

    /*
        create another app. so that we can run the stream outside of
        the context of the app. 
    */

    if (!LoadString(ghInst, IDS_TASKSTUB, szName, sizeof(szName)))
        return TASKERR_NOTASKSUPPORT;

    TaskStruct.cb = sizeof(TaskStruct);
    TaskStruct.lpfn = lpfn;
    TaskStruct.dwInst = dwInst;
    TaskStruct.dwStack = 0L;

    wRes = BWinExec(szName, SW_SHOWNOACTIVATE, &TaskStruct);

    if (wRes > 32)
    {
        hTask = wRes;
        wRes = MMSYSERR_NOERROR;
    }
    else if (wRes == 0)
    {
        wRes = TASKERR_OUTOFMEMORY;
        hTask = NULL;
    }
    else
    {
        wRes  = TASKERR_NOTASKSUPPORT;
        hTask = NULL;
    }
    
    if (lph)
        *lph = hTask;

    DPRINTF2("mmTaskCreate: hTask = %04X, wErr = %04X\r\n", hTask, wRes);

    return wRes;
}
コード例 #20
0
ファイル: caching.c プロジェクト: hh/emacs
void recoverFromCache() {
	int i;
	char *readedUntil;
	assert(s_cache.cpi >= 1);
	s_cache.activeCache = 0;
/*	s_cache.recoveringFromCache = 1;*/
	DPRINTF1(": reading from cache\n");
	readedUntil = s_cache.cp[0].lbcc;
	for(i=1; i<s_cache.cpi; i++) {
/*fprintf(dumpOut,"try to recover cache point %d\n",i);fflush(dumpOut);*/
		if (cachedInputPass(i,&readedUntil) == 0) break;
		if (cachedIncludedFilePass(i) == 0) break;
	}
	assert(i > 1);
	/* now, recover state from the cache point 'i-1' */
	DPRINTF2("recovering cache point %d\n",i-1);
	recoverCachePoint(i-1, readedUntil, 1);
}
コード例 #21
0
ファイル: f_generic.c プロジェクト: andreiw/polaris
int32_t
_m_get_media_info(rmedia_handle_t *handle, void *ip)
{
	smmedium_prop_t *med_info = (smmedium_prop_t *)ip;
struct fd_char fdchar;

	/* Check for valid handle */
	if (handle == NULL) {
		DPRINTF("Null Handle\n");
		errno = EINVAL;
		return (-1);
	}
	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
		DPRINTF("Invalid signature in handle.\n");
		DPRINTF2(
			"Signature expected=0x%x found=0x%x\n",
				LIBSMEDIA_SIGNATURE,
				handle->sm_signature);
		errno = EINVAL;
		return (-1);
	}
	if (handle->sm_fd < 0) {
		DPRINTF("Invalid file handle.\n");
		errno = EINVAL;
		return (-1);
	}
	if (ioctl(handle->sm_fd, FDIOGCHAR, &fdchar) < 0) {
		PERROR("Ioctl failed :");
		return (-1);
	}

	med_info->sm_media_type = SM_FLOPPY;
	med_info->sm_blocksize  = fdchar.fdc_sec_size;
	med_info->sm_capacity = fdchar.fdc_ncyl * fdchar.fdc_nhead
					* fdchar.fdc_secptrack;
	med_info->sm_pcyl = fdchar.fdc_ncyl;
	med_info->sm_nhead = fdchar.fdc_nhead;
	med_info->sm_nsect = fdchar.fdc_secptrack;
	return (0);
}
コード例 #22
0
ファイル: caching.c プロジェクト: hh/emacs
void poseCachePoint(int inputCaching) {
	struct cachePoint *pp;
	if (s_cache.activeCache == 0) return;
	if (inStacki != 0 || macStacki != 0) return;
	if (s_cache.cpi >= MAX_CACHE_POINTS) {
		s_cache.activeCache = 0;
		return;
	}
	if (inputCaching) cacheInput();
	if (s_cache.activeCache == 0) return;
	if (tmpWorkMemoryi != 0) return; /* something in non cached tmp memory */
	pp = &s_cache.cp[s_cache.cpi];
	DPRINTF2("posing cache point %d \n",s_cache.cpi);
//&fprintf(dumpOut,"posing cache point %d\n",s_cache.cpi);
	FILL_cachePoint(pp, s_topBlock, *s_topBlock,
						ppmMemoryi, cxMemory->i, mbMemoryi, 
						s_cache.lbcc, s_cache.ibi, 
					cFile.lineNumber, cFile.ifDeep, cFile.ifstack,
						s_javaStat, s_count
					);
	s_cache.cpi ++;
}
コード例 #23
0
ファイル: an.c プロジェクト: ajinkya93/OpenBSD
void
an_txeof(struct an_softc *sc, u_int16_t status)
{
	struct ifnet *ifp = &sc->sc_ic.ic_if;
	int cur, id;

	sc->sc_tx_timer = 0;
	ifq_clr_oactive(&ifp->if_snd);

	id = CSR_READ_2(sc, AN_TX_CMP_FID);
	CSR_WRITE_2(sc, AN_EVENT_ACK, status & (AN_EV_TX | AN_EV_TX_EXC));

	if (status & AN_EV_TX_EXC)
		ifp->if_oerrors++;
	else
		ifp->if_opackets++;

	cur = sc->sc_txcur;
	if (sc->sc_txd[cur].d_fid == id) {
		sc->sc_txd[cur].d_inuse = 0;
		DPRINTF2(("an_txeof: sent %x/%d\n", id, cur));
		AN_INC(cur, AN_TX_RING_CNT);
		sc->sc_txcur = cur;
	} else {
		for (cur = 0; cur < AN_TX_RING_CNT; cur++) {
			if (id == sc->sc_txd[cur].d_fid) {
				sc->sc_txd[cur].d_inuse = 0;
				break;
			}
		}
		if (ifp->if_flags & IFF_DEBUG)
			printf("%s: tx mismatch: "
			    "expected %x(%d), actual %x(%d)\n",
			    sc->sc_dev.dv_xname,
			    sc->sc_txd[sc->sc_txcur].d_fid, sc->sc_txcur,
			    id, cur);
	}
}
コード例 #24
0
ファイル: signals.c プロジェクト: junjiemars/rlwrap
int
adapt_tty_winsize(int from_fd, int to_fd)
{
    int ret;

    struct winsize old_winsize = winsize;

    ret = ioctl(from_fd, TIOCGWINSZ, &winsize);
    DPRINTF1(DEBUG_SIGNALS, "ioctl (..., TIOCGWINSZ) = %d", ret);
    if (winsize.ws_col != old_winsize.ws_col || winsize.ws_row != old_winsize.ws_row) {
        DPRINTF4(DEBUG_SIGNALS, "ws.col: %d -> %d, ws.row: %d -> %d", old_winsize.ws_col, winsize.ws_col, old_winsize.ws_row, winsize.ws_row);
        if (always_readline &&!dont_wrap_command_waits())  /* if --always_readline option is set, the client will probably spew a */
            deferred_adapt_commands_window_size = TRUE;      /* volley of control chars at us when its terminal is resized. Hence we don't do it now */
        else {
            ret = ioctl(to_fd, TIOCSWINSZ, &winsize);
            DPRINTF1(DEBUG_SIGNALS, "ioctl (..., TIOCSWINSZ) = %d", ret);
        }
        DPRINTF2(DEBUG_READLINE, "rl_prompt: %s, line_buffer: %s", mangle_string_for_debug_log(rl_prompt, 100), rl_line_buffer);
        rl_set_screen_size(winsize.ws_row, winsize.ws_col); /* this is safe: we know that right now rlwrap is not calling
                                                           the readline library because we keep SIGWINCH blocked all the time */

        if (!within_line_edit && !skip_rlwrap()) {
            wipe_textarea(&old_winsize);

            received_WINCH = TRUE;           /* we can't start line edit in signal handler, so we only set a flag */
        } else if (within_line_edit) {      /* try to keep displayed line tidy */
            wipe_textarea(&old_winsize);
            rl_on_new_line();
            rl_redisplay();

        }

        return (!always_readline || dont_wrap_command_waits()); /* pass the signal on (except when always_readline is set and command is not waiting) */
    } else {                      /* window size has not changed */
        return FALSE;
    }

}
コード例 #25
0
ファイル: readline.c プロジェクト: andreyvit/rlwrap
/* format line and add it to history list, avoiding duplicates if necessary */
static void
my_add_history(char *line)
{       
  int lookback, count, here;
  char *new_entry, *filtered_line;

  filtered_line =  pass_through_filter(TAG_HISTORY, line);
 
  
  switch (history_duplicate_avoidance_policy) { 
  case KEEP_ALL_DOUBLES:
    lookback = 0; break;
  case ELIMINATE_SUCCESIVE_DOUBLES:
    lookback = 1; break;
  case ELIMINATE_ALL_DOUBLES:
    lookback = history_length; break;
  }

  
  new_entry = filtered_line;    
  
  lookback = min(history_length, lookback);      
  for (count = 0, here = history_length + history_base - 1;
       count < lookback ;
       count++, here--) {
    /* DPRINTF3(DEBUG_READLINE, "strcmping <%s> and <%s> (count = %d)", line, history_get(here)->line ,count); */
    if (strncmp(new_entry, history_get(here) -> line, 10000) == 0) {
      HIST_ENTRY *entry = remove_history (here - history_base); /* according to the history library doc this should be
                                                                   remove_history(here) @@@?*/
      DPRINTF2(DEBUG_READLINE, "removing duplicate entry #%d (%s)", here, entry->line);
      free_foreign(entry->line);
      free_foreign(entry);
    }
  }
  add_history(new_entry);
  free(new_entry);
}
コード例 #26
0
ファイル: pxdns.c プロジェクト: bayasist/vbox
/**
 * Forward request to the next resolver in the pxdns::resolvers array
 * of upstream resolvers if there are any left.
 */
static int
pxdns_rexmit(struct pxdns *pxdns, struct request *req)
{
    int sent;

    if (/* __predict_false */ req->generation != pxdns->generation) {
        DPRINTF2(("%s: req %p: generation %lu != pxdns generation %lu\n",
                  __func__, (void *)req,
                  (unsigned long)req->generation,
                  (unsigned long)pxdns->generation));
        return 0;
    }

    LWIP_ASSERT1(req->residx < pxdns->nresolvers);
    do {
        if (++req->residx == pxdns->nresolvers) {
            return 0;
        }

        sent = pxdns_forward_outbound(pxdns, req);
    } while (!sent);

    return 1;
}
コード例 #27
0
/* format line and add it to history list, avoiding duplicates if necessary */
static void
my_add_history(char *line)
{       
  int lookback, count, here;
  char *new_entry, *filtered_line;

  filtered_line =  pass_through_filter(TAG_HISTORY, line);
 
  
  switch (history_duplicate_avoidance_policy) { 
  case KEEP_ALL_DOUBLES:
    lookback = 0; break;
  case ELIMINATE_SUCCESIVE_DOUBLES:
    lookback = 1; break;
  case ELIMINATE_ALL_DOUBLES:
    lookback = history_length; break;
  }

  
  new_entry = filtered_line;    
  
  lookback = min(history_length, lookback);      
  for (count = 0, here = history_length - 1;
       count < lookback ;
       count++, here--) {
    DPRINTF4(DEBUG_READLINE, "strcmping <%s> and <%s> (count = %d, here = %d)", line, history_get(history_base + here)->line ,count, here);
    if (strncmp(new_entry, history_get(history_base + here) -> line, 10000) == 0) { /* history_get uses the logical offset history_base .. */
       HIST_ENTRY *entry = remove_history (here);                                   /* .. but remove_history doesn't!                      */
      DPRINTF2(DEBUG_READLINE, "removing duplicate entry #%d (%s)", here, entry->line);
      free_foreign(entry->line);
      free_foreign(entry);
    }
  }
  add_history(new_entry);
  free(new_entry);
}
コード例 #28
0
int cook_prompt_if_necessary () {
  char *pre_cooked, *rubbish_from_alternate_screen,  *filtered, *uncoloured, *cooked, *p, *non_rubbish = NULL;
  static char **term_ctrl_seqs[] 
    = {&term_rmcup, &term_rmkx, NULL}; /* (NULL-terminated) list of (pointers to) term control sequences that may be
                                       used by clients to return from an 'alternate screen'. If we spot one of those,
                                       assume that it, and anything before it, is rubbish and better left untouched */

  char ***tcptr;
  filtered = NULL;

  DPRINTF2(DEBUG_READLINE, "Prompt <%s>: %s", saved_rl_state.raw_prompt, prompt_is_still_uncooked ? "still raw" : "cooked already");

  if (saved_rl_state.cooked_prompt)    /* if (!prompt_is_still_uncooked) bombs with multi-line paste. Apparently
                                        prompt_is_still_uncooked can be FALSE while saved_rl_state.cooked_prompt = NULL. Ouch!@@@! */
    return FALSE;  /* cooked already */
  
  pre_cooked = mysavestring(saved_rl_state.raw_prompt);

  
  for (tcptr = term_ctrl_seqs; *tcptr; tcptr++) { 
    /* find last occurence of one of term_ctrl_seq */
    if (**tcptr && (p = mystrstr(pre_cooked, **tcptr))) {
      p += strlen(**tcptr);  /* p now points 1 char past term control sequence */ 
      if (p > non_rubbish) 
        non_rubbish = p; 
    }   
  }     
  /* non_rubbish now points 1 past the last 'alternate screen terminating' control char in prompt */
  if (non_rubbish) { 
    rubbish_from_alternate_screen = pre_cooked;
    pre_cooked = mysavestring(non_rubbish);
    *non_rubbish = '\0'; /* 0-terminate rubbish_from_alternate_screen */ 
  } else { 
    rubbish_from_alternate_screen = mysavestring("");
  }
  

  unbackspace(pre_cooked); /* programs that display a running counter would otherwise make rlwrap keep prompts
                              like " 1%\r 2%\r 3%\ ......" */

  if ( /* raw prompt doesn't match '--only-cook' regexp */
      (prompt_regexp && ! match_regexp(pre_cooked, prompt_regexp, FALSE)) ||
       /* now filter it, but filter may "refuse" the prompt */
      (strcmp((filtered =  pass_through_filter(TAG_PROMPT, pre_cooked)), "_THIS_CANNOT_BE_A_PROMPT_")== 0)) { 
    /* don't cook, eat raw (and eat nothing if patient) */       
    saved_rl_state.cooked_prompt =  (impatient_prompt ? mysavestring(pre_cooked) : mysavestring("")); 
    /* NB: if impatient, the rubbish_from_alternate_screen has been output already, no need to send it again */  
    free(pre_cooked);
    free(filtered); /* free(NULL) is never an error */
    return FALSE;
  }     
  free(pre_cooked);
  if(substitute_prompt) {
    uncoloured = mysavestring(substitute_prompt); 
    free(filtered);
  } else {
    uncoloured = filtered;
  }     
  if (colour_the_prompt) { 
    cooked =  colourise(uncoloured);
    free(uncoloured);
  } else {
    cooked = uncoloured;
  }
  if (! impatient_prompt)  /* in this case our rubbish hasn't been output yet. Output it now, but don't store
                              it in the prompt, as this may be re-printed e.g. after resuming a suspended rlwrap */
                              
    write_patiently(STDOUT_FILENO,rubbish_from_alternate_screen, strlen(rubbish_from_alternate_screen), "to stdout");
  saved_rl_state.cooked_prompt = cooked;
  return TRUE;
}       
コード例 #29
0
static void
line_handler(char *line)
{
  char *rewritten_line, *filtered_line;
  
  if (line == NULL) {           /* EOF on input, forward it  */
    DPRINTF1(DEBUG_READLINE, "EOF detected, writing character %d", term_eof);
    /* colour_the_prompt = FALSE; don't mess with the cruft that may come out of dying command @@@ but command may not die!*/
    write_EOF_to_master_pty();
  } else {
    if (*line &&                 /* forget empty lines  */
        redisplay &&             /* forget passwords    */
        !forget_line &&          /* forget lines entered by CTRL-O */
        !match_regexp(line, forget_regexp, TRUE)) {     /* forget lines (case-inseitively) matching -g option regexp */ 
      my_add_history(line);
    }
    forget_line = FALSE; /* until CTRL-O is used again */

    /* Time for a design decision: when we send the accepted line to the client command, it will most probably be echoed
       back. We have two choices: we leave the entered line on screen and suppress just enough of the clients output (I
       believe this is what rlfe does), or we remove the entered input (but not the prompt!) and let it be replaced by
       the echo.

       This is what we do; as a bonus, if the program doesn't echo, e.g. at a password prompt, the **** which has been
       put there by our homegrown_redisplay function will be removed (@@@is this what we want?)

       I think this method is more natural for multi-line input as well, (we will actually see our multi-line input as
       multiple lines) but not everyone will agree with that.
          
       O.K, we know for sure that cursor is at start of line. When clients output arrives, it will be printed at
       just the right place - but first we 'll erase the user input (as it may be about to be changed by the filter) */
    
    rl_delete_text(0, rl_end);  /* clear line  (after prompt) */
    rl_point = 0;
    my_redisplay();             /* and redisplay (this time without user input, cf the comments for the line_handler() function below) */

    rewritten_line =
      (multiline_separator ? 
       search_and_replace(multiline_separator, "\n", line, 0, NULL,
                          NULL) : mysavestring(line));


    
      
    if (redisplay)
      filtered_line = pass_through_filter(TAG_INPUT, rewritten_line);
    else { /* password, none of filters business */
      pass_through_filter(TAG_INPUT, "***"); /* filter some input anyway, to keep filter in sync (result is discarded).  */
      filtered_line = mysavestring(rewritten_line);
    }   
    free(rewritten_line);
        
    
    /* do we have to adapt clients winzsize now? */
    if (deferred_adapt_commands_window_size) {
      adapt_tty_winsize(STDIN_FILENO, master_pty_fd);
      kill(-command_pid, SIGWINCH);
      deferred_adapt_commands_window_size = FALSE;
    }


    
    /*OK, now feed line to underlying command and wait for the echo to come back */
    put_in_output_queue(filtered_line);
    DPRINTF2(DEBUG_READLINE, "putting %d bytes %s in output queue", (int) strlen(rewritten_line),
             mangle_string_for_debug_log(rewritten_line, 40));
    write_EOL_to_master_pty(return_key ? &return_key : "\n");

    accepted_lines++;
    free_foreign(line);         /* free_foreign because line was malloc'ed by readline, not by rlwrap */
    free(filtered_line);        /* we're done with them  */
        
    return_key = 0;
    within_line_edit = FALSE;
    if(!RL_ISSTATE(RL_STATE_MACROINPUT)) /* when called during playback of a multi-line macro, line_handler() will be called more 
                                            than once whithout re-entering main_loop(). If we'd remove it here, the second call
                                            would crash  */ 
       rl_callback_handler_remove();
    set_echo(FALSE);
    free(saved_rl_state.input_buffer);
    free(saved_rl_state.raw_prompt);
    free(saved_rl_state.cooked_prompt); 
    
    saved_rl_state.input_buffer = mysavestring("");
    saved_rl_state.raw_prompt = mysavestring("");
    saved_rl_state.cooked_prompt = NULL;
    saved_rl_state.point = 0;
    saved_rl_state.already_saved = TRUE;
    redisplay  = TRUE;

    if (one_shot_rlwrap)
      write_EOF_to_master_pty();
  }
}
コード例 #30
0
static void
pollmgr_loop(void)
{
    int nready;
    SOCKET delfirst;
    SOCKET *pdelprev;
    int i;

    for (;;) {
#ifndef RT_OS_WINDOWS
        nready = poll(pollmgr.fds, pollmgr.nfds, -1);
#else
        int rc = RTWinPoll(pollmgr.fds, pollmgr.nfds,RT_INDEFINITE_WAIT, &nready);
        if (RT_FAILURE(rc)) {
            err(EXIT_FAILURE, "poll"); /* XXX: what to do on error? */
            /* NOTREACHED*/
        }
#endif

	DPRINTF2(("%s: ready %d fd%s\n",
                  __func__, nready, (nready == 1 ? "" : "s")));

        if (nready < 0) {
            if (errno == EINTR) {
                continue;
            }

            err(EXIT_FAILURE, "poll"); /* XXX: what to do on error? */
            /* NOTREACHED*/
        }
        else if (nready == 0) { /* cannot happen, we wait forever (-1) */
            continue;           /* - but be defensive */
        }


        delfirst = INVALID_SOCKET;
        pdelprev = &delfirst;

        for (i = 0; (nfds_t)i < pollmgr.nfds && nready > 0; ++i) {
            struct pollmgr_handler *handler;
            SOCKET fd; 
            int revents, nevents;

	    fd = pollmgr.fds[i].fd;
	    revents = pollmgr.fds[i].revents;

            /*
             * Channel handlers can request deletion of dynamic slots
             * by calling pollmgr_del_slot() that clobbers slot's fd.
             */
            if (fd == INVALID_SOCKET && i >= POLLMGR_SLOT_FIRST_DYNAMIC) {
                /* adjust count if events were pending for that slot */
                if (revents != 0) {
                    --nready;
                }

                /* pretend that slot handler requested deletion */
                nevents = -1;
                goto update_events;
            }

            if (revents == 0) {
                continue; /* next fd */
            }
            --nready;

            handler = pollmgr.handlers[i];

            if (handler != NULL && handler->callback != NULL) {
#if LWIP_PROXY_DEBUG /* DEBUG */
                if (i < POLLMGR_SLOT_FIRST_DYNAMIC) {
                    if (revents == POLLIN) {
                        DPRINTF2(("%s: ch %d\n", __func__, i));
                    }
                    else {
                        DPRINTF2(("%s: ch %d @ revents 0x%x!\n",
                                  __func__, i, revents));
                    }
                }
                else {
                    DPRINTF2(("%s: fd %d @ revents 0x%x\n",
                              __func__, fd, revents));
                }
#endif /* DEBUG */
                nevents = (*handler->callback)(handler, fd, revents);
            }
            else {
                DPRINTF0(("%s: invalid handler for fd %d: ", __func__, fd));
                if (handler == NULL) {
                    DPRINTF0(("NULL\n"));
                }
                else {
                    DPRINTF0(("%p (callback = NULL)\n", (void *)handler));
                }
                nevents = -1;   /* delete it */
            }

          update_events:
            if (nevents >= 0) {
                if (nevents != pollmgr.fds[i].events) {
                    DPRINTF2(("%s: fd %d ! nevents 0x%x\n",
                              __func__, fd, nevents));
                }
                pollmgr.fds[i].events = nevents;
            }
	    else if (i < POLLMGR_SLOT_FIRST_DYNAMIC) {
                /* Don't garbage-collect channels. */
                DPRINTF2(("%s: fd %d ! DELETED (channel %d)\n",
                          __func__, fd, i));
                pollmgr.fds[i].fd = INVALID_SOCKET;
                pollmgr.fds[i].events = 0;
                pollmgr.fds[i].revents = 0;
                pollmgr.handlers[i] = NULL;
            }
            else {
                DPRINTF2(("%s: fd %d ! DELETED\n", __func__, fd));

                /* schedule for deletion (see g/c loop for details) */
                *pdelprev = i;	/* make previous entry point to us */
                pdelprev = &pollmgr.fds[i].fd;

                pollmgr.fds[i].fd = INVALID_SOCKET; /* end of list (for now) */
                pollmgr.fds[i].events = POLLMGR_GARBAGE;
                pollmgr.fds[i].revents = 0;
                pollmgr.handlers[i] = NULL;
            }
        } /* processing loop */


        /*
	 * Garbage collect and compact the array.
         *
         * We overload pollfd::fd of garbage entries to store the
         * index of the next garbage entry.  The garbage list is
         * co-directional with the fds array.  The index of the first
         * entry is in "delfirst", the last entry "points to"
         * INVALID_SOCKET.
         *
         * See update_events code for nevents < 0 at the end of the
         * processing loop above.
	 */
        while (delfirst != INVALID_SOCKET) {
            const int last = pollmgr.nfds - 1;

            /*
             * We want a live entry in the last slot to swap into the
             * freed slot, so make sure we have one.
             */
            if (pollmgr.fds[last].events == POLLMGR_GARBAGE /* garbage */
                || pollmgr.fds[last].fd == INVALID_SOCKET)  /* or killed */
            {
                /* drop garbage entry at the end of the array */
                --pollmgr.nfds;

                if (delfirst == last) {
                    /* congruent to delnext >= pollmgr.nfds test below */
                    delfirst = INVALID_SOCKET; /* done */
                }
            }
            else {
                const SOCKET delnext = pollmgr.fds[delfirst].fd;

                /* copy live entry at the end to the first slot being freed */
                pollmgr.fds[delfirst] = pollmgr.fds[last]; /* struct copy */
                pollmgr.handlers[delfirst] = pollmgr.handlers[last];
                pollmgr.handlers[delfirst]->slot = (int)delfirst;
                --pollmgr.nfds;

                if ((nfds_t)delnext >= pollmgr.nfds) {
                    delfirst = INVALID_SOCKET; /* done */
                }
                else {
                    delfirst = delnext;
                }
            }

            pollmgr.fds[last].fd = INVALID_SOCKET;
            pollmgr.fds[last].events = 0;
            pollmgr.fds[last].revents = 0;
            pollmgr.handlers[last] = NULL;
        }
    } /* poll loop */
}