Hi,
I have created a new version of the FreeBSD patch.
My cloned git repository is at
http://www.cs.toronto.edu/~siavosh/parted-freebsd/
(Unfortunately directory listing is disabled on the server)
I have placed a compressed version of the directory here:
http://www.cs.toronto.edu/~siavosh/parted-freebsd.tar.gz
I have applied all the comments, compiled and everything runs fine
here. Two of the issues still remain:
1) There is still one printf in the libparted/arch/freebsd.c file that
is informational, e.g., it is not an exception or anything. What
should I change this to?
2) I have "#ifndef __FreeBSD__"-ed out all the si_code values that are
not present on FreeBSD. As was already said on the list changing this
to one #ifdef per value might be desirable.

I am waiting for more comments specially on my use of
ped_exception_throw, which I guessed.
Regards,
Siavosh
diff --exclude=.git -NruBb parted/configure.ac parted-freebsd/configure.ac
--- parted/configure.ac	Tue Mar  6 00:41:14 2007
+++ parted-freebsd/configure.ac	Tue Mar  6 00:41:42 2007
@@ -51,6 +51,8 @@
 	linux*) OS=linux ;;
 	gnu*)	OS=gnu ;;
 	beos*)	OS=beos ;;
+	freebsd* | kfreebsd*-gnu)
+			OS=freebsd ;;
 	*)	AC_MSG_ERROR([Unknown or unsupported OS "$host_os".  Only "linux", "gnu" and "beos" are supported in this version of GNU Parted.]) ;;
 esac
 AC_SUBST(OS)
@@ -184,6 +186,7 @@
 	#include <sys/types.h>
 	#include <unistd.h>
 ])
+AC_CHECK_TYPE(loff_t, off_t)
 
 AM_ENABLE_SHARED
 if test "$OS" = linux -a $ac_cv_sizeof_off_t -lt 8; then
@@ -368,6 +371,20 @@
 	OS_LIBS="$OS_LIBS -lsocket"
 fi
 
+dnl FreeBSD (and GNU/kFreeBSD):
+if test "$OS" = freebsd; then
+dnl    CFLAGS="$CFLAGS -D_GNU_SOURCE=1"
+
+dnl libgeom
+	AC_CHECK_LIB(geom, gctl_get_handle,
+		OS_LIBS="$OS_LIBS -lgeom",
+		AC_MSG_ERROR(
+GNU Parted requires libgeom when running on FreeBSD or derivative systems.
+		)
+		exit
+	)
+fi
+
 AC_SUBST(OS_LIBS)
 
 dnl One day, gettext might support libtool...
@@ -391,6 +408,9 @@
 
 AC_CHECK_HEADERS(getopt.h)
 
+dnl The following is FreeBSD specific
+AC_CHECK_HEADERS(endian.h sys/endian.h)
+
 dnl required for libparted/llseek.c  (TODO: make linux-x86 only)
 if test "$OS" = linux; then
 	AC_CHECK_HEADER(linux/unistd.h)
@@ -450,7 +470,9 @@
 
 
 dnl Checks for library functions.
-AC_CHECK_FUNCS(sigaction)
+if test "$OS" != freebsd; then
+   AC_CHECK_FUNCS(sigaction)
+fi
 AC_CHECK_FUNCS(getuid)
 
 if test "$with_readline" = yes; then
diff --exclude=.git -NruBb parted/include/parted/Makefile.am parted-freebsd/include/parted/Makefile.am
--- parted/include/parted/Makefile.am	Tue Mar  6 00:41:14 2007
+++ parted-freebsd/include/parted/Makefile.am	Tue Mar  6 00:41:42 2007
@@ -1,6 +1,7 @@
 partedincludedir      =	$(includedir)/parted
 partedinclude_HEADERS = gnu.h		\
 			linux.h		\
+			freebsd.h	\
 			constraint.h	\
 			debug.h		\
 			device.h	\
diff --exclude=.git -NruBb parted/include/parted/freebsd.h parted-freebsd/include/parted/freebsd.h
--- parted/include/parted/freebsd.h	Wed Dec 31 19:00:00 1969
+++ parted-freebsd/include/parted/freebsd.h	Tue Mar  6 00:41:42 2007
@@ -0,0 +1,47 @@
+/*
+    libparted - a library for manipulating disk partitions
+    Copyright (C) 2001 Free Software Foundation, Inc.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#ifndef PED_FREEBSD_H_INCLUDED
+#define PED_FREEBSD_H_INCLUDED
+
+#include <parted/parted.h>
+#include <parted/device.h>
+
+#include <sys/param.h>
+
+#if !defined(__FreeBSD_version) && defined(__FreeBSD_kernel_version)
+#define __FreeBSD_version __FreeBSD_kernel_version
+#endif
+
+#define FREEBSD_SPECIFIC(dev)	((FreeBSDSpecific*) (dev)->arch_specific)
+
+typedef	struct _FreeBSDSpecific	FreeBSDSpecific;
+
+struct _FreeBSDSpecific {
+#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
+	unsigned char channel;
+	unsigned char device;
+#endif
+	int	fd;
+};
+
+extern PedArchitecture ped_freebsd_arch;
+
+#endif /* PED_FREEBSD_H_INCLUDED */
+
diff --exclude=.git -NruBb parted/libparted/Makefile.am parted-freebsd/libparted/Makefile.am
--- parted/libparted/Makefile.am	Tue Mar  6 00:41:14 2007
+++ parted-freebsd/libparted/Makefile.am	Tue Mar  6 00:41:42 2007
@@ -32,7 +32,8 @@
 
 EXTRA_libparted_la_SOURCES    = arch/linux.c		\
 				arch/gnu.c \
-				arch/beos.c
+				arch/beos.c \
+				arch/freebsd.c
 
 libparted_la_LIBADD   = $(OS_LIBS)		\
 			$(DL_LIBS)		\
diff --exclude=.git -NruBb parted/libparted/arch/freebsd.c parted-freebsd/libparted/arch/freebsd.c
--- parted/libparted/arch/freebsd.c	Wed Dec 31 19:00:00 1969
+++ parted-freebsd/libparted/arch/freebsd.c	Tue Mar  6 00:41:42 2007
@@ -0,0 +1,1261 @@
+/*
+    libparted - a library for manipulating disk partitions
+    Copyright (C) 1999 - 2005 Free Software Foundation, Inc.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include "config.h"
+
+#include <parted/parted.h>
+#include <parted/debug.h>
+#include <parted/unit.h>
+#include <parted/freebsd.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+#include <libgeom.h>
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/disk.h>
+#include <sys/ata.h>
+#include <sys/diskmbr.h>
+
+#if ENABLE_NLS
+#  include <libintl.h>
+#  define _(String) dgettext (PACKAGE, String)
+#else
+#  define _(String) (String)
+#endif /* ENABLE_NLS */
+
+static char* _device_get_part_path (PedDevice* dev, int slice_num, int part_num);
+static int _partition_is_mounted_by_path (const char* path);
+
+static int
+_device_stat (PedDevice* dev, struct stat * dev_stat)
+{
+	PED_ASSERT (dev != NULL, return 0);
+	PED_ASSERT (!dev->external_mode, return 0);
+
+	while (1) {
+		if (!stat (dev->path, dev_stat)) {
+			return 1;
+		} else {
+			if (ped_exception_throw (
+				PED_EXCEPTION_ERROR,
+				PED_EXCEPTION_RETRY_CANCEL,
+				_("Could not stat device %s - %s."),
+				dev->path,
+				strerror (errno))
+					!= PED_EXCEPTION_RETRY)
+				return 0;
+		}
+	}
+}
+
+static int
+_device_probe_type (PedDevice* dev)
+{
+	struct stat		dev_stat;
+	char *np;
+	PedExceptionOption	ex_status;
+
+#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
+	FreeBSDSpecific*	arch_specific = FREEBSD_SPECIFIC (dev);
+#endif
+	
+	if (!_device_stat (dev, &dev_stat))
+		return 0;
+	
+	if (!S_ISCHR(dev_stat.st_mode)) {
+		dev->type = PED_DEVICE_FILE;
+		return 1;
+	}
+
+	/* On FreeBSD ad0 ist the ATA device */
+	np = strrchr(dev->path, '/');
+	if(np == NULL)
+	{
+		dev->type = PED_DEVICE_UNKNOWN;
+		return 0;
+	}
+	np += 1; /* advance past '/' */
+	
+	if(strncmp(np, "ad", 2) == 0)
+	{
+		dev->type = PED_DEVICE_IDE;
+
+		/* ad0 -> channel 0, master
+		 * ad1 -> channel 0, slave
+		 * ad2 -> channel 1, master
+		 * ad3 -> channel 1, slave
+		 */
+#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
+		switch(*(np+3))
+		{
+		case 0:
+			arch_specific->channel = 0;
+			arch_specific->device = 0;
+			break;
+		case 1:
+			arch_specific->channel = 0;
+			arch_specific->device = 1;
+			break;
+		case 2:
+			arch_specific->channel = 1;
+			arch_specific->device = 0;
+			break;
+		case 4:
+			arch_specific->channel = 1;
+			arch_specific->device = 1;
+			break;
+		}
+#endif
+	}
+	else
+	{
+		dev->type = PED_DEVICE_UNKNOWN;
+	}
+	
+	return 1;
+}
+
+static int
+_device_get_sector_size (PedDevice* dev)
+{
+	FreeBSDSpecific*	arch_specific = FREEBSD_SPECIFIC (dev);
+	u_int sector_size = PED_SECTOR_SIZE_DEFAULT; /*makes Valgrind happy*/
+
+	PED_ASSERT (dev->open_count, return 0);
+
+	if (ioctl (arch_specific->fd, DIOCGSECTORSIZE, &sector_size) == -1)
+		return PED_SECTOR_SIZE_DEFAULT;
+
+	if (sector_size != PED_SECTOR_SIZE_DEFAULT) {
+		if (ped_exception_throw (
+			PED_EXCEPTION_BUG,
+			PED_EXCEPTION_IGNORE_CANCEL,
+			_("The sector size on %s is %d bytes.  Parted is known "
+			"not to work properly with drives with sector sizes "
+			"other than %d bytes."),
+			dev->path,
+			sector_size,
+			PED_SECTOR_SIZE_DEFAULT)
+				== PED_EXCEPTION_IGNORE)
+			return sector_size;
+		else
+			return PED_SECTOR_SIZE_DEFAULT;
+	}
+
+	return sector_size;
+}
+
+static PedSector
+_device_get_length (PedDevice* dev)
+{
+	FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+	off_t bytes = 0;
+
+	PED_ASSERT (dev->open_count > 0, return 0);
+
+	if(ioctl(arch_specific->fd, DIOCGMEDIASIZE, &bytes) == 0) {
+		return bytes / dev->sector_size;
+	}
+	
+	return 0;
+}
+
+
+#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
+# define freebsd_get_ata_params freebsd_get_ata_params_compat5
+#elif (__FreeBSD_version >= 600000)
+# define freebsd_get_ata_params freebsd_get_ata_params_compat6
+#else
+# error "parted currently compiles on FreeBSD 5.X and 6.X only"
+#endif
+
+#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
+
+static int freebsd_get_ata_params_compat5(PedDevice *dev,
+										  struct ata_params *ap)
+{
+	struct ata_cmd iocmd;
+	int fd, ret;
+	FreeBSDSpecific*		arch_specific = FREEBSD_SPECIFIC (dev);
+
+	if ((fd = open("/dev/ata", O_RDWR)) == -1)
+	{
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("Could not open /dev/ata."));
+
+		ret = -1;
+		goto out;
+	}
+	
+	bzero(&iocmd, sizeof(struct ata_cmd));
+	iocmd.channel = arch_specific->channel;
+	iocmd.device = arch_specific->device;
+	iocmd.cmd = ATAGPARM;
+	
+	if (ioctl(fd, IOCATA, &iocmd) == -1)
+	{
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("Could not get ATA parameters. Please"
+			  "contact the maintainer."));
+
+		ret = -1;
+		goto out;
+	}
+	
+	if (iocmd.u.param.type[arch_specific->device]) {
+		*ap = iocmd.u.param.params[arch_specific->device];
+	} else
+	{
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("Could not get ATA parameters. Please"
+			  "contact the maintainer."));
+		ret = -1;
+		goto out;
+	}
+
+	ret = 0;
+	
+out:
+	close(fd);
+	
+	return ret;
+}
+
+#elif __FreeBSD_version >= 600000
+
+static int freebsd_get_ata_params_compat6(PedDevice *dev,
+										  struct ata_params *ap)
+{
+	FreeBSDSpecific*		arch_specific = FREEBSD_SPECIFIC (dev);
+
+	return ioctl (arch_specific->fd, IOCATAGPARM, ap);
+}
+
+#endif
+
+static int
+_device_probe_geometry (PedDevice* dev)
+{
+	FreeBSDSpecific*		arch_specific = FREEBSD_SPECIFIC (dev);
+	struct stat		dev_stat;
+	struct ata_params ap;
+
+	if (!_device_stat (dev, &dev_stat))
+		return 0;
+	PED_ASSERT (S_ISCHR (dev_stat.st_mode), return 0);
+
+	dev->sector_size = _device_get_sector_size (dev);
+	// XXX This is how phys_sector_size is set on Linux, but it is not a good idea!
+	dev->phys_sector_size = dev->sector_size;
+	if (!dev->sector_size)
+		return 0;
+
+	dev->length = _device_get_length (dev);
+	if (!dev->length)
+		return 0;
+
+	dev->bios_geom.sectors = 63;
+	dev->bios_geom.heads = 255;
+	dev->bios_geom.cylinders
+	       	= dev->length / (63 * 255)
+	       		/ (dev->sector_size / PED_SECTOR_SIZE_DEFAULT);
+
+	if (freebsd_get_ata_params (dev, &ap) == 0) {
+		dev->hw_geom.sectors = ap.sectors;
+		dev->hw_geom.heads = ap.heads;
+		dev->hw_geom.cylinders = ap.cylinders;
+	} else {
+		dev->hw_geom = dev->bios_geom;
+	}
+
+	return 1;
+}
+
+static char*
+strip_name(char* str)
+{
+	int	i;
+	int	end = 0;
+
+	for (i = 0; str[i] != 0; i++) {
+		if (!isspace (str[i])
+		    || (isspace (str[i]) && !isspace (str[i+1]) && str[i+1])) {
+			str [end] = str[i];
+			end++;
+		}
+	}
+	str[end] = 0;
+	return strdup (str);
+}
+
+static int
+init_ide (PedDevice* dev)
+{
+	FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC(dev);
+	struct stat	dev_stat;
+	struct ata_params ap;
+	PedExceptionOption ex_status;
+	char vendor_buf[64];
+
+	if (!_device_stat (dev, &dev_stat))
+		goto error;
+
+	if (!ped_device_open (dev))
+		goto error;
+
+	if (freebsd_get_ata_params (dev, &ap) == -1) {
+		ex_status = ped_exception_throw (
+			PED_EXCEPTION_WARNING,
+			PED_EXCEPTION_IGNORE_CANCEL,
+			_("Could not get identity of device %s - %s"),
+			dev->path, strerror (errno));
+		switch (ex_status) {
+		case PED_EXCEPTION_CANCEL:
+			goto error_close_dev;
+
+		case PED_EXCEPTION_UNHANDLED:
+			ped_exception_catch ();
+		case PED_EXCEPTION_IGNORE:
+			dev->model = strdup(_("IDE"));
+		}
+	} else {
+		snprintf (vendor_buf, 64, "%s/%s", ap.model, ap.revision);
+		dev->model = strip_name (vendor_buf);
+	}
+
+	if (!_device_probe_geometry (dev))
+		goto error_close_dev;
+
+	ped_device_close (dev);
+	return 1;
+
+error_close_dev:
+	ped_device_close (dev);
+error:
+	return 0;
+}
+
+static int
+init_file (PedDevice* dev)
+{
+	struct stat	dev_stat;
+ 
+	if (!_device_stat (dev, &dev_stat))
+		goto error;
+
+	if (!ped_device_open (dev))
+		goto error;
+
+	if (S_ISCHR(dev_stat.st_mode))
+		dev->length = _device_get_length (dev);
+	else
+		dev->length = dev_stat.st_size / 512;
+	if (dev->length <= 0) {
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("The device %s is zero-length, and can't possibly "
+			  "store a file system or partition table.  Perhaps "
+			  "you selected the wrong device?"),
+			dev->path);
+		goto error_close_dev;
+	}
+
+	ped_device_close (dev);
+
+	dev->bios_geom.cylinders = dev->length / 4 / 32;
+	dev->bios_geom.heads = 4;
+	dev->bios_geom.sectors = 32;
+	dev->hw_geom = dev->bios_geom;
+	dev->sector_size = 512;
+	dev->model = strdup ("");
+	return 1;
+
+error_close_dev:
+	ped_device_close (dev);
+error:
+	return 0;
+}
+
+static int
+init_generic (PedDevice* dev, char* model_name)
+{
+	struct stat		dev_stat;
+	PedExceptionOption	ex_status;
+
+	if (!_device_stat (dev, &dev_stat))
+		goto error;
+
+	if (!ped_device_open (dev))
+		goto error;
+
+	ped_exception_fetch_all ();
+	if (_device_probe_geometry (dev)) {
+		ped_exception_leave_all ();
+	} else {
+		/* hack to allow use of files, for testing */
+		ped_exception_catch ();
+		ped_exception_leave_all ();
+
+		ex_status = ped_exception_throw (
+				PED_EXCEPTION_WARNING,
+				PED_EXCEPTION_IGNORE_CANCEL,
+				_("Unable to determine geometry of "
+				"file/device.  You should not use Parted "
+				"unless you REALLY know what you're doing!"));
+		switch (ex_status) {
+			case PED_EXCEPTION_CANCEL:
+				goto error_close_dev;
+
+			case PED_EXCEPTION_UNHANDLED:
+				ped_exception_catch ();
+			case PED_EXCEPTION_IGNORE:
+				; // just workaround for gcc 3.0
+		}
+
+		/* what should we stick in here? */
+		dev->length = dev_stat.st_size / PED_SECTOR_SIZE_DEFAULT;
+		dev->bios_geom.cylinders = dev->length / 4 / 32;
+		dev->bios_geom.heads = 4;
+		dev->bios_geom.sectors = 32;
+		dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
+	}
+
+	dev->model = strdup (model_name);
+
+	ped_device_close (dev);
+	return 1;
+
+error_close_dev:
+	ped_device_close (dev);
+error:
+	return 0;
+}
+
+static PedDevice*
+freebsd_new (const char* path)
+{
+	PedDevice*	dev;
+
+	PED_ASSERT (path != NULL, return NULL);
+
+	dev = (PedDevice*) ped_malloc (sizeof (PedDevice));
+	if (!dev)
+		goto error;
+
+	dev->path = strdup (path);
+	if (!dev->path)
+		goto error_free_dev;
+
+	dev->arch_specific
+		= (FreeBSDSpecific*) ped_malloc (sizeof (FreeBSDSpecific));
+	if (!dev->arch_specific)
+		goto error_free_path;
+
+	dev->open_count = 0;
+	dev->read_only = 0;
+	dev->external_mode = 0;
+	dev->dirty = 0;
+	dev->boot_dirty = 0;
+
+	if (!_device_probe_type (dev))
+		goto error_free_arch_specific;
+	
+	switch (dev->type) {
+	case PED_DEVICE_IDE:
+		if (!init_ide (dev))
+			goto error_free_arch_specific;
+		break;
+
+	default:
+		ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
+				PED_EXCEPTION_CANCEL,
+				_("ped_device_new()  Unsupported device type"));
+		goto error_free_arch_specific;
+	}
+	return dev;
+
+error_free_arch_specific:
+	ped_free (dev->arch_specific);
+error_free_path:
+	ped_free (dev->path);
+error_free_dev:
+	ped_free (dev);
+error:
+	return NULL;
+}
+
+static void
+freebsd_destroy (PedDevice* dev)
+{
+	ped_free (dev->arch_specific);
+	ped_free (dev->path);
+	ped_free (dev->model);
+	ped_free (dev);
+}
+
+/* check if a partition of a device is mounted */
+/* see comments for _device_get_part_path() */
+static int
+freebsd_is_busy (PedDevice* dev)
+{
+	int	slice, part;
+	char*	part_name;
+
+	for (slice = -1; slice < 16; slice++) {
+		for(part = -1; part < 26; part++) {
+			int status;
+			
+			part_name = _device_get_part_path (dev, slice, part);
+			if (!part_name)
+				return 1;
+			status = _partition_is_mounted_by_path (part_name);
+			ped_free (part_name);
+
+			if (status)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
+# define _flush_cache freebsd_flush_cache_compat5
+#elif (__FreeBSD_version >= 600000)
+# define _flush_cache freebsd_flush_cache_compat6
+#else
+# error "parted currently compiles on FreeBSD 5.X and 6.X only"
+#endif
+
+#if (__FreeBSD_version >= 500000) && (__FreeBSD_version < 600000)
+
+static void
+freebsd_flush_cache_compat5 (PedDevice* dev)
+{
+	FreeBSDSpecific*	arch_specific = FREEBSD_SPECIFIC (dev);
+	int fd;
+	struct ata_cmd iocmd;
+
+	/* don't flush cache on mounted devices */
+	if (freebsd_is_busy(dev))
+		return;
+	
+	if ((fd = open("/dev/ata", O_RDWR)) == -1)
+	{
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("Could not open /dev/ata."));
+
+		goto out;
+	}
+
+	if (dev->read_only)
+		goto out;
+	dev->dirty = 0;
+	
+	bzero(&iocmd, sizeof(struct ata_cmd));
+	iocmd.channel = arch_specific->channel;
+	iocmd.device = arch_specific->device;
+	iocmd.cmd = ATAREQUEST;
+	iocmd.u.request.u.ata.command = ATA_FLUSHCACHE;
+	iocmd.u.request.timeout = 5;
+	
+	if (ioctl(fd, IOCATA, &iocmd) == -1)
+	{
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("Could not flush cache."));
+		
+		goto out;
+	}
+
+out:
+	close (fd);
+	
+	return;
+}
+
+#elif __FreeBSD_version >= 600000
+
+static void
+freebsd_flush_cache_compat6 (PedDevice* dev)
+{
+	FreeBSDSpecific*	arch_specific = FREEBSD_SPECIFIC (dev);
+	struct ata_ioc_request ioreq;
+
+	/* don't flush cache on mounted devices */
+	if (freebsd_is_busy(dev))
+		return;
+	
+	if (dev->read_only)
+		return;
+	dev->dirty = 0;
+	
+	bzero(&ioreq, sizeof(struct ata_ioc_request));
+	ioreq.u.ata.command = ATA_FLUSHCACHE;
+	ioreq.flags = ATA_CMD_CONTROL;
+	ioreq.timeout = 5;
+	
+	if (ioctl(arch_specific->fd, IOCATAREQUEST, &ioreq) == -1)
+	{
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("Could not flush cache."));
+		return;
+	}
+
+	return;
+}
+
+#endif
+
+/* By default, kernel of FreeBSD does not allow overwriting MBR */
+#define GEOM_SYSCTL     "kern.geom.debugflags"
+
+static int
+freebsd_open (PedDevice* dev)
+{
+	int old_flags, flags;
+	size_t sizeof_int = sizeof (int);
+	FreeBSDSpecific*	arch_specific = FREEBSD_SPECIFIC (dev);
+
+retry:
+/* 	if (sysctlbyname (GEOM_SYSCTL, &old_flags, */
+/* 					  &sizeof_int, NULL, 0) != 0) */
+/* 		printf ("failed to get " GEOM_SYSCTL "sysctl: %s\n", */
+/* 				strerror (errno)); */
+	
+/* 	if ((old_flags & 0x10) == 0) */
+/* 	{ */
+/* 		/\* "allow foot shooting", see geom(4) *\/ */
+/* 		flags = old_flags | 0x10; */
+		
+/* 		if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, */
+/* 						  &flags, sizeof (int)) != 0) */
+/* 			printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", */
+/* 					strerror (errno)); */
+/* 	} */
+	
+	arch_specific->fd = open (dev->path, O_RDWR);
+
+/* 	if (flags != old_flags) */
+/* 	{ */
+/* 		if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, */
+/* 						  &old_flags, sizeof (int)) != 0) */
+/* 			printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", */
+/* 					strerror (errno)); */
+/* 	} */
+	
+	if (arch_specific->fd == -1) {
+		char*	rw_error_msg = strerror (errno);
+
+		arch_specific->fd = open (dev->path, O_RDONLY);
+		if (arch_specific->fd == -1) {
+			if (ped_exception_throw (
+				PED_EXCEPTION_ERROR,
+				PED_EXCEPTION_RETRY_CANCEL,
+				_("Error opening %s: %s"),
+				dev->path, strerror (errno))
+					!= PED_EXCEPTION_RETRY) {
+				return 0;
+			} else {
+				goto retry;
+			}
+		} else {
+			ped_exception_throw (
+				PED_EXCEPTION_WARNING,
+				PED_EXCEPTION_OK,
+				_("Unable to open %s read-write (%s).\n%s has "
+				  "been opened read-only. Maybe %s is mounted?"),
+				dev->path, rw_error_msg, dev->path, dev->path);
+			dev->read_only = 1;
+		}
+	} else {
+		dev->read_only = 0;
+	}
+
+	_flush_cache (dev);
+
+	return 1;
+}
+
+static int
+freebsd_refresh_open (PedDevice* dev)
+{
+	return 1;
+}
+
+static int
+freebsd_close (PedDevice* dev)
+{
+	FreeBSDSpecific*		arch_specific = FREEBSD_SPECIFIC (dev);
+
+	if (dev->dirty)
+		_flush_cache (dev);
+	close (arch_specific->fd);
+	return 1;
+}
+
+static int
+freebsd_refresh_close (PedDevice* dev)
+{
+	if (dev->dirty)
+		_flush_cache (dev);
+	return 1;
+}
+
+static int
+_device_seek (const PedDevice* dev, PedSector sector)
+{
+	FreeBSDSpecific*	arch_specific;
+	off_t	pos;
+	
+	PED_ASSERT (dev != NULL, return 0);
+	PED_ASSERT (!dev->external_mode, return 0);
+	
+	arch_specific = FREEBSD_SPECIFIC (dev);
+
+	pos = sector * PED_SECTOR_SIZE_DEFAULT;
+	return lseek (arch_specific->fd, pos, SEEK_SET) == pos;
+}
+
+static int
+freebsd_read (const PedDevice* dev, void* buffer, PedSector start, PedSector count)
+{
+	FreeBSDSpecific*		arch_specific = FREEBSD_SPECIFIC (dev);
+	int			status;
+	PedExceptionOption	ex_status;
+	size_t			read_length = count * PED_SECTOR_SIZE_DEFAULT;
+
+	while (1) {
+		if (_device_seek (dev, start))
+			break;
+
+		ex_status = ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+			_("%s during seek for read on %s"),
+			strerror (errno), dev->path);
+
+		switch (ex_status) {
+			case PED_EXCEPTION_IGNORE:
+				return 1;
+
+			case PED_EXCEPTION_RETRY:
+				break;
+
+			case PED_EXCEPTION_UNHANDLED:
+				ped_exception_catch ();
+			case PED_EXCEPTION_CANCEL:
+				return 0;
+		}
+	}
+
+	while (1) {
+		status = read (arch_specific->fd, buffer, read_length);
+		if (status == count * PED_SECTOR_SIZE_DEFAULT) break;
+		if (status > 0) {
+			read_length -= status;
+			buffer += status;
+			continue;
+		}
+
+		ex_status = ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+			_("%s during read on %s"),
+			strerror (errno),
+			dev->path);
+
+		switch (ex_status) {
+			case PED_EXCEPTION_IGNORE:
+				return 1;
+
+			case PED_EXCEPTION_RETRY:
+				break;
+
+			case PED_EXCEPTION_UNHANDLED:
+				ped_exception_catch ();
+			case PED_EXCEPTION_CANCEL:
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+static int
+freebsd_write (PedDevice* dev, const void* buffer, PedSector start,
+	     PedSector count)
+{
+	FreeBSDSpecific*		arch_specific = FREEBSD_SPECIFIC (dev);
+	int			status;
+	PedExceptionOption	ex_status;
+	size_t			write_length = count * PED_SECTOR_SIZE_DEFAULT;
+
+	if (dev->read_only) {
+		if (ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_IGNORE_CANCEL,
+			_("Can't write to %s, because it is opened read-only."),
+			dev->path)
+				!= PED_EXCEPTION_IGNORE)
+			return 0;
+		else
+			return 1;
+	}
+
+	while (1) {
+		if (_device_seek (dev, start))
+			break;
+
+		ex_status = ped_exception_throw (
+			PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+			_("%s during seek for write on %s"),
+			strerror (errno), dev->path);
+
+		switch (ex_status) {
+			case PED_EXCEPTION_IGNORE:
+				return 1;
+
+			case PED_EXCEPTION_RETRY:
+				break;
+
+			case PED_EXCEPTION_UNHANDLED:
+				ped_exception_catch ();
+			case PED_EXCEPTION_CANCEL:
+				return 0;
+		}
+	}
+
+#ifdef READ_ONLY
+	printf ("ped_device_write (\"%s\", %p, %d, %d)\n",
+		dev->path, buffer, (int) start, (int) count);
+#else
+	dev->dirty = 1;
+	while (1) {
+		status = write (arch_specific->fd, buffer, write_length);
+		if (status == count * PED_SECTOR_SIZE_DEFAULT) break;
+		if (status > 0) {
+			write_length -= status;
+			buffer += status;
+			continue;
+		}
+
+		ex_status = ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+			_("%s during write on %s"),
+			strerror (errno), dev->path);
+
+		switch (ex_status) {
+			case PED_EXCEPTION_IGNORE:
+				return 1;
+
+			case PED_EXCEPTION_RETRY:
+				break;
+
+			case PED_EXCEPTION_UNHANDLED:
+				ped_exception_catch ();
+			case PED_EXCEPTION_CANCEL:
+				return 0;
+		}
+	}
+#endif /* !READ_ONLY */
+	return 1;
+}
+
+/* returns the number of sectors that are ok.
+ */
+static PedSector
+freebsd_check (PedDevice* dev, void* buffer, PedSector start, PedSector count)
+{
+	FreeBSDSpecific*	arch_specific = FREEBSD_SPECIFIC (dev);
+	PedSector	done = 0;
+	int		status;
+
+	if (!_device_seek (dev, start))
+		return 0;
+
+	for (done = 0; done < count; done += status / PED_SECTOR_SIZE_DEFAULT) {
+		status = read (arch_specific->fd, buffer,
+			       (size_t) ((count-done) * PED_SECTOR_SIZE_DEFAULT));
+		if (status < 0)
+			break;
+	}
+
+	return done;
+}
+
+static int
+_do_fsync (PedDevice* dev)
+{
+	FreeBSDSpecific*		arch_specific = FREEBSD_SPECIFIC (dev);
+	int			status;
+	PedExceptionOption	ex_status;
+
+	while (1) {
+		status = fsync (arch_specific->fd);
+		if (status >= 0) break;
+
+		ex_status = ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+			_("%s during write on %s"),
+			strerror (errno), dev->path);
+
+		switch (ex_status) {
+			case PED_EXCEPTION_IGNORE:
+				return 1;
+
+			case PED_EXCEPTION_RETRY:
+				break;
+
+			case PED_EXCEPTION_UNHANDLED:
+				ped_exception_catch ();
+			case PED_EXCEPTION_CANCEL:
+				return 0;
+		}
+	} 
+	return 1;
+}
+
+static int
+freebsd_sync (PedDevice* dev)
+{
+	PED_ASSERT (dev != NULL, return 0);
+	PED_ASSERT (!dev->external_mode, return 0);
+
+	if (dev->read_only)
+		return 1;
+	if (!_do_fsync (dev))
+		return 0;
+	_flush_cache (dev);
+	return 1;
+}
+
+static int
+freebsd_sync_fast (PedDevice* dev)
+{
+	PED_ASSERT (dev != NULL, return 0);
+	PED_ASSERT (!dev->external_mode, return 0);
+
+	if (dev->read_only)
+		return 1;
+	if (!_do_fsync (dev))
+		return 0;
+	/* no cache flush... */
+	return 1;
+}
+
+static int
+_probe_standard_devices ()
+{
+	char		devname [17];
+	char		devtype [17];
+	char		fullpath [256];
+	int 		ret;
+	char*		conftxt;
+	size_t		confsize;
+	char*		cptr;
+
+	ret = sysctlbyname("kern.geom.conftxt", NULL, &confsize, NULL, 0);
+	if (ret) {
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("kern.geom.conftxt sysctl not available, giving up!"));//Was printf
+		return 0;
+	}
+
+	conftxt = ped_malloc(confsize + 1);
+	if (conftxt == NULL) {
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("cannot malloc memory for conftxt"));//Was printf
+		return 0;
+	}
+	
+	ret = sysctlbyname("kern.geom.conftxt", conftxt, &confsize, NULL, 0);
+	if (ret) {
+		ped_exception_throw (
+			PED_EXCEPTION_ERROR,
+			PED_EXCEPTION_CANCEL,
+			_("error reading kern.geom.conftxt from the system"));//Was printf
+		free (conftxt);
+		return 0;
+	}
+	
+	cptr = conftxt;
+	
+	while (sscanf (cptr, "%*d %16s %16s",
+				   devtype, devname) != EOF) {
+		if (strcmp(devtype, "DISK") == 0)
+		{
+			strncpy (fullpath, _PATH_DEV, sizeof(fullpath) - 1);
+			fullpath[sizeof(fullpath) - 1] = '\0';
+			strncat (fullpath, devname,
+					 sizeof(fullpath) - strlen(fullpath) - 1);
+			printf("Probing %s ...\n", fullpath);
+			_ped_device_probe (fullpath);
+			
+			if(_partition_is_mounted_by_path (fullpath)){
+                                ped_exception_throw (
+                                PED_EXCEPTION_WARNING,
+                                PED_EXCEPTION_OK,
+                                _("WARNING: %s or parts of it are mounted!.\n"),
+                                fullpath);//Was printf
+			}
+		}
+		
+		if((cptr = strchr(cptr, '\n')) == NULL)
+			break;
+		else
+			cptr++;
+	}
+
+	ped_free(conftxt);
+	
+	return 1;
+}
+
+static void
+freebsd_probe_all ()
+{
+	_probe_standard_devices ();
+}
+
+/* slice_num is slice number */
+/* part_num is the partition number in this slice */
+/* both slice_num and part_num can be -1. */
+/* when slice_num is -1, then we're making paths for a raw disk */
+/* e.g. ad0a, ad0c, ad0e, etc */
+/* when part_num is -1, then we're making a path that takes */
+/* the whole slice e.g. ad0s0, ad0s1, ad0s5. */
+/* ad6s2e                */
+/*     ||                */
+/*     | \__ part_num    */
+/*      \___ slice_num   */
+static char*
+_device_get_part_path (PedDevice* dev, int slice_num, int part_num)
+{
+	int		path_len = strlen (dev->path);
+	int		result_len = path_len + 16;
+	char*		result;
+	char	part[2] = { '\0', '\0' };
+	char*	fmt;
+	
+	result = (char*) ped_malloc (result_len);
+	if (!result)
+		return NULL;
+
+	/* slice_num = -1 when covering raw disk (ad0a, ad0c, etc) */
+	if(slice_num == -1)
+		fmt = "%s%s";
+	else
+		fmt = "%ss%d%s";
+
+	/* if part_num is -1, then the part[] array is already a null string */
+	/* if it's not -1, then transform slice_num into a character and put it */
+	/* in part[] */
+	if(part_num != -1)
+	{
+		part[0] = (char) part_num + 'a';
+		part[1] = '\0';
+	}
+	
+	if(slice_num == -1)
+		/* append slice number (ad0, slice 2 => ad0s2) */
+		snprintf (result, result_len, fmt, dev->path, part);
+	else
+		/* append slice and partition number (ad0, slice 1, part 2 => ad0s1c) */
+		snprintf (result, result_len, fmt, dev->path, slice_num, part);
+	
+	return result;
+}
+
+static char*
+freebsd_partition_get_path (const PedPartition* part)
+{
+	return _device_get_part_path (part->disk->dev, part->num, -1);
+}
+
+static int
+_partition_is_mounted_by_path (const char *path)
+{
+	struct stat partstat, mntdevstat;
+	struct statfs *mntbuf, *statfsp;
+	char *devname;
+	char device[256];
+	int mntsize, i;
+
+	if (stat (path, &partstat) != 0)
+		return 0;
+
+	if (!S_ISCHR(partstat.st_mode))
+		return 0;
+
+	mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
+	for (i = 0; i < mntsize; i++) {
+		statfsp = &mntbuf[i];
+		devname = statfsp->f_mntfromname;
+
+		if(strncmp(path, devname, strlen(devname)) == 0)
+			return 1;
+	}
+
+	return 0;
+}
+
+static int
+_partition_is_mounted (const PedPartition *part)
+{
+	dev_t dev;
+	if (!ped_partition_is_active (part))
+		return 0;
+	
+	return _partition_is_mounted_by_path (part->disk->dev->path);
+}
+
+static int
+freebsd_partition_is_busy (const PedPartition* part)
+{
+	PedPartition*	walk;
+
+	PED_ASSERT (part != NULL, return 0);
+
+	if (_partition_is_mounted (part))
+		return 1;
+	if (part->type == PED_PARTITION_EXTENDED) {
+		for (walk = part->part_list; walk; walk = walk->next) {
+			if (freebsd_partition_is_busy (walk))
+				return 1;
+		}
+	}
+	return 0;
+}
+
+static int
+_kernel_reread_part_table (PedDevice* dev)
+{
+	FreeBSDSpecific*	arch_specific = FREEBSD_SPECIFIC (dev);
+	int		retry_count = 5, ret;
+	struct gctl_req *grq;
+	unsigned char mbr_buf[512];
+	const char *q;
+	
+	sync();
+
+	/* read the MBR, which was written in the first sector */
+	freebsd_read (dev, mbr_buf, 0, 1);
+
+	/* the freebsd_close/open pair around the gctl's is a workaround */
+	/* for a problem that is yet to be clarified. without them, geom */
+	/* isn't able to commit the MBR. */
+	freebsd_close(dev);
+
+	do {
+		grq = gctl_get_handle();
+		gctl_ro_param(grq, "verb", -1, "write MBR");
+		gctl_ro_param(grq, "class", -1, "MBR");
+
+		/* find geom name */
+		if (strncmp(dev->path, _PATH_DEV, strlen(_PATH_DEV)) == 0)
+			q = (char *) (dev->path + strlen(_PATH_DEV));
+		else {
+			q = dev->path;
+		}
+
+		gctl_ro_param(grq, "geom", -1, q);
+		gctl_ro_param(grq, "data", dev->sector_size, mbr_buf);
+		q = gctl_issue(grq);
+		gctl_free(grq);
+
+		if (q != NULL) {
+			ret = 1;
+			goto out;
+		}
+
+		ret = 0;
+	} while(0);
+
+out:
+	freebsd_open(dev);
+	
+	return ret;
+}
+
+static int
+freebsd_disk_commit (PedDisk* disk)
+{
+	if (disk->dev->type != PED_DEVICE_FILE)
+		return _kernel_reread_part_table (disk->dev);
+
+	return 1;
+}
+
+static PedDeviceArchOps freebsd_dev_ops = {
+	_new:			freebsd_new,
+	destroy:		freebsd_destroy,
+	is_busy:		freebsd_is_busy,
+	open:			freebsd_open,
+	refresh_open:	freebsd_refresh_open,
+	close:			freebsd_close,
+	refresh_close:	freebsd_refresh_close,
+	read:			freebsd_read,
+	write:			freebsd_write,
+	check:			freebsd_check,
+	sync:			freebsd_sync,
+	sync_fast:		freebsd_sync_fast,
+	probe_all:		freebsd_probe_all
+};
+
+PedDiskArchOps freebsd_disk_ops =  {
+	partition_get_path:	freebsd_partition_get_path,
+	partition_is_busy:	freebsd_partition_is_busy,
+	disk_commit:		freebsd_disk_commit
+};
+
+PedArchitecture ped_freebsd_arch = {
+	dev_ops:	&freebsd_dev_ops,
+	disk_ops:	&freebsd_disk_ops
+};
diff --exclude=.git -NruBb parted/libparted/fs/xfs/platform_defs.h parted-freebsd/libparted/fs/xfs/platform_defs.h
--- parted/libparted/fs/xfs/platform_defs.h	Tue Mar  6 00:41:14 2007
+++ parted-freebsd/libparted/fs/xfs/platform_defs.h	Tue Mar  6 00:41:42 2007
@@ -38,7 +38,11 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <assert.h>
-#include <endian.h>
+#if HAVE_ENDIAN_H
+# include <endian.h>
+#elif HAVE_SYS_ENDIAN_H
+# include <sys/endian.h>
+#endif
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
diff --exclude=.git -NruBb parted/libparted/labels/bsd.c parted-freebsd/libparted/labels/bsd.c
--- parted/libparted/labels/bsd.c	Tue Mar  6 00:41:14 2007
+++ parted-freebsd/libparted/labels/bsd.c	Tue Mar  6 00:41:42 2007
@@ -22,6 +22,8 @@
 
 #include "config.h"
 
+#include <sys/types.h>
+
 #include <parted/parted.h>
 #include <parted/debug.h>
 #include <parted/endian.h>
diff --exclude=.git -NruBb parted/libparted/labels/sun.c parted-freebsd/libparted/labels/sun.c
--- parted/libparted/labels/sun.c	Tue Mar  6 00:41:14 2007
+++ parted-freebsd/libparted/labels/sun.c	Tue Mar  6 00:41:42 2007
@@ -22,6 +22,8 @@
 
 #include "config.h"
 
+#include <sys/types.h>
+
 #include <parted/parted.h>
 #include <parted/debug.h>
 #include <parted/endian.h>
diff --exclude=.git -NruBb parted/libparted/libparted.c parted-freebsd/libparted/libparted.c
--- parted/libparted/libparted.c	Tue Mar  6 00:41:14 2007
+++ parted-freebsd/libparted/libparted.c	Tue Mar  6 00:41:42 2007
@@ -27,6 +27,8 @@
 #  include <parted/linux.h>
 #elif defined(__BEOS__)
 #  include <parted/beos.h>
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#  include <parted/freebsd.h>
 #else
 #  include <parted/gnu.h>
 #endif
@@ -192,6 +194,8 @@
 	ped_set_architecture (&ped_linux_arch);
 #elif defined(__BEOS__)
 	ped_set_architecture (&ped_beos_arch);
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+	ped_set_architecture (&ped_freebsd_arch);
 #else
 	ped_set_architecture (&ped_gnu_arch);
 #endif
diff --exclude=.git -NruBb parted/parted/strlist.h parted-freebsd/parted/strlist.h
--- parted/parted/strlist.h	Tue Mar  6 00:41:14 2007
+++ parted-freebsd/parted/strlist.h	Tue Mar  6 00:41:42 2007
@@ -20,7 +20,16 @@
 #ifndef STRLIST_H_INCLUDED
 #define STRLIST_H_INCLUDED
 
-#include <wchar.h>
+
+#ifdef ENABLE_NLS
+#       include <wchar.h>
+#else
+#       ifdef wchar_t
+#               undef wchar_t
+#       endif
+#       include <string.h>
+#       define wchar_t char
+#endif
 
 typedef struct _StrList StrList;
 struct _StrList {
diff --exclude=.git -NruBb parted/parted/table.c parted-freebsd/parted/table.c
--- parted/parted/table.c	Tue Mar  6 00:41:14 2007
+++ parted-freebsd/parted/table.c	Tue Mar  6 00:41:42 2007
@@ -47,8 +47,24 @@
         size_t strnlen (const char *, size_t);
 #endif
 
-#include "strlist.h"
+size_t strnlen (const char *s, size_t maxlen)
+{
+        size_t len = 0;
+        const char *tp = s;
+
+        if(s == NULL)
+             return 0;
+
+        while(*tp && len < maxlen)
+        {
+             len++;
+             tp++;
+        }
 
+        return len;
+}
+
+#include "strlist.h"
 
 static const unsigned int       MAX_WIDTH = 512;
 static const wchar_t*           DELIMITER = L_("  ");
@@ -180,7 +196,8 @@
 {
         wchar_t** row = t->rows[rownum];
         int len = 1, i;
-        size_t newsize;
+        size_t newsize, oldsize;
+		char *temps;
 
         assert(t);
         assert(s != NULL);
@@ -191,7 +208,11 @@
         len += wcslen(COLSUFFIX);
 
         newsize = (wcslen(*s) + len + 1) * sizeof(wchar_t);
+		oldsize = (wcslen(*s) + 1) * sizeof(wchar_t);
+
+		temps = *s;
         *s = realloc (*s, newsize);
+		memcpy(*s, temps, oldsize);
 
         for (i = 0; i < ncols; ++i)
         {
diff --exclude=.git -NruBb parted/parted/ui.c parted-freebsd/parted/ui.c
--- parted/parted/ui.c	Tue Mar  6 00:41:14 2007
+++ parted-freebsd/parted/ui.c	Tue Mar  6 00:44:50 2007
@@ -63,6 +63,10 @@
 
 #endif /* HAVE_LIBREADLINE */
 
+#ifdef __FreeBSD__
+typedef sig_t sighandler_t;
+#endif //__FreeBSD__
+
 char* prog_name = "GNU Parted " VERSION "\n";
 
 static char* banner_msg = N_(
@@ -239,7 +243,7 @@
         #ifdef HAVE_SIGACTION
         sigaction (SIGINT, &sig_int, NULL);
         #else
-        signal (SIGINT, &sigint_handler);
+        signal (SIGINT, (sighandler_t) &sigint_handler);
         mask_signal();
         #endif /* HAVE_SIGACTION */
 
@@ -253,7 +257,7 @@
         #ifdef HAVE_SIGACTION   
         sigaction (SIGSEGV, &sig_segv, NULL);
         #else
-        signal (SIGSEGV, &sigsegv_handler);
+        signal (SIGSEGV, (sighandler_t) &sigsegv_handler);
         mask_signal();
         #endif /* HAVE_SIGACTION */
 
@@ -264,6 +268,7 @@
  
         switch (info->si_code) {
 
+#ifndef __FreeBSD__
                 case SEGV_MAPERR:
                         fputs(_("\nError: SEGV_MAPERR (Address not mapped "
                                 "to object)\n"), stdout);
@@ -274,6 +279,7 @@
                         fputs(_("\nError: SEGV_ACCERR (Invalid permissions "
                                 "for mapped object)\n"), stdout);
                         break;
+#endif //__FreeBSD__
 
                 default:
                         fputs(_("\nError: A general SIGSEGV signal was "
@@ -292,7 +298,7 @@
         #ifdef HAVE_SIGACTION
         sigaction (SIGFPE, &sig_fpe, NULL);
         #else
-        signal (SIGFPE, &sigfpe_handler);
+        signal (SIGFPE, (sighandler_t) &sigfpe_handler);
         mask_signal();
         #endif /* HAVE_SIGACTION */
 
@@ -360,7 +366,7 @@
         #ifdef HAVE_SIGACTION
         sigaction (SIGILL, &sig_ill, NULL);
         #else
-        signal (SIGILL, &sigill_handler);
+        signal (SIGILL, (sighandler_t) &sigill_handler);
         mask_signal();
         #endif /* HAVE_SIGACTION */
 
@@ -371,6 +377,7 @@
 
         switch (info->si_code) {
 
+#ifndef __FreeBSD__
                 case ILL_ILLOPC:
                         fputs(_("\nError: ILL_ILLOPC "
                                 "(Illegal Opcode)"), stdout);
@@ -410,6 +417,7 @@
                         fputs(_("\nError: ILL_BADSTK "
                                 "(Internal Stack Error)"), stdout);
                         break;
+#endif //__FreeBSD__
 
                 default:
                         fputs(_("\nError: A general SIGILL "
_______________________________________________
parted-devel mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/parted-devel

Reply via email to