mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
146 lines
3.9 KiB
C++
146 lines
3.9 KiB
C++
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "ert/util/build_config.hpp"
|
|
#include <ert/util/ert_api_config.hpp>
|
|
#include <ert/util/util.h>
|
|
|
|
#ifndef ERT_HAVE_SYMLINK
|
|
|
|
bool util_is_link(const char * path) {
|
|
return false;
|
|
}
|
|
|
|
char * util_alloc_link_target(const char * link) {
|
|
return util_alloc_string_copy( link );
|
|
}
|
|
|
|
#else
|
|
|
|
#include <dirent.h>
|
|
#include <unistd.h>
|
|
|
|
void util_make_slink(const char *target , const char * link) {
|
|
if (util_file_exists(link)) {
|
|
if (util_is_link(link)) {
|
|
if (!util_same_file(target , link))
|
|
util_abort("%s: %s already exists - not pointing to: %s - aborting \n",__func__ , link , target);
|
|
} else
|
|
util_abort("%s: %s already exists - is not a link - aborting \n",__func__ , link);
|
|
} else {
|
|
if (symlink(target , link) != 0)
|
|
util_abort("%s: linking %s -> %s failed - aborting: %s \n",__func__ , link , target , strerror(errno));
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
This function returns true if path is a symbolic link.
|
|
*/
|
|
|
|
bool util_is_link(const char * path) {
|
|
stat_type stat_buffer;
|
|
if (lstat(path , &stat_buffer) == 0)
|
|
return S_ISLNK(stat_buffer.st_mode);
|
|
else if (errno == ENOENT)
|
|
/*Path does not exist at all. */
|
|
return false;
|
|
else {
|
|
util_abort("%s: stat(%s) failed: %s \n",__func__ , path , strerror(errno));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
A wrapper around readlink() which will:
|
|
|
|
1. Allocate a sufficiently large buffer - reallocating if necessary.
|
|
2. Append a terminating \0 at the end of the return string.
|
|
|
|
If the input argument is not a symbolic link the function will just
|
|
return a string copy of the input.
|
|
*/
|
|
|
|
char * util_alloc_link_target(const char * link) {
|
|
if (util_is_link( link )) {
|
|
bool retry = true;
|
|
int target_length;
|
|
int buffer_size = 256;
|
|
char * target = NULL;
|
|
do {
|
|
target = (char*)util_realloc(target , buffer_size );
|
|
target_length = readlink(link , target , buffer_size);
|
|
|
|
if (target_length == -1)
|
|
util_abort("%s: readlink(%s,...) failed with error:%s - aborting\n",__func__ , link , strerror(errno));
|
|
|
|
if (target_length < (buffer_size - 1)) /* Must leave room for the trailing \0 */
|
|
retry = false;
|
|
else
|
|
buffer_size *= 2;
|
|
|
|
} while (retry);
|
|
target[target_length] = '\0';
|
|
target = (char*)util_realloc( target , strlen( target ) + 1 ); /* Shrink down to accurate size. */
|
|
return target;
|
|
} else
|
|
return util_alloc_string_copy( link );
|
|
}
|
|
|
|
#ifdef ERT_HAVE_READLINKAT
|
|
|
|
#if !defined(ERT_HAVE_READLINKAT_DECLARATION)
|
|
/*
|
|
The manual page says that the readlinkat() function should be in the
|
|
unistd.h header file, but not on RedHat5. On RedHat6 it is.
|
|
|
|
*/
|
|
extern ssize_t readlinkat (int __fd, __const char *__restrict __path, char *__restrict __buf, size_t __len);
|
|
#endif /* !defined(ERT_HAVE_READLINKAT_DECLARATION) */
|
|
|
|
char * util_alloc_atlink_target(const char * path , const char * link) {
|
|
if (util_is_abs_path( link ))
|
|
return util_alloc_link_target( link );
|
|
else {
|
|
char * target = NULL;
|
|
DIR * dir;
|
|
int path_fd;
|
|
|
|
dir = opendir( path );
|
|
if (dir == NULL)
|
|
return NULL;
|
|
|
|
path_fd = dirfd( dir );
|
|
if (path_fd == -1)
|
|
return NULL;
|
|
|
|
{
|
|
bool retry = true;
|
|
int target_length;
|
|
int buffer_size = 256;
|
|
do {
|
|
target = (char*)util_realloc(target , buffer_size );
|
|
target_length = readlinkat( path_fd , link , target , buffer_size);
|
|
|
|
if (target_length == -1)
|
|
util_abort("%s: readlinkat(%s,...) failed with error:%s - aborting\n",__func__ , link , strerror(errno));
|
|
|
|
if (target_length < (buffer_size - 1)) /* Must leave room for the trailing \0 */
|
|
retry = false;
|
|
else
|
|
buffer_size *= 2;
|
|
|
|
} while (retry);
|
|
target[target_length] = '\0';
|
|
target = (char*)util_realloc( target , strlen( target ) + 1 ); /* Shrink down to accurate size. */
|
|
}
|
|
closedir( dir );
|
|
return target;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#endif // ERT_HAVE_SYMLINK
|