mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
extract real path of executable instead of argv[0]
This commit is contained in:
parent
5d507c593b
commit
2c3732ed3a
@ -21,11 +21,16 @@
|
||||
#endif
|
||||
|
||||
#if defined OS_DARWIN
|
||||
# include <mach-o/dyld.h>
|
||||
# include <libkern/OSByteOrder.h>
|
||||
// define 64 bit macros
|
||||
# define le64toh(x) OSSwapLittleToHostInt64(x)
|
||||
#endif
|
||||
|
||||
#if defined(OS_FREEBSD)
|
||||
# include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/// decompress part
|
||||
@ -82,7 +87,7 @@ int decompress(char * input, char * output, off_t start, off_t end, size_t max_n
|
||||
pid = fork();
|
||||
if (-1 == pid)
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("fork");
|
||||
/// If fork failed just decompress data in main process.
|
||||
if (0 != doDecompress(input, output, in_pointer, out_pointer, size, decompressed_size, dctx))
|
||||
{
|
||||
@ -170,7 +175,7 @@ int decompressFiles(int input_fd, char * path, char * name, bool & have_compress
|
||||
struct stat info_in;
|
||||
if (0 != fstat(input_fd, &info_in))
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("fstat");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -178,7 +183,7 @@ int decompressFiles(int input_fd, char * path, char * name, bool & have_compress
|
||||
char * input = static_cast<char*>(mmap(nullptr, info_in.st_size, PROT_READ, MAP_PRIVATE, input_fd, 0));
|
||||
if (input == MAP_FAILED)
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("mmap");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -202,9 +207,9 @@ int decompressFiles(int input_fd, char * path, char * name, bool & have_compress
|
||||
struct statfs fs_info;
|
||||
if (0 != fstatfs(input_fd, &fs_info))
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("fstatfs");
|
||||
if (0 != munmap(input, info_in.st_size))
|
||||
perror(nullptr);
|
||||
perror("munmap");
|
||||
return 1;
|
||||
}
|
||||
if (fs_info.f_blocks * info_in.st_blksize < decompressed_full_size)
|
||||
@ -241,7 +246,7 @@ int decompressFiles(int input_fd, char * path, char * name, bool & have_compress
|
||||
int fd = mkstemp(file_name);
|
||||
if (fd == -1)
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("mkstemp");
|
||||
return 1;
|
||||
}
|
||||
close(fd);
|
||||
@ -254,18 +259,18 @@ int decompressFiles(int input_fd, char * path, char * name, bool & have_compress
|
||||
|
||||
if (output_fd == -1)
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("open");
|
||||
if (0 != munmap(input, info_in.st_size))
|
||||
perror(nullptr);
|
||||
perror("munmap");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// Prepare output file
|
||||
if (0 != ftruncate(output_fd, le64toh(file_info.uncompressed_size)))
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("ftruncate");
|
||||
if (0 != munmap(input, info_in.st_size))
|
||||
perror(nullptr);
|
||||
perror("munmap");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -278,9 +283,9 @@ int decompressFiles(int input_fd, char * path, char * name, bool & have_compress
|
||||
);
|
||||
if (output == MAP_FAILED)
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("mmap");
|
||||
if (0 != munmap(input, info_in.st_size))
|
||||
perror(nullptr);
|
||||
perror("munmap");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -288,29 +293,70 @@ int decompressFiles(int input_fd, char * path, char * name, bool & have_compress
|
||||
if (0 != decompress(input, output, le64toh(file_info.start), le64toh(file_info.end)))
|
||||
{
|
||||
if (0 != munmap(input, info_in.st_size))
|
||||
perror(nullptr);
|
||||
perror("munmap");
|
||||
if (0 != munmap(output, le64toh(file_info.uncompressed_size)))
|
||||
perror(nullptr);
|
||||
perror("munmap");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != fsync(output_fd))
|
||||
perror(nullptr);
|
||||
perror("fsync");
|
||||
if (0 != close(output_fd))
|
||||
perror(nullptr);
|
||||
perror("close");
|
||||
}
|
||||
|
||||
if (0 != munmap(input, info_in.st_size))
|
||||
perror(nullptr);
|
||||
perror("munmap");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(OS_DARWIN)
|
||||
|
||||
int read_exe_path(char *exe, size_t buf_sz)
|
||||
{
|
||||
uint32_t size = buf_sz;
|
||||
char apple[size];
|
||||
if (_NSGetExecutablePath(apple, &size) != 0)
|
||||
return 1;
|
||||
if (realpath(apple, exe) == nullptr)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(OS_FREEBSD)
|
||||
|
||||
int read_exe_path(char *exe, size_t buf_sz)
|
||||
{
|
||||
int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
||||
size_t length = buf_sz;
|
||||
int error = sysctl(name, 4, exe, &length, nullptr, 0);
|
||||
if (error < 0 || length <= 1)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int read_exe_path(char *exe, size_t/* buf_sz*/)
|
||||
{
|
||||
if (realpath("/proc/self/exe", exe) == nullptr)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main(int/* argc*/, char* argv[])
|
||||
{
|
||||
char file_path[strlen(argv[0]) + 1];
|
||||
memset(file_path, 0, sizeof(file_path));
|
||||
strcpy(file_path, argv[0]);
|
||||
char self[4096] = {0};
|
||||
if (read_exe_path(self, 4096) == -1)
|
||||
{
|
||||
perror("read_exe_path");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char file_path[strlen(self) + 1];
|
||||
strcpy(file_path, self);
|
||||
|
||||
char * path = nullptr;
|
||||
char * name = strrchr(file_path, '/');
|
||||
@ -323,10 +369,10 @@ int main(int/* argc*/, char* argv[])
|
||||
else
|
||||
name = file_path;
|
||||
|
||||
int input_fd = open(argv[0], O_RDONLY);
|
||||
int input_fd = open(self, O_RDONLY);
|
||||
if (input_fd == -1)
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("open");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -339,16 +385,16 @@ int main(int/* argc*/, char* argv[])
|
||||
{
|
||||
printf("Error happened during decompression.\n");
|
||||
if (0 != close(input_fd))
|
||||
perror(nullptr);
|
||||
perror("close");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != close(input_fd))
|
||||
perror(nullptr);
|
||||
perror("close");
|
||||
|
||||
if (unlink(argv[0]))
|
||||
if (unlink(self))
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("unlink");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -357,34 +403,34 @@ int main(int/* argc*/, char* argv[])
|
||||
else
|
||||
{
|
||||
const char * const decompressed_name_fmt = "%s.decompressed.%s";
|
||||
int decompressed_name_len = snprintf(nullptr, 0, decompressed_name_fmt, argv[0], decompressed_suffix);
|
||||
int decompressed_name_len = snprintf(nullptr, 0, decompressed_name_fmt, self, decompressed_suffix);
|
||||
char decompressed_name[decompressed_name_len + 1];
|
||||
(void)snprintf(decompressed_name, decompressed_name_len + 1, decompressed_name_fmt, argv[0], decompressed_suffix);
|
||||
(void)snprintf(decompressed_name, decompressed_name_len + 1, decompressed_name_fmt, self, decompressed_suffix);
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::copy_file(static_cast<char *>(decompressed_name), argv[0], ec);
|
||||
std::filesystem::copy_file(static_cast<char *>(decompressed_name), static_cast<char *>(self), ec);
|
||||
if (ec)
|
||||
{
|
||||
std::cerr << ec.message() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (chmod(argv[0], decompressed_umask))
|
||||
if (chmod(self, decompressed_umask))
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("chmod");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (unlink(decompressed_name))
|
||||
{
|
||||
perror(nullptr);
|
||||
perror("unlink");
|
||||
return 1;
|
||||
}
|
||||
|
||||
execv(argv[0], argv);
|
||||
execv(self, argv);
|
||||
|
||||
/// This part of code will be reached only if error happened
|
||||
perror(nullptr);
|
||||
perror("execv");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user