Logo Search packages:      
Sourcecode: fence-agents version File versions  Download package

int ExpectToken ( int  fd,
struct Etoken toklist,
int  to_secs,
char *  buf,
int  maxline 
)

Look for ('expect') any of a series of tokens in the input Return the token type for the given token or -1 on error.

Parameters:
fdThe file descriptor to watch.
toklistThe series of tokens to look for.
to_secsTimeout (in seconds).
bufReceive buffer (preallocated).
maxlineLength of receive buffer.

Definition at line 61 of file expect.c.

References Etoken::matchto, Etoken::string, and Etoken::toktype.

{
      clock_t           starttime;
      clock_t           endtime;
      int         wraparound=0;
      int         tickstousec = (1000000/CLOCKS_PER_SEC);
      clock_t           now;
      clock_t           ticks;
      int         nchars = 1; /* reserve space for an EOS */
      struct timeval    tv;
      struct tms      tms_unused; /*This tms is unused, but cygwin doesn't like NULL in times*/
      struct Etoken *   this;

      /* Figure out when to give up.  Handle lbolt wraparound */
      if (fd < 0) {
            errno = EINVAL;
            return -1;
      }
      
      starttime = times(&tms_unused);
      ticks = (to_secs*CLOCKS_PER_SEC);
      endtime = starttime + ticks;

      if (endtime < starttime) {
            wraparound = 1;
      }

      if (buf) {
            *buf = EOS;
      }

      for (this=toklist; this->string; ++this) {
            this->matchto = 0;
      }


      while (now = times(&tms_unused),
            (wraparound && (now > starttime || now <= endtime))
            ||    (!wraparound && now <= endtime)) {

            fd_set infds;
            char  ch;
            clock_t           timeleft;
            int         retval;

            timeleft = endtime - now;

            tv.tv_sec = timeleft / CLOCKS_PER_SEC;
            tv.tv_usec = (timeleft % CLOCKS_PER_SEC) * tickstousec;

            if (tv.tv_sec == 0 && tv.tv_usec < tickstousec) {
                  /* Give 'em a little chance */
                  tv.tv_usec = tickstousec;
            }

            /* Watch our FD to see when it has input. */
            FD_ZERO(&infds);
            FD_SET(fd, &infds);

            retval = select(fd+1, &infds, NULL, NULL, &tv); 
            if (retval <= 0) {
                  errno = ETIMEDOUT;
                  return(-1);
            }
            /* Whew!  All that work just to read one character! */
            
            if (read(fd, &ch, sizeof(ch)) <= 0) {
                  return(-1);
            }
            /* Save the text, if we can */
            if (buf && nchars < maxline-1) {
                  *buf = ch;
                  ++buf;
                  *buf = EOS;
                  ++nchars;
            }
#if 0
            fprintf(stderr, "%c", ch);
#endif

            /* See how this character matches our expect strings */

            for (this=toklist; this->string; ++this) {

                  if (ch == this->string[this->matchto]) {

                        /* It matches the current token */

                        ++this->matchto;
                        if (this->string[this->matchto] == EOS){
                              /* Hallelujah! We matched */
                              return(this->toktype);
                        }
                  }else{

                        /* It doesn't appear to match this token */

                        int   curlen;
                        int   nomatch=1;
                        /*
                         * If we already had a match (matchto is
                         * greater than zero), we look for a match
                         * of the tail of the pattern matched so far
                         * (with the current character) against the
                         * head of the pattern.
                         */

                        /*
                         * This is to make the string "aab" match
                         * the pattern "ab" correctly 
                         * Painful, but nice to do it right.
                         */

                        for (curlen = (this->matchto)
                        ;     nomatch && curlen >= 0
                        ;     --curlen)               {
                              const char *      tail;
                              tail=(this->string)
                              +     this->matchto
                              -     curlen;

                              if (strncmp(this->string, tail
                              ,     curlen) == 0
                              &&    this->string[curlen] == ch)  {
                                    
                                    if (this->string[curlen+1]==EOS){
                                          /* We matched!  */
                                          /* (can't happen?) */
                                          return(this->toktype);
                                    }
                                    this->matchto = curlen+1;
                                    nomatch=0;
                              }
                        }
                        if (nomatch) {
                              this->matchto = 0;
                        }
                  }
            }
      }
      errno = ETIMEDOUT;
      return(-1);
}

Generated by  Doxygen 1.6.0   Back to index