aboutsummaryrefslogtreecommitdiffstats
path: root/pseudo_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'pseudo_util.c')
-rw-r--r--pseudo_util.c82
1 files changed, 70 insertions, 12 deletions
diff --git a/pseudo_util.c b/pseudo_util.c
index 0a2c683..4bc2d5a 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -30,7 +30,9 @@
#include "pseudo_ipc.h"
#include "pseudo_db.h"
-/* 3 = detailed protocol analysis
+/* 5 = ridiculous levels of duplication
+ * 4 = exhaustive detail
+ * 3 = detailed protocol analysis
* 2 = higher-level protocol analysis
* 1 = stuff that might go wrong
* 0 = fire and arterial bleeding
@@ -43,6 +45,8 @@ static size_t pid_len;
static int pseudo_append_element(char **newpath, size_t *allocated, char **current, const char *element, size_t elen, int leave_last);
static int pseudo_append_elements(char **newpath, size_t *allocated, char **current, const char *elements, size_t elen, int leave_last);
extern char **environ;
+static ssize_t pseudo_max_pathlen = -1;
+static ssize_t pseudo_sys_max_pathlen = -1;
char *pseudo_version = PSEUDO_VERSION;
@@ -198,11 +202,11 @@ pseudo_append_element(char **pnewpath, size_t *pallocated, char **pcurrent, cons
is_link = 0;
}
if (is_link) {
- char linkbuf[PATH_MAX + 1];
+ char linkbuf[pseudo_path_max() + 1];
ssize_t linklen;
int retval;
- linklen = readlink(newpath, linkbuf, PATH_MAX);
+ linklen = readlink(newpath, linkbuf, pseudo_path_max());
if (linklen == -1) {
pseudo_diag("uh-oh! '%s' seems to be a symlink, but I can't read it. Ignoring.", newpath);
return 0;
@@ -459,29 +463,29 @@ pseudo_get_prefix(char *pathname) {
char *s;
s = getenv("PSEUDO_PREFIX");
if (!s) {
- char mypath[PATH_MAX];
+ char mypath[pseudo_path_max()];
char *dir;
char *tmp_path;
if (pathname[0] == '/') {
- snprintf(mypath, PATH_MAX, "%s", pathname);
+ snprintf(mypath, pseudo_path_max(), "%s", pathname);
s = mypath + strlen(mypath);
} else {
- if (!getcwd(mypath, PATH_MAX)) {
+ if (!getcwd(mypath, pseudo_path_max())) {
mypath[0] = '\0';
}
s = mypath + strlen(mypath);
- s += snprintf(s, PATH_MAX - (s - mypath), "/%s",
+ s += snprintf(s, pseudo_path_max() - (s - mypath), "/%s",
pathname);
}
- tmp_path = pseudo_fix_path(NULL, mypath, 0, 0, 0);
+ tmp_path = pseudo_fix_path(NULL, mypath, 0, 0, AT_SYMLINK_NOFOLLOW);
/* point s to the end of the fixed path */
- if (strlen(tmp_path) >= PATH_MAX) {
- pseudo_diag("Can't expand path '%s' -- expansion exceeds PATH_MAX.\n",
- mypath);
+ if (strlen(tmp_path) >= pseudo_path_max()) {
+ pseudo_diag("Can't expand path '%s' -- expansion exceeds %d.\n",
+ mypath, (int) pseudo_path_max());
free(tmp_path);
} else {
- s = mypath + snprintf(mypath, PATH_MAX, "%s", tmp_path);
+ s = mypath + snprintf(mypath, pseudo_path_max(), "%s", tmp_path);
free(tmp_path);
}
@@ -508,3 +512,57 @@ pseudo_get_prefix(char *pathname) {
}
return s;
}
+
+/* these functions define the sizes pseudo will try to use
+ * when trying to allocate space, or guess how much space
+ * other people will have allocated; see the GNU man page
+ * for realpath(3) for an explanation of why the sys_path_max
+ * functions exists, approximately -- it's there to be a size
+ * that I'm pretty sure the user will have allocated if they
+ * provided a buffer to that defective function.
+ */
+/* I'm pretty sure this will be larger than real PATH_MAX */
+#define REALLY_BIG_PATH 16384
+/* A likely common value for PATH_MAX */
+#define SORTA_BIG_PATH 4096
+ssize_t
+pseudo_path_max(void) {
+ if (pseudo_max_pathlen == -1) {
+ long l = pathconf("/", _PC_PATH_MAX);
+ if (l < 0) {
+ if (_POSIX_PATH_MAX > 0) {
+ pseudo_max_pathlen = _POSIX_PATH_MAX;
+ } else {
+ pseudo_max_pathlen = REALLY_BIG_PATH;
+ }
+ } else {
+ if (l <= REALLY_BIG_PATH) {
+ pseudo_max_pathlen = l;
+ } else {
+ pseudo_max_pathlen = REALLY_BIG_PATH;
+ }
+ }
+ }
+ return pseudo_max_pathlen;
+}
+
+ssize_t
+pseudo_sys_path_max(void) {
+ if (pseudo_sys_max_pathlen == -1) {
+ long l = pathconf("/", _PC_PATH_MAX);
+ if (l < 0) {
+ if (_POSIX_PATH_MAX > 0) {
+ pseudo_sys_max_pathlen = _POSIX_PATH_MAX;
+ } else {
+ pseudo_sys_max_pathlen = SORTA_BIG_PATH;
+ }
+ } else {
+ if (l <= SORTA_BIG_PATH) {
+ pseudo_sys_max_pathlen = l;
+ } else {
+ pseudo_sys_max_pathlen = SORTA_BIG_PATH;
+ }
+ }
+ }
+ return pseudo_sys_max_pathlen;
+}