mirror of
https://github.com/haproxy/haproxy.git
synced 2026-03-21 10:00:32 -04:00
MINOR: tools: add a function to load a file into a tar archive
New function load_file_into_tar() concatenates a file into an in-memory tar archive and grows its size. Only the base name and a provided prefix are used to name the faile. If the file cannot be loaded, it's added as size zero and permissions 0 to show that it failed to load. This will be used to load post-mortem information so it needs to remain simple.
This commit is contained in:
parent
c1dfea3ab3
commit
94a4578ccf
2 changed files with 81 additions and 0 deletions
|
|
@ -1148,6 +1148,7 @@ int may_access(const void *ptr);
|
|||
const void *resolve_sym_name(struct buffer *buf, const char *pfx, const void *addr);
|
||||
const void *resolve_dso_name(struct buffer *buf, const char *pfx, const void *addr);
|
||||
void make_tar_header(char *output, const char *pfx, const char *fname, const char *link, size_t size, mode_t mode);
|
||||
int load_file_into_tar(char **storage, size_t *size, const char *pfx, const char *fname, const char *input, const char *link);
|
||||
const char *get_exec_path(void);
|
||||
void *get_sym_curr_addr(const char *name);
|
||||
void *get_sym_next_addr(const char *name);
|
||||
|
|
|
|||
80
src/tools.c
80
src/tools.c
|
|
@ -5874,6 +5874,86 @@ void make_tar_header(char *output, const char *pfx, const char *fname, const cha
|
|||
memcpy(output, &blk, sizeof(blk));
|
||||
}
|
||||
|
||||
/* appends file <input> into the tar file at location <storage> and size
|
||||
* <size>. The file's location in the archive will appear at <pfx>/<fname>. If
|
||||
* <pfx> is NULL, no prefix is inserted. Note that <pfx> must not end with a
|
||||
* slash. If <fname> is NULL, then the basename of <input> is used. If <input>
|
||||
* is NULL, then <fname> is used. The two may not be NULL simultaneously. An
|
||||
* optional <link> tag (100 chars max) may be added if not NULL. The file's
|
||||
* mode is set with just r/x depending on what was present, or zero in case of
|
||||
* open error (so as to keep trace of the attempt to load the file). Returns 0
|
||||
* on success, non-zero with errno set on error.
|
||||
*/
|
||||
int load_file_into_tar(char **storage, size_t *size, const char *pfx, const char *fname, const char *input, const char *link)
|
||||
{
|
||||
size_t alloc_size;
|
||||
ssize_t fsize = 0;
|
||||
struct stat buf;
|
||||
ssize_t ret = -1;
|
||||
mode_t mode;
|
||||
int fd = -1;
|
||||
char *ptr;
|
||||
|
||||
if (!input)
|
||||
input = fname;
|
||||
else if (!fname) {
|
||||
fname = strrchr(input, '/');
|
||||
if (!fname++)
|
||||
fname = input;
|
||||
}
|
||||
|
||||
/* do not concatenate slashes */
|
||||
if (*fname == '/')
|
||||
fname++;
|
||||
|
||||
if (stat(input, &buf) != 0)
|
||||
goto leave;
|
||||
|
||||
fsize = buf.st_size;
|
||||
|
||||
/* only keep read and exec */
|
||||
mode = buf.st_mode;
|
||||
if (mode & 0111)
|
||||
mode |= 0111;
|
||||
if (mode & 0444)
|
||||
mode |= 0444;
|
||||
mode &= 0555;
|
||||
|
||||
/* Open the file. In case of failure, we'll still create an entry of
|
||||
* size zero to indicate that we tried to read this file.
|
||||
*/
|
||||
fd = open(input, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fsize = 0;
|
||||
mode = 0;
|
||||
}
|
||||
|
||||
/* we need one 512B block for the header + as many 512B blocks as
|
||||
* needed for the file.
|
||||
*/
|
||||
alloc_size = (fsize + 512 + 511) & -512;
|
||||
ptr = realloc(*storage, *size + alloc_size);
|
||||
if (!ptr)
|
||||
goto leave;
|
||||
|
||||
*storage = ptr;
|
||||
ptr += *size; // previous end
|
||||
*size += alloc_size; // new end
|
||||
|
||||
make_tar_header(ptr, pfx, fname, link, fsize, mode);
|
||||
|
||||
ret = fsize ? read(fd, ptr + 512, fsize) : 0;
|
||||
/* always pad with zeroes (complete of partial reads) */
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
memset(ptr + 512 + ret, 0, alloc_size - 512 - ret);
|
||||
|
||||
leave:
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
return ret == fsize ? 0 : 1;
|
||||
}
|
||||
|
||||
/* On systems where this is supported, let's provide a possibility to enumerate
|
||||
* the list of object files. The output is appended to a buffer initialized by
|
||||
* the caller, with one name per line. A trailing zero is always emitted if data
|
||||
|
|
|
|||
Loading…
Reference in a new issue