Add an ftruncate call paired with fallocate to play safe with some FSes (namely, BtrFS fallocate sets file size to allocated size, i.e. multiple of block size)
This commit is contained in:
		
							parent
							
								
									c710fe540e
								
							
						
					
					
						commit
						098cb9d233
					
				
					 2 changed files with 9 additions and 0 deletions
				
			
		| 
						 | 
					@ -181,6 +181,8 @@ static void parseContents(ParseSink & sink, Source & source, const Path & path)
 | 
				
			||||||
        left -= n;
 | 
					        left -= n;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sink.finalizeContents(size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    readPadding(size, source);
 | 
					    readPadding(size, source);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -310,6 +312,12 @@ struct RestoreSink : ParseSink
 | 
				
			||||||
        writeFull(fd, data, len);
 | 
					        writeFull(fd, data, len);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void finalizeContents(unsigned long long size)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        errno = ftruncate(fd, size);
 | 
				
			||||||
 | 
					        if (errno) throw SysError(format("truncating file to its allocated length of %1% bytes") % size);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void createSymlink(const Path & path, const string & target)
 | 
					    void createSymlink(const Path & path, const string & target)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Path p = dstPath + path;
 | 
					        Path p = dstPath + path;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +64,7 @@ struct ParseSink
 | 
				
			||||||
    virtual void isExecutable() { };
 | 
					    virtual void isExecutable() { };
 | 
				
			||||||
    virtual void preallocateContents(unsigned long long size) { };
 | 
					    virtual void preallocateContents(unsigned long long size) { };
 | 
				
			||||||
    virtual void receiveContents(unsigned char * data, unsigned int len) { };
 | 
					    virtual void receiveContents(unsigned char * data, unsigned int len) { };
 | 
				
			||||||
 | 
					    virtual void finalizeContents(unsigned long long size) { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual void createSymlink(const Path & path, const string & target) { };
 | 
					    virtual void createSymlink(const Path & path, const string & target) { };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue