dj(1): remove function pointer hijinks (fixes #66)
This commit is contained in:
		
							parent
							
								
									90de1bf9a4
								
							
						
					
					
						commit
						58245c9484
					
				
							
								
								
									
										42
									
								
								src/dj.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								src/dj.c
									
									
									
									
									
								
							| @ -203,28 +203,28 @@ Io_fdseek(struct Io *io){ | ||||
| 	 | ||||
| 	if(!fdisstd(io->fd) && lseek(io->fd, io->seek, SEEK_SET) != -1) | ||||
| 		return -1; | ||||
| 	else if(io->fl == write_flags){ | ||||
| 		memset(io->buf, '\0', io->bs); | ||||
| 		/* This is a dirty trick; rather than testing conditions and operating
 | ||||
| 		 * likewise, because the parameters to read or write are going to be | ||||
| 		 * the same either way, just use a function pointer to keep track of | ||||
| 		 * the intended operation. */ | ||||
| 		op = (int (*)(int, void *, size_t))&write; | ||||
| 		/* Function pointer casts are risky; this works because the difference
 | ||||
| 		 * is in the second parameter and only that write(2) makes the buffer | ||||
| 		 * const whereas read(2) does not. To avoid even the slightest | ||||
| 		 * undefined behavior comment out the cast, just be ready for a | ||||
| 		 * -Wincompatible-function-pointer-types if your compiler notices it. | ||||
| 		 */ | ||||
| 	}else | ||||
| 		op = &read; | ||||
| 
 | ||||
| 	/* We're going to cheat and use bufuse as the retval for write(2), which is
 | ||||
| 	 * fine because it'll be zeroed as this function returns anyway. */ | ||||
| 	do{	if(	(io->bufuse = (*op)(io->fd, io->buf, MIN(io->bs, io->seek))) == 0) | ||||
| 			/* second chance */ | ||||
| 			io->bufuse = (*op)(io->fd, io->buf, MIN(io->bs, io->seek)); | ||||
| 	}while((io->seek -= io->bufuse) > 0 && io->bufuse != 0); | ||||
| 	/* repeated code to get the condition out of the loop */ | ||||
| 	if(io->fl == write_flags){ | ||||
| 		memset(io->buf, '\0', io->bs); | ||||
| 		/* We're going to cheat and use bufuse as the retval for write(2),
 | ||||
| 		 * which is fine because it'll be zeroed as this function returns | ||||
| 		 * anyway. */ | ||||
| 		do{ | ||||
| 			if((io->bufuse = write(io->fd, io->buf, MIN(io->bs, io->seek))) | ||||
| 					== 0) | ||||
| 				/* second chance */ | ||||
| 				io->bufuse = write(io->fd, io->buf, MIN(io->bs, io->seek)); | ||||
| 		}while((io->seek -= io->bufuse) > 0 && io->bufuse != 0); | ||||
| 	}else if(io->fl == read_flags){ | ||||
| 		do{ | ||||
| 			if((io->bufuse = read(io->fd, io->buf, MIN(io->bs, io->seek))) | ||||
| 					== 0) | ||||
| 				/* second chance */ | ||||
| 				io->bufuse = read(io->fd, io->buf, MIN(io->bs, io->seek)); | ||||
| 		}while((io->seek -= io->bufuse) > 0 && io->bufuse != 0); | ||||
| 	}else | ||||
| 		return EX_SOFTWARE; | ||||
| 
 | ||||
| 	io->bufuse = 0; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user