aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2013-06-21 15:46:30 -0500
committerPeter Seebach <peter.seebach@windriver.com>2013-06-25 20:32:25 -0500
commite199ed80a0a67a2135d419e169ba378621dd55bd (patch)
treec284919558317f6a122df93438e2c93ce96acd68
parent62177dc38fabb880132e63aeef3b8d3878f9584c (diff)
downloadpseudo-e199ed80a0a67a2135d419e169ba378621dd55bd.tar.gz
pseudo-e199ed80a0a67a2135d419e169ba378621dd55bd.tar.bz2
pseudo-e199ed80a0a67a2135d419e169ba378621dd55bd.zip
Change debugging to use flags rather than levels
This is a moderately intrusive change. The basic overall effect: Debugging messages are now controlled, not by a numeric "level", but by a series of flags, which are expressed as a string of letters. Each flag has a single-letter form used for string specifications, a name, a description, a numeric value (1 through N), and a flag value (which is 1 << the numeric value). (This does mean that no flag has the value 1, so we only have 31 bits available. Tiny violins play.) The other significant change is that the pseudo_debug calls are now implemented with a do/while macro containing a conditional, so that computationally-expensive arguments are never evaluated if the corresponding debug flags weren't set. The assumption is that in the vast majority of cases (specifically, all of them so far) the debug flags for a given call are a compile-time constant, so the nested conditional will never actually show up in code when compiled with optimization; we'll just see the appropriate conditional test. The VERBOSE flag is magical, in that if the VERBOSE flag is used in a message, the debug flags have to have both VERBOSE and at least one other flag for the call to be made. This should dramatically improve performance for a lot of cases without as much need for PSEUDO_NDEBUG, and improve the ability of users to get coherent debugging output that means something and is relevant to a given case. It's also intended to set the stage for future development work involving improving the clarity and legibility of pseudo's diagnostic messages in general. Old things which used numeric values for PSEUDO_DEBUG will sort of continue to work, though they will almost always be less verbose than they used to. There should probably be a pass through adding "| PDBGF_CONSISTENCY" to a lot of the messages that are specific to some other type.
-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}
}