void 
write_buffer_queue_init(
	write_buffer_queue_t* queue, 
	request_context_t* request_context, 
	write_callback_t write_callback,
	void* write_context,
	bool_t reuse_buffers)
{
	queue->request_context = request_context;
	queue->write_callback = write_callback;
	queue->write_context = write_context;
	queue->reuse_buffers = reuse_buffers;

	initialize_list_head(&queue->buffers);
	queue->cur_write_buffer = NULL;
	queue->cur_offset = 0;
}
示例#2
0
int main(int argc, char **argv)
{
	buffer_t* new_buffer;
	FILE *source;
	long buffer_start_offset;
	long cur_line_count;
	long initial_offset;
	long bytes_to_read;
	long offset;
	long requested_line_count = DEFAULT_N_LINES;
	int inotify_fd = -1;
	
	// parse the command line
	parse_options(argc, argv, &requested_line_count);
	requested_line_count++;
	
	if (optind + 1 != argc)
	{
		usage(EXIT_FAILURE);
	}
	
	// open the file
	source = fopen(argv[optind], "rb");
	if (source == NULL)
	{
		printf("fopen %s failed %d\n", argv[optind], errno);
		goto error;
	}

	if (forever)
	{
		// set an inotify watch
		inotify_fd = inotify_init();
		if (inotify_fd == -1)
		{
			printf("inotify_init failed %d", errno);
			goto error;
		}

		if (inotify_add_watch(inotify_fd, argv[optind], IN_MODIFY) == -1)
		{
			printf("inotify_add_watch failed %d", errno);
			goto error;
		}	
	}
	
	// seek to the end
	if (fseek(source, 0, SEEK_END) == -1)
	{
		printf("fseek failed (1) %d\n", errno);
		goto error;
	}
	
	initial_offset = ftell(source);
	if (initial_offset == -1)
	{
		printf("ftell failed %d\n", errno);
		goto error;
	}
	
	offset = initial_offset;

	initialize_list_head(&buffer_queue);
	
	for (;;)
	{
		if (offset > CHUNK_SIZE_READ)
		{
			bytes_to_read = CHUNK_SIZE_READ;
		}
		else
		{
			bytes_to_read = offset;
		}
		offset -= bytes_to_read;
		
		if (offset + MEMORY_LIMIT < initial_offset)
		{
			printf("memory limit exceeded\n");
			goto error;
		}

		// allocate a buffer
		new_buffer = (buffer_t*)malloc(sizeof(buffer_t));
		if (new_buffer == NULL)
		{
			printf("malloc failed (1)\n");
			goto error;
		}
		
		new_buffer->data = malloc(bytes_to_read);
		if (new_buffer->data == NULL)
		{
			printf("malloc failed (2)\n");
			goto error;
		}
		
		insert_head_list(&buffer_queue, &new_buffer->node);		
		new_buffer->offset = offset;
		new_buffer->size = bytes_to_read;
		
		// read from the file
		if (fseek(source, offset, SEEK_SET) == -1)
		{
			printf("fseek failed (2) %d\n", errno);
			goto error;
		}
		
		if (fread(new_buffer->data, 1, bytes_to_read, source) != bytes_to_read)
		{
			printf("fread failed %d\n", errno);
			goto error;
		}

		cur_line_count = get_line_count(new_buffer, &buffer_start_offset);
		
		if (cur_line_count >= requested_line_count)
		{
			// read enough data, seek to the initial offset and print the result
			if (fseek(source, initial_offset, SEEK_SET) == -1)
			{
				printf("fseek failed (3) %d\n", errno);
				goto error;
			}
		
			return print_lines(source, inotify_fd, new_buffer, buffer_start_offset, cur_line_count - requested_line_count + 1);
		}
		
		if (offset > 0)
		{
			continue;
		}
		
		if (cur_line_count <= 0)
		{
			goto error;
		}
		
		// reached the beginning of the file, seek to the initial offset and print the result
		if (fseek(source, initial_offset, SEEK_SET) == -1)
		{
			printf("fseek failed (4) %d\n", errno);
			goto error;
		}
		
		return print_lines(source, inotify_fd, new_buffer, buffer_start_offset, 0);
	}
	
	return 0;
	
error:

	// not bothering to clean up anything since the process quits
	return 1;
}