--- gio/gcredentials.c.orig	2010-07-30 15:36:31.000000000 -0400
+++ gio/gcredentials.c	2010-08-29 17:05:48.000000000 -0400
@@ -22,6 +22,11 @@
 
 #include "config.h"
 
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+#endif
 #include <stdlib.h>
 
 #include <gobject/gvaluecollector.h>
@@ -55,6 +60,9 @@
  * <citerefentry><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry>
  * man page for details. This corresponds to
  * %G_CREDENTIALS_TYPE_LINUX_UCRED.
+ *
+ * On FreeBSD, the native credential type is a <type>struct cmsgcred</type>.
+ * This corresponds to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED.
  */
 
 /**
@@ -72,6 +80,8 @@ struct _GCredentials
 
 #ifdef __linux__
   struct ucred native;
+#elif defined(__FreeBSD__)
+  struct cmsgcred native;
 #else
 #ifdef __GNUC__
 #warning Please add GCredentials support for your OS
@@ -120,6 +130,11 @@ g_credentials_init (GCredentials *creden
   credentials->native.pid = getpid ();
   credentials->native.uid = geteuid ();
   credentials->native.gid = getegid ();
+#elif defined(__FreeBSD__)
+  memset (&credentials->native, 0, sizeof (struct cmsgcred));
+  credentials->native.cmcred_pid  = getpid ();
+  credentials->native.cmcred_euid = geteuid ();
+  credentials->native.cmcred_gid  = getegid ();
 #endif
 }
 
@@ -173,6 +188,14 @@ g_credentials_to_string (GCredentials *c
     g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
   if (ret->str[ret->len - 1] == ',')
     ret->str[ret->len - 1] = '\0';
+#elif defined(__FreeBSD__)
+  g_string_append (ret, "freebsd-cmsgcred:");
+  if (credentials->native.cmcred_pid != -1)
+    g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_pid);
+  if (credentials->native.cmcred_euid != -1)
+    g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_euid);
+  if (credentials->native.cmcred_gid != -1)
+    g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_gid);
 #else
   g_string_append (ret, "unknown");
 #endif
@@ -213,6 +236,9 @@ g_credentials_is_same_user (GCredentials
 #ifdef __linux__
   if (credentials->native.uid == other_credentials->native.uid)
     ret = TRUE;
+#elif defined(__FreeBSD__)
+  if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
+    ret = TRUE;
 #else
   g_set_error_literal (error,
                        G_IO_ERROR,
@@ -263,6 +289,17 @@ g_credentials_get_native (GCredentials  
     {
       ret = &credentials->native;
     }
+#elif defined(__FreeBSD__)
+  if (native_type != G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED)
+    {
+      g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only "
+		 "G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED is supported.",
+		 native_type);
+    }
+  else
+    {
+      ret = &credentials->native;
+    }
 #else
   g_warning ("g_credentials_get_native: Trying to get credentials but GLib has no support "
              "for the native credentials type. Please add support.");
@@ -302,6 +339,17 @@ g_credentials_set_native (GCredentials  
     {
       memcpy (&credentials->native, native, sizeof (struct ucred));
     }
+#elif defined(__FreeBSD__)
+  if (native_type != G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED)
+    {
+      g_warning ("g_credentials_set_native: Trying to set credentials of type %d "
+		  "but only G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED is supported.",
+		  native_type);
+    }
+  else
+    {
+      memcpy (&credentials->native, native, sizeof (struct cmsgcred));
+    }
 #else
   g_warning ("g_credentials_set_native: Trying to set credentials but GLib has no support "
              "for the native credentials type. Please add support.");
@@ -338,6 +386,8 @@ g_credentials_get_unix_user (GCredential
 
 #ifdef __linux__
   ret = credentials->native.uid;
+#elif defined(__FreeBSD__)
+  ret = credentials->native.cmcred_euid;
 #else
   ret = -1;
   g_set_error_literal (error,
@@ -381,6 +431,9 @@ g_credentials_set_unix_user (GCredential
 #ifdef __linux__
   credentials->native.uid = uid;
   ret = TRUE;
+#elif defined(__FreeBSD__)
+  credentials->native.cmcred_euid = uid;
+  ret = TRUE;
 #else
   g_set_error_literal (error,
                        G_IO_ERROR,
--- gio/gioenums.h.orig	2010-08-29 12:43:20.000000000 -0400
+++ gio/gioenums.h	2010-08-29 12:44:12.000000000 -0400
@@ -1173,6 +1173,7 @@ typedef enum
  * GCredentialsType:
  * @G_CREDENTIALS_TYPE_INVALID: Indicates an invalid native credential type.
  * @G_CREDENTIALS_TYPE_LINUX_UCRED: The native credentials type is a <type>struct ucred</type>.
+ * @G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED: The native credentials type is a <type>struct cmsgcred</type>.
  *
  * Enumeration describing different kinds of native credential types.
  *
@@ -1181,7 +1182,8 @@ typedef enum
 typedef enum
 {
   G_CREDENTIALS_TYPE_INVALID,
-  G_CREDENTIALS_TYPE_LINUX_UCRED
+  G_CREDENTIALS_TYPE_LINUX_UCRED,
+  G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED
 } GCredentialsType;
 
 /**
--- gio/gioenumtypes.c.orig	2010-08-29 12:45:26.000000000 -0400
+++ gio/gioenumtypes.c	2010-08-29 12:45:58.000000000 -0400
@@ -1130,6 +1130,7 @@ g_credentials_type_get_type (void)
       static const GEnumValue values[] = {
         { G_CREDENTIALS_TYPE_INVALID, "G_CREDENTIALS_TYPE_INVALID", "invalid" },
         { G_CREDENTIALS_TYPE_LINUX_UCRED, "G_CREDENTIALS_TYPE_LINUX_UCRED", "linux-ucred" },
+        { G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED, "G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED", "freebsd-cmsgcred" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
--- gio/gsocket.c.orig	2010-08-29 18:57:52.000000000 -0400
+++ gio/gsocket.c	2010-08-29 18:57:55.000000000 -0400
@@ -2893,8 +2893,13 @@ g_socket_send_message (GSocket          
       for (i = 0; i < num_messages; i++)
 	msg.msg_controllen += CMSG_SPACE (g_socket_control_message_get_size (messages[i]));
 
-      msg.msg_control = g_alloca (msg.msg_controllen);
-      memset (msg.msg_control, '\0', msg.msg_controllen);
+      if (msg.msg_controllen == 0)
+        msg.msg_control = NULL;
+      else
+        {
+          msg.msg_control = g_alloca (msg.msg_controllen);
+          memset (msg.msg_control, '\0', msg.msg_controllen);
+        }
 
       cmsg = CMSG_FIRSTHDR (&msg);
       for (i = 0; i < num_messages; i++)
--- gio/gunixcredentialsmessage.c.orig	2010-08-29 13:05:21.000000000 -0400
+++ gio/gunixcredentialsmessage.c	2010-08-29 13:42:42.000000000 -0400
@@ -46,6 +46,13 @@
 #include <fcntl.h>
 #define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
 
+#elif defined(__FreeBSD__)
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
+#define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
 #else
 /* TODO: please add support for your UNIX flavor */
 #define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 0
@@ -79,6 +86,8 @@ g_unix_credentials_message_get_size (GSo
 {
 #ifdef __linux__
   return sizeof (struct ucred);
+#elif defined(__FreeBSD__)
+  return sizeof (struct cmsgcred);
 #else
   return 0;
 #endif
@@ -89,6 +98,8 @@ g_unix_credentials_message_get_level (GS
 {
 #ifdef __linux__
   return SOL_SOCKET;
+#elif defined(__FreeBSD__)
+  return SOL_SOCKET;
 #else
   return 0;
 #endif
@@ -99,6 +110,8 @@ g_unix_credentials_message_get_msg_type 
 {
 #ifdef __linux__
   return SCM_CREDENTIALS;
+#elif defined(__FreeBSD__)
+  return SCM_CREDS;
 #else
   return 0;
 #endif
@@ -140,6 +153,33 @@ g_unix_credentials_message_deserialize (
  out:
     ;
   }
+#elif defined(__FreeBSD__)
+  {
+    GCredentials *credentials;
+    struct cmsgcred *cred;
+
+    if (level != SOL_SOCKET || type != SCM_CREDS)
+      {
+        goto out;
+      }
+    if (size < CMSG_LEN (sizeof *cred))
+      {
+        g_warning ("Expected a struct ucred (%" G_GSIZE_FORMAT " bytes) but "
+                   "got %" G_GSIZE_FORMAT " bytes of data",
+                   CMSG_LEN (sizeof *cred),
+                   size);
+        goto out;
+      }
+
+    cred = data;
+
+    credentials = g_credentials_new ();
+    g_credentials_set_native (credentials, G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED, cred);
+    message = g_unix_credentials_message_new_with_credentials (credentials);
+    g_object_unref (credentials);
+ out:
+    ;
+  }
 #endif
 
   return message;
@@ -155,6 +195,12 @@ g_unix_credentials_message_serialize (GS
           g_credentials_get_native (message->priv->credentials,
                                     G_CREDENTIALS_TYPE_LINUX_UCRED),
           sizeof (struct ucred));
+#elif defined(__FreeBSD__)
+  memcpy (data,
+          g_credentials_get_native (message->priv->credentials,
+                                    G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED),
+          sizeof (struct cmsgcred));
+
 #endif
 }
 
