plan 9 kernel history: overview | file list | diff list

1991/0926/port/stream.c (diff list | history)

1991/0904/sys/src/9/port/stream.c:791,7971991/0926/sys/src/9/port/stream.c:791,796 (short | long | prev | next)
1990/0227    
	/* 
 	 *  hang a device and process q off the stream 
	 */ 
1991/0504    
	s->forcedelim = 0; 
1990/0227    
	s->inuse = 1; 
1990/1009    
	if(noopen) 
		s->opens = 0; 
1991/0904/sys/src/9/port/stream.c:808,8141991/0926/sys/src/9/port/stream.c:807,812
1990/0227    
	RD(s->procq)->next = 0; 
	RD(s->devq)->next = RD(s->procq); 
	WR(s->devq)->next = 0; 
1991/0809    
	s->flushmsg = 0; 
1990/0227    
 
	if(qi->open) 
		(*qi->open)(RD(s->devq), s); 
1991/0904/sys/src/9/port/stream.c:1264,12731991/0926/sys/src/9/port/stream.c:1262,1271
1990/0312    
streamwrite(Chan *c, void *a, long n, int docopy) 
1990/0227    
{ 
	Stream *s; 
	Block *bp; 
	Queue *q; 
	long rem; 
	int i; 
1991/0926    
	Block *bp, *first, *last; 
1990/0227    
 
1990/0911    
	s = c->stream; 
 
1991/0904/sys/src/9/port/stream.c:1289,13481991/0926/sys/src/9/port/stream.c:1287,1319
1991/0411    
	} 
1990/0227    
 
1991/0502    
	/* 
	 *  if an error occurs during write n, 
	 *  force a delim before write n+1 
1991/0926    
	 *  copy the whole write into kernel space 
1991/0502    
	 */ 
	if(waserror()){ 
		s->forcedelim = 1; 
		nexterror(); 
	} 
	if(s->forcedelim){ 
		FLOWCTL(q); 
		bp = allocb(0); 
		bp->flags |= S_DELIM; 
1991/0926    
	first = last = 0; 
	for(rem = n; ; rem -= i) { 
		bp = allocb(rem); 
		i = bp->lim - bp->wptr; 
		if(i >= rem) 
			i = rem; 
		memmove(bp->wptr, a, i); 
		bp->wptr += i; 
1991/0502    
		bp->type = M_DATA; 
		PUTNEXT(q, bp); 
		s->forcedelim = 0; 
1991/0926    
		a = ((char*)a) + i; 
		if(first == 0) 
			first = bp; 
		else 
			last->next = bp; 
		last = bp; 
		if(i == rem) 
			break; 
1991/0502    
	} 
 
	if(0 && !docopy && isphys(a)){ 
1990/0227    
		/* 
		 *  `a' is global to the whole system, just create a 
		 *  pointer to it and pass it on. 
		 */ 
1990/0403    
		FLOWCTL(q); 
1990/0227    
		bp = allocb(0); 
		bp->rptr = bp->base = (uchar *)a; 
		bp->wptr = bp->lim = (uchar *)a+n; 
		bp->flags |= S_DELIM; 
		bp->type = M_DATA; 
		PUTNEXT(q, bp); 
	} else { 
		/* 
		 *  `a' is in the user's address space, copy it into 
		 *  system buffers and pass the buffers on. 
		 */ 
		for(rem = n; ; rem -= i) { 
1990/0403    
			FLOWCTL(q); 
1990/0227    
			bp = allocb(rem); 
			i = bp->lim - bp->wptr; 
			if(i >= rem){ 
1991/0318    
				memmove(bp->wptr, a, rem); 
1990/0227    
				bp->flags |= S_DELIM; 
				bp->wptr += rem; 
				bp->type = M_DATA; 
				PUTNEXT(q, bp); 
				break; 
			} else { 
1991/0318    
				memmove(bp->wptr, a, i); 
1990/0227    
				bp->wptr += i; 
				bp->type = M_DATA; 
				PUTNEXT(q, bp); 
				a = ((char*)a) + i; 
			} 
		} 
	} 
1991/0502    
	poperror(); 
1991/0926    
	/* 
	 *  send it down stream 
	 */ 
	last->flags |= S_DELIM; 
	FLOWCTL(q); 
	PUTNEXT(q, first); 
1990/0227    
	return n; 
1990/0312    
} 
 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)