[PATCH] s3: Add headers for sysctlbyname() and rewrite get_freebsd_corepath()
Timur I. Bakeyev
timur at FreeBSD.org
Mon Jul 20 20:52:46 MDT 2009
In lib/fault.c and param/loadparm.c there are functions that use
sysctlbyname() which is defined in sys/sysctl.h. So, this header HAS to
be included. I do add it localy to the affected files, but maybe
includes.h would be better idea.
To guess core file name and location on FreeBSD a kernel tunable is
consulted. It can use expandable variables %N, %P and %U to reflect name
of the program, it's PID and UID. So, if we want to use that kernel
tunable, we have to do expansion ourselves.
---
source3/configure.in | 2 +-
source3/lib/fault.c | 126 +++++++++++++++++++++++++++++++---------------
source3/param/loadparm.c | 4 ++
3 files changed, 90 insertions(+), 42 deletions(-)
diff --git a/source3/configure.in b/source3/configure.in
index 7cfd3fb..c2faa41 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -655,7 +655,7 @@ AC_CHECK_HEADERS(aio.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h
AC_CHECK_HEADERS(unistd.h grp.h sys/id.h memory.h alloca.h)
AC_CHECK_HEADERS(limits.h float.h pthread.h libintl.h)
AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h)
-AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/prctl.h)
+AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/prctl.h sys/sysctl.h)
AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h)
AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h)
diff --git a/source3/lib/fault.c b/source3/lib/fault.c
index 51fc53b..7e969e0 100644
--- a/source3/lib/fault.c
+++ b/source3/lib/fault.c
@@ -20,6 +20,10 @@
#include "includes.h"
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#endif
@@ -138,52 +142,93 @@ static char *get_default_corepath(const char *logbase, const char *progname)
* before dump_core() calls abort.
*/
#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME))
-static char *get_freebsd_corepath(void)
+/*
+ * Expand the name described in corefilename, using name, uid, and pid.
+ * corefilename is a printf-like string, with three format specifiers:
+ * %N name of process ("name")
+ * %P process id (pid)
+ * %U user id (uid)
+ * For example, "%N.core" is the default; they can be disabled completely
+ * by using "/dev/null", or all core files can be stored in "/cores/%U/%N-%P".
+ */
+static char *get_freebsd_corepath(const char *name)
{
- char *tmp_corepath = NULL;
- char *end = NULL;
- size_t len = 128;
+ TALLOC_CTX *tmp_ctx;
+ char format[MAXPATHLEN];
+ char *freebsd_corepath = NULL, *buffer = NULL;
+ char *start, *end;
+ size_t len;
int ret;
- /* Loop with increasing sizes so we don't allocate too much. */
- do {
- if (len > 1024) {
- goto err_out;
- }
-
- tmp_corepath = (char *)talloc_realloc(NULL, tmp_corepath,
- char, len);
- if (!tmp_corepath) {
- return NULL;
- }
-
- ret = sysctlbyname("kern.corefile", tmp_corepath, &len, NULL,
- 0);
- if (ret == -1) {
- if (errno != ENOMEM) {
- DEBUG(0, ("sysctlbyname failed getting "
- "kern.corefile %s\n",
- strerror(errno)));
- goto err_out;
- }
-
- /* Not a large enough array, try a bigger one. */
- len = len << 1;
- }
- } while (ret == -1);
-
+ len = sizeof(format);
+ /* Read format string */
+ if((ret = sysctlbyname("kern.corefile", format, &len, NULL, 0)) == -1) {
+ return NULL;
+ }
/* Strip off the common filename expansion */
- if ((end = strrchr_m(tmp_corepath, '/'))) {
+ if ((end=strrchr_m(format, '/')) != NULL) {
*end = '\0';
}
+ /* Core file is relative to the cwd */
+ if(!format[0] || format[0] != '/') {
+ return NULL;
+ }
- return tmp_corepath;
-
- err_out:
- if (tmp_corepath) {
- talloc_free(tmp_corepath);
+ if((tmp_ctx = talloc_new(NULL)) == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ return NULL;
}
- return NULL;
+ if((buffer = talloc_strdup(tmp_ctx, "")) == NULL) {
+ DEBUG(0, ("talloc_strdup: Out of memory!\n"));
+ goto failed;
+ }
+ /* Parse format string and expand variables */
+ start = format;
+ while((end=strchr_m(start, '%')) != NULL) {
+ /* Copy part of the string without format arguments */
+ if(end != start) {
+ buffer = talloc_strndup_append_buffer(buffer, start, end - start);
+ if(buffer == NULL) {
+ DEBUG(0, ("talloc_strdup: Out of memory!\n"));
+ goto failed;
+ }
+ }
+ start = end + 1;
+ switch (*start) {
+ case '%':
+ buffer = talloc_strdup_append_buffer(buffer, "%%");
+ break;
+ case 'N': /* process name */
+ buffer = talloc_asprintf_append_buffer(buffer, "%s", name);
+ break;
+ case 'P': /* process id */
+ buffer = talloc_asprintf_append_buffer(buffer, "%u", getpid());
+ break;
+ case 'U': /* user id */
+ buffer = talloc_asprintf_append_buffer(buffer, "%u", getuid());
+ break;
+ default:
+ DEBUG(0,(
+ "Unknown format character %c in "
+ "corename `%s'\n", *start, format));
+ }
+ if(buffer == NULL) {
+ DEBUG(0, ("talloc_asprintf_append_buffer: Out of memory!\n"));
+ goto failed;
+ }
+ start++;
+ }
+ /* Copy remaining part, if any */
+ if((buffer = talloc_strdup_append_buffer(buffer, start)) == NULL) {
+ DEBUG(0, ("talloc_strdup_append_buffer: Out of memory!\n"));
+ goto failed;
+ }
+ /* Duplicate assembled string in the unattached contenxt */
+ freebsd_corepath = talloc_strdup(NULL, buffer);
+failed:
+ TALLOC_FREE(tmp_ctx);
+
+ return freebsd_corepath;
}
#endif
@@ -199,8 +244,7 @@ static char *get_corepath(const char *logbase, const char *progname)
/* @todo: Add support for the linux corepath. */
char *tmp_corepath = NULL;
- tmp_corepath = get_freebsd_corepath();
-
+ tmp_corepath = get_freebsd_corepath(progname);
/* If this has been set correctly, we're done. */
if (tmp_corepath) {
return tmp_corepath;
@@ -276,7 +320,7 @@ void dump_core_setup(const char *progname)
SAFE_FREE(logbase);
}
- void dump_core(void)
+void dump_core(void)
{
static bool called;
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index dbbd6e3..e3de084 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -58,6 +58,10 @@
#include <cups/http.h>
#endif
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
bool bLoaded = False;
extern enum protocol_types Protocol;
--
1.6.3.1
--jRHKVT23PllUwdXP--
More information about the samba-technical
mailing list