rem: s = (unsigned char *)ip->ungotten;
context: long scheme_get_byte_string_unless(const char *who,				   Scheme_Object *port,				   char *buffer, long offset, long size,				   int only_avail,				   int peek, Scheme_Object *peek_skip,				   Scheme_Object *unless_evt){  Scheme_Input_Port *ip;  long got = 0, total_got = 0, gc;  int special_ok = special_is_ok, check_special;  Scheme_Get_String_Fun gs;  Scheme_Peek_String_Fun ps;  /* back-door argument: */  special_is_ok = 0;  if (!size) {    if (only_avail == -1) {      /* We might need to break. */      if (scheme_current_thread->external_break) {	scheme_thread_block_enable_break(0.0, 1);	scheme_current_thread->ran_some = 1;      }    }    return 0;  }  if (!peek_skip)    peek_skip = scheme_make_integer(0);  ip = (Scheme_Input_Port *)port;  gs = ip->get_string_fun;  ps = ip->peek_string_fun;  while (1) {    SCHEME_USE_FUEL(1);    CHECK_PORT_CLOSED(who, "input", port, ip->closed);    if (ip->input_lock)      scheme_wait_input_allowed(ip, only_avail);    if (only_avail == -1) {      /* We might need to break. */      if (scheme_current_thread->external_break) {	scheme_thread_block_enable_break(0.0, 1);	scheme_current_thread->ran_some = 1;      }    }    if ((ip->ungotten_count || pipe_char_count(ip->peeked_read))	&& (!total_got || !peek)) {      long l, i;      unsigned char *s;      i = ip->ungotten_count;      s = (unsigned char *)ip->ungotten;      /* s is in reverse order */      if (peek) {	if (!SCHEME_INTP(peek_skip) || (i < SCHEME_INT_VAL(peek_skip))) {	  peek_skip = scheme_bin_minus(peek_skip, scheme_make_integer(i));	  i = 0;	} else {	  i -= SCHEME_INT_VAL(peek_skip);	  peek_skip = scheme_make_integer(0);	}      }      if (i < size)	l = i;      else	l = size;      size -= l;      while (l--) {	buffer[offset + got++] = s[--i];      }      if (!peek)	ip->ungotten_count = i;      l = pipe_char_count(ip->peeked_read);      if (size && l) {	if (SCHEME_INTP(peek_skip) && (l > SCHEME_INT_VAL(peek_skip))) {	  l -= SCHEME_INT_VAL(peek_skip);	  if (l > size)	    l = size;	  if (l) {	    scheme_get_byte_string("depipe", ip->peeked_read,				   buffer, offset + got, l,				   1, peek, peek_skip);	    size -= l;	    got += l;	    peek_skip = scheme_make_integer(0);	    if (!peek && ip->progress_evt)	      post_progress(ip);	  }	} else	  peek_skip = scheme_bin_minus(peek_skip, scheme_make_integer(l));      }      check_special = (!got || peek);    } else      check_special = 1;    if (check_special && ip->ungotten_special) {      if (!special_ok) {	if (!peek && ip->progress_evt)	  post_progress(ip);	scheme_bad_time_for_special(who, port);      }      if (!peek) {	ip->special = ip->ungotten_special;	ip->ungotten_special = NULL;      } else {	if (peek_skip != scheme_make_integer(0))	  scheme_bad_time_for_special(who, port);      }      if (!peek) {	if (ip->p.position >= 0)	  ip->p.position++;	if (ip->p.count_lines)	  inc_pos((Scheme_Port *)ip, 1);      }      if (!peek && ip->progress_evt)	post_progress(ip);      return SCHEME_SPECIAL;    }    if (got && ((only_avail == 1) || (only_avail == -1)))      only_avail = 2;    /* If we get this far in peek mode, ps is NULL, peek_skip is non-zero, and       we haven't gotten anything so far, it means that we need to read before we       can actually peek. Handle this case with a recursive peek that starts       from the current position, then set peek_skip to 0 and go on. */    while (peek && !ps && (peek_skip != scheme_make_integer(0)) && !total_got && !got	   && (ip->pending_eof < 2)) {      char *tmp;      int v, pcc;      long skip;      Scheme_Cont_Frame_Data cframe;#     define MAX_SKIP_TRY_AMOUNT 65536      if (SCHEME_INTP(peek_skip)) {	skip = SCHEME_INT_VAL(peek_skip);	if (skip > MAX_SKIP_TRY_AMOUNT)	  skip = MAX_SKIP_TRY_AMOUNT;      } else	skip = MAX_SKIP_TRY_AMOUNT;      tmp = (char *)scheme_malloc_atomic(skip);      pcc = pipe_char_count(ip->peeked_read);      if (only_avail == -1) {	/* To implement .../enable-break, we enable	   breaks during the skip-ahead peek. */	scheme_push_break_enable(&cframe, 1, 1);      }      v = scheme_get_byte_string_unless(who, port, tmp, 0, skip,					(only_avail == 2) ? 2 : 0,					1, scheme_make_integer(ip->ungotten_count + pcc),					unless_evt);      if (only_avail == -1) {	scheme_pop_break_enable(&cframe, 0);      }      if (v == EOF) {	ip->p.utf8state = 0;	return EOF;      } else if (v == SCHEME_SPECIAL) {	ip->special = NULL;	scheme_bad_time_for_special(who, port);      } else if (v == skip) {	peek_skip = scheme_bin_minus(peek_skip, scheme_make_integer(skip));	/* Ok... ready to continue (if skip == peek_skip) */      } else	return 0;    }    if (size) {      int nonblock;      if (only_avail == 2) {	if (got)	  nonblock = 2;	else	  nonblock = 1;      } else if (only_avail == -1)	nonblock = -1;      else	nonblock = 0;      if (unless_evt && SAME_TYPE(SCHEME_TYPE(unless_evt), scheme_progress_evt_type))	unless_evt = SCHEME_PTR2_VAL(unless_evt);      if (ip->pending_eof > 1) {	ip->pending_eof = 1;	gc = EOF;      } else {	/* Call port's get or peek function. But first, set up	   an "unless" to detect other accesses of the port	   if we block. */	Scheme_Object *unless;	  	if (nonblock > 0) {	  if (ip->unless)	    unless = ip->unless;	  else	    unless = NULL;	} else if (ip->unless_cache) {	  if (ip->unless) {	    unless = ip->unless;	    /* Setting car to #f means that it can't be recycled */	    SCHEME_CAR(unless) = scheme_false;	  } else if (SCHEME_TRUEP(ip->unless_cache)) {	    unless = ip->unless_cache;	    ip->unless_cache = scheme_false;	    ip->unless = unless;	  } else {	    unless = scheme_make_pair(NULL, NULL);	    ip->unless = unless;	  }	  if (unless_evt)	    SCHEME_CDR(unless) = unless_evt;	} else	  unless = unless_evt;	/* Finally, call port's get or peek: */	if (peek && ps)	  gc = ps(ip, buffer, offset + got, size, peek_skip, nonblock, unless);	else {	  gc = gs(ip, buffer, offset + got, size, nonblock, unless);	  if (!peek && gc && ip->progress_evt	      && (gc != EOF) 	      && (gc != SCHEME_UNLESS_READY))	    post_progress(ip);	}	/* Let other threads know that something happened,	   and/or deregister this thread's request for information. */	if (unless && ip->unless_cache) {	  if (!SCHEME_CAR(unless)) {	    /* Recycle "unless", since we were the only user */	    ip->unless_cache = unless;	    SCHEME_CDR(unless) = NULL;	  } else {	    if (SCHEME_TRUEP(SCHEME_CAR(unless))) {	      /* gc should be SCHEME_UNLESS_READY; only a user		 port without a peek can incorrectly produce something 		 else */	      if (gc == SCHEME_UNLESS_READY) {		gc = 0;	      }	    } else if (gc) {	      /* Notify other threads that something happened */	      SCHEME_CAR(unless) = scheme_true;	    }	  }	  ip->unless = NULL;	}      }      if (gc == SCHEME_SPECIAL) {	if (!got && !total_got && special_ok) {	  if (!peek) {	    if (ip->p.position >= 0)	      ip->p.position++;	    if (ip->p.count_lines)	      inc_pos((Scheme_Port *)ip, 1);	  }	  	  return SCHEME_SPECIAL;	}	if ((got || total_got) && only_avail) {	  ip->ungotten_special = ip->special;	  ip->special = NULL;	  gc = 0;	} else {	  ip->special = NULL;	  scheme_bad_time_for_special(who, port);	  return 0;	}      } else if (gc == EOF) {	ip->p.utf8state = 0;	if (!got && !total_got) {	  if (peek && ip->pending_eof)	    ip->pending_eof = 2;	  return EOF;	}	/* remember the EOF for next time */	if (ip->pending_eof)	  ip->pending_eof = 2;	gc = 0;	size = 0; /* so that we stop */      } else if (gc == SCHEME_UNLESS_READY) {	gc = 0;	size = 0; /* so that we stop */      }      mzAssert(gc >= 0);    } else      gc = 0;    got += gc;    if (peek)      peek_skip = quick_plus(peek_skip, gc);    size -= gc;    if (!peek) {      /****************************************************/      /* Adjust position information for chars got so far */      /****************************************************/      /* We don't get here if SCHEME_SPECIAL is returned, so	 the positions are updated separately in the two	 returning places above. */      if (ip->p.position >= 0)	ip->p.position += got;      if (ip->p.count_lines)	do_count_lines((Scheme_Port *)ip, buffer, offset, got);    } else if (!ps) {      /***************************************************/      /* save newly peeked string for future peeks/reads */      /***************************************************/      if (gc) {	if ((gc == 1) && !ip->ungotten_count && !ip->peeked_write) {	  ip->ungotten[ip->ungotten_count++] = buffer[offset];	} else {	  if (!ip->peeked_write) {	    Scheme_Object *rd, *wt;	    scheme_pipe(&rd, &wt);	    ip->peeked_read = rd;	    ip->peeked_write = wt;	  }	  scheme_put_byte_string("peek", ip->peeked_write,				 buffer, offset + got - gc, gc, 0);	}      }    }    offset += got;    total_got += got;    got = 0; /* for next round, if any */    if (!size	|| (total_got && ((only_avail == 1) || (only_avail == -1)))	|| (only_avail == 2))      break;    /* Need to try to get more. */  }    return total_got;}