--- libtool.c.orig	2007-02-02 15:19:02.000000000 +0100
+++ libtool.c	2007-03-06 14:45:42.000000000 +0100
@@ -47,6 +47,9 @@
 #include "stuff/execute.h"
 #include "stuff/version_number.h"
 
+#include <unistd.h>
+#include <sys/mman.h>
+
 #include "make.h"
 #include <mach/mach_init.h>
 #if defined(__OPENSTEP__) || defined(__GONZO_BUNSEN_BEAKER__)
@@ -1915,6 +1918,14 @@
  * archs into the specified output file.  Only when more than one architecture
  * is in archs will a fat file be created.
  */
+
+static void write_padding(int fd, size_t padding_size)
+{
+    char *padding = calloc(1, padding_size);
+    write(fd, padding, padding_size);
+    free(padding);
+}
+
 static
 void
 create_library(
@@ -1922,10 +1933,8 @@
 {
     unsigned long i, j, k, l, library_size, offset, pad, *time_offsets;
     enum byte_sex target_byte_sex;
-    char *library, *p;
-    kern_return_t r;
     struct arch *arch;
-    struct fat_header *fat_header;
+    struct fat_header fat_header;
     struct fat_arch *fat_arch;
     int fd;
 #ifndef __OPENSTEP__
@@ -2006,25 +2015,33 @@
 	    exit(EXIT_SUCCESS);
 
 	/*
-	 * This buffer is vm_allocate'ed to make sure all holes are filled with
-	 * zero bytes.
+	 * Create the output file.  The unlink() is done to handle the problem
+	 * when the outputfile is not writable but the directory allows the
+	 * file to be removed (since the file may not be there the return code
+	 * of the unlink() is ignored).
 	 */
-	if((r = vm_allocate(mach_task_self(), (vm_address_t *)&library,
-			    library_size, TRUE)) != KERN_SUCCESS)
-	    mach_fatal(r, "can't vm_allocate() buffer for output file: %s of "
-		       "size %lu", output, library_size);
+	(void)unlink(output);
+	if((fd = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1){
+	    system_error("can't create output file: %s", output);
+	    return;
+	}
+
 
 	/*
 	 * If there is more than one architecture then fill in the fat file
 	 * header and the fat_arch structures in the buffer.
 	 */
 	if(narchs > 1){
-	    fat_header = (struct fat_header *)library;
-	    fat_header->magic = FAT_MAGIC;
-	    fat_header->nfat_arch = narchs;
+	    memset(&fat_header, 0, sizeof(struct fat_header));
+	    fat_header.magic = FAT_MAGIC;
+	    fat_header.nfat_arch = narchs;
 	    offset = sizeof(struct fat_header) +
 			    sizeof(struct fat_arch) * narchs;
-	    fat_arch = (struct fat_arch *)(library + sizeof(struct fat_header));
+#ifdef __LITTLE_ENDIAN__
+	    swap_fat_header(&fat_header, BIG_ENDIAN_BYTE_SEX);
+#endif /* __LITTLE_ENDIAN__ */
+	    write(fd, &fat_header, sizeof(struct fat_header));
+	    fat_arch = calloc(narchs, sizeof(struct fat_arch));
 	    for(i = 0; i < narchs; i++){
 		fat_arch[i].cputype = archs[i].arch_flag.cputype;
 		fat_arch[i].cpusubtype = archs[i].arch_flag.cpusubtype;
@@ -2033,12 +2050,13 @@
 		fat_arch[i].align = 2;
 		offset += archs[i].size;
 	    }
+	    offset = sizeof(struct fat_header) +
+			    sizeof(struct fat_arch) * narchs;
 #ifdef __LITTLE_ENDIAN__
-	    swap_fat_header(fat_header, BIG_ENDIAN_BYTE_SEX);
 	    swap_fat_arch(fat_arch, narchs, BIG_ENDIAN_BYTE_SEX);
 #endif /* __LITTLE_ENDIAN__ */
-	    offset = sizeof(struct fat_header) +
-			    sizeof(struct fat_arch) * narchs;
+	    write(fd, fat_arch, sizeof(struct fat_arch) * narchs);
+	    free(fat_arch);
 	}
 	else
 	    offset = 0;
@@ -2052,8 +2070,8 @@
 	/*
 	 * Now put each arch in the buffer.
 	 */
+
 	for(i = 0; i < narchs; i++){
-	    p = library + offset;
 	    arch = archs + i;
 
 	    /*
@@ -2065,8 +2083,7 @@
 	     */
 
 	    /* put in the archive magic string */
-	    memcpy(p, ARMAG, SARMAG);
-	    p += SARMAG;
+	    write(fd, ARMAG, SARMAG);
 
 	    /*
 	     * Warn for what really is a bad library that has an empty table of
@@ -2105,60 +2122,52 @@
 	     *	a long for the number of bytes of the strings for the ranlibs
 	     *	the strings for the ranlib structs
 	     */
+
 	    time_offsets[i] =
-			 (p - library) +
-			 ((char *)&toc_ar_hdr.ar_date - (char *)&toc_ar_hdr);
-	    memcpy(p, (char *)&arch->toc_ar_hdr, sizeof(struct ar_hdr));
-	    p += sizeof(struct ar_hdr);
+		lseek(fd, 0, SEEK_CUR) +
+		((char *)&toc_ar_hdr.ar_date - (char *)&toc_ar_hdr);
+	    write(fd, (char *)&arch->toc_ar_hdr, sizeof(struct ar_hdr));
 
 	    if(arch->toc_long_name == TRUE){
-		memcpy(p, arch->toc_name, arch->toc_name_size);
-		p += arch->toc_name_size +
-		     (round(sizeof(struct ar_hdr), 8) -
-		      sizeof(struct ar_hdr));
+		write(fd, arch->toc_name, arch->toc_name_size);
+		write_padding(fd, round(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr));
 	    }
 
 	    l = arch->toc_nranlibs * sizeof(struct ranlib);
 	    if(target_byte_sex != host_byte_sex)
 		l = SWAP_LONG(l);
-	    memcpy(p, (char *)&l, sizeof(long));
-	    p += sizeof(long);
+	    write(fd, (char *)&l, sizeof(long));
 
 	    if(target_byte_sex != host_byte_sex)
 		swap_ranlib(arch->toc_ranlibs, arch->toc_nranlibs,
 			    target_byte_sex);
-	    memcpy(p, (char *)arch->toc_ranlibs,
-		   arch->toc_nranlibs * sizeof(struct ranlib));
-	    p += arch->toc_nranlibs * sizeof(struct ranlib);
+	    write(fd, (char *)arch->toc_ranlibs,
+		  arch->toc_nranlibs * sizeof(struct ranlib));
 
 	    l = arch->toc_strsize;
 	    if(target_byte_sex != host_byte_sex)
 		l = SWAP_LONG(l);
-	    memcpy(p, (char *)&l, sizeof(long));
-	    p += sizeof(long);
+	    write(fd, (char *)&l, sizeof(long));
 
-	    memcpy(p, (char *)arch->toc_strings, arch->toc_strsize);
-	    p += arch->toc_strsize;
+	    write(fd, (char *)arch->toc_strings, arch->toc_strsize);
 
 	    /*
 	     * Put in the archive header and member contents for each member.
 	     */
 	    for(j = 0; j < arch->nmembers; j++){
-		memcpy(p, (char *)&(arch->members[j].ar_hdr),
-		       sizeof(struct ar_hdr));
-		p += sizeof(struct ar_hdr);
-
+		write(fd, (char *)&(arch->members[j].ar_hdr), sizeof(struct ar_hdr));
 		/*
 		 * If we are using extended format #1 for long names write out
 		 * the name.  Note the name is padded with '\0' and the
 		 * member_name_size is the unrounded size.
 		 */
 		if(arch->members[j].output_long_name == TRUE){
-		    strncpy(p, arch->members[j].member_name,
-			    arch->members[j].member_name_size);
-		    p += round(arch->members[j].member_name_size, 8) +
-			       (round(sizeof(struct ar_hdr), 8) -
-				sizeof(struct ar_hdr));
+		    write(fd, arch->members[j].member_name, arch->members[j].member_name_size);
+		    write_padding(fd,
+				  (round(arch->members[j].member_name_size, 8) -
+				   arch->members[j].member_name_size) +
+				  (round(sizeof(struct ar_hdr), 8) -
+				   sizeof(struct ar_hdr)));
 		}
 
 		/*
@@ -2178,33 +2187,16 @@
 		       arch->members[j].load_commands) == FALSE)
 			fatal("internal error: swap_object_headers() failed");
 		}
-		memcpy(p, arch->members[j].object_addr,
-		       arch->members[j].object_size);
-		p += arch->members[j].object_size;
+		write(fd, arch->members[j].object_addr, arch->members[j].object_size);
 		pad = round(arch->members[j].object_size, 8) -
 		      arch->members[j].object_size;
 		/* as with the UNIX ar(1) program pad with '\n' characters */
 		for(k = 0; k < pad; k++)
-		    *p++ = '\n';
+		    write(fd, "\n", 1);
 	    }
 	    offset += arch->size;
 	}
 
-	/*
-	 * Create the output file.  The unlink() is done to handle the problem
-	 * when the outputfile is not writable but the directory allows the
-	 * file to be removed (since the file may not be there the return code
-	 * of the unlink() is ignored).
-	 */
-	(void)unlink(output);
-	if((fd = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1){
-	    system_error("can't create output file: %s", output);
-	    return;
-	}
-	if(write(fd, library, library_size) != (int)library_size){
-	    system_error("can't write output file: %s", output);
-	    return;
-	}
 	if(close(fd) == -1){
 	    system_fatal("can't close output file: %s", output);
 	    return;
@@ -2265,11 +2257,6 @@
 			 output);
 	    return;
 	}
-	if((r = vm_deallocate(mach_task_self(), (vm_address_t)library,
-			      library_size)) != KERN_SUCCESS){
-	    my_mach_error(r, "can't vm_deallocate() buffer for output file");
-	    return;
-	}
 }
 
 /*
