forked from bonsai/harakit
		
	dj(1): Refactor out Io_fdseek entirely
This commit is contained in:
		
							parent
							
								
									66ca4b9a12
								
							
						
					
					
						commit
						944feef434
					
				
							
								
								
									
										93
									
								
								src/dj.c
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								src/dj.c
									
									
									
									
									
								
							@ -129,52 +129,6 @@ Io_fdopen(struct Io *io, char *fn){
 | 
			
		||||
	return fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Seeks io->seek bytes through *io's file descriptor, subtracting the number
 | 
			
		||||
 * of sought bytes from io->seek. This procedure leaves garbage in io->buf.
 | 
			
		||||
 * Read/written bytes here aren't counted in the statistics because successful
 | 
			
		||||
 * seeking is guaranteed. */
 | 
			
		||||
static void
 | 
			
		||||
Io_fdseek(struct Io *io){
 | 
			
		||||
 | 
			
		||||
	assert(io != NULL);
 | 
			
		||||
	assert(io->fd != STDIN_FILENO  || io->fl == read_flags);
 | 
			
		||||
	assert(io->fd != STDOUT_FILENO || io->fl == write_flags);
 | 
			
		||||
 | 
			
		||||
	if(io->seek == 0
 | 
			
		||||
			|| (!fdisstd(io->fd) && lseek(io->fd, io->seek, SEEK_SET) != -1)){
 | 
			
		||||
		io->seek = 0;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(io->fl == write_flags)
 | 
			
		||||
		memset(io->buf, '\0', io->bs);
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
		assert(0); /* UNREACHABLE */
 | 
			
		||||
 | 
			
		||||
	io->bufuse = 0;
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Reads io->bs bytes from *io's file descriptor into io->buf, storing the
 | 
			
		||||
 * number of read bytes in io->bufuse and updating io->bytes. If io->bufuse is
 | 
			
		||||
 * 0, errno will probably be set. Returns io. */
 | 
			
		||||
@ -307,24 +261,61 @@ int main(int argc, char *argv[]){
 | 
			
		||||
			}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	assert(io->fd != STDIN_FILENO  || io->fl == read_flags);
 | 
			
		||||
	assert(io->fd != STDOUT_FILENO || io->fl == write_flags);
 | 
			
		||||
 | 
			
		||||
	if(argc > optind){
 | 
			
		||||
		return usage(program_name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for(i = 0; i < 2; ++i){
 | 
			
		||||
		/* buffer allocation */
 | 
			
		||||
		if((io[i].buf = malloc(io[i].bs * (sizeof *(io[i].buf)))) == NULL){
 | 
			
		||||
			fprintf(stderr, "%s: Failed to allocate %d bytes\n",
 | 
			
		||||
				program_name, io[i].bs);
 | 
			
		||||
			return EX_OSERR;
 | 
			
		||||
		}else if(io[i].seek > 0){
 | 
			
		||||
			Io_fdseek(&io[i]);
 | 
			
		||||
			if(io[i].seek > 0){
 | 
			
		||||
				return oserr(io[i].fn);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		/* easy seeking */
 | 
			
		||||
		if(!fdisstd(io[i].fd) && lseek(io[i].fd, io[i].seek, SEEK_SET) != -1)
 | 
			
		||||
			io[i].seek = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* hard skipping */
 | 
			
		||||
	if(io[0].seek > 0){
 | 
			
		||||
		do{
 | 
			
		||||
			if((io[0].bufuse = read(
 | 
			
		||||
						io[0].fd, io[0].buf, MIN(io[0].bs, io[0].seek)))
 | 
			
		||||
					== 0)
 | 
			
		||||
				/* second chance */
 | 
			
		||||
				io->bufuse = read(
 | 
			
		||||
					io[0].fd, io[0].buf, MIN(io[0].bs, io[0].seek));
 | 
			
		||||
		}while((io[0].seek -= io[0].bufuse) > 0 && io[0].bufuse != 0);
 | 
			
		||||
		io[0].bufuse = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* hard seeking */
 | 
			
		||||
	if(io[1].seek > 0){
 | 
			
		||||
		memset(io[1].buf, '\0', io[1].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[1].bufuse = write(
 | 
			
		||||
						io[1].fd, io[1].buf, MIN(io[1].bs, io[1].seek)))
 | 
			
		||||
					== 0)
 | 
			
		||||
				/* second chance */
 | 
			
		||||
				io[1].bufuse = write(
 | 
			
		||||
					io[1].fd, io[1].buf, MIN(io[1].bs, io[1].seek));
 | 
			
		||||
		}while((io[1].seek -= io[1].bufuse) > 0 && io[1].bufuse != 0);
 | 
			
		||||
		io[1].bufuse = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Sought bytes aren't counted in the statistics because successful seeking
 | 
			
		||||
	 * is guaranteed here. */
 | 
			
		||||
	for(i = 0; i < 2; ++i)
 | 
			
		||||
		if(io[i].seek > 0)
 | 
			
		||||
			return oserr(io[i].fn);
 | 
			
		||||
 | 
			
		||||
	do{	/* read */
 | 
			
		||||
		Io_read(&io[0]);
 | 
			
		||||
		if(!noerror && io[0].bufuse == 0)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user