Replace the fixed-size "cwd" buffer with a dynamically allocated one.
This commit is contained in:
+2
-1
@@ -29,6 +29,7 @@ AC_CHECK_FUNCS([getopt_long])
|
||||
AC_CHECK_FUNCS([vsnprintf vasprintf strlcat strtoul memrchr])
|
||||
AC_CHECK_FUNCS([fdatasync])
|
||||
AC_CHECK_FUNCS([fpathconf sysconf posix_memalign posix_fadvise])
|
||||
AC_CHECK_FUNCS([getcwd])
|
||||
AC_CHECK_FUNCS([nanosleep])
|
||||
AC_CHECK_FUNCS([setitimer])
|
||||
AC_CHECK_FUNCS([setproctitle])
|
||||
@@ -58,7 +59,7 @@ dnl Libraries that may contain key functions.
|
||||
AC_SEARCH_LIBS([clock_gettime],[rt])
|
||||
|
||||
dnl Items we can't do without.
|
||||
AC_CHECK_FUNCS([alarm basename clock_gettime dup2 getcwd memcpy memmove memset mkdir select setlocale strchr strerror strrchr strstr], [], [AC_MSG_ERROR([required function is missing])])
|
||||
AC_CHECK_FUNCS([alarm basename clock_gettime dup2 memcpy memmove memset mkdir select setlocale strchr strerror strrchr strstr], [], [AC_MSG_ERROR([required function is missing])])
|
||||
AC_CHECK_HEADERS([fcntl.h sys/file.h sys/time.h unistd.h], [], [AC_MSG_ERROR([required header file is missing])])
|
||||
|
||||
dnl Make sure all the types we use are defined.
|
||||
|
||||
@@ -44,7 +44,6 @@ extern "C" {
|
||||
/* Sizes for various statically sized buffers. */
|
||||
|
||||
#define PV_SIZEOF_DEFAULT_FORMAT 512
|
||||
#define PV_SIZEOF_CWD 4096
|
||||
#define PV_SIZEOF_LASTWRITTEN_BUFFER 256
|
||||
#define PV_SIZEOF_PREVLINE_BUFFER 1024
|
||||
#define PV_FORMAT_ARRAY_MAX 100
|
||||
@@ -157,7 +156,7 @@ struct pvstate_s {
|
||||
* Program status *
|
||||
******************/
|
||||
struct pvprogramstatus_s {
|
||||
char cwd[PV_SIZEOF_CWD]; /* current working directory for relative path */
|
||||
nullable_only_string_t cwd; /* for relative paths in --watchfd */
|
||||
int current_input_file; /* index of current file being read */
|
||||
int exit_status; /* exit status to give (0=OK) */
|
||||
bool terminal_supports_utf8; /* whether the terminal supports UTF-8 */
|
||||
|
||||
+30
-8
@@ -190,6 +190,7 @@ void pv_state_reset(pvstate_t state)
|
||||
pvstate_t pv_state_alloc(void)
|
||||
{
|
||||
pvstate_t state;
|
||||
size_t try_size;
|
||||
|
||||
state = calloc(1, sizeof(*state));
|
||||
if (NULL == state)
|
||||
@@ -209,19 +210,35 @@ pvstate_t pv_state_alloc(void)
|
||||
|
||||
pv_state_reset(state);
|
||||
|
||||
#ifdef HAVE_GETCWD
|
||||
/*
|
||||
* Get the current working directory, if possible, as a base for
|
||||
* showing relative filenames with --watchfd.
|
||||
*
|
||||
* If this fails then --watchfd will fall back to always showing the
|
||||
* full path.
|
||||
*/
|
||||
if (NULL == getcwd(state->status.cwd, PV_SIZEOF_CWD - 1)) {
|
||||
/* failed - will always show full path. */
|
||||
state->status.cwd[0] = '\0';
|
||||
for (try_size = 32; try_size <= 16384; try_size = try_size * 2) {
|
||||
bool buffer_too_small;
|
||||
|
||||
/*@-mustfreeonly@ *//* splint mis-detects a memory leak here */
|
||||
state->status.cwd = malloc(try_size);
|
||||
/*@+mustfreeonly@ */
|
||||
if (NULL == state->status.cwd)
|
||||
break;
|
||||
|
||||
buffer_too_small = false;
|
||||
if (NULL == getcwd(state->status.cwd, try_size)) {
|
||||
if (errno != ERANGE)
|
||||
buffer_too_small = true;
|
||||
free(state->status.cwd);
|
||||
state->status.cwd = NULL;
|
||||
}
|
||||
|
||||
if (!buffer_too_small)
|
||||
break;
|
||||
}
|
||||
if ('\0' == state->status.cwd[1]) {
|
||||
/* CWD is root directory - always show full path. */
|
||||
state->status.cwd[0] = '\0';
|
||||
}
|
||||
state->status.cwd[PV_SIZEOF_CWD - 1] = '\0';
|
||||
#endif /* HAVE_GETCWD */
|
||||
|
||||
return state;
|
||||
}
|
||||
@@ -360,6 +377,11 @@ void pv_state_free(pvstate_t state)
|
||||
state->control.output_name = NULL;
|
||||
}
|
||||
|
||||
if (NULL != state->status.cwd) {
|
||||
free(state->status.cwd);
|
||||
state->status.cwd = NULL;
|
||||
}
|
||||
|
||||
pv_freecontents_display(&(state->display));
|
||||
pv_freecontents_display(&(state->extra_display));
|
||||
|
||||
|
||||
+5
-2
@@ -683,9 +683,12 @@ void pv_watchpid_setname(pvstate_t state, pvwatchfd_t info)
|
||||
memset(info->display_name, 0, PV_SIZEOF_DISPLAY_NAME);
|
||||
|
||||
path_length = strlen(info->file_fdpath); /* flawfinder: ignore */
|
||||
cwd_length = strlen(state->status.cwd); /* flawfinder: ignore */
|
||||
cwd_length = 0;
|
||||
if (NULL != state->status.cwd) {
|
||||
cwd_length = strlen(state->status.cwd); /* flawfinder: ignore */
|
||||
}
|
||||
/* flawfinder: both strings are always \0 terminated. */
|
||||
if (cwd_length > 0 && path_length > cwd_length) {
|
||||
if (cwd_length > 0 && path_length > cwd_length && NULL != state->status.cwd) {
|
||||
if (0 == strncmp(info->file_fdpath, state->status.cwd, cwd_length)) {
|
||||
file_fdpath += cwd_length + 1;
|
||||
path_length -= cwd_length + 1;
|
||||
|
||||
Reference in New Issue
Block a user