aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt4
-rw-r--r--Makefile.in2
-rw-r--r--enums/debug_type.in27
-rwxr-xr-xmaketables59
-rw-r--r--ports/common/pseudo_wrappers.c32
-rw-r--r--ports/darwin/guts/fcntl.c4
-rw-r--r--ports/darwin/guts/open.c4
-rw-r--r--ports/linux/guts/__fxstat64.c2
-rw-r--r--ports/linux/guts/__fxstatat64.c2
-rw-r--r--ports/linux/guts/fcntl.c2
-rw-r--r--ports/linux/guts/fopen64.c4
-rw-r--r--ports/linux/guts/freopen64.c4
-rw-r--r--ports/linux/guts/get_current_dir_name.c1
-rw-r--r--ports/linux/guts/mkstemp64.c2
-rw-r--r--ports/linux/guts/openat.c4
-rw-r--r--ports/linux/newclone/pseudo_wrappers.c4
-rw-r--r--ports/linux/oldclone/pseudo_wrappers.c4
-rw-r--r--ports/uids_generic/guts/getgrgid_r.c2
-rw-r--r--ports/unix/guts/chdir.c2
-rw-r--r--ports/unix/guts/chroot.c4
-rw-r--r--ports/unix/guts/dup.c2
-rw-r--r--ports/unix/guts/dup2.c2
-rw-r--r--ports/unix/guts/fchmodat.c2
-rw-r--r--ports/unix/guts/fchown.c6
-rw-r--r--ports/unix/guts/fchownat.c2
-rw-r--r--ports/unix/guts/fopen.c4
-rw-r--r--ports/unix/guts/freopen.c4
-rw-r--r--ports/unix/guts/getcwd.c6
-rw-r--r--ports/unix/guts/getwd.c2
-rw-r--r--ports/unix/guts/mkdirat.c2
-rw-r--r--ports/unix/guts/mkdtemp.c2
-rw-r--r--ports/unix/guts/mkstemp.c2
-rw-r--r--ports/unix/guts/opendir.c2
-rw-r--r--ports/unix/guts/rename.c4
-rw-r--r--ports/unix/guts/renameat.c4
-rw-r--r--ports/unix/guts/rmdir.c2
-rw-r--r--ports/unix/guts/unlinkat.c2
-rw-r--r--ports/unix/pseudo_wrappers.c6
-rw-r--r--pseudo.179
-rw-r--r--pseudo.c111
-rw-r--r--pseudo.h15
-rw-r--r--pseudo_client.c140
-rw-r--r--pseudo_db.c64
-rw-r--r--pseudo_ipc.c26
-rw-r--r--pseudo_server.c42
-rw-r--r--pseudo_util.c145
-rw-r--r--pseudolog.117
-rw-r--r--pseudolog.c20
-rw-r--r--table_templates/pseudo_tables.h1
-rw-r--r--templates/wrapfuncs.c10
50 files changed, 555 insertions, 340 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index f257c7c..87f3f9f 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,7 @@
+2013-06-20:
+ * (seebs) refactor debugging code
+ * (seebs) start using 1.5.2 numbering
+
2013-06-18:
* (seebs) Fix bug in oldclone (reported by rich@noir.com).
diff --git a/Makefile.in b/Makefile.in
index 21324f9..f3f67ea 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -29,7 +29,7 @@ BITS=@BITS@
ARCH_FLAGS=@ARCH_FLAGS@
MARK64=@MARK64@
RPATH=@RPATH@
-VERSION=1.5.1
+VERSION=1.5.2
LIB=@LIB@
BIN=bin
diff --git a/enums/debug_type.in b/enums/debug_type.in
new file mode 100644
index 0000000..4e3126e
--- /dev/null
+++ b/enums/debug_type.in
@@ -0,0 +1,27 @@
+debug_type: PDBG; INDEXED unsigned char symbolic = '\0', const char * description = NULL, FLAGS
+# Note: For convenience/consistency with the old numerc debug levels
+# stuff, these are sorted in a very rough approximation of "likelihood
+# that the user will care." So, PSEUDO_DEBUG=1 will pick up the
+# consistency checks. In general, most numeric debug levels will be
+# significantly less chatty than they used to be; there was one
+# level 5 message, I think, and nothing else above a 4. Which was a
+# problem.
+# Note: Descriptions should be under 32 characters to match the formatting
+# in pseudo's help message.
+consistency, 'n', "consistency checks"
+file, 'f', "file creation/deletion"
+op, 'o', "operations"
+pid, 'P', "show process IDs"
+client, 'c', "client side startup/shutdown"
+server, 'v', "server side startup/shutdown"
+db, 'd', "database interactions"
+syscall, 'y', "system calls"
+env, 'e', "environment manipulation"
+chroot, 'r', "chroot functionality"
+path, 'p', "path computations"
+sql, 's', "SQL query information"
+wrapper, 'w', "wrapper functionality"
+ipc, 'i', "client/server interactions"
+invoke, 'k', "invocation and launching"
+benchmark, 'b', "performance statistics"
+verbose, 'V', "extra detail"
diff --git a/maketables b/maketables
index 7c54c6a..b32312e 100755
--- a/maketables
+++ b/maketables
@@ -66,10 +66,19 @@ class DataType:
else:
self.prefix = qualifiers
columns = []
+ self.flags = False
if len(columns):
self.columns = []
columns = string.split(columns, ', ')
for col in columns:
+ indexed = False
+ if col.startswith("FLAGS"):
+ print "Flags: set for %s" % self.name
+ self.flags = True
+ continue
+ if col.startswith("INDEXED "):
+ col = col[8:]
+ indexed = True
if "=" in col:
name, default = string.split(col, ' = ')
else:
@@ -81,11 +90,12 @@ class DataType:
type = ' '.join(words)
else:
type = "char *"
- self.columns.append({"type":type, "name":name, "value":default})
+ self.columns.append({"indexed":indexed, "type":type, "name":name, "value":default})
else:
self.columns = []
self.data = []
self.comments = []
+ index = 1
for line in source.readlines():
item = {}
if line.startswith('#'):
@@ -99,10 +109,22 @@ class DataType:
column_list = []
for col in self.columns:
if len(cols) > 0:
- column_list.append({"name":col["name"], "value":cols.pop(0)})
+ value = cols.pop(0)
+ if col["indexed"]:
+ if not "max" in col:
+ col["max"] = value
+ if value > col["max"]:
+ col["max"] = value
+ if not "min" in col:
+ col["min"] = value
+ if value < col["min"]:
+ col["min"] = value
+ column_list.append({"name":col["name"], "value":value})
else:
column_list.append({"name":col["name"], "value":col["value"]})
item["cols"] = column_list
+ item["index"] = index
+ index = index + 1
self.data.append(item)
def __getitem__(self, key):
@@ -143,6 +165,18 @@ class DataType:
def enums(self):
return ',\n\t'.join('%s_%s' % (self.prefix, x["upper"]) for x in self.data)
+ def flag_enums(self):
+ if not self.flags:
+ return ""
+ enum_lines = []
+ enum_lines.append('typedef enum {')
+ prefix = self.prefix + 'F'
+ for x in self.data:
+ enum_lines.append('\t%s_%s = (1 << %s_%s),' %
+ (prefix, x["upper"], self.prefix, x["upper"]))
+ enum_lines.append('} pseudo_%s_f;' % self.name)
+ return '\n'.join(enum_lines)
+
def column_names(self):
decl_lines = []
column = 0
@@ -153,6 +187,11 @@ class DataType:
decl_lines.append('\t%s,' % item["cols"][column]["value"])
decl_lines.append('\t0')
decl_lines.append("};")
+ if col["indexed"]:
+ decl_lines.append("static int %s_%s_to_id[] = {" % (self.name, col["name"]))
+ for item in self.data:
+ decl_lines.append('\t[%s] = %d,' % (item["cols"][column]["value"], item["index"]))
+ decl_lines.append("};")
column = column + 1
return '\n'.join(decl_lines)
@@ -167,6 +206,19 @@ class DataType:
decl_lines.append('\treturn %s_id_to_%s[id];' %
(self.name, col["name"]))
decl_lines.append('}')
+ if col["indexed"]:
+ table_name = '%s_%s_to_id' % (self.name, col["name"])
+ decl_lines.append('extern int')
+ decl_lines.append('pseudo_%s_%s_id(%s val) {' %
+ (self.name, col["name"], col["type"]))
+ decl_lines.append('\tif ((val < %s) || (val > %s)) {' % (col["min"], col["max"]))
+ decl_lines.append('\t\treturn -1;')
+ decl_lines.append('\t}')
+ decl_lines.append('\tif (%s[val] != 0) {' % table_name)
+ decl_lines.append('\t\treturn %s[val];' % table_name)
+ decl_lines.append('\t}')
+ decl_lines.append('\treturn -1;')
+ decl_lines.append('}')
return '\n'.join(decl_lines)
def column_protos(self):
@@ -174,6 +226,9 @@ class DataType:
for col in self.columns:
decl_lines.append('extern %s pseudo_%s_%s(pseudo_%s_t id);' %
(col["type"], self.name, col["name"], self.name))
+ if col["indexed"]:
+ decl_lines.append('extern int pseudo_%s_%s_id(%s val);' %
+ (self.name, col["name"], col["type"]))
return '\n'.join(decl_lines)
def main():
diff --git a/ports/common/pseudo_wrappers.c b/ports/common/pseudo_wrappers.c
index 2cfc400..3652ad4 100644
--- a/ports/common/pseudo_wrappers.c
+++ b/ports/common/pseudo_wrappers.c
@@ -33,7 +33,7 @@ execl_to_v(va_list ap, const char *argv0, char *const **envp) {
char **argv = malloc((sizeof *argv) * alloc_size);
if (!argv) {
- pseudo_debug(1, "execl failed: couldn't allocate memory for %lu arguments\n",
+ pseudo_debug(PDBGF_CLIENT, "execl failed: couldn't allocate memory for %lu arguments\n",
(unsigned long) alloc_size);
return NULL;
}
@@ -45,7 +45,7 @@ execl_to_v(va_list ap, const char *argv0, char *const **envp) {
alloc_size = alloc_size + 256;
argv = realloc(argv, (sizeof *argv) * alloc_size);
if (!argv) {
- pseudo_debug(1, "execl failed: couldn't allocate memory for %lu arguments\n",
+ pseudo_debug(PDBGF_CLIENT, "execl failed: couldn't allocate memory for %lu arguments\n",
(unsigned long) alloc_size);
return NULL;
}
@@ -81,7 +81,7 @@ execl(const char *file, const char *arg, ...) {
return -1;
}
- pseudo_debug(4, "called: execl\n");
+ pseudo_debug(PDBGF_WRAPPER, "called: execl\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
errno = EBUSY;
@@ -98,7 +98,7 @@ execl(const char *file, const char *arg, ...) {
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execl\n");
+ pseudo_debug(PDBGF_WRAPPER, "completed: execl\n");
errno = save_errno;
free(argv);
return rc;
@@ -126,7 +126,7 @@ execlp(const char *file, const char *arg, ...) {
return -1;
}
- pseudo_debug(4, "called: execlp\n");
+ pseudo_debug(PDBGF_WRAPPER, "called: execlp\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
errno = EBUSY;
@@ -143,7 +143,7 @@ execlp(const char *file, const char *arg, ...) {
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execlp\n");
+ pseudo_debug(PDBGF_WRAPPER, "completed: execlp\n");
errno = save_errno;
free(argv);
return rc;
@@ -172,7 +172,7 @@ execle(const char *file, const char *arg, ...) {
return -1;
}
- pseudo_debug(4, "called: execle\n");
+ pseudo_debug(PDBGF_WRAPPER, "called: execle\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
errno = EBUSY;
@@ -189,7 +189,7 @@ execle(const char *file, const char *arg, ...) {
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execle\n");
+ pseudo_debug(PDBGF_WRAPPER, "completed: execle\n");
errno = save_errno;
free(argv);
return rc;
@@ -207,7 +207,7 @@ execv(const char *file, char *const *argv) {
return rc;
}
- pseudo_debug(4, "called: execv\n");
+ pseudo_debug(PDBGF_WRAPPER, "called: execv\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
errno = EBUSY;
@@ -224,7 +224,7 @@ execv(const char *file, char *const *argv) {
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execv\n");
+ pseudo_debug(PDBGF_WRAPPER, "completed: execv\n");
errno = save_errno;
return rc;
}
@@ -241,7 +241,7 @@ execve(const char *file, char *const *argv, char *const *envp) {
return rc;
}
- pseudo_debug(4, "called: execve\n");
+ pseudo_debug(PDBGF_WRAPPER, "called: execve\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
errno = EBUSY;
@@ -258,7 +258,7 @@ execve(const char *file, char *const *argv, char *const *envp) {
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execve\n");
+ pseudo_debug(PDBGF_WRAPPER, "completed: execve\n");
errno = save_errno;
return rc;
}
@@ -275,7 +275,7 @@ execvp(const char *file, char *const *argv) {
return rc;
}
- pseudo_debug(4, "called: execvp\n");
+ pseudo_debug(PDBGF_WRAPPER, "called: execvp\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
errno = EBUSY;
@@ -292,7 +292,7 @@ execvp(const char *file, char *const *argv) {
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: execvp\n");
+ pseudo_debug(PDBGF_WRAPPER, "completed: execvp\n");
errno = save_errno;
return rc;
}
@@ -309,7 +309,7 @@ fork(void) {
return rc;
}
- pseudo_debug(4, "called: fork\n");
+ pseudo_debug(PDBGF_WRAPPER, "called: fork\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
errno = EBUSY;
@@ -325,7 +325,7 @@ fork(void) {
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: fork\n");
+ pseudo_debug(PDBGF_WRAPPER, "completed: fork\n");
errno = save_errno;
return rc;
}
diff --git a/ports/darwin/guts/fcntl.c b/ports/darwin/guts/fcntl.c
index 1cc8258..c0b142b 100644
--- a/ports/darwin/guts/fcntl.c
+++ b/ports/darwin/guts/fcntl.c
@@ -24,7 +24,7 @@
/* actually do something */
save_errno = errno;
if (rc != -1) {
- pseudo_debug(2, "fcntl_dup: %d->%d\n", fd, rc);
+ pseudo_debug(PDBGF_OP, "fcntl_dup: %d->%d\n", fd, rc);
pseudo_client_op(OP_DUP, 0, fd, rc, 0, 0);
}
errno = save_errno;
@@ -35,7 +35,7 @@
}
save_errno = errno;
- pseudo_debug(3, "fcntl(fd %d, cmd %d, %llx) => %d (%s)\n",
+ pseudo_debug(PDBGF_OP, "fcntl(fd %d, cmd %d, %llx) => %d (%s)\n",
fd, cmd, flag, rc, strerror(errno));
errno = save_errno;
diff --git a/ports/darwin/guts/open.c b/ports/darwin/guts/open.c
index c66cc15..8680e20 100644
--- a/ports/darwin/guts/open.c
+++ b/ports/darwin/guts/open.c
@@ -19,7 +19,7 @@
rc = real_stat(path, &buf);
existed = (rc != -1);
if (!existed)
- pseudo_debug(2, "open_creat: %s -> 0%o\n", path, mode);
+ pseudo_debug(PDBGF_FILE, "open_creat: %s -> 0%o\n", path, mode);
errno = save_errno;
}
@@ -42,7 +42,7 @@
}
pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, -1, path, &buf);
} else {
- pseudo_debug(1, "open (fd %d, path %s, flags %d) succeeded, but stat failed (%s).\n",
+ pseudo_debug(PDBGF_CONSISTENCY, "open (fd %d, path %s, flags %d) succeeded, but stat failed (%s).\n",
rc, path, flags, strerror(errno));
pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, -1, path, 0);
}
diff --git a/ports/linux/guts/__fxstat64.c b/ports/linux/guts/__fxstat64.c
index 92c8219..8601904 100644
--- a/ports/linux/guts/__fxstat64.c
+++ b/ports/linux/guts/__fxstat64.c
@@ -15,7 +15,7 @@
return rc;
}
if (ver != _STAT_VER) {
- pseudo_debug(1, "version mismatch: got stat version %d, only supporting %d\n", ver, _STAT_VER);
+ pseudo_debug(PDBGF_CLIENT, "version mismatch: got stat version %d, only supporting %d\n", ver, _STAT_VER);
errno = save_errno;
return rc;
}
diff --git a/ports/linux/guts/__fxstatat64.c b/ports/linux/guts/__fxstatat64.c
index f8a9298..b989e7b 100644
--- a/ports/linux/guts/__fxstatat64.c
+++ b/ports/linux/guts/__fxstatat64.c
@@ -37,7 +37,7 @@
save_errno = errno;
if (ver != _STAT_VER) {
- pseudo_debug(1, "version mismatch: got stat version %d, only supporting %d\n", ver, _STAT_VER);
+ pseudo_debug(PDBGF_CLIENT, "version mismatch: got stat version %d, only supporting %d\n", ver, _STAT_VER);
errno = save_errno;
return rc;
}
diff --git a/ports/linux/guts/fcntl.c b/ports/linux/guts/fcntl.c
index 2e3e96d..639fd24 100644
--- a/ports/linux/guts/fcntl.c
+++ b/ports/linux/guts/fcntl.c
@@ -24,7 +24,7 @@
rc = real_fcntl(fd, cmd, arg);
save_errno = errno;
if (rc != -1) {
- pseudo_debug(2, "fcntl_dup: %d->%d\n", fd, rc);
+ pseudo_debug(PDBGF_OP, "fcntl_dup: %d->%d\n", fd, rc);
pseudo_client_op(OP_DUP, 0, fd, rc, 0, 0);
}
errno = save_errno;
diff --git a/ports/linux/guts/fopen64.c b/ports/linux/guts/fopen64.c
index b2724de..ac3fde1 100644
--- a/ports/linux/guts/fopen64.c
+++ b/ports/linux/guts/fopen64.c
@@ -17,14 +17,14 @@
if (rc) {
int fd = fileno(rc);
- pseudo_debug(2, "fopen64 '%s': fd %d <FILE %p>\n", path, fd, (void *) rc);
+ pseudo_debug(PDBGF_FILE, "fopen64 '%s': fd %d <FILE %p>\n", path, fd, (void *) rc);
if (real___fxstat64(_STAT_VER, fd, &buf) != -1) {
if (!existed) {
pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
}
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
} else {
- pseudo_debug(1, "fopen64 (fd %d) succeeded, but fstat failed (%s).\n",
+ pseudo_debug(PDBGF_CONSISTENCY, "fopen64 (fd %d) succeeded, but fstat failed (%s).\n",
fd, strerror(errno));
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, 0);
}
diff --git a/ports/linux/guts/freopen64.c b/ports/linux/guts/freopen64.c
index b8e576b..bb69b34 100644
--- a/ports/linux/guts/freopen64.c
+++ b/ports/linux/guts/freopen64.c
@@ -16,14 +16,14 @@
if (rc) {
int fd = fileno(rc);
- pseudo_debug(2, "freopen64 '%s': fd %d\n", path, fd);
+ pseudo_debug(PDBGF_FILE, "freopen64 '%s': fd %d\n", path, fd);
if (real___fxstat64(_STAT_VER, fd, &buf) != -1) {
if (!existed) {
pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
}
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
} else {
- pseudo_debug(1, "fopen (fd %d) succeeded, but stat failed (%s).\n",
+ pseudo_debug(PDBGF_FILE, "fopen (fd %d) succeeded, but stat failed (%s).\n",
fd, strerror(errno));
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, 0);
}
diff --git a/ports/linux/guts/get_current_dir_name.c b/ports/linux/guts/get_current_dir_name.c
index e07a6ee..79f82f9 100644
--- a/ports/linux/guts/get_current_dir_name.c
+++ b/ports/linux/guts/get_current_dir_name.c
@@ -7,7 +7,6 @@
* char * rc = NULL;
*/
- pseudo_debug(3, "get_current_dir_name (getcwd)\n");
/* this relies on a Linux extension, but we dutifully
* emulated that extension.
*/
diff --git a/ports/linux/guts/mkstemp64.c b/ports/linux/guts/mkstemp64.c
index def4126..6497f2e 100644
--- a/ports/linux/guts/mkstemp64.c
+++ b/ports/linux/guts/mkstemp64.c
@@ -33,7 +33,7 @@
pseudo_client_op(OP_CREAT, 0, -1, -1, tmp_template, &buf);
pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, &buf);
} else {
- pseudo_debug(1, "mkstemp (fd %d) succeeded, but fstat failed (%s).\n",
+ pseudo_debug(PDBGF_CONSISTENCY, "mkstemp (fd %d) succeeded, but fstat failed (%s).\n",
rc, strerror(errno));
pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, 0);
}
diff --git a/ports/linux/guts/openat.c b/ports/linux/guts/openat.c
index 8460073..1225368 100644
--- a/ports/linux/guts/openat.c
+++ b/ports/linux/guts/openat.c
@@ -45,7 +45,7 @@
#endif
existed = (rc != -1);
if (!existed)
- pseudo_debug(2, "openat_creat: %s -> 0%o\n", path, mode);
+ pseudo_debug(PDBGF_FILE, "openat_creat: %s -> 0%o\n", path, mode);
errno = save_errno;
}
@@ -76,7 +76,7 @@
}
pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, dirfd, path, &buf);
} else {
- pseudo_debug(1, "openat (fd %d, path %d/%s, flags %d) succeeded, but stat failed (%s).\n",
+ pseudo_debug(PDBGF_FILE, "openat (fd %d, path %d/%s, flags %d) succeeded, but stat failed (%s).\n",
rc, dirfd, path, flags, strerror(errno));
pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, dirfd, path, 0);
}
diff --git a/ports/linux/newclone/pseudo_wrappers.c b/ports/linux/newclone/pseudo_wrappers.c
index 9dbac42..092e532 100644
--- a/ports/linux/newclone/pseudo_wrappers.c
+++ b/ports/linux/newclone/pseudo_wrappers.c
@@ -60,7 +60,7 @@ clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
ctid = va_arg(ap, pid_t *);
va_end(ap);
- pseudo_debug(4, "called: clone\n");
+ pseudo_debug(PDBGF_WRAPPER, "called: clone\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
errno = EBUSY;
@@ -86,7 +86,7 @@ clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: clone\n");
+ pseudo_debug(PDBGF_WRAPPER, "completed: clone\n");
errno = save_errno;
return rc;
}
diff --git a/ports/linux/oldclone/pseudo_wrappers.c b/ports/linux/oldclone/pseudo_wrappers.c
index d6ea41e..f0a8eec 100644
--- a/ports/linux/oldclone/pseudo_wrappers.c
+++ b/ports/linux/oldclone/pseudo_wrappers.c
@@ -44,7 +44,7 @@ clone(int (*fn)(void *), void *child_stack, int flags, void *arg) {
return rc;
}
- pseudo_debug(4, "called: clone\n");
+ pseudo_debug(PDBGF_WRAPPER, "called: clone\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
errno = EBUSY;
@@ -70,7 +70,7 @@ clone(int (*fn)(void *), void *child_stack, int flags, void *arg) {
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
- pseudo_debug(4, "completed: clone\n");
+ pseudo_debug(PDBGF_WRAPPER, "completed: clone\n");
errno = save_errno;
return rc;
}
diff --git a/ports/uids_generic/guts/getgrgid_r.c b/ports/uids_generic/guts/getgrgid_r.c
index 06a91c9..b043995 100644
--- a/ports/uids_generic/guts/getgrgid_r.c
+++ b/ports/uids_generic/guts/getgrgid_r.c
@@ -11,7 +11,7 @@
while ((rc = wrap_getgrent_r(gbuf, buf, buflen, gbufp)) == 0) {
/* 0 means no error occurred, and *gbufp == gbuf */
if (gbuf->gr_gid == gid) {
- pseudo_debug(1, "found group gid %d, name %s\n",
+ pseudo_debug(PDBGF_CLIENT, "found group gid %d, name %s\n",
gbuf->gr_gid, gbuf->gr_name);
endgrent();
return rc;
diff --git a/ports/unix/guts/chdir.c b/ports/unix/guts/chdir.c
index 59a262f..9e30348 100644
--- a/ports/unix/guts/chdir.c
+++ b/ports/unix/guts/chdir.c
@@ -6,7 +6,7 @@
* wrap_chdir(const char *path) {
* int rc = -1;
*/
- pseudo_debug(2, "chdir: '%s'\n",
+ pseudo_debug(PDBGF_CLIENT, "chdir: '%s'\n",
path ? path : "<nil>");
if (!path) {
diff --git a/ports/unix/guts/chroot.c b/ports/unix/guts/chroot.c
index c5b6f2f..ac24955 100644
--- a/ports/unix/guts/chroot.c
+++ b/ports/unix/guts/chroot.c
@@ -6,9 +6,9 @@
* wrap_chroot(const char *path) {
* int rc = -1;
*/
- pseudo_debug(2, "chroot: %s\n", path);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_CHROOT, "chroot: %s\n", path);
if (!pseudo_client_op(OP_CHROOT, 0, -1, -1, path, 0)) {
- pseudo_debug(1, "chroot failed: %s\n", strerror(errno));
+ pseudo_debug(PDBGF_OP | PDBGF_CHROOT, "chroot failed: %s\n", strerror(errno));
rc = -1;
} else {
rc = 0;
diff --git a/ports/unix/guts/dup.c b/ports/unix/guts/dup.c
index 13612b1..f03c2ad 100644
--- a/ports/unix/guts/dup.c
+++ b/ports/unix/guts/dup.c
@@ -10,7 +10,7 @@
rc = real_dup(fd);
save_errno = errno;
- pseudo_debug(2, "dup: %d->%d\n", fd, rc);
+ pseudo_debug(PDBGF_CLIENT, "dup: %d->%d\n", fd, rc);
pseudo_client_op(OP_DUP, 0, fd, rc, 0, 0);
errno = save_errno;
diff --git a/ports/unix/guts/dup2.c b/ports/unix/guts/dup2.c
index 04666d1..cd335ac 100644
--- a/ports/unix/guts/dup2.c
+++ b/ports/unix/guts/dup2.c
@@ -10,7 +10,7 @@
/* close existing one first - this also causes the socket to the
* server to get moved around if someone tries to overwrite it. */
- pseudo_debug(2, "dup2: %d->%d\n", oldfd, newfd);
+ pseudo_debug(PDBGF_CLIENT, "dup2: %d->%d\n", oldfd, newfd);
pseudo_client_op(OP_CLOSE, 0, newfd, -1, 0, 0);
rc = real_dup2(oldfd, newfd);
save_errno = errno;
diff --git a/ports/unix/guts/fchmodat.c b/ports/unix/guts/fchmodat.c
index 59a92ce..36a8490 100644
--- a/ports/unix/guts/fchmodat.c
+++ b/ports/unix/guts/fchmodat.c
@@ -42,7 +42,7 @@
*/
msg = pseudo_client_op(OP_STAT, 0, -1, -1, path, &buf);
if (!msg || msg->result != RESULT_SUCCEED) {
- pseudo_debug(2, "chmodat to 0%o on %d/%s, ino %llu, new file.\n",
+ pseudo_debug(PDBGF_FILE, "chmodat to 0%o on %d/%s, ino %llu, new file.\n",
mode, dirfd, path, (unsigned long long) buf.st_ino);
}
diff --git a/ports/unix/guts/fchown.c b/ports/unix/guts/fchown.c
index 1514e35..6e33f0f 100644
--- a/ports/unix/guts/fchown.c
+++ b/ports/unix/guts/fchown.c
@@ -12,7 +12,7 @@
if (base_fstat(fd, &buf) == -1) {
save_errno = errno;
- pseudo_debug(2, "fchown failing because fstat failed: %s\n",
+ pseudo_debug(PDBGF_CONSISTENCY, "fchown failing because fstat failed: %s\n",
strerror(errno));
errno = save_errno;
return -1;
@@ -24,7 +24,7 @@
if (msg->result == RESULT_SUCCEED) {
pseudo_stat_msg(&buf, msg);
} else {
- pseudo_debug(2, "fchown fd %d, ino %llu, unknown file.\n",
+ pseudo_debug(PDBGF_FILE, "fchown fd %d, ino %llu, unknown file.\n",
fd, (unsigned long long) buf.st_ino);
}
} else {
@@ -39,7 +39,7 @@
if (group != (gid_t) -1) {
buf.st_gid = group;
}
- pseudo_debug(2, "fchown, fd %d: %d:%d -> %d:%d\n",
+ pseudo_debug(PDBGF_OP, "fchown, fd %d: %d:%d -> %d:%d\n",
fd, owner, group, buf.st_uid, buf.st_gid);
pseudo_client_op(OP_FCHOWN, 0, fd, -1, 0, &buf);
/* pretend we worked, errno should be unchanged */
diff --git a/ports/unix/guts/fchownat.c b/ports/unix/guts/fchownat.c
index 60ccfa5..f976d91 100644
--- a/ports/unix/guts/fchownat.c
+++ b/ports/unix/guts/fchownat.c
@@ -40,7 +40,7 @@
if (msg->result == RESULT_SUCCEED) {
pseudo_stat_msg(&buf, msg);
} else {
- pseudo_debug(2, "chownat to %d:%d on %d/%s, ino %llu, new file.\n",
+ pseudo_debug(PDBGF_FILE, "chownat to %d:%d on %d/%s, ino %llu, new file.\n",
owner, group, dirfd, path,
(unsigned long long) buf.st_ino);
}
diff --git a/ports/unix/guts/fopen.c b/ports/unix/guts/fopen.c
index c7b8da5..de940f5 100644
--- a/ports/unix/guts/fopen.c
+++ b/ports/unix/guts/fopen.c
@@ -16,14 +16,14 @@
if (rc) {
int fd = fileno(rc);
- pseudo_debug(2, "fopen '%s': fd %d <FILE %p>\n", path, fd, (void *) rc);
+ pseudo_debug(PDBGF_OP, "fopen '%s': fd %d <FILE %p>\n", path, fd, (void *) rc);
if (base_fstat(fd, &buf) != -1) {
if (!existed) {
pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
}
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
} else {
- pseudo_debug(1, "fopen (fd %d) succeeded, but fstat failed (%s).\n",
+ pseudo_debug(PDBGF_CONSISTENCY, "fopen (fd %d) succeeded, but fstat failed (%s).\n",
fd, strerror(errno));
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, 0);
}
diff --git a/ports/unix/guts/freopen.c b/ports/unix/guts/freopen.c
index eb788b3..45ca135 100644
--- a/ports/unix/guts/freopen.c
+++ b/ports/unix/guts/freopen.c
@@ -16,14 +16,14 @@
if (rc) {
int fd = fileno(rc);
- pseudo_debug(2, "freopen '%s': fd %d\n", path, fd);
+ pseudo_debug(PDBGF_OP, "freopen '%s': fd %d\n", path, fd);
if (base_fstat(fd, &buf) != -1) {
if (!existed) {
pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf);
}
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, &buf);
} else {
- pseudo_debug(1, "fopen (fd %d) succeeded, but stat failed (%s).\n",
+ pseudo_debug(PDBGF_OP, "fopen (fd %d) succeeded, but stat failed (%s).\n",
fd, strerror(errno));
pseudo_client_op(OP_OPEN, pseudo_access_fopen(mode), fd, -1, path, 0);
}
diff --git a/ports/unix/guts/getcwd.c b/ports/unix/guts/getcwd.c
index b3f552c..2915a18 100644
--- a/ports/unix/guts/getcwd.c
+++ b/ports/unix/guts/getcwd.c
@@ -6,7 +6,7 @@
* wrap_getcwd(char *buf, size_t size) {
* char * rc = NULL;
*/
- pseudo_debug(3, "wrap_getcwd: %p, %lu\n",
+ pseudo_debug(PDBGF_CLIENT, "wrap_getcwd: %p, %lu\n",
(void *) buf, (unsigned long) size);
if (!pseudo_cwd) {
pseudo_diag("Asked for CWD, but don't have it!\n");
@@ -44,7 +44,7 @@
}
}
if (pseudo_cwd_len - (pseudo_cwd_rel - pseudo_cwd) >= size) {
- pseudo_debug(1, "only %ld bytes available, need %ld (%ld + 1 - %ld)\n",
+ pseudo_debug(PDBGF_CLIENT, "only %ld bytes available, need %ld (%ld + 1 - %ld)\n",
(unsigned long) size,
(unsigned long) pseudo_cwd_len + 1 - pseudo_chroot_len,
(unsigned long) pseudo_cwd_len,
@@ -53,7 +53,7 @@
return NULL;
}
rc = buf;
- pseudo_debug(3, "getcwd: copying %d (%d + 1 - %d) characters from <%s>.\n",
+ pseudo_debug(PDBGF_CLIENT, "getcwd: copying %d (%d + 1 - %d) characters from <%s>.\n",
(int) ((pseudo_cwd_len + 1) - pseudo_chroot_len),
(int) pseudo_cwd_len, (int) pseudo_chroot_len,
pseudo_cwd_rel);
diff --git a/ports/unix/guts/getwd.c b/ports/unix/guts/getwd.c
index 836301e..b1bcf90 100644
--- a/ports/unix/guts/getwd.c
+++ b/ports/unix/guts/getwd.c
@@ -7,7 +7,7 @@
* char * rc = NULL;
*/
- pseudo_debug(3, "getwd (getcwd)\n");
+ pseudo_debug(PDBGF_CLIENT, "getwd (getcwd)\n");
rc = wrap_getcwd(buf, pseudo_path_max());
/* because it would violate everything we have ever known about
* UNIX for these functions to have the same errno semantics,
diff --git a/ports/unix/guts/mkdirat.c b/ports/unix/guts/mkdirat.c
index e846b70..a8fd825 100644
--- a/ports/unix/guts/mkdirat.c
+++ b/ports/unix/guts/mkdirat.c
@@ -27,7 +27,7 @@
if (stat_rc != -1) {
pseudo_client_op(OP_MKDIR, 0, -1, dirfd, path, &buf);
} else {
- pseudo_debug(1, "mkdir of %s succeeded, but stat failed: %s\n",
+ pseudo_debug(PDBGF_OP, "mkdir of %s succeeded, but stat failed: %s\n",
path, strerror(errno));
}
}
diff --git a/ports/unix/guts/mkdtemp.c b/ports/unix/guts/mkdtemp.c
index 194f0cb..5ef647b 100644
--- a/ports/unix/guts/mkdtemp.c
+++ b/ports/unix/guts/mkdtemp.c
@@ -32,7 +32,7 @@
if (base_stat(rc, &buf) != -1) {
pseudo_client_op(OP_CREAT, 0, -1, -1, tmp_template, &buf);
} else {
- pseudo_debug(1, "mkdtemp (path %s) succeeded, but fstat failed (%s).\n",
+ pseudo_debug(PDBGF_CONSISTENCY, "mkdtemp (path %s) succeeded, but fstat failed (%s).\n",
rc, strerror(errno));
}
errno = save_errno;
diff --git a/ports/unix/guts/mkstemp.c b/ports/unix/guts/mkstemp.c
index 2ad3f19..1f055fd 100644
--- a/ports/unix/guts/mkstemp.c
+++ b/ports/unix/guts/mkstemp.c
@@ -33,7 +33,7 @@
pseudo_client_op(OP_CREAT, 0, -1, -1, tmp_template, &buf);
pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, &buf);
} else {
- pseudo_debug(1, "mkstemp (fd %d) succeeded, but fstat failed (%s).\n",
+ pseudo_debug(PDBGF_CONSISTENCY, "mkstemp (fd %d) succeeded, but fstat failed (%s).\n",
rc, strerror(errno));
pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, 0);
}
diff --git a/ports/unix/guts/opendir.c b/ports/unix/guts/opendir.c
index 31f5738..c8a78f8 100644
--- a/ports/unix/guts/opendir.c
+++ b/ports/unix/guts/opendir.c
@@ -15,7 +15,7 @@
save_errno = errno;
fd = dirfd(rc);
if (base_fstat(fd, &buf) == -1) {
- pseudo_debug(1, "diropen (fd %d) succeeded, but fstat failed (%s).\n",
+ pseudo_debug(PDBGF_CONSISTENCY, "diropen (fd %d) succeeded, but fstat failed (%s).\n",
fd, strerror(errno));
pseudo_client_op(OP_OPEN, PSA_READ, fd, -1, path, 0);
} else {
diff --git a/ports/unix/guts/rename.c b/ports/unix/guts/rename.c
index 1473a8d..ad28293 100644
--- a/ports/unix/guts/rename.c
+++ b/ports/unix/guts/rename.c
@@ -12,7 +12,7 @@
int save_errno;
int old_db_entry = 0;
- pseudo_debug(2, "rename: %s->%s\n",
+ pseudo_debug(PDBGF_OP, "rename: %s->%s\n",
oldpath ? oldpath : "<nil>",
newpath ? newpath : "<nil>");
@@ -84,7 +84,7 @@
oldbuf.st_ino = newbuf.st_ino;
}
}
- pseudo_debug(1, "creating new '%s' [%llu] to rename\n",
+ pseudo_debug(PDBGF_FILE, "creating new '%s' [%llu] to rename\n",
oldpath, (unsigned long long) oldbuf.st_ino);
pseudo_client_op(OP_LINK, 0, -1, -1, oldpath, &oldbuf);
}
diff --git a/ports/unix/guts/renameat.c b/ports/unix/guts/renameat.c
index d8138bb..ade0509 100644
--- a/ports/unix/guts/renameat.c
+++ b/ports/unix/guts/renameat.c
@@ -12,7 +12,7 @@
int save_errno;
int old_db_entry = 0;
- pseudo_debug(2, "renameat: %d,%s->%d,%s\n",
+ pseudo_debug(PDBGF_FILE, "renameat: %d,%s->%d,%s\n",
olddirfd, oldpath ? oldpath : "<nil>",
newdirfd, newpath ? newpath : "<nil>");
@@ -96,7 +96,7 @@
oldbuf.st_ino = newbuf.st_ino;
}
}
- pseudo_debug(1, "creating new '%s' [%llu] to rename\n",
+ pseudo_debug(PDBGF_OP, "creating new '%s' [%llu] to rename\n",
oldpath, (unsigned long long) oldbuf.st_ino);
pseudo_client_op(OP_LINK, 0, -1, olddirfd, oldpath, &oldbuf);
}
diff --git a/ports/unix/guts/rmdir.c b/ports/unix/guts/rmdir.c
index a47e01c..ebc522a 100644
--- a/ports/unix/guts/rmdir.c
+++ b/ports/unix/guts/rmdir.c
@@ -28,7 +28,7 @@
pseudo_client_op(OP_DID_UNLINK, 0, -1, -1, path, &buf);
}
} else {
- pseudo_debug(1, "rmdir on <%s>, not in database, no effect.\n", path);
+ pseudo_debug(PDBGF_FILE, "rmdir on <%s>, not in database, no effect.\n", path);
}
/* return rc;
diff --git a/ports/unix/guts/unlinkat.c b/ports/unix/guts/unlinkat.c
index bd51b09..e723a01 100644
--- a/ports/unix/guts/unlinkat.c
+++ b/ports/unix/guts/unlinkat.c
@@ -53,7 +53,7 @@
pseudo_client_op(OP_DID_UNLINK, 0, -1, -1, path, &buf);
}
} else {
- pseudo_debug(1, "unlink on <%s>, not in database, no effect.\n", path);
+ pseudo_debug(PDBGF_FILE, "unlink on <%s>, not in database, no effect.\n", path);
}
/* return rc;
diff --git a/ports/unix/pseudo_wrappers.c b/ports/unix/pseudo_wrappers.c
index dddb1ec..b825d56 100644
--- a/ports/unix/pseudo_wrappers.c
+++ b/ports/unix/pseudo_wrappers.c
@@ -10,7 +10,7 @@ popen(const char *command, const char *mode) {
return rc;
}
- pseudo_debug(4, "called: popen\n");
+ pseudo_debug(PDBGF_WRAPPER, "called: popen\n");
pseudo_sigblock(&saved);
if (pseudo_getlock()) {
errno = EBUSY;
@@ -30,9 +30,9 @@ popen(const char *command, const char *mode) {
/* This can cause hangs on some recentish systems which use locale
* stuff for strerror...
*/
- pseudo_debug(4, "completed: popen (maybe: %s)\n", strerror(save_errno));
+ pseudo_debug(PDBGF_WRAPPER, "completed: popen (maybe: %s)\n", strerror(save_errno));
#endif
- pseudo_debug(4, "completed: popen (errno: %d)\n", save_errno);
+ pseudo_debug(PDBGF_WRAPPER, "completed: popen (errno: %d)\n", save_errno);
errno = save_errno;
return rc;
}
diff --git a/pseudo.1 b/pseudo.1
index f7f5bca..a929a54 100644
--- a/pseudo.1
+++ b/pseudo.1
@@ -19,29 +19,74 @@
.SH SYNOPSIS
.B pseudo
.RB [ \-dflv ]
-.RB [ \-P\ prefix ]
-.RB [ \-rR\ root ]
-.RB [ \-t\ timeout ]
-.RB [ command ]
+[
+.B \-x
+.I flags
+]
+[
+.B \-P
+.I prefix
+]
+[
+.B \-rR
+.I root
+]
+[
+.B \-t
+.I timeout
+]
+.RI [ command ]
.PP
.B pseudo \-h
.PP
.B pseudo
-.RB [ \-P\ prefix ]
+.RB [ \-dflv ]
+[
+.B \-x
+.I flags
+]
+[
+.B \-P
+.I prefix
+]
.RB [ \-BC ]
.BR \-i\ path
.PP
.B pseudo
-.RB [ \-P\ prefix ]
+.RB [ \-dflv ]
+[
+.B \-x
+.I flags
+]
+[
+.B \-P
+.I prefix
+]
.RB [ \-BC ]
.BR \-m\ from\ \-M\ to
.PP
.B pseudo
-.RB [ \-P\ prefix ]
+.RB [ \-dflv ]
+[
+.B \-x
+.I flags
+]
+[
+.B \-P
+.I prefix
+]
.B \-S
.PP
.B pseudo
-.RB [ \-P\ prefix ]
+.RB [ \-dflv ]
+[
+.B \-x
+.I flags
+]
+[
+.B \-P
+.I prefix
+]
.B \-V
.SH DESCRIPTION
The
@@ -240,12 +285,21 @@ Increase the verbosity of the
daemon, and the client library for any programs started by this
invocation of
.IR pseudo .
-This is equivalent to the
+This is equivalent to the numeric form of the
.B PSEUDO_DEBUG
environment variable; multiple
.B \-v
options increase the debugging level.
+.TP 8
+.BI \-x\ (debug)
+Set specific deugging flags (the
+.I pseudo
+utility's help message lists them). This is equivalent to the string
+form of the
+.B PSEUDO_DEBUG
+environment variable.
+
.SH EXAMPLES
The two most common usages of
.I pseudo
@@ -378,9 +432,12 @@ path. Paths that are relative to this are treated as though they were
instead relative to the filesystem root.
.TP 8
.B PSEUDO_DEBUG
-This variable holds the "debug level" for
+This variable holds either a numeric "debug level" for
.I pseudo
-to run at. In general, this is useful only for debugging
+to run at, or a set of specific debugging flags, generally letters.
+Use
+.B pseudo -h
+to see the available flags. In general, this is useful only for debugging
.I pseudo
itself.
.TP 8
diff --git a/pseudo.c b/pseudo.c
index ad71062..4d5ada9 100644
--- a/pseudo.c
+++ b/pseudo.c
@@ -56,13 +56,30 @@ static int pseudo_db_check(int fix);
void
usage(int status) {
FILE *f = status ? stderr : stdout;
- fputs("Usage: pseudo [-dflv] [-P prefix] [-rR root] [-t timeout] [command]\n", f);
+ fputs("Usage: pseudo [-dflv] [-x flags] [-P prefix] [-rR root] [-t timeout] [command]\n", f);
fputs(" pseudo -h\n", f);
- fputs(" pseudo [-dflv] [-P prefix] [-BC] -i path\n", f);
- fputs(" pseudo [-dflv] [-P prefix] [-BC] -m from -M to\n", f);
- fputs(" pseudo [-dflv] [-P prefix] -C\n", f);
- fputs(" pseudo [-dflv] [-P prefix] -S\n", f);
- fputs(" pseudo [-dflv] [-P prefix] -V\n", f);
+ fputs(" pseudo [-dflv] [-x flags] [-P prefix] [-BC] -i path\n", f);
+ fputs(" pseudo [-dflv] [-x flags] [-P prefix] [-BC] -m from -M to\n", f);
+ fputs(" pseudo [-dflv] [-x flags] [-P prefix] -C\n", f);
+ fputs(" pseudo [-dflv] [-x flags] [-P prefix] -S\n", f);
+ fputs(" pseudo [-dflv] [-x flags] [-P prefix] -V\n", f);
+ fputs("Debugging flags:\n", f);
+ for (int i = 1; i < PDBG_MAX; i += 2) {
+ unsigned char symbolics[2];
+ const char *descriptions[2];
+ symbolics[1] = pseudo_debug_type_symbolic(i);
+ symbolics[2] = pseudo_debug_type_symbolic(i + 1);
+ descriptions[1] = pseudo_debug_type_description(i);
+ descriptions[2] = pseudo_debug_type_description(i + 1);
+ if (symbolics[2]) {
+ fprintf(f, " %c %-32s %c %-32s\n",
+ symbolics[1], descriptions[1],
+ symbolics[2], descriptions[2]);
+ } else {
+ fprintf(f, " %c %-32s\n",
+ symbolics[1], descriptions[1]);
+ }
+ }
exit(status);
}
@@ -105,11 +122,11 @@ main(int argc, char *argv[]) {
pseudo_init_util();
if (ld_env && strstr(ld_env, "libpseudo")) {
- pseudo_debug(2, "can't run daemon with libpseudo in %s\n", PRELINK_LIBRARIES);
+ pseudo_debug(PDBGF_SERVER, "can't run daemon with libpseudo in %s\n", PRELINK_LIBRARIES);
s = pseudo_get_value("PSEUDO_UNLOAD");
if (s) {
- pseudo_diag("I can't seem to make %s go away. Sorry.\n", PRELINK_LIBRARIES);
- pseudo_diag("%s: %s\n", PRELINK_LIBRARIES, ld_env);
+ pseudo_diag("pseudo: I can't seem to make %s go away. Sorry.\n", PRELINK_LIBRARIES);
+ pseudo_diag("pseudo: %s: %s\n", PRELINK_LIBRARIES, ld_env);
exit(EXIT_FAILURE);
}
free(s);
@@ -137,7 +154,7 @@ main(int argc, char *argv[]) {
* wrong. The + suppresses this annoying behavior, but may not
* be compatible with sane option libraries.
*/
- while ((o = getopt(argc, argv, "+BCdfhi:lm:M:p:P:r:R:St:vV")) != -1) {
+ while ((o = getopt(argc, argv, "+BCdfhi:lm:M:p:P:r:R:St:vVx:")) != -1) {
switch (o) {
case 'B': /* rebuild database */
opt_B = 1;
@@ -234,6 +251,9 @@ main(int argc, char *argv[]) {
printf("Set PSEUDO_PREFIX to run with a different prefix.\n");
exit(0);
break;
+ case 'x': /* debug flags */
+ pseudo_debug_set(optarg);
+ break;
case '?':
default:
pseudo_diag("unknown/invalid argument (option '%c').\n", optopt);
@@ -241,6 +261,7 @@ main(int argc, char *argv[]) {
break;
}
}
+ pseudo_debug_flags_finalize();
/* Options are processed, preserve them... */
pseudo_set_value("PSEUDO_OPTS", opts);
@@ -346,14 +367,14 @@ main(int argc, char *argv[]) {
}
}
if (argc > optind) {
- pseudo_debug(2, "running command: %s\n",
+ pseudo_debug(PDBGF_INVOKE, "running command: %s\n",
argv[optind]);
argc -= optind;
argv += optind;
} else {
static char *newargv[2];
argv = newargv;
- pseudo_debug(2, "running shell.\n");
+ pseudo_debug(PDBGF_INVOKE, "running shell.\n");
argv[0] = getenv("SHELL");
if (!argv[0])
argv[0] = "/bin/sh";
@@ -401,7 +422,7 @@ main(int argc, char *argv[]) {
*/
pseudo_new_pid();
- pseudo_debug(3, "opening lock.\n");
+ pseudo_debug(PDBGF_SERVER, "opening lock.\n");
lockpath = pseudo_localstatedir_path(NULL);
if (!lockpath) {
pseudo_diag("Couldn't allocate a file path.\n");
@@ -432,18 +453,18 @@ main(int argc, char *argv[]) {
}
}
- pseudo_debug(3, "acquiring lock.\n");
+ pseudo_debug(PDBGF_SERVER, "acquiring lock.\n");
if (flock(lockfd, LOCK_EX | LOCK_NB) < 0) {
if (errno == EACCES || errno == EAGAIN) {
- pseudo_debug(1, "Existing server has lock. Exiting.\n");
+ pseudo_debug(PDBGF_SERVER, "Existing server has lock. Exiting.\n");
} else {
- pseudo_diag("Error obtaining lock: %s\n", strerror(errno));
+ pseudo_diag("pseudo: Error obtaining lock: %s\n", strerror(errno));
}
exit(0);
} else {
- pseudo_debug(2, "Acquired lock.\n");
+ pseudo_debug(PDBGF_SERVER, "Acquired lock.\n");
}
- pseudo_debug(3, "serving (%s)\n", opt_d ? "daemon" : "foreground");
+ pseudo_debug(PDBGF_SERVER, "serving (%s)\n", opt_d ? "daemon" : "foreground");
return pseudo_server_start(opt_d);
}
@@ -473,12 +494,12 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
case OP_FCHMOD: /* FALLTHROUGH */
case OP_FSTAT:
prefer_ino = 1;
- pseudo_debug(2, "%s %llu [%s]: ", pseudo_op_name(msg->op),
+ pseudo_debug(PDBGF_OP, "%s %llu [%s]: ", pseudo_op_name(msg->op),
(unsigned long long) msg->ino,
msg->pathlen ? msg->path : "no path");
break;
default:
- pseudo_debug(2, "%s %s [%llu]: ", pseudo_op_name(msg->op),
+ pseudo_debug(PDBGF_OP, "%s %s [%llu]: ", pseudo_op_name(msg->op),
msg->pathlen ? msg->path : "no path",
(unsigned long long) msg->ino);
break;
@@ -491,7 +512,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
if (msg->pathlen && msg->op == OP_RENAME) {
/* In a rename there are two paths, null seperate in msg->path */
oldpath = msg->path + strlen(msg->path) + 1;
- pseudo_debug(2, "rename: path %s, oldpath %s\n",
+ pseudo_debug(PDBGF_OP | PDBGF_FILE, "rename: path %s, oldpath %s\n",
msg->path, oldpath);
}
@@ -526,7 +547,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
found_path = 1;
} else {
if (msg->op != OP_RENAME && msg->op != OP_LINK) {
- pseudo_debug(3, "(new?) ");
+ pseudo_debug(PDBGF_FILE, "(new?) ");
}
}
}
@@ -539,7 +560,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
}
}
- pseudo_debug(3, "incoming: '%s'%s [%llu]%s\n",
+ pseudo_debug(PDBGF_OP, "incoming: '%s'%s [%llu]%s\n",
msg->pathlen ? msg->path : "no path",
found_path ? "+" : "-",
(unsigned long long) msg_header.ino,
@@ -561,7 +582,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
* as deleted.
*/
if (by_path.deleting != 0) {
- pseudo_debug(1, "inode mismatch for '%s' -- old one was marked for deletion, deleting.\n",
+ pseudo_debug(PDBGF_FILE, "inode mismatch for '%s' -- old one was marked for deletion, deleting.\n",
msg->path);
pdb_did_unlink_file(msg->path, by_path.deleting);
} else {
@@ -609,12 +630,12 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
* at leisure.
*/
if (msg->pathlen && !path_by_ino) {
- pseudo_debug(2, "db path missing: ino %llu, request '%s'.\n",
+ pseudo_debug(PDBGF_FILE, "db path missing: ino %llu, request '%s'.\n",
(unsigned long long) msg_header.ino, msg->path);
pdb_update_file_path(msg);
} else if (!msg->pathlen && path_by_ino) {
/* harmless */
- pseudo_debug(2, "req path missing: ino %llu, db '%s'.\n",
+ pseudo_debug(PDBGF_FILE, "req path missing: ino %llu, db '%s'.\n",
(unsigned long long) msg_header.ino, path_by_ino);
} else if (msg->pathlen && path_by_ino) {
/* this suggests a database error, except in LINK
@@ -650,7 +671,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
* already.
*/
if (by_ino.deleting != 0) {
- pseudo_debug(1, "inode mismatch for '%s' -- old one was marked for deletion, deleting.\n",
+ pseudo_debug(PDBGF_FILE, "inode mismatch for '%s' -- old one was marked for deletion, deleting.\n",
msg->path);
pdb_did_unlink_file(path_by_ino, by_ino.deleting);
} else {
@@ -664,7 +685,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
}
} else {
/* I don't think I've ever seen this one. */
- pseudo_debug(1, "warning: ino %llu in db (mode 0%o, owner %d), no path known.\n",
+ pseudo_debug(PDBGF_FILE, "warning: ino %llu in db (mode 0%o, owner %d), no path known.\n",
(unsigned long long) msg_header.ino,
(int) by_ino.mode, (int) by_ino.uid);
}
@@ -737,7 +758,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
break;
case OP_CHMOD: /* FALLTHROUGH */
case OP_FCHMOD:
- pseudo_debug(2, "mode 0%o ", (int) msg->mode);
+ pseudo_debug(PDBGF_OP, "mode 0%o ", (int) msg->mode);
/* if the inode is known, update it */
if (found_ino) {
/* obtain the existing data, merge with mode */
@@ -757,13 +778,13 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
}
/* if the path is not known, link it */
if (!found_path) {
- pseudo_debug(2, "(new) ");
+ pseudo_debug(PDBGF_FILE, "(new) ");
pdb_link_file(msg);
}
break;
case OP_CHOWN: /* FALLTHROUGH */
case OP_FCHOWN:
- pseudo_debug(2, "owner %d:%d ", (int) msg_header.uid, (int) msg_header.gid);
+ pseudo_debug(PDBGF_OP, "owner %d:%d ", (int) msg_header.uid, (int) msg_header.gid);
/* if the inode is known, update it */
if (found_ino) {
/* obtain the existing data, merge with mode */
@@ -797,7 +818,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
} else {
msg->result = RESULT_FAIL;
}
- pseudo_debug(3, "%s, ino %llu (old mode 0%o): mode 0%o\n",
+ pseudo_debug(PDBGF_OP | PDBGF_VERBOSE, "%s, ino %llu (old mode 0%o): mode 0%o\n",
pseudo_op_name(msg->op), (unsigned long long) msg->ino,
(int) msg_header.mode, (int) msg->mode);
break;
@@ -811,7 +832,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
* underlying file data in the client.
*/
if (found_path) {
- pseudo_debug(2, "replace %slink: path %s, old ino %llu, mode 0%o, new ino %llu, mode 0%o\n",
+ pseudo_debug(PDBGF_OP | PDBGF_FILE, "replace %slink: path %s, old ino %llu, mode 0%o, new ino %llu, mode 0%o\n",
msg->op == OP_SYMLINK ? "sym" : "",
msg->path, (unsigned long long) msg->ino,
(int) msg->mode,
@@ -819,7 +840,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
(int) msg_header.mode);
pdb_unlink_file(msg);
} else {
- pseudo_debug(2, "new %slink: path %s, ino %llu, mode 0%o\n",
+ pseudo_debug(PDBGF_OP | PDBGF_FILE, "new %slink: path %s, ino %llu, mode 0%o\n",
msg->op == OP_SYMLINK ? "sym" : "",
msg->path,
(unsigned long long) msg_header.ino,
@@ -827,12 +848,12 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
}
if (found_ino) {
if (msg->op == OP_SYMLINK) {
- pseudo_debug(2, "symlink: ignoring existing file %llu ['%s']\n",
+ pseudo_debug(PDBGF_OP | PDBGF_FILE, "symlink: ignoring existing file %llu ['%s']\n",
(unsigned long long) by_ino.ino,
path_by_ino ? path_by_ino : "no path");
} else {
*msg = by_ino;
- pseudo_debug(2, "link: copying data from existing file %llu ['%s']\n",
+ pseudo_debug(PDBGF_OP | PDBGF_FILE, "link: copying data from existing file %llu ['%s']\n",
(unsigned long long) by_ino.ino,
path_by_ino ? path_by_ino : "no path");
}
@@ -878,7 +899,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
* This should cease to be needed once symlinks are tracked.
*/
if (msg_header.nlink == 1 && found_ino) {
- pseudo_debug(2, "link count 1, unlinking anything with ino %llu.\n",
+ pseudo_debug(PDBGF_FILE | PDBGF_OP, "link count 1, unlinking anything with ino %llu.\n",
(unsigned long long) msg->ino);
pdb_unlink_file_dev(msg);
}
@@ -886,7 +907,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
break;
case OP_MKDIR: /* FALLTHROUGH */
case OP_MKNOD:
- pseudo_debug(2, "mode 0%o", (int) msg->mode);
+ pseudo_debug(PDBGF_OP, "mode 0%o", (int) msg->mode);
/* for us to get called, the client has to have succeeded in
* a creation (of a regular file, for mknod) -- meaning this
* file DID NOT exist before the call. Fix database:
@@ -916,7 +937,7 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag) {
if (path_by_ino != msg->path) {
free(path_by_ino);
}
- pseudo_debug(2, "completed %s.\n", pseudo_op_name(msg->op));
+ pseudo_debug(PDBGF_OP, "completed %s.\n", pseudo_op_name(msg->op));
if (opt_l)
pdb_log_msg(SEVERITY_INFO, msg, program, tag, NULL);
return 0;
@@ -961,13 +982,13 @@ pseudo_db_check(int fix) {
return EXIT_FAILURE;
}
while ((m = pdb_file(l)) != NULL) {
- pseudo_debug(2, "m: %p (%d: %s)\n",
+ pseudo_debug(PDBGF_DB, "m: %p (%d: %s)\n",
(void *) m,
m ? (int) m->pathlen : -1,
m ? m->path : "<n/a>");
if (m->pathlen > 0) {
int fixup_needed = 0;
- pseudo_debug(1, "Checking <%s>\n", m->path);
+ pseudo_debug(PDBGF_DB, "Checking <%s>\n", m->path);
if (lstat(m->path, &buf)) {
errors = EXIT_FAILURE;
pseudo_diag("can't stat <%s>\n", m->path);
@@ -978,7 +999,7 @@ pseudo_db_check(int fix) {
* can't really set.
*/
if (buf.st_ino != m->ino) {
- pseudo_debug(fix, "ino mismatch <%s>: ino %llu, db %llu\n",
+ pseudo_debug(PDBGF_DB, "ino mismatch <%s>: ino %llu, db %llu\n",
m->path,
(unsigned long long) buf.st_ino,
(unsigned long long) m->ino);
@@ -986,7 +1007,7 @@ pseudo_db_check(int fix) {
fixup_needed = 1;
}
if (buf.st_dev != m->dev) {
- pseudo_debug(fix, "dev mismatch <%s>: dev %llu, db %llu\n",
+ pseudo_debug(PDBGF_DB, "dev mismatch <%s>: dev %llu, db %llu\n",
m->path,
(unsigned long long) buf.st_dev,
(unsigned long long) m->dev);
@@ -994,14 +1015,14 @@ pseudo_db_check(int fix) {
fixup_needed = 1;
}
if (S_ISLNK(buf.st_mode) != S_ISLNK(m->mode)) {
- pseudo_debug(fix, "symlink mismatch <%s>: file %d, db %d\n",
+ pseudo_debug(PDBGF_DB, "symlink mismatch <%s>: file %d, db %d\n",
m->path,
S_ISLNK(buf.st_mode),
S_ISLNK(m->mode));
fixup_needed = 2;
}
if (S_ISDIR(buf.st_mode) != S_ISDIR(m->mode)) {
- pseudo_debug(fix, "symlink mismatch <%s>: file %d, db %d\n",
+ pseudo_debug(PDBGF_DB, "symlink mismatch <%s>: file %d, db %d\n",
m->path,
S_ISDIR(buf.st_mode),
S_ISDIR(m->mode));
diff --git a/pseudo.h b/pseudo.h
index 56760a4..15df164 100644
--- a/pseudo.h
+++ b/pseudo.h
@@ -33,12 +33,22 @@ char *pseudo_get_value(const char *key);
extern void pseudo_debug_verbose(void);
extern void pseudo_debug_terse(void);
+extern void pseudo_debug_set(char *);
+extern void pseudo_debug_clear(char *);
+extern void pseudo_debug_flags_finalize(void);
+extern unsigned long pseudo_util_debug_flags;
extern int pseudo_util_debug_fd;
extern int pseudo_disabled;
extern int pseudo_allow_fsync;
+extern int pseudo_diag(char *, ...) __attribute__ ((format (printf, 1, 2)));
#ifndef NDEBUG
-extern int pseudo_debug_real(int, char *, ...) __attribute__ ((format (printf, 2, 3)));
-#define pseudo_debug pseudo_debug_real
+#define pseudo_debug(x, ...) do { \
+ if ((x) & PDBGF_VERBOSE) { \
+ if ((pseudo_util_debug_flags & PDBGF_VERBOSE) && (pseudo_util_debug_flags & ((x) & ~PDBGF_VERBOSE))) { pseudo_diag(__VA_ARGS__); } \
+ } else { \
+ if (pseudo_util_debug_flags & (x)) { pseudo_diag(__VA_ARGS__); } \
+ } \
+} while (0)
#else
/* this used to be a static inline function, but that meant that arguments
* were still evaluated for side effects. We don't want that. The ...
@@ -46,7 +56,6 @@ extern int pseudo_debug_real(int, char *, ...) __attribute__ ((format (printf, 2
*/
#define pseudo_debug(...) 0
#endif
-extern int pseudo_diag(char *, ...) __attribute__ ((format (printf, 1, 2)));
void pseudo_new_pid(void);
/* pseudo_fix_path resolves symlinks up to this depth */
#define PSEUDO_MAX_LINK_RECURSION 16
diff --git a/pseudo_client.c b/pseudo_client.c
index b6d11a6..9e0de96 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -225,7 +225,7 @@ pseudo_init_client(void) {
pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
/* directory is missing? */
if (pseudo_prefix_dir_fd == -1 && errno == ENOENT) {
- pseudo_debug(1, "prefix directory doesn't exist, trying to create\n");
+ pseudo_debug(PDBGF_CLIENT, "prefix directory doesn't exist, trying to create\n");
mkdir_p(pseudo_path);
pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
}
@@ -248,7 +248,7 @@ pseudo_init_client(void) {
pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
/* directory is missing? */
if (pseudo_localstate_dir_fd == -1 && errno == ENOENT) {
- pseudo_debug(1, "local state directory doesn't exist, trying to create\n");
+ pseudo_debug(PDBGF_CLIENT, "local state directory doesn't exist, trying to create\n");
mkdir_p(pseudo_path);
pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
}
@@ -468,7 +468,7 @@ pseudo_client_chroot(const char *path) {
/* free old value */
free(pseudo_chroot);
- pseudo_debug(2, "client chroot: %s\n", path);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_CHROOT, "client chroot: %s\n", path);
if (!strcmp(path, "/")) {
pseudo_chroot_len = 0;
pseudo_chroot = 0;
@@ -499,7 +499,7 @@ pseudo_root_path(const char *func, int line, int dirfd, const char *path, int le
pseudo_diag("couldn't allocate absolute path for '%s'.\n",
path);
}
- pseudo_debug(3, "root_path [%s, %d]: '%s' from '%s'\n",
+ pseudo_debug(PDBGF_CHROOT, "root_path [%s, %d]: '%s' from '%s'\n",
func, line,
rc ? rc : "<nil>",
path ? path : "<nil>");
@@ -514,13 +514,13 @@ pseudo_client_getcwd(void) {
pseudo_diag("Can't allocate CWD buffer!\n");
return -1;
}
- pseudo_debug(3, "getcwd: trying to find cwd.\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "getcwd: trying to find cwd.\n");
if (getcwd(cwd, pseudo_path_max())) {
/* cwd now holds a canonical path to current directory */
free(pseudo_cwd);
pseudo_cwd = cwd;
pseudo_cwd_len = strlen(pseudo_cwd);
- pseudo_debug(3, "getcwd okay: [%s] %d bytes\n", pseudo_cwd, (int) pseudo_cwd_len);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "getcwd okay: [%s] %d bytes\n", pseudo_cwd, (int) pseudo_cwd_len);
if (pseudo_chroot_len &&
pseudo_cwd_len >= pseudo_chroot_len &&
!memcmp(pseudo_cwd, pseudo_chroot, pseudo_chroot_len) &&
@@ -530,9 +530,9 @@ pseudo_client_getcwd(void) {
} else {
pseudo_cwd_rel = pseudo_cwd;
}
- pseudo_debug(4, "abscwd: <%s>\n", pseudo_cwd);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "abscwd: <%s>\n", pseudo_cwd);
if (pseudo_cwd_rel != pseudo_cwd) {
- pseudo_debug(4, "relcwd: <%s>\n", pseudo_cwd_rel);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "relcwd: <%s>\n", pseudo_cwd_rel);
}
return 0;
} else {
@@ -559,7 +559,7 @@ pseudo_client_path(int fd, const char *path) {
if (fd >= nfds) {
int i;
- pseudo_debug(2, "expanding fds from %d to %d\n",
+ pseudo_debug(PDBGF_CLIENT, "expanding fds from %d to %d\n",
nfds, fd + 1);
fd_paths = realloc(fd_paths, (fd + 1) * sizeof(char *));
for (i = nfds; i < fd + 1; ++i)
@@ -567,7 +567,7 @@ pseudo_client_path(int fd, const char *path) {
nfds = fd + 1;
} else {
if (fd_paths[fd]) {
- pseudo_debug(2, "reopening fd %d [%s] -- didn't see close\n",
+ pseudo_debug(PDBGF_CLIENT, "reopening fd %d [%s] -- didn't see close\n",
fd, fd_paths[fd]);
}
/* yes, it is safe to free null pointers. yay for C89 */
@@ -600,7 +600,7 @@ client_spawn_server(void) {
pseudo_diag("couldn't fork server: %s\n", strerror(errno));
return 1;
}
- pseudo_debug(4, "spawned server, pid %d\n", server_pid);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_SERVER, "spawned server, pid %d\n", server_pid);
/* wait for the child process to terminate, indicating server
* is ready
*/
@@ -610,14 +610,14 @@ client_spawn_server(void) {
fp = fopen(pseudo_pidfile, "r");
if (fp) {
if (fscanf(fp, "%d", &server_pid) != 1) {
- pseudo_debug(1, "Opened server PID file, but didn't get a pid.\n");
+ pseudo_debug(PDBGF_CLIENT, "Opened server PID file, but didn't get a pid.\n");
}
fclose(fp);
} else {
- pseudo_debug(1, "no pid file (%s): %s\n",
+ pseudo_debug(PDBGF_CLIENT, "no pid file (%s): %s\n",
pseudo_pidfile, strerror(errno));
}
- pseudo_debug(2, "read new pid file: %d\n", server_pid);
+ pseudo_debug(PDBGF_CLIENT, "read new pid file: %d\n", server_pid);
free(pseudo_pidfile);
/* at this point, we should have a new server_pid */
return 0;
@@ -679,7 +679,7 @@ client_spawn_server(void) {
pseudo_setupenv();
pseudo_dropenv(); /* drop PRELINK_LIBRARIES */
- pseudo_debug(4, "calling execv on %s\n", argv[0]);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_SERVER | PDBGF_INVOKE, "calling execv on %s\n", argv[0]);
execv(argv[0], argv);
pseudo_diag("critical failure: exec of pseudo daemon failed: %s\n", strerror(errno));
@@ -707,25 +707,25 @@ client_ping(void) {
ping.client = getpid();
ping.result = 0;
errno = 0;
- pseudo_debug(4, "sending ping\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sending ping\n");
if (pseudo_msg_send(connect_fd, &ping, ping.pathlen, tagbuf)) {
- pseudo_debug(3, "error pinging server: %s\n", strerror(errno));
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "error pinging server: %s\n", strerror(errno));
return 1;
}
ack = pseudo_msg_receive(connect_fd);
if (!ack) {
- pseudo_debug(2, "no ping response from server: %s\n", strerror(errno));
+ pseudo_debug(PDBGF_CLIENT, "no ping response from server: %s\n", strerror(errno));
/* and that's not good, so... */
server_pid = 0;
return 1;
}
if (ack->type != PSEUDO_MSG_ACK) {
- pseudo_debug(1, "invalid ping response from server: expected ack, got %d\n", ack->type);
+ pseudo_debug(PDBGF_CLIENT, "invalid ping response from server: expected ack, got %d\n", ack->type);
/* and that's not good, so... */
server_pid = 0;
return 1;
}
- pseudo_debug(5, "ping ok\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "ping ok\n");
return 0;
}
@@ -771,7 +771,7 @@ client_connect(void) {
return 1;
}
- pseudo_debug(3, "connecting socket...\n");
+ pseudo_debug(PDBGF_CLIENT, "connecting socket...\n");
cwd_fd = open(".", O_RDONLY);
if (cwd_fd == -1) {
pseudo_diag("Couldn't stash directory before opening socket: %s",
@@ -789,7 +789,7 @@ client_connect(void) {
return 1;
}
if (connect(connect_fd, (struct sockaddr *) &sun, sizeof(sun)) == -1) {
- pseudo_debug(3, "can't connect socket to pseudo.socket: (%s)\n", strerror(errno));
+ pseudo_debug(PDBGF_CLIENT, "can't connect socket to pseudo.socket: (%s)\n", strerror(errno));
close(connect_fd);
if (fchdir(cwd_fd) == -1) {
pseudo_diag("return to previous directory failed: %s\n",
@@ -804,7 +804,7 @@ client_connect(void) {
strerror(errno));
}
close(cwd_fd);
- pseudo_debug(4, "connected socket.\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "connected socket.\n");
return 0;
}
@@ -824,13 +824,13 @@ pseudo_client_setup(void) {
fp = fopen(pseudo_pidfile, "r");
if (fp) {
if (fscanf(fp, "%d", &server_pid) != 1) {
- pseudo_debug(1, "Opened server PID file, but didn't get a pid.\n");
+ pseudo_debug(PDBGF_CLIENT, "Opened server PID file, but didn't get a pid.\n");
}
fclose(fp);
}
if (server_pid) {
if (kill(server_pid, 0) == -1) {
- pseudo_debug(1, "couldn't find server at pid %d: %s\n",
+ pseudo_debug(PDBGF_CLIENT, "couldn't find server at pid %d: %s\n",
server_pid, strerror(errno));
server_pid = 0;
}
@@ -843,20 +843,17 @@ pseudo_client_setup(void) {
if (!client_connect() && !client_ping()) {
return 0;
}
- pseudo_debug(2, "server seems to be gone, trying to restart\n");
+ pseudo_debug(PDBGF_CLIENT, "server seems to be gone, trying to restart\n");
if (client_spawn_server()) {
- pseudo_debug(1, "failed to spawn server, giving up.\n");
+ pseudo_debug(PDBGF_CLIENT, "failed to spawn server, giving up.\n");
return 1;
} else {
- pseudo_debug_verbose();
- pseudo_debug(2, "restarted, new pid %d\n", server_pid);
+ pseudo_debug(PDBGF_CLIENT, "restarted, new pid %d\n", server_pid);
if (!client_connect() && !client_ping()) {
- pseudo_debug_terse();
return 0;
}
- pseudo_debug_terse();
}
- pseudo_debug(1, "couldn't get a server, giving up.\n");
+ pseudo_debug(PDBGF_CLIENT, "couldn't get a server, giving up.\n");
return 1;
}
@@ -871,35 +868,35 @@ pseudo_client_request(pseudo_msg_t *msg, size_t len, const char *path) {
do {
do {
- pseudo_debug(4, "sending a message: ino %llu\n",
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sending a message: ino %llu\n",
(unsigned long long) msg->ino);
if (connect_fd < 0) {
- pseudo_debug(2, "trying to get server\n");
+ pseudo_debug(PDBGF_CLIENT, "trying to get server\n");
if (pseudo_client_setup()) {
return 0;
}
}
rc = pseudo_msg_send(connect_fd, msg, len, path);
if (rc != 0) {
- pseudo_debug(2, "msg_send: %d%s\n",
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "msg_send: %d%s\n",
rc,
rc == -1 ? " (sigpipe)" :
" (short write)");
pseudo_client_setup();
++tries;
if (tries > 3) {
- pseudo_debug(1, "can't get server going again.\n");
+ pseudo_debug(PDBGF_CLIENT, "can't get server going again.\n");
return 0;
}
}
} while (rc != 0);
- pseudo_debug(5, "sent!\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sent!\n");
if (msg->type != PSEUDO_MSG_FASTOP) {
response = pseudo_msg_receive(connect_fd);
if (!response) {
++tries;
if (tries > 3) {
- pseudo_debug(1, "can't get responses.\n");
+ pseudo_debug(PDBGF_CLIENT, "can't get responses.\n");
return 0;
}
}
@@ -908,10 +905,10 @@ pseudo_client_request(pseudo_msg_t *msg, size_t len, const char *path) {
}
} while (response == 0);
if (response->type != PSEUDO_MSG_ACK) {
- pseudo_debug(2, "got non-ack response %d\n", response->type);
+ pseudo_debug(PDBGF_CLIENT, "got non-ack response %d\n", response->type);
return 0;
} else {
- pseudo_debug(4, "got response type %d\n", response->type);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "got response type %d\n", response->type);
}
return response;
}
@@ -922,13 +919,14 @@ pseudo_client_shutdown(void) {
pseudo_msg_t *ack;
char *pseudo_path;
+ pseudo_debug(PDBGF_INVOKE, "attempting to shut down server.\n");
pseudo_path = pseudo_prefix_path(NULL);
if (pseudo_prefix_dir_fd == -1) {
if (pseudo_path) {
pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
/* directory is missing? */
if (pseudo_prefix_dir_fd == -1 && errno == ENOENT) {
- pseudo_debug(1, "prefix directory doesn't exist, trying to create\n");
+ pseudo_debug(PDBGF_CLIENT, "prefix directory doesn't exist, trying to create\n");
mkdir_p(pseudo_path);
pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
}
@@ -952,7 +950,7 @@ pseudo_client_shutdown(void) {
pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
/* directory is missing? */
if (pseudo_localstate_dir_fd == -1 && errno == ENOENT) {
- pseudo_debug(1, "local state dir doesn't exist, trying to create\n");
+ pseudo_debug(PDBGF_CLIENT, "local state dir doesn't exist, trying to create\n");
mkdir_p(pseudo_path);
pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
}
@@ -977,9 +975,9 @@ pseudo_client_shutdown(void) {
msg.type = PSEUDO_MSG_SHUTDOWN;
msg.op = OP_NONE;
msg.client = getpid();
- pseudo_debug(2, "sending shutdown request\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_SERVER, "sending shutdown request\n");
if (pseudo_msg_send(connect_fd, &msg, 0, NULL)) {
- pseudo_debug(1, "error requesting shutdown: %s\n", strerror(errno));
+ pseudo_debug(PDBGF_CLIENT | PDBGF_SERVER, "error requesting shutdown: %s\n", strerror(errno));
return 1;
}
ack = pseudo_msg_receive(connect_fd);
@@ -1043,7 +1041,7 @@ base_path(int dirfd, const char *path, int leave_last) {
}
newpath = pseudo_fix_path(basepath, path, minlen, baselen, NULL, leave_last);
- pseudo_debug(4, "base_path: %s</>%s\n",
+ pseudo_debug(PDBGF_PATH, "base_path: %s</>%s\n",
basepath ? basepath : "<nil>",
path ? path : "<nil>");
return newpath;
@@ -1103,7 +1101,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
snprintf(both_paths, full_len, "%.*s%c%s",
(int) (pathlen - 1 - strip_slash),
path, 0, oldpath);
- pseudo_debug(2, "rename: %s -> %s [%d]\n",
+ pseudo_debug(PDBGF_PATH | PDBGF_FILE, "rename: %s -> %s [%d]\n",
both_paths + pathlen, both_paths, (int) full_len);
alloced_path = both_paths;
path = alloced_path;
@@ -1125,30 +1123,30 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
path = 0;
msg.pathlen = 0;
}
- pseudo_debug(2, "%s%s", pseudo_op_name(op),
+ pseudo_debug(PDBGF_OP, "%s%s", pseudo_op_name(op),
(dirfd != -1 && dirfd != AT_FDCWD && op != OP_DUP) ? "at" : "");
if (oldpath) {
- pseudo_debug(2, " %s ->", (char *) oldpath);
+ pseudo_debug(PDBGF_OP, " %s ->", (char *) oldpath);
}
if (path) {
- pseudo_debug(2, " %s", path);
+ pseudo_debug(PDBGF_OP, " %s", path);
}
/* for OP_RENAME in renameat, "fd" is also used for the
* second dirfd.
*/
if (fd != -1 && op != OP_RENAME) {
- pseudo_debug(2, " [fd %d]", fd);
+ pseudo_debug(PDBGF_OP, " [fd %d]", fd);
}
if (buf) {
- pseudo_debug(2, " (+buf)");
+ pseudo_debug(PDBGF_OP, " (+buf)");
pseudo_msg_stat(&msg, buf);
if (buf && fd != -1) {
- pseudo_debug(2, " [dev/ino: %d/%llu]",
+ pseudo_debug(PDBGF_OP, " [dev/ino: %d/%llu]",
(int) buf->st_dev, (unsigned long long) buf->st_ino);
}
- pseudo_debug(2, " (0%o)", (int) buf->st_mode);
+ pseudo_debug(PDBGF_OP, " (0%o)", (int) buf->st_mode);
}
- pseudo_debug(2, ": ");
+ pseudo_debug(PDBGF_OP, ": ");
msg.type = PSEUDO_MSG_OP;
msg.op = op;
msg.fd = fd;
@@ -1157,7 +1155,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
msg.client = getpid();
/* do stuff */
- pseudo_debug(4, "processing request [ino %llu]\n", (unsigned long long) msg.ino);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "processing request [ino %llu]\n", (unsigned long long) msg.ino);
switch (msg.op) {
case OP_CHDIR:
pseudo_client_getcwd();
@@ -1207,7 +1205,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
break;
case OP_DUP:
/* just copy the path over */
- pseudo_debug(2, "dup: fd_path(%d) = %p [%s], dup to %d\n",
+ pseudo_debug(PDBGF_CLIENT, "dup: fd_path(%d) = %p [%s], dup to %d\n",
fd, fd_path(fd), fd_path(fd) ? fd_path(fd) : "<nil>",
dirfd);
pseudo_client_path(dirfd, fd_path(fd));
@@ -1221,7 +1219,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
case OP_SYMLINK:
msg.uid = pseudo_fuid;
msg.gid = pseudo_fgid;
- pseudo_debug(2, "fuid: %d ", pseudo_fuid);
+ pseudo_debug(PDBGF_OP, "fuid: %d ", pseudo_fuid);
/* FALLTHROUGH */
/* chown/fchown uid/gid already calculated, and
* a link or rename should not change a file's ownership.
@@ -1249,7 +1247,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
struct timeval tv1, tv2;
if (!pseudo_op_wait(msg.op))
msg.type = PSEUDO_MSG_FASTOP;
- pseudo_debug(4, "sending request [ino %llu]\n", (unsigned long long) msg.ino);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sending request [ino %llu]\n", (unsigned long long) msg.ino);
gettimeofday(&tv1, NULL);
if (pseudo_local_only) {
/* disable server */
@@ -1269,27 +1267,27 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
++message_time.tv_sec;
}
if (result) {
- pseudo_debug(2, "(%d) %s", getpid(), pseudo_res_name(result->result));
+ pseudo_debug(PDBGF_OP, "(%d) %s", getpid(), pseudo_res_name(result->result));
if (op == OP_STAT || op == OP_FSTAT) {
- pseudo_debug(2, " mode 0%o uid %d:%d",
+ pseudo_debug(PDBGF_OP, " mode 0%o uid %d:%d",
(int) result->mode,
(int) result->uid,
(int) result->gid);
} else if (op == OP_CHMOD || op == OP_FCHMOD) {
- pseudo_debug(2, " mode 0%o",
+ pseudo_debug(PDBGF_OP, " mode 0%o",
(int) result->mode);
} else if (op == OP_CHOWN || op == OP_FCHOWN) {
- pseudo_debug(2, " uid %d:%d",
+ pseudo_debug(PDBGF_OP, " uid %d:%d",
(int) result->uid,
(int) result->gid);
}
} else {
- pseudo_debug(2, "(%d) no answer", getpid());
+ pseudo_debug(PDBGF_OP, "(%d) no answer", getpid());
}
} else {
- pseudo_debug(2, "(%d) (no request)", getpid());
+ pseudo_debug(PDBGF_OP, "(%d) (no request)", getpid());
}
- pseudo_debug(2, "\n");
+ pseudo_debug(PDBGF_OP, "\n");
/* if not NULL, alloced_path is an allocated buffer for both
* paths, or for modified paths...
@@ -1297,7 +1295,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
free(alloced_path);
if (do_request && (messages % 1000 == 0)) {
- pseudo_debug(2, "%d messages handled in %.4f seconds\n",
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE | PDBGF_BENCHMARK, "%d messages handled in %.4f seconds\n",
messages,
(double) message_time.tv_sec +
(double) message_time.tv_usec / 1000000.0);
@@ -1418,21 +1416,21 @@ pseudo_exec_path(const char *filename, int search_path) {
for (i = 0; path_segs[i]; ++i) {
path = path_segs[i];
- pseudo_debug(2, "exec_path: checking %s for %s\n", path, filename);
+ pseudo_debug(PDBGF_CLIENT, "exec_path: checking %s for %s\n", path, filename);
if (!*path || (*path == '.' && path_lens[i] == 1)) {
/* empty path or . is cwd */
candidate = pseudo_fix_path(pseudo_cwd, filename, 0, pseudo_cwd_len, NULL, 0);
- pseudo_debug(2, "exec_path: in cwd, got %s\n", candidate);
+ pseudo_debug(PDBGF_CLIENT, "exec_path: in cwd, got %s\n", candidate);
} else if (*path == '/') {
candidate = pseudo_fix_path(path, filename, 0, path_lens[i], NULL, 0);
- pseudo_debug(2, "exec_path: got %s\n", candidate);
+ pseudo_debug(PDBGF_CLIENT, "exec_path: got %s\n", candidate);
} else {
/* oh you jerk, making me do extra work */
size_t len;
char *dir = pseudo_fix_path(pseudo_cwd, path, 0, pseudo_cwd_len, &len, 0);
if (dir) {
candidate = pseudo_fix_path(dir, filename, 0, len, NULL, 0);
- pseudo_debug(2, "exec_path: got %s for non-absolute path\n", candidate);
+ pseudo_debug(PDBGF_CLIENT, "exec_path: got %s for non-absolute path\n", candidate);
} else {
pseudo_diag("couldn't allocate intermediate path.\n");
candidate = NULL;
@@ -1440,7 +1438,7 @@ pseudo_exec_path(const char *filename, int search_path) {
free(dir);
}
if (candidate && !stat(candidate, &buf) && !S_ISDIR(buf.st_mode) && (buf.st_mode & 0111)) {
- pseudo_debug(1, "exec_path: %s => %s\n", filename, candidate);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "exec_path: %s => %s\n", filename, candidate);
pseudo_magic();
return candidate;
} else {
diff --git a/pseudo_db.c b/pseudo_db.c
index 21f2f53..0d6f5ca 100644
--- a/pseudo_db.c
+++ b/pseudo_db.c
@@ -441,14 +441,14 @@ make_tables(sqlite3 *db,
dberr(db, "not done after the single row we expected?", rc);
return 1;
}
- pseudo_debug(2, "existing database version: %d\n", version);
+ pseudo_debug(PDBGF_DB, "existing database version: %d\n", version);
rc = sqlite3_finalize(stmt);
if (rc) {
dberr(db, "couldn't finalize version check");
return 1;
}
} else {
- pseudo_debug(2, "no existing database version\n");
+ pseudo_debug(PDBGF_DB, "no existing database version\n");
version = -1;
}
for (m = sql_migrations; m->sql; ++m)
@@ -462,10 +462,10 @@ make_tables(sqlite3 *db,
version = available_migrations - 1;
for (m = sql_migrations + (version + 1); m->sql; ++m) {
int migration = (m - sql_migrations);
- pseudo_debug(3, "considering migration %d\n", migration);
+ pseudo_debug(PDBGF_DB, "considering migration %d\n", migration);
if (version >= migration)
continue;
- pseudo_debug(2, "running migration %d\n", migration);
+ pseudo_debug(PDBGF_DB, "running migration %d\n", migration);
rc = sqlite3_prepare_v2(db,
m->sql,
strlen(m->sql),
@@ -512,7 +512,7 @@ make_tables(sqlite3 *db,
sqlite3_finalize(update_version);
return 1;
} else {
- pseudo_debug(3, "update of migrations (after %d) fine.\n",
+ pseudo_debug(PDBGF_DB, "update of migrations (after %d) fine.\n",
migration);
}
sqlite3_finalize(update_version);
@@ -526,7 +526,7 @@ make_tables(sqlite3 *db,
/* registered with atexit */
static void
cleanup_db(void) {
- pseudo_debug(1, "server exiting\n");
+ pseudo_debug(PDBGF_SERVER, "server exiting\n");
#ifdef USE_MEMORY_DB
if (real_file_db) {
pdb_backup();
@@ -1124,7 +1124,7 @@ pdb_query(char *stmt_type, pseudo_query_t *traits, unsigned long fields, int uni
}
if (want_results)
frag(sql, "ORDER BY %s %s;", order_by, order_dir);
- pseudo_debug(1, "created SQL: <%s>\n", sql->data);
+ pseudo_debug(PDBGF_SQL, "created SQL: <%s>\n", sql->data);
/* second, prepare it */
rc = sqlite3_prepare_v2(log_db, sql->data, strlen(sql->data), &stmt, NULL);
@@ -1388,7 +1388,7 @@ pdb_link_file(pseudo_msg_t *msg) {
sqlite3_bind_int(insert, 5, msg->gid);
sqlite3_bind_int(insert, 6, msg->mode);
sqlite3_bind_int(insert, 7, msg->rdev);
- pseudo_debug(2, "linking %s: dev %llu, ino %llu, mode %o, owner %d\n",
+ pseudo_debug(PDBGF_DB, "linking %s: dev %llu, ino %llu, mode %o, owner %d\n",
(msg->pathlen ? msg->path : "<nil> (as NAMELESS FILE)"),
(unsigned long long) msg->dev, (unsigned long long) msg->ino,
(int) msg->mode, msg->uid);
@@ -1455,7 +1455,7 @@ pdb_update_file_path(pseudo_msg_t *msg) {
}
}
if (!msg || !msg->pathlen) {
- pseudo_debug(1, "can't update a file without a message or path.\n");
+ pseudo_debug(PDBGF_DB, "can't update a file without a message or path.\n");
return 1;
}
sqlite3_bind_text(update, 1, msg->path, -1, SQLITE_STATIC);
@@ -1496,7 +1496,7 @@ pdb_may_unlink_file(pseudo_msg_t *msg, int deleting) {
sqlite3_bind_int(mark_file, 1, deleting);
sqlite3_bind_text(mark_file, 2, msg->path, -1, SQLITE_STATIC);
} else {
- pseudo_debug(1, "cannot mark a file for pending deletion without a path.");
+ pseudo_debug(PDBGF_DB, "cannot mark a file for pending deletion without a path.");
return 1;
}
file_db_dirty = 1;
@@ -1506,7 +1506,7 @@ pdb_may_unlink_file(pseudo_msg_t *msg, int deleting) {
return 1;
}
exact = sqlite3_changes(file_db);
- pseudo_debug(3, "(exact %d) ", exact);
+ pseudo_debug(PDBGF_DB, "(exact %d) ", exact);
sqlite3_reset(mark_file);
sqlite3_clear_bindings(mark_file);
/* indicate whether we marked something */
@@ -1540,7 +1540,7 @@ pdb_cancel_unlink_file(pseudo_msg_t *msg) {
if (msg->pathlen) {
sqlite3_bind_text(mark_file, 1, msg->path, -1, SQLITE_STATIC);
} else {
- pseudo_debug(1, "cannot unmark a file for pending deletion without a path.");
+ pseudo_debug(PDBGF_DB, "cannot unmark a file for pending deletion without a path.");
return 1;
}
file_db_dirty = 1;
@@ -1549,7 +1549,7 @@ pdb_cancel_unlink_file(pseudo_msg_t *msg) {
dberr(file_db, "unmark for deletion may have failed");
}
exact = sqlite3_changes(file_db);
- pseudo_debug(3, "(exact %d) ", exact);
+ pseudo_debug(PDBGF_DB, "(exact %d) ", exact);
sqlite3_reset(mark_file);
sqlite3_clear_bindings(mark_file);
return rc != SQLITE_DONE;
@@ -1586,7 +1586,7 @@ pdb_did_unlink_files(int deleting) {
dberr(file_db, "cleanup of files marked for deletion may have failed");
}
exact = sqlite3_changes(file_db);
- pseudo_debug(3, "(exact %d)\n", exact);
+ pseudo_debug(PDBGF_DB, "(exact %d)\n", exact);
sqlite3_reset(delete_exact);
sqlite3_clear_bindings(delete_exact);
return rc != SQLITE_DONE;
@@ -1611,7 +1611,7 @@ pdb_did_unlink_file(char *path, int deleting) {
}
}
if (!path) {
- pseudo_debug(1, "cannot unlink a file without a path.");
+ pseudo_debug(PDBGF_DB, "cannot unlink a file without a path.");
return 1;
}
sqlite3_bind_text(delete_exact, 1, path, -1, SQLITE_STATIC);
@@ -1622,7 +1622,7 @@ pdb_did_unlink_file(char *path, int deleting) {
dberr(file_db, "cleanup of file marked for deletion may have failed");
}
exact = sqlite3_changes(file_db);
- pseudo_debug(3, "(exact %d)\n", exact);
+ pseudo_debug(PDBGF_DB, "(exact %d)\n", exact);
sqlite3_reset(delete_exact);
sqlite3_clear_bindings(delete_exact);
return rc != SQLITE_DONE;
@@ -1652,7 +1652,7 @@ pdb_unlink_file(pseudo_msg_t *msg) {
if (msg->pathlen) {
sqlite3_bind_text(delete_exact, 1, msg->path, -1, SQLITE_STATIC);
} else {
- pseudo_debug(1, "cannot unlink a file without a path.");
+ pseudo_debug(PDBGF_DB, "cannot unlink a file without a path.");
return 1;
}
file_db_dirty = 1;
@@ -1661,7 +1661,7 @@ pdb_unlink_file(pseudo_msg_t *msg) {
dberr(file_db, "delete exact by path may have failed");
}
exact = sqlite3_changes(file_db);
- pseudo_debug(3, "(exact %d) ", exact);
+ pseudo_debug(PDBGF_DB, "(exact %d) ", exact);
sqlite3_reset(delete_exact);
sqlite3_clear_bindings(delete_exact);
return rc != SQLITE_DONE;
@@ -1700,7 +1700,7 @@ pdb_unlink_contents(pseudo_msg_t *msg) {
sqlite3_bind_text(delete_sub, 1, msg->path, -1, SQLITE_STATIC);
sqlite3_bind_text(delete_sub, 2, msg->path, -1, SQLITE_STATIC);
} else {
- pseudo_debug(1, "cannot unlink a file without a path.");
+ pseudo_debug(PDBGF_DB, "cannot unlink a file without a path.");
return 1;
}
file_db_dirty = 1;
@@ -1709,7 +1709,7 @@ pdb_unlink_contents(pseudo_msg_t *msg) {
dberr(file_db, "delete sub by path may have failed");
}
sub = sqlite3_changes(file_db);
- pseudo_debug(3, "(sub %d) ", sub);
+ pseudo_debug(PDBGF_DB, "(sub %d) ", sub);
sqlite3_reset(delete_sub);
sqlite3_clear_bindings(delete_sub);
return rc != SQLITE_DONE;
@@ -1754,14 +1754,14 @@ pdb_rename_file(const char *oldpath, pseudo_msg_t *msg) {
return 1;
}
if (!msg->pathlen) {
- pseudo_debug(1, "rename: No path provided (ino %llu)\n", (unsigned long long) msg->ino);
+ pseudo_debug(PDBGF_DB, "rename: No path provided (ino %llu)\n", (unsigned long long) msg->ino);
return 1;
}
if (!oldpath) {
- pseudo_debug(1, "rename: No old path for %s\n", msg->path);
+ pseudo_debug(PDBGF_DB, "rename: No old path for %s\n", msg->path);
return 1;
}
- pseudo_debug(2, "rename: Changing %s to %s\n", oldpath, msg->path);
+ pseudo_debug(PDBGF_DB, "rename: Changing %s to %s\n", oldpath, msg->path);
rc = sqlite3_bind_text(update_exact, 1, msg->path, -1, SQLITE_STATIC);
rc = sqlite3_bind_text(update_exact, 2, oldpath, -1, SQLITE_STATIC);
rc = sqlite3_bind_text(update_sub, 1, oldpath, -1, SQLITE_STATIC);
@@ -1829,7 +1829,7 @@ pdb_renumber_all(dev_t from, dev_t to) {
}
sqlite3_reset(update);
sqlite3_clear_bindings(update);
- pseudo_debug(2, "updating device dev %llu to %llu\n",
+ pseudo_debug(PDBGF_DB, "updating device dev %llu to %llu\n",
(unsigned long long) from, (unsigned long long) to);
return rc != SQLITE_DONE;
}
@@ -1880,7 +1880,7 @@ pdb_update_inode(pseudo_msg_t *msg) {
}
sqlite3_reset(update);
sqlite3_clear_bindings(update);
- pseudo_debug(2, "updating path %s to dev %llu, ino %llu\n",
+ pseudo_debug(PDBGF_DB, "updating path %s to dev %llu, ino %llu\n",
msg->path,
(unsigned long long) msg->dev, (unsigned long long) msg->ino);
return rc != SQLITE_DONE;
@@ -1925,7 +1925,7 @@ pdb_update_file(pseudo_msg_t *msg) {
}
sqlite3_reset(update);
sqlite3_clear_bindings(update);
- pseudo_debug(2, "updating dev %llu, ino %llu, new mode %o, owner %d\n",
+ pseudo_debug(PDBGF_DB, "updating dev %llu, ino %llu, new mode %o, owner %d\n",
(unsigned long long) msg->dev, (unsigned long long) msg->ino,
(int) msg->mode, msg->uid);
return rc != SQLITE_DONE;
@@ -1969,7 +1969,7 @@ pdb_find_file_exact(pseudo_msg_t *msg) {
rc = 0;
break;
case SQLITE_DONE:
- pseudo_debug(3, "find_exact: sqlite_done on first row\n");
+ pseudo_debug(PDBGF_DB, "find_exact: sqlite_done on first row\n");
rc = 1;
break;
default:
@@ -2025,7 +2025,7 @@ pdb_find_file_path(pseudo_msg_t *msg) {
rc = 0;
break;
case SQLITE_DONE:
- pseudo_debug(3, "find_path: sqlite_done on first row\n");
+ pseudo_debug(PDBGF_DB, "find_path: sqlite_done on first row\n");
rc = 1;
break;
default:
@@ -2075,7 +2075,7 @@ pdb_get_file_path(pseudo_msg_t *msg) {
}
break;
case SQLITE_DONE:
- pseudo_debug(3, "find_dev: sqlite_done on first row\n");
+ pseudo_debug(PDBGF_DB, "find_dev: sqlite_done on first row\n");
response = 0;
break;
default:
@@ -2122,7 +2122,7 @@ pdb_find_file_dev(pseudo_msg_t *msg) {
rc = 0;
break;
case SQLITE_DONE:
- pseudo_debug(3, "find_dev: sqlite_done on first row\n");
+ pseudo_debug(PDBGF_DB, "find_dev: sqlite_done on first row\n");
rc = 1;
break;
default:
@@ -2171,7 +2171,7 @@ pdb_find_file_ino(pseudo_msg_t *msg) {
rc = 0;
break;
case SQLITE_DONE:
- pseudo_debug(3, "find_ino: sqlite_done on first row\n");
+ pseudo_debug(PDBGF_DB, "find_ino: sqlite_done on first row\n");
rc = 1;
break;
default:
@@ -2231,7 +2231,7 @@ pdb_file(pdb_file_list l) {
pseudo_diag("couldn't allocate file message.\n");
return NULL;
}
- pseudo_debug(2, "pdb_file: '%s'\n", s ? (const char *) s : "<nil>");
+ pseudo_debug(PDBGF_DB, "pdb_file: '%s'\n", s ? (const char *) s : "<nil>");
m->dev = sqlite3_column_int64(l->stmt, column++);
m->ino = sqlite3_column_int64(l->stmt, column++);
m->uid = sqlite3_column_int64(l->stmt, column++);
diff --git a/pseudo_ipc.c b/pseudo_ipc.c
index b76e37a..82c6f70 100644
--- a/pseudo_ipc.c
+++ b/pseudo_ipc.c
@@ -56,12 +56,12 @@ allow_sigpipe(void) {
/* useful only when debugging crazy stuff */
static void
display_msg_header(pseudo_msg_t *msg) {
- pseudo_debug(4, "type: %d\n", msg->type);
- pseudo_debug(4, "inode: %llu\n", (unsigned long long) msg->ino);
- pseudo_debug(4, "uid: %d\n", msg->uid);
- pseudo_debug(4, "pathlen: %d\n", (int) msg->pathlen);
+ pseudo_debug(PDBGF_IPC | PDBGF_VERBOSE, "type: %d\n", msg->type);
+ pseudo_debug(PDBGF_IPC | PDBGF_VERBOSE, "inode: %llu\n", (unsigned long long) msg->ino);
+ pseudo_debug(PDBGF_IPC | PDBGF_VERBOSE, "uid: %d\n", msg->uid);
+ pseudo_debug(PDBGF_IPC | PDBGF_VERBOSE, "pathlen: %d\n", (int) msg->pathlen);
if (msg->pathlen) {
- pseudo_debug(4, "path: %s\n", msg->path);
+ pseudo_debug(PDBGF_IPC | PDBGF_VERBOSE, "path: %s\n", msg->path);
}
}
#endif
@@ -84,7 +84,7 @@ pseudo_msg_send(int fd, pseudo_msg_t *msg, size_t len, const char *path) {
return -1;
if (path) {
- pseudo_debug(4, "msg type %d (%s), external path %s, mode 0%o\n",
+ pseudo_debug(PDBGF_IPC, "msg type %d (%s), external path %s, mode 0%o\n",
msg->type, pseudo_op_name(msg->op), path, (int) msg->mode);
if (len == (size_t) -1)
len = strlen(path) + 1;
@@ -95,12 +95,12 @@ pseudo_msg_send(int fd, pseudo_msg_t *msg, size_t len, const char *path) {
r += write(fd, path, len);
}
allow_sigpipe();
- pseudo_debug(5, "wrote %d bytes\n", r);
+ pseudo_debug(PDBGF_IPC | PDBGF_VERBOSE, "wrote %d bytes\n", r);
if (pipe_error || (r == -1 && errno == EBADF))
return -1;
return ((size_t) r != PSEUDO_HEADER_SIZE + len);
} else {
- pseudo_debug(4, "msg type %d (%s), result %d (%s), path %.*s, mode 0%o\n",
+ pseudo_debug(PDBGF_IPC, "msg type %d (%s), result %d (%s), path %.*s, mode 0%o\n",
msg->type, pseudo_op_name(msg->op),
msg->result, pseudo_res_name(msg->result),
msg->pathlen, msg->path, (int) msg->mode);
@@ -108,7 +108,7 @@ pseudo_msg_send(int fd, pseudo_msg_t *msg, size_t len, const char *path) {
ignore_sigpipe();
r = write(fd, msg, PSEUDO_HEADER_SIZE + msg->pathlen);
allow_sigpipe();
- pseudo_debug(5, "wrote %d bytes\n", r);
+ pseudo_debug(PDBGF_IPC | PDBGF_VERBOSE, "wrote %d bytes\n", r);
if (pipe_error || (r == -1 && errno == EBADF))
return -1;
return ((size_t) r != PSEUDO_HEADER_SIZE + msg->pathlen);
@@ -130,14 +130,14 @@ pseudo_msg_receive(int fd) {
errno = 0;
r = read(fd, &header, PSEUDO_HEADER_SIZE);
if (r == -1) {
- pseudo_debug(2, "read failed: %s\n", strerror(errno));
+ pseudo_debug(PDBGF_IPC, "read failed: %s\n", strerror(errno));
return 0;
}
if (r < (int) PSEUDO_HEADER_SIZE) {
- pseudo_debug(2, "got only %d bytes (%s)\n", r, strerror(errno));
+ pseudo_debug(PDBGF_IPC, "got only %d bytes (%s)\n", r, strerror(errno));
return 0;
}
- pseudo_debug(4, "got header, type %d, pathlen %d\n", header.type, (int) header.pathlen);
+ pseudo_debug(PDBGF_IPC, "got header, type %d, pathlen %d\n", header.type, (int) header.pathlen);
// display_msg_header(&header);
if (!incoming || header.pathlen >= incoming_pathlen) {
newmsg = pseudo_msg_new(header.pathlen + 128, 0);
@@ -154,7 +154,7 @@ pseudo_msg_receive(int fd) {
if (incoming->pathlen) {
r = read(fd, incoming->path, incoming->pathlen);
if (r < (int) incoming->pathlen) {
- pseudo_debug(2, "short read on path, expecting %d, got %d\n",
+ pseudo_debug(PDBGF_IPC, "short read on path, expecting %d, got %d\n",
(int) incoming->pathlen, r);
return 0;
}
diff --git a/pseudo_server.c b/pseudo_server.c
index 2597def..822df2b 100644
--- a/pseudo_server.c
+++ b/pseudo_server.c
@@ -155,7 +155,7 @@ pseudo_server_start(int daemonize) {
pseudo_diag("couldn't spawn server: %s\n", strerror(errno));
return 0;
}
- pseudo_debug(2, "started server, pid %d\n", rc);
+ pseudo_debug(PDBGF_SERVER, "started server, pid %d\n", rc);
close(listen_fd);
/* Parent writes pid, that way it's always correct */
return pseudo_server_write_pid(rc);
@@ -189,7 +189,7 @@ open_client(int fd) {
/* if possible, use first open client slot */
for (i = 0; i < max_clients; ++i) {
if (clients[i].fd == -1) {
- pseudo_debug(2, "reusing client %d for fd %d\n", i, fd);
+ pseudo_debug(PDBGF_SERVER, "reusing client %d for fd %d\n", i, fd);
clients[i].fd = fd;
clients[i].pid = 0;
clients[i].tag = NULL;
@@ -232,7 +232,7 @@ open_client(int fd) {
*/
static void
close_client(int client) {
- pseudo_debug(2, "lost client %d [%d], closing fd %d\n", client,
+ pseudo_debug(PDBGF_SERVER, "lost client %d [%d], closing fd %d\n", client,
clients[client].pid, clients[client].fd);
/* client went away... */
if (client > highest_client || client <= 0) {
@@ -260,7 +260,7 @@ serve_client(int i) {
pseudo_msg_t *in;
int rc;
- pseudo_debug(2, "message from client %d [%d:%s - %s] fd %d\n",
+ pseudo_debug(PDBGF_SERVER, "message from client %d [%d:%s - %s] fd %d\n",
i, (int) clients[i].pid,
clients[i].program ? clients[i].program : "???",
clients[i].tag ? clients[i].tag : "NO TAG",
@@ -269,35 +269,35 @@ serve_client(int i) {
if (in) {
char *response_path = 0;
int send_response = 1;
- pseudo_debug(4, "got a message (%d): %s\n", in->type, (in->pathlen ? in->path : "<no path>"));
+ pseudo_debug(PDBGF_SERVER | PDBGF_VERBOSE, "got a message (%d): %s\n", in->type, (in->pathlen ? in->path : "<no path>"));
/* handle incoming ping */
if (in->type == PSEUDO_MSG_PING && !clients[i].pid) {
- pseudo_debug(2, "new client: %d -> %d",
+ pseudo_debug(PDBGF_SERVER, "new client: %d -> %d",
i, in->client);
clients[i].pid = in->client;
if (in->pathlen) {
size_t proglen;
proglen = strlen(in->path);
- pseudo_debug(2, " <%s>", in->path);
+ pseudo_debug(PDBGF_SERVER, " <%s>", in->path);
free(clients[i].program);
clients[i].program = malloc(proglen + 1);
if (clients[i].program) {
snprintf(clients[i].program, proglen + 1, "%s", in->path);
}
if (in->pathlen > proglen) {
- pseudo_debug(2, " [%s]", in->path + proglen + 1);
+ pseudo_debug(PDBGF_SERVER, " [%s]", in->path + proglen + 1);
clients[i].tag = malloc(in->pathlen - proglen);
if (clients[i].tag)
snprintf(clients[i].tag, in->pathlen - proglen,
"%s", in->path + proglen + 1);
}
}
- pseudo_debug(2, "\n");
+ pseudo_debug(PDBGF_SERVER, "\n");
}
/* sanity-check client ID */
if (in->client != clients[i].pid) {
- pseudo_debug(1, "uh-oh, expected pid %d for client %d, got %d\n",
+ pseudo_debug(PDBGF_SERVER, "uh-oh, expected pid %d for client %d, got %d\n",
(int) clients[i].pid, i, in->client);
}
/* regular requests are processed in place by
@@ -310,7 +310,7 @@ serve_client(int i) {
in->type = PSEUDO_MSG_NAK;
} else {
in->type = PSEUDO_MSG_ACK;
- pseudo_debug(4, "response: %d (%s)\n",
+ pseudo_debug(PDBGF_SERVER | PDBGF_VERBOSE, "response: %d (%s)\n",
in->result, pseudo_res_name(in->result));
}
/* no path in response */
@@ -348,7 +348,7 @@ serve_client(int i) {
}
if (send_response) {
if ((rc = pseudo_msg_send(clients[i].fd, in, -1, response_path)) != 0) {
- pseudo_debug(1, "failed to send response to client %d [%d]: %d (%s)\n",
+ pseudo_debug(PDBGF_SERVER, "failed to send response to client %d [%d]: %d (%s)\n",
i, (int) clients[i].pid, rc, strerror(errno));
}
} else {
@@ -360,7 +360,7 @@ serve_client(int i) {
/* this should not be happening, but the exceptions aren't
* being detected in select() for some reason.
*/
- pseudo_debug(2, "client %d: no message\n", (int) clients[i].pid);
+ pseudo_debug(PDBGF_SERVER, "client %d: no message\n", (int) clients[i].pid);
close_client(i);
return 0;
}
@@ -398,7 +398,7 @@ pseudo_server_loop(void) {
max_clients = 16;
highest_client = 0;
- pseudo_debug(2, "server loop started.\n");
+ pseudo_debug(PDBGF_SERVER, "server loop started.\n");
if (listen_fd < 0) {
pseudo_diag("got into loop with no valid listen fd.\n");
exit(1);
@@ -426,11 +426,11 @@ pseudo_server_loop(void) {
/* maybe flush database to disk */
pdb_maybe_backup();
if (loop_timeout <= 0) {
- pseudo_debug(1, "no more clients, got bored.\n");
+ pseudo_debug(PDBGF_SERVER, "no more clients, got bored.\n");
die_peacefully = 1;
} else {
/* display this if not exiting */
- pseudo_debug(1, "%d messages handled in %.4f seconds, %d responses\n",
+ pseudo_debug(PDBGF_SERVER | PDBGF_BENCHMARK, "%d messages handled in %.4f seconds, %d responses\n",
messages,
(double) message_time.tv_sec +
(double) message_time.tv_usec / 1000000.0,
@@ -472,15 +472,15 @@ pseudo_server_loop(void) {
FD_ISSET(clients[0].fd, &reads))) {
len = sizeof(client);
if ((fd = accept(listen_fd, (struct sockaddr *) &client, &len)) != -1) {
- pseudo_debug(2, "new client fd %d\n", fd);
+ pseudo_debug(PDBGF_SERVER, "new client fd %d\n", fd);
open_client(fd);
}
}
- pseudo_debug(2, "server loop complete [%d clients left]\n", active_clients);
+ pseudo_debug(PDBGF_SERVER, "server loop complete [%d clients left]\n", active_clients);
}
if (die_peacefully || die_forcefully) {
- pseudo_debug(2, "quitting.\n");
- pseudo_debug(1, "server %d exiting: handled %d messages in %.4f seconds\n",
+ pseudo_debug(PDBGF_SERVER, "quitting.\n");
+ pseudo_debug(PDBGF_SERVER | PDBGF_BENCHMARK, "server %d exiting: handled %d messages in %.4f seconds\n",
getpid(), messages,
(double) message_time.tv_sec +
(double) message_time.tv_usec / 1000000.0);
@@ -512,7 +512,7 @@ pseudo_server_loop(void) {
}
}
if (current_clients != active_clients) {
- pseudo_debug(1, "miscount of current clients (%d) against active_clients (%d)?\n",
+ pseudo_debug(PDBGF_SERVER, "miscount of current clients (%d) against active_clients (%d)?\n",
current_clients, active_clients);
}
/* reinitialize timeout because Linux select alters it */
diff --git a/pseudo_util.c b/pseudo_util.c
index 8d0969e..0d80008 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -84,14 +84,14 @@ static void
dump_env(char **envp) {
size_t i = 0;
for (i = 0; envp[i]; i++) {
- pseudo_debug(0,"dump_envp: [%d]%s\n", (int) i, envp[i]);
+ pseudo_debug(PDBGF_ENV, "dump_envp: [%d]%s\n", (int) i, envp[i]);
}
for (i = 0; pseudo_env[i].key; i++) {
- pseudo_debug(0,"dump_envp: {%d}%s=%s\n", (int) i, pseudo_env[i].key, pseudo_env[i].value);
+ pseudo_debug(PDBGF_ENV, "dump_envp: {%d}%s=%s\n", (int) i, pseudo_env[i].key, pseudo_env[i].value);
}
- pseudo_debug(0, "dump_envp: _in_init %d\n", pseudo_util_initted);
+ pseudo_debug(PDBGF_ENV, "dump_envp: _in_init %d\n", pseudo_util_initted);
}
#endif
@@ -175,21 +175,19 @@ pseudo_init_util(void) {
if (env) {
int i;
int level = atoi(env);
- for (i = 0; i < level; ++i) {
- pseudo_debug_verbose();
- }
+ if (level > 0) {
+ for (i = 0; i < level; ++i) {
+ pseudo_debug_verbose();
+ }
+ } else {
+ pseudo_debug_set(env);
+ }
+ pseudo_debug_flags_finalize();
}
free(env);
}
-/* 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
- */
-static int max_debug_level = 0;
+unsigned long pseudo_util_debug_flags = 0;
int pseudo_util_debug_fd = 2;
static int debugged_newline = 1;
static char pid_text[32];
@@ -335,63 +333,78 @@ with_libpseudo(char *list, char *libdir_path) {
char *pseudo_version = PSEUDO_VERSION;
+/* going away soon */
+static int max_debug_level = 0;
+
void
pseudo_debug_terse(void) {
- if (max_debug_level > 0)
- --max_debug_level;
+ char s[2] = { pseudo_debug_type_symbolic(max_debug_level) };
- char s[16];
- snprintf(s, 16, "%d", max_debug_level);
- pseudo_set_value("PSEUDO_DEBUG", s);
+ if (max_debug_level > 0) {
+ --max_debug_level;
+ pseudo_debug_clear(s);
+ }
}
void
pseudo_debug_verbose(void) {
- ++max_debug_level;
+ char s[2] = { pseudo_debug_type_symbolic(max_debug_level + 1) };
- char s[16];
- snprintf(s, 16, "%d", max_debug_level);
- pseudo_set_value("PSEUDO_DEBUG", s);
+ if (s[0]) {
+ pseudo_debug_set(s);
+ ++max_debug_level;
+ }
}
-int
-pseudo_diag(char *fmt, ...) {
- va_list ap;
- char debuff[8192];
- int len;
- /* gcc on Ubuntu 8.10 requires that you examine the return from
- * write(), and won't let you cast it to void. Of course, if you
- * can't print error messages, there's nothing to do.
- */
- int wrote = 0;
-
- va_start(ap, fmt);
- len = vsnprintf(debuff, 8192, fmt, ap);
- va_end(ap);
-
- if (len > 8192)
- len = 8192;
+/* This exists because we don't want to allocate a bunch of strings
+ * and free them immediately if you have several flags set.
+ */
+void
+pseudo_debug_flags_finalize(void) {
+ char buf[PDBG_MAX + 1] = "", *s = buf;
+ for (int i = 0; i < PDBG_MAX; ++i) {
+ if (pseudo_util_debug_flags & (1 << i)) {
+ *s++ = pseudo_debug_type_symbolic(i);
+ }
+ }
+ pseudo_set_value("PSEUDO_DEBUG", buf);
+}
- if (debugged_newline && max_debug_level > 1) {
- wrote += write(pseudo_util_debug_fd, pid_text, pid_len);
+void
+pseudo_debug_set(char *s) {
+ if (!s)
+ return;
+ for (; *s; ++s) {
+ int id = pseudo_debug_type_symbolic_id(*s);
+ if (id > 0) {
+ pseudo_util_debug_flags |= (1 << id);
+ }
}
- debugged_newline = (debuff[len - 1] == '\n');
+}
- wrote += write(pseudo_util_debug_fd, "pseudo: ", 8);
- wrote += write(pseudo_util_debug_fd, debuff, len);
- return wrote;
+void
+pseudo_debug_clear(char *s) {
+ if (!s)
+ return;
+ for (; *s; ++s) {
+ int id = pseudo_debug_type_symbolic_id(*s);
+ if (id > 0) {
+ pseudo_util_debug_flags &= ~(1 << id);
+ }
+ }
}
int
-pseudo_debug_real(int level, char *fmt, ...) {
+pseudo_diag(char *fmt, ...) {
va_list ap;
char debuff[8192];
int len;
+ /* gcc on Ubuntu 8.10 requires that you examine the return from
+ * write(), and won't let you cast it to void. Of course, if you
+ * can't print error messages, there's nothing to do.
+ */
int wrote = 0;
- if (max_debug_level < level)
- return 0;
-
va_start(ap, fmt);
len = vsnprintf(debuff, 8192, fmt, ap);
va_end(ap);
@@ -399,7 +412,7 @@ pseudo_debug_real(int level, char *fmt, ...) {
if (len > 8192)
len = 8192;
- if (debugged_newline && max_debug_level > 1) {
+ if (debugged_newline && (pseudo_util_debug_flags & PDBGF_PID)) {
wrote += write(pseudo_util_debug_fd, pid_text, pid_len);
}
debugged_newline = (debuff[len - 1] == '\n');
@@ -419,8 +432,9 @@ round_up(size_t n, size_t block) {
/* store pid in text form for prepending to messages */
void
pseudo_new_pid() {
- pid_len = snprintf(pid_text, 32, "%d: ", getpid());
- pseudo_debug(2, "new pid.\n");
+ int pid = getpid();
+ pid_len = snprintf(pid_text, 32, "%d: ", pid);
+ pseudo_debug(PDBGF_PID, "new pid: %d\n", pid);
}
/* helper function for pseudo_fix_path
@@ -637,7 +651,7 @@ pseudo_fix_path(const char *base, const char *path, size_t rootlen, size_t basel
if (*current == '/' && current > effective_root) {
*current = '\0';
}
- pseudo_debug(5, "%s + %s => <%s>\n",
+ pseudo_debug(PDBGF_PATH, "%s + %s => <%s>\n",
base ? base : "<nil>",
path ? path : "<nil>",
newpath ? newpath : "<nil>");
@@ -716,7 +730,7 @@ void
pseudo_setupenv() {
size_t i = 0;
- pseudo_debug(2, "setting up pseudo environment.\n");
+ pseudo_debug(PDBGF_CLIENT, "setting up pseudo environment.\n");
/* Make sure everything has been evaluated */
free(pseudo_get_prefix(NULL));
@@ -725,8 +739,11 @@ pseudo_setupenv() {
free(pseudo_get_localstatedir());
while (pseudo_env[i].key) {
- if (pseudo_env[i].value)
+ if (pseudo_env[i].value) {
setenv(pseudo_env[i].key, pseudo_env[i].value, 0);
+ pseudo_debug(PDBGF_ENV | PDBGF_VERBOSE, "pseudo_env: %s => %s\n",
+ pseudo_env[i].key, pseudo_env[i].value);
+ }
i++;
}
@@ -800,7 +817,7 @@ pseudo_setupenvp(char * const *envp) {
char *ld_preload = NULL, *ld_library_path = NULL;
- pseudo_debug(2, "setting up envp environment.\n");
+ pseudo_debug(PDBGF_ENV, "setting up envp environment.\n");
/* Make sure everything has been evaluated */
free(pseudo_get_prefix(NULL));
@@ -1249,28 +1266,28 @@ pseudo_etc_file(const char *file, char *realname, int flags, char **search_dirs,
if (rc >= 0) {
if (realname)
strcpy(realname, filename);
- pseudo_debug(2, "using <%s> for <%s>\n",
+ pseudo_debug(PDBGF_CHROOT, "using <%s> for <%s>\n",
filename, file);
return rc;
} else {
- pseudo_debug(3, "didn't find <%s>\n",
+ pseudo_debug(PDBGF_CHROOT, "didn't find <%s>\n",
filename);
}
}
} else {
- pseudo_debug(2, "pseudo_etc_file: no search dirs.\n");
+ pseudo_debug(PDBGF_CHROOT, "pseudo_etc_file: no search dirs.\n");
}
#if PSEUDO_PORT_DARWIN
if (!strcmp("passwd", file)) {
- pseudo_debug(2, "Darwin hackery: pseudo_etc_passwd returning magic passwd fd\n");
+ pseudo_debug(PDBGF_CHROOT, "Darwin hackery: pseudo_etc_passwd returning magic passwd fd\n");
return pseudo_host_etc_passwd_fd;
} else if (!strcmp("group", file)) {
- pseudo_debug(2, "Darwin hackery: pseudo_etc_passwd returning magic group fd\n");
+ pseudo_debug(PDBGF_CHROOT, "Darwin hackery: pseudo_etc_passwd returning magic group fd\n");
return pseudo_host_etc_group_fd;
}
#endif
snprintf(filename, pseudo_path_max(), "/etc/%s", file);
- pseudo_debug(2, "falling back on <%s> for <%s>\n",
+ pseudo_debug(PDBGF_CHROOT, "falling back on <%s> for <%s>\n",
filename, file);
rc = open(filename, flags, 0600);
if (rc >= 0 && realname)
@@ -1293,7 +1310,7 @@ pseudo_logfile(char *defname) {
if (!filename) {
if (!defname) {
- pseudo_debug(3, "no special log file requested, using stderr.\n");
+ pseudo_debug(PDBGF_INVOKE, "no special log file requested, using stderr.\n");
return -1;
}
pseudo_path = pseudo_localstatedir_path(defname);
diff --git a/pseudolog.1 b/pseudolog.1
index f11751f..b6e76f9 100644
--- a/pseudolog.1
+++ b/pseudolog.1
@@ -23,6 +23,10 @@
.B \-E
.I timeformat
]
+[
+.B \-x
+.I flags
+]
.RI [ SPECIFICATIONS ]
.PP
.B pseudolog
@@ -35,6 +39,10 @@
.B \-F
.I format
]
+[
+.B \-x
+.I flags
+]
.PP
.B pseudolog \-h
.PP
@@ -44,6 +52,10 @@
.B \-E
.I timeformat
]
+[
+.B \-x
+.I flags
+]
.RI [ SPECIFICATIONS ]
.RI [ SPECIFICATIONS ]
.SH DESCRIPTION
@@ -110,6 +122,11 @@ is displayed. Applies only to queries.
.TP 8
.B \-v
Increase verbosity (debug level). Not useful except when debugging pseudo.
+Deprecated; use
+.BR \-x .
+.TP 8
+.BI \-x flags
+Specify debugging flags of interest. Not useful except when debugging pseudo.
Other option characters are defined as specifications, and all of those
require arguments to specify their values.
diff --git a/pseudolog.c b/pseudolog.c
index b2b0686..ced421d 100644
--- a/pseudolog.c
+++ b/pseudolog.c
@@ -80,13 +80,15 @@ usage(int status) {
int i;
fputs("pseudolog: create or report log entries. usage:\n", f);
- fputs("pseudolog -l [-P pfx] [-E timefmt] [SPECIFIERS] -- create entries\n", f);
- fputs("pseudolog [-U] [-P pfx] [-F fmt] [-E timefmt] [SPECIFIERS] -- report entries\n", f);
- fputs("pseudolog -D [-P pfx] [-E timefmt] [SPECIFIERS] -- delete entries\n", f);
- fputs(" fmt is a printf-like format string using the option letters\n", f);
+ fputs("pseudolog -l [SPECIFIERS] -- create entries\n", f);
+ fputs("pseudolog [-U] [-F format] [SPECIFIERS] -- report entries\n", f);
+ fputs("pseudolog -D [SPECIFIERS] -- delete entries\n", f);
+ fputs("shared options: [-P prefix] [-E timeformat] [-x flags]\n", f);
+ fputs(" format is a printf-like format string using the option letters\n", f);
fputs(" listed below as format specifiers for the corresponding field.\n", f);
- fputs(" timefmt is a strftime-like format string, the default is '%x %X'.\n", f);
- fputs(" pfx is the PSEUDO_PREFIX in which to find the database.\n", f);
+ fputs(" timeformat is a strftime-like format string, the default is '%x %X'.\n", f);
+ fputs(" prefix is the PSEUDO_PREFIX in which to find the database.\n", f);
+ fputs(" flags are characters from the same debug flag set used by pseudo.\n", f);
fputs("\n", f);
fputs("SPECIFIERS are options of the form -X <value>, where X is one of\n", f);
fputs("the following option letters, and value is the value to match.\n", f);
@@ -521,7 +523,7 @@ main(int argc, char **argv) {
int bad_args = 0;
char *format = "%s %-12.12R %-4y %7o: [mode %04m, %2a] %p %T";
- while ((o = getopt(argc, argv, "vla:c:d:DE:f:F:g:G:hi:I:m:M:o:O:p:P:r:R:s:S:t:T:u:Uy:")) != -1) {
+ while ((o = getopt(argc, argv, "vla:c:d:DE:f:F:g:G:hi:I:m:M:o:O:p:P:r:R:s:S:t:T:u:Ux:y:")) != -1) {
switch (o) {
case 'P':
s = PSEUDO_ROOT_PATH(AT_FDCWD, optarg, AT_SYMLINK_NOFOLLOW);
@@ -532,6 +534,9 @@ main(int argc, char **argv) {
case 'v':
pseudo_debug_verbose();
break;
+ case 'x':
+ pseudo_debug_set(optarg);
+ break;
case 'l':
opt_l = 1;
break;
@@ -599,6 +604,7 @@ main(int argc, char **argv) {
new_trait = 0;
}
}
+ pseudo_debug_flags_finalize();
if (optind < argc) {
pseudo_diag("Error: Extra arguments not associated with any option.\n");
diff --git a/table_templates/pseudo_tables.h b/table_templates/pseudo_tables.h
index 7323658..6d0e355 100644
--- a/table_templates/pseudo_tables.h
+++ b/table_templates/pseudo_tables.h
@@ -16,6 +16,7 @@ typedef enum {
${enums},
${prefix}_MAX
} pseudo_${name}_t;
+${flag_enums}
extern const char *pseudo_${name}_name(pseudo_${name}_t);
extern pseudo_${name}_t pseudo_${name}_id(const char *);
${column_protos}
diff --git a/templates/wrapfuncs.c b/templates/wrapfuncs.c
index 86fd557..faac1b7 100644
--- a/templates/wrapfuncs.c
+++ b/templates/wrapfuncs.c
@@ -39,17 +39,20 @@ ${maybe_async_skip}
${rc_return}
}
- pseudo_debug(4, "called: ${name}\n");
+ pseudo_debug(PDBGF_WRAPPER, "wrapper called: ${name}\n");
pseudo_sigblock(&saved);
+ pseudo_debug(PDBGF_WRAPPER | PDBGF_VERBOSE, "${name} - signals blocked, obtaining lock\n");
if (pseudo_getlock()) {
errno = EBUSY;
sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(PDBGF_WRAPPER, "${name} failed to get lock, giving EBUSY.\n");
${def_return}
}
int save_errno;
if (antimagic > 0) {
/* call the real syscall */
+ pseudo_debug(PDBGF_SYSCALL, "${name} calling real syscall.\n");
${rc_assign} (*real_${name})(${call_args});
} else {
${alloc_paths}
@@ -62,13 +65,14 @@ ${maybe_async_skip}
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
+ pseudo_debug(PDBGF_WRAPPER | PDBGF_VERBOSE, "${name} - yielded lock, restored signals\n");
#if 0
/* This can cause hangs on some recentish systems which use locale
* stuff for strerror...
*/
- pseudo_debug(4, "completed: $name (maybe: %s)\n", strerror(save_errno));
+ pseudo_debug(PDBGF_WRAPPER, "wrapper completed: ${name} (maybe: %s)\n", strerror(save_errno));
#endif
- pseudo_debug(4, "completed: $name (errno: %d)\n", save_errno);
+ pseudo_debug(PDBGF_WRAPPER, "wrapper completed: ${name} (errno: %d)\n", save_errno);
errno = save_errno;
${rc_return}
}