file_io.h revision 312517
1207753Smm/////////////////////////////////////////////////////////////////////////////// 2207753Smm// 3207753Smm/// \file file_io.h 4207753Smm/// \brief I/O types and functions 5207753Smm// 6207753Smm// Author: Lasse Collin 7207753Smm// 8207753Smm// This file has been put into the public domain. 9207753Smm// You can do whatever you want with this file. 10207753Smm// 11207753Smm/////////////////////////////////////////////////////////////////////////////// 12207753Smm 13207753Smm// Some systems have suboptimal BUFSIZ. Use a bit bigger value on them. 14207753Smm// We also need that IO_BUFFER_SIZE is a multiple of 8 (sizeof(uint64_t)) 15207753Smm#if BUFSIZ <= 1024 16207753Smm# define IO_BUFFER_SIZE 8192 17207753Smm#else 18207753Smm# define IO_BUFFER_SIZE (BUFSIZ & ~7U) 19207753Smm#endif 20207753Smm 21207753Smm 22207753Smm/// is_sparse() accesses the buffer as uint64_t for maximum speed. 23207753Smm/// Use an union to make sure that the buffer is properly aligned. 24207753Smmtypedef union { 25207753Smm uint8_t u8[IO_BUFFER_SIZE]; 26207753Smm uint32_t u32[IO_BUFFER_SIZE / sizeof(uint32_t)]; 27207753Smm uint64_t u64[IO_BUFFER_SIZE / sizeof(uint64_t)]; 28207753Smm} io_buf; 29207753Smm 30207753Smm 31207753Smmtypedef struct { 32207753Smm /// Name of the source filename (as given on the command line) or 33207753Smm /// pointer to static "(stdin)" when reading from standard input. 34207753Smm const char *src_name; 35207753Smm 36207753Smm /// Destination filename converted from src_name or pointer to static 37207753Smm /// "(stdout)" when writing to standard output. 38207753Smm char *dest_name; 39207753Smm 40207753Smm /// File descriptor of the source file 41207753Smm int src_fd; 42207753Smm 43207753Smm /// File descriptor of the target file 44207753Smm int dest_fd; 45207753Smm 46207753Smm /// True once end of the source file has been detected. 47207753Smm bool src_eof; 48207753Smm 49207753Smm /// If true, we look for long chunks of zeros and try to create 50207753Smm /// a sparse file. 51207753Smm bool dest_try_sparse; 52207753Smm 53207753Smm /// This is used only if dest_try_sparse is true. This holds the 54207753Smm /// number of zero bytes we haven't written out, because we plan 55207753Smm /// to make that byte range a sparse chunk. 56207753Smm off_t dest_pending_sparse; 57207753Smm 58207753Smm /// Stat of the source file. 59207753Smm struct stat src_st; 60207753Smm 61207753Smm /// Stat of the destination file. 62207753Smm struct stat dest_st; 63207753Smm 64207753Smm} file_pair; 65207753Smm 66207753Smm 67207753Smm/// \brief Initialize the I/O module 68207753Smmextern void io_init(void); 69207753Smm 70207753Smm 71278433Srpaulo#ifndef TUKLIB_DOSLIKE 72278433Srpaulo/// \brief Write a byte to user_abort_pipe[1] 73278433Srpaulo/// 74278433Srpaulo/// This is called from a signal handler. 75278433Srpauloextern void io_write_to_user_abort_pipe(void); 76278433Srpaulo#endif 77278433Srpaulo 78278433Srpaulo 79207753Smm/// \brief Disable creation of sparse files when decompressing 80207753Smmextern void io_no_sparse(void); 81207753Smm 82207753Smm 83312517Sdelphij#ifdef ENABLE_SANDBOX 84312517Sdelphij/// \brief main() calls this if conditions for sandboxing have been met. 85312517Sdelphijextern void io_allow_sandbox(void); 86312517Sdelphij#endif 87312517Sdelphij 88312517Sdelphij 89207753Smm/// \brief Open the source file 90207753Smmextern file_pair *io_open_src(const char *src_name); 91207753Smm 92207753Smm 93207753Smm/// \brief Open the destination file 94207753Smmextern bool io_open_dest(file_pair *pair); 95207753Smm 96207753Smm 97207753Smm/// \brief Closes the file descriptors and frees possible allocated memory 98207753Smm/// 99207753Smm/// The success argument determines if source or destination file gets 100207753Smm/// unlinked: 101207753Smm/// - false: The destination file is unlinked. 102207753Smm/// - true: The source file is unlinked unless writing to stdout or --keep 103207753Smm/// was used. 104207753Smmextern void io_close(file_pair *pair, bool success); 105207753Smm 106207753Smm 107207753Smm/// \brief Reads from the source file to a buffer 108207753Smm/// 109207753Smm/// \param pair File pair having the source file open for reading 110207753Smm/// \param buf Destination buffer to hold the read data 111207753Smm/// \param size Size of the buffer; assumed be smaller than SSIZE_MAX 112207753Smm/// 113207753Smm/// \return On success, number of bytes read is returned. On end of 114207753Smm/// file zero is returned and pair->src_eof set to true. 115207753Smm/// On error, SIZE_MAX is returned and error message printed. 116207753Smmextern size_t io_read(file_pair *pair, io_buf *buf, size_t size); 117207753Smm 118207753Smm 119278433Srpaulo/// \brief Fix the position in src_fd 120278433Srpaulo/// 121278433Srpaulo/// This is used when --single-thream has been specified and decompression 122278433Srpaulo/// is successful. If the input file descriptor supports seeking, this 123278433Srpaulo/// function fixes the input position to point to the next byte after the 124278433Srpaulo/// decompressed stream. 125278433Srpaulo/// 126278433Srpaulo/// \param pair File pair having the source file open for reading 127278433Srpaulo/// \param rewind_size How many bytes of extra have been read i.e. 128278433Srpaulo/// how much to seek backwards. 129278433Srpauloextern void io_fix_src_pos(file_pair *pair, size_t rewind_size); 130278433Srpaulo 131278433Srpaulo 132207753Smm/// \brief Read from source file from given offset to a buffer 133207753Smm/// 134207753Smm/// This is remotely similar to standard pread(). This uses lseek() though, 135207753Smm/// so the read offset is changed on each call. 136207753Smm/// 137207753Smm/// \param pair Seekable source file 138207753Smm/// \param buf Destination buffer 139207753Smm/// \param size Amount of data to read 140207753Smm/// \param pos Offset relative to the beginning of the file, 141207753Smm/// from which the data should be read. 142207753Smm/// 143207753Smm/// \return On success, false is returned. On error, error message 144207753Smm/// is printed and true is returned. 145207753Smmextern bool io_pread(file_pair *pair, io_buf *buf, size_t size, off_t pos); 146207753Smm 147207753Smm 148207753Smm/// \brief Writes a buffer to the destination file 149207753Smm/// 150207753Smm/// \param pair File pair having the destination file open for writing 151207753Smm/// \param buf Buffer containing the data to be written 152207753Smm/// \param size Size of the buffer; assumed be smaller than SSIZE_MAX 153207753Smm/// 154207753Smm/// \return On success, zero is returned. On error, -1 is returned 155207753Smm/// and error message printed. 156207753Smmextern bool io_write(file_pair *pair, const io_buf *buf, size_t size); 157