Exemplo n.º 1
0
/*
 * Get server data and make sure there is a continuation response inside them.
 */
int
response_continuation(session *ssn, int tag)
{
	int r;
	ssize_t n;

	buffer_reset(&ibuf);

	do {
		buffer_check(&ibuf, ibuf.len + INPUT_BUF);
		if ((n = receive_response(ssn, ibuf.data + ibuf.len, 0, 1)) ==
		    -1)
			return -1;
		ibuf.len += n;

		if (check_bye(ibuf.data))
			return STATUS_BYE;
	} while ((r = check_tag(ibuf.data, ssn, tag)) == STATUS_NONE &&
	    !check_continuation(ibuf.data));

	if (r == STATUS_NO &&
	    (check_trycreate(ibuf.data) || get_option_boolean("create")))
		return STATUS_TRYCREATE;

	if (r == STATUS_NONE)
		return STATUS_CONTINUE;

	return r;
}
Exemplo n.º 2
0
void read_parameter_file ( char *filename )
{
     FILE *f;
     char buffer[MAXPARAMLINELENGTH+1];
     char *buf2;
     int buf2size;
     int line = 0;
     int errors = 0;
     int including = 1;
      int flag;
     int buflen, buf2len;
     int cont;

     /** open it. **/
     f = fopen ( filename, "r" );
     if ( f == NULL )
	  fprintf( stderr ,  "\ncan't open parameter file \"%s\".",
		 filename );

     /** lines are read into buffer.  they are appended to buf2 until a
       line which is not continued is hit, then buf2 is parsed and the
       parameter added. **/

     /* initial allocation of buf2. */
     buf2 = (char *)malloc ( MAXPARAMLINELENGTH * sizeof ( char ) );
     buf2size = MAXPARAMLINELENGTH;
     buf2[0] = 0;
     buf2len = 0;
     cont = 0;

     while ( fgets ( buffer, MAXPARAMLINELENGTH, f ) != NULL )
     {
	  ++line;

	  /* remove comments, skip line if it's blank after comment
	     removal. */
	  if ( delete_comment ( buffer ) )
	       continue;

	  /* is this line continued?  (is the last nonwhitespace character
	     a backslash?) */
	  cont = check_continuation ( buffer );

	  /** make buf2 bigger if necessary. **/
	  buflen = strlen ( buffer );
	  while ( buf2len + buflen > buf2size + 10 )
	  {
	       buf2size += MAXPARAMLINELENGTH;
	       buf2 = (char *)realloc ( buf2, buf2size * sizeof ( char ) );
	  }

	  /** tack the current line onto buf2. **/
	  strcat ( buf2, buffer );
	  buf2len += buflen;

	  /** if this line is not continued further, then parse buf2. and
	   add the parameter. **/
	  if ( !cont )
	  {
	       if ( parse_one_parameter ( buf2 ))
	       {
		    errors = 1;
		    fprintf( stderr ,  "\n%s line %d: syntax error.",
			   filename, line );
	       }

	       /** reset buf2 as empty. **/
	       buf2len = 0;
	       buf2[0] = 0;
	  }
     }

     /* close file. */
     fclose ( f );

     /** if the last line was continued, and nothing followed it, that's
       an error. **/
     if ( buf2len != 0 )
     {
	  errors = 1;
	   fprintf( stderr ,  "\nunexpected EOF." );
     }

     /** if any errors occurred during parsing, stop now. **/
     if ( errors )
     {
	 fprintf( stderr ,
		 "\nsome syntax errors occurred parsing \"%s\".", filename );
	 free( buf2 );
	 exit(1);
    }

     free ( buf2 );

}
Exemplo n.º 3
0
int
_pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
		       const struct timespec * abstime)
{
	struct pthread	*curthread = _get_curthread();
	int	rval = 0;
	int	done = 0;
	int	mutex_locked = 1;
	int	seqno;

	THR_ASSERT(curthread->locklevel == 0,
	    "cv_timedwait: locklevel is not zero!");

	if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
	    abstime->tv_nsec >= 1000000000)
		return (EINVAL);
	/*
	 * If the condition variable is statically initialized, perform dynamic
	 * initialization.
	 */
	if (*cond == NULL && (rval = _pthread_cond_init(cond, NULL)) != 0)
		return (rval);

	if (!_kse_isthreaded())
		_kse_setthreaded(1);

	/*
	 * Enter a loop waiting for a condition signal or broadcast
	 * to wake up this thread.  A loop is needed in case the waiting
	 * thread is interrupted by a signal to execute a signal handler.
	 * It is not (currently) possible to remain in the waiting queue
	 * while running a handler.  Instead, the thread is interrupted
	 * and backed out of the waiting queue prior to executing the
	 * signal handler.
	 */

	/* Lock the condition variable structure: */
	THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock);
	seqno = (*cond)->c_seqno;
	do {
		/*
		 * If the condvar was statically allocated, properly
		 * initialize the tail queue.
		 */
		if (((*cond)->c_flags & COND_FLAGS_INITED) == 0) {
			TAILQ_INIT(&(*cond)->c_queue);
			(*cond)->c_flags |= COND_FLAGS_INITED;
		}

		/* Process according to condition variable type: */
		switch ((*cond)->c_type) {
		/* Fast condition variable: */
		case COND_TYPE_FAST:
			if ((mutex == NULL) || (((*cond)->c_mutex != NULL) &&
			    ((*cond)->c_mutex != *mutex))) {
				/* Return invalid argument error: */
				rval = EINVAL;
			} else {
				/* Reset the timeout and interrupted flags: */
				curthread->timeout = 0;
				curthread->interrupted = 0;

				/*
				 * Queue the running thread for the condition
				 * variable:
				 */
				cond_queue_enq(*cond, curthread);

				/* Unlock the mutex: */
				if (mutex_locked &&
				   ((rval = _mutex_cv_unlock(mutex)) != 0)) {
					/*
					 * Cannot unlock the mutex; remove the
					 * running thread from the condition
					 * variable queue: 
					 */
					cond_queue_remove(*cond, curthread);
				} else {
					/* Remember the mutex: */
					(*cond)->c_mutex = *mutex;

					/*
					 * Don't unlock the mutex the next
					 * time through the loop (if the
					 * thread has to be requeued after
					 * handling a signal).
					 */
					mutex_locked = 0;

					/*
					 * This thread is active and is in a
					 * critical region (holding the cv
					 * lock); we should be able to safely
					 * set the state.
					 */
					THR_SCHED_LOCK(curthread, curthread);
					/* Set the wakeup time: */
					curthread->wakeup_time.tv_sec =
					    abstime->tv_sec;
					curthread->wakeup_time.tv_nsec =
					    abstime->tv_nsec;
					THR_SET_STATE(curthread, PS_COND_WAIT);

					/* Remember the CV: */
					curthread->data.cond = *cond;
					curthread->sigbackout = cond_wait_backout;
					THR_SCHED_UNLOCK(curthread, curthread);

					/* Unlock the CV structure: */
					THR_LOCK_RELEASE(curthread,
					    &(*cond)->c_lock);

					/* Schedule the next thread: */
					_thr_sched_switch(curthread);

					/*
					 * XXX - This really isn't a good check
					 * since there can be more than one
					 * thread waiting on the CV.  Signals
					 * sent to threads waiting on mutexes
					 * or CVs should really be deferred
					 * until the threads are no longer
					 * waiting, but POSIX says that signals
					 * should be sent "as soon as possible".
					 */
					done = (seqno != (*cond)->c_seqno);
					if (done && !THR_IN_CONDQ(curthread)) {
						/*
						 * The thread is dequeued, so
						 * it is safe to clear these.
						 */
						curthread->data.cond = NULL;
						curthread->sigbackout = NULL;
						check_continuation(curthread,
						    NULL, mutex);
						return (_mutex_cv_lock(mutex));
					}

					/* Relock the CV structure: */
					THR_LOCK_ACQUIRE(curthread,
					    &(*cond)->c_lock);

					/*
					 * Clear these after taking the lock to
					 * prevent a race condition where a
					 * signal can arrive before dequeueing
					 * the thread.
					 */
					curthread->data.cond = NULL;
					curthread->sigbackout = NULL;

					done = (seqno != (*cond)->c_seqno);

					if (THR_IN_CONDQ(curthread)) {
						cond_queue_remove(*cond,
						    curthread);

						/* Check for no more waiters: */
						if (TAILQ_EMPTY(&(*cond)->c_queue))
							(*cond)->c_mutex = NULL;
					}

					if (curthread->timeout != 0) {
						/* The wait timedout. */
						rval = ETIMEDOUT;
					}
				}
			}
			break;

		/* Trap invalid condition variable types: */
		default:
			/* Return an invalid argument error: */
			rval = EINVAL;
			break;
		}

		check_continuation(curthread, *cond,
		    mutex_locked ? NULL : mutex);
	} while ((done == 0) && (rval == 0));

	/* Unlock the condition variable structure: */
	THR_LOCK_RELEASE(curthread, &(*cond)->c_lock);

	if (mutex_locked == 0)
		_mutex_cv_lock(mutex);

	/* Return the completion status: */
	return (rval);
}