diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 2f209889e3..223dd1191a 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -678,6 +678,7 @@ AddTargetVariableToScript $(script) : addattr ; AddTargetVariableToScript $(script) : bfs_shell : bfsShell ; AddTargetVariableToScript $(script) : fs_shell_command : fsShellCommand ; AddTargetVariableToScript $(script) : copyattr ; +AddTargetVariableToScript $(script) : create_image : createImage ; AddTargetVariableToScript $(script) : makebootable ; AddTargetVariableToScript $(script) : rc ; AddTargetVariableToScript $(script) : resattr ; diff --git a/build/scripts/build_haiku_image b/build/scripts/build_haiku_image index 651ab2ef46..a981794ae8 100755 --- a/build/scripts/build_haiku_image +++ b/build/scripts/build_haiku_image @@ -116,17 +116,15 @@ if [ $isImage ]; then if [ ! $updateOnly ]; then echo "Creating image ..." - ddFlags= + imageFlags="-i${imageSize}M" + if [ ! "$dontClearImage" ]; then + imageFlags="$imageFlags -c" + fi + if [ $isVMwareImage ]; then - vmdkImageFlags= - if [ ! "$dontClearImage" ]; then - vmdkImageFlags="-c" - fi - $vmdkimage -h 64k -i${imageSize}M $vmdkImageFlags "$imagePath" \ - || exit 1 - elif [ ! -e "$imagePath" -o ! "$dontClearImage" ]; then - dd if=/dev/zero of="$imagePath" bs=1048576 count=$imageSize \ - || exit 1 + $vmdkimage -h 64k $imageFlags "$imagePath" || exit 1 + else + $createImage $imageFlags "$imagePath" || exit 1 fi $bfsShell --initialize $imageOffsetFlags "$imagePath" \ diff --git a/src/tools/Jamfile b/src/tools/Jamfile index 6ad793158a..9a75cf77db 100644 --- a/src/tools/Jamfile +++ b/src/tools/Jamfile @@ -37,6 +37,8 @@ UsePrivateObjectHeaders copyattr.cpp : shared : : true ; BuildPlatformMain copyattr : copyattr.cpp : $(HOST_LIBBE) $(HOST_LIBSTDC++) $(HOST_LIBSUPC++) ; +BuildPlatformMain create_image : create_image.cpp : $(HOST_LIBSUPC++) ; + BuildPlatformMain data_to_source : data_to_source.cpp : $(HOST_LIBSUPC++) ; diff --git a/src/tools/create_image.cpp b/src/tools/create_image.cpp new file mode 100644 index 0000000000..7f79f46bf1 --- /dev/null +++ b/src/tools/create_image.cpp @@ -0,0 +1,148 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2007, Marcus Overhagen. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define EXIT_FAILURE 1 + + +static void +print_usage(bool error) +{ + printf("\n"); + printf("create_image\n"); + printf("\n"); + printf("usage: create_image -i [-c] [-f] \n"); + printf(" -i, --imagesize size of raw partition image file\n"); + printf(" -f, --file the raw partition image file\n"); + printf(" -c, --clear-image set the image content to zero\n"); + exit(error ? EXIT_FAILURE : 0); +} + + +int +main(int argc, char *argv[]) +{ + off_t imageSize = 0; + const char *file = NULL; + bool clearImage = false; + + while (1) { + int c; + static struct option long_options[] = { + {"file", required_argument, 0, 'f'}, + {"clear-image", no_argument, 0, 'c'}, + {"help", no_argument, 0, 'h'}, + {"imagesize", required_argument, 0, 'i'}, + {0, 0, 0, 0} + }; + + opterr = 0; /* don't print errors */ + c = getopt_long(argc, argv, "+hi:cf:", long_options, NULL); + if (c == -1) + break; + + switch (c) { + case 'h': + print_usage(false); + break; + + case 'i': + imageSize = strtoull(optarg, NULL, 10); + if (strchr(optarg, 'G') || strchr(optarg, 'g')) + imageSize *= 1024 * 1024 * 1024; + else if (strchr(optarg, 'M') || strchr(optarg, 'm')) + imageSize *= 1024 * 1024; + else if (strchr(optarg, 'K') || strchr(optarg, 'k')) + imageSize *= 1024; + break; + + case 'f': + file = optarg; + break; + + case 'c': + clearImage = true; + break; + + default: + print_usage(true); + } + } + + if (file == NULL && optind == argc - 1) + file = argv[optind]; + + if (!imageSize || !file) + print_usage(true); + + if (imageSize < 0) { + fprintf(stderr, "Error: invalid image size\n"); + exit(EXIT_FAILURE); + } + + if (imageSize % 512) { + fprintf(stderr, "Error: image size must be a multiple of 512 bytes\n"); + exit(EXIT_FAILURE); + } + + int fd = open(file, O_RDWR | O_CREAT, 0666); + if (fd < 0) { + fprintf(stderr, "Error: couldn't open file %s (%s)\n", file, + strerror(errno)); + exit(EXIT_FAILURE); + } + + struct stat st; + if (fstat(fd, &st) < 0) { + fprintf(stderr, "Error: stat()ing file %s failed (%s)\n", file, + strerror(errno)); + exit(EXIT_FAILURE); + } + + if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) { + fprintf(stderr, "Error: type of file %s not supported\n", file); + exit(EXIT_FAILURE); + } + + if (S_ISREG(st.st_mode)) { + // regular file -- use ftruncate() to resize it + if ((clearImage && ftruncate(fd, 0) != 0) + || ftruncate(fd, imageSize) != 0) { + fprintf(stderr, "Error: resizing file %s failed (%s)\n", file, + strerror(errno)); + exit(EXIT_FAILURE); + } + } else { + // some kind of device -- clear it manually, if we have to + if (clearImage) { + char buffer[1024 * 1024]; + memset(buffer, 0, sizeof(buffer)); + + ssize_t written; + while ((written = write(fd, buffer, sizeof(buffer))) > 0) { + } + + if (written < 0) { + fprintf(stderr, "Error: writing to device file %s failed " + "(%s)\n", file, strerror(errno)); + exit(EXIT_FAILURE); + } + } + } + + close(fd); + return 0; +}