Provide a file-based implementation for the image API. This almost
copies the logic verbatim from mkimg.c to image.c. The difference is that in image.c the temporary file is always created, whereas before we only created a temporary file when writing to stdout. Cleanup mkimg.c now that the song and dance of using a temporary file is gone.
This commit is contained in:
parent
ec5097c811
commit
8e16ce11e9
72
image.c
72
image.c
@ -38,6 +38,18 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define BUFFER_SIZE (1024*1024)
|
||||
|
||||
static char image_tmpfile[] = "/tmp/mkimg-XXXXXX";
|
||||
static int image_fd = -1;
|
||||
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
|
||||
if (image_fd != -1)
|
||||
close(image_fd);
|
||||
unlink(image_tmpfile);
|
||||
}
|
||||
|
||||
int
|
||||
image_copyin(lba_t blk, int fd, uint64_t *sizep)
|
||||
{
|
||||
@ -76,17 +88,69 @@ image_copyin(lba_t blk, int fd, uint64_t *sizep)
|
||||
}
|
||||
|
||||
int
|
||||
image_set_size(lba_t blk __unused)
|
||||
image_copyout(int fd)
|
||||
{
|
||||
char *buffer;
|
||||
off_t ofs;
|
||||
ssize_t rdsz, wrsz;
|
||||
int error;
|
||||
|
||||
ofs = lseek(fd, 0L, SEEK_CUR);
|
||||
|
||||
buffer = malloc(BUFFER_SIZE);
|
||||
if (buffer == NULL)
|
||||
return (errno);
|
||||
if (lseek(image_fd, 0, SEEK_SET) != 0)
|
||||
return (errno);
|
||||
error = 0;
|
||||
while (1) {
|
||||
rdsz = read(image_fd, buffer, BUFFER_SIZE);
|
||||
if (rdsz <= 0) {
|
||||
error = (rdsz < 0) ? errno : 0;
|
||||
break;
|
||||
}
|
||||
wrsz = (ofs == -1) ?
|
||||
write(fd, buffer, rdsz) :
|
||||
sparse_write(fd, buffer, rdsz);
|
||||
if (wrsz < 0) {
|
||||
error = errno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
image_set_size(lba_t blk)
|
||||
{
|
||||
|
||||
/* TODO */
|
||||
if (ftruncate(image_fd, blk * secsz) == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
image_write(lba_t blk __unused, void *buf __unused, ssize_t len __unused)
|
||||
image_write(lba_t blk, void *buf, ssize_t len)
|
||||
{
|
||||
|
||||
/* TODO */
|
||||
blk *= secsz;
|
||||
if (lseek(image_fd, blk, SEEK_SET) != blk)
|
||||
return (errno);
|
||||
len *= secsz;
|
||||
if (write(image_fd, buf, len) != len)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
image_init(void)
|
||||
{
|
||||
|
||||
if (atexit(cleanup) == -1)
|
||||
return (errno);
|
||||
image_fd = mkstemp(image_tmpfile);
|
||||
if (image_fd == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
2
image.h
2
image.h
@ -32,6 +32,8 @@
|
||||
typedef int64_t lba_t;
|
||||
|
||||
int image_copyin(lba_t blk, int fd, uint64_t *sizep);
|
||||
int image_copyout(int fd);
|
||||
int image_init(void);
|
||||
int image_set_size(lba_t blk);
|
||||
int image_write(lba_t blk, void *buf, ssize_t len);
|
||||
|
||||
|
111
mkimg.c
111
mkimg.c
@ -46,12 +46,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include "mkimg.h"
|
||||
#include "scheme.h"
|
||||
|
||||
#if !defined(SPARSE_WRITE)
|
||||
#define sparse_write write
|
||||
#endif
|
||||
|
||||
#define BUFFER_SIZE (1024*1024)
|
||||
|
||||
struct partlisthead partlist = STAILQ_HEAD_INITIALIZER(partlist);
|
||||
u_int nparts = 0;
|
||||
|
||||
@ -63,21 +57,6 @@ u_int nsecs = 1;
|
||||
u_int secsz = 512;
|
||||
u_int blksz = 0;
|
||||
|
||||
static int bcfd = -1;
|
||||
static int outfd = 0;
|
||||
static int tmpfd = -1;
|
||||
|
||||
static char tmpfname[] = "/tmp/mkimg-XXXXXX";
|
||||
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
|
||||
if (tmpfd != -1)
|
||||
close(tmpfd);
|
||||
unlink(tmpfname);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(const char *why)
|
||||
{
|
||||
@ -229,7 +208,7 @@ parse_part(const char *spec)
|
||||
}
|
||||
|
||||
#if defined(SPARSE_WRITE)
|
||||
static ssize_t
|
||||
ssize_t
|
||||
sparse_write(int fd, const char *buf, size_t sz)
|
||||
{
|
||||
const char *p;
|
||||
@ -269,56 +248,8 @@ sparse_write(int fd, const char *buf, size_t sz)
|
||||
}
|
||||
#endif /* SPARSE_WRITE */
|
||||
|
||||
static int
|
||||
fdcopy(int src, lba_t sblk, int dst, lba_t dblk, uint64_t *count)
|
||||
{
|
||||
char *buffer;
|
||||
off_t ofs;
|
||||
ssize_t rdsz, wrsz;
|
||||
|
||||
if (sblk != -1) {
|
||||
ofs = sblk * secsz;
|
||||
if (lseek(src, ofs, SEEK_SET) != ofs)
|
||||
return (errno);
|
||||
}
|
||||
|
||||
if (dblk != -1) {
|
||||
ofs = dblk * secsz;
|
||||
if (lseek(dst, ofs, SEEK_SET) != ofs)
|
||||
return (errno);
|
||||
} else
|
||||
ofs = lseek(dst, 0L, SEEK_CUR);
|
||||
|
||||
/*
|
||||
* We can't write a sparse file when ofs holds -1 at this point.
|
||||
*/
|
||||
|
||||
if (count != NULL)
|
||||
*count = 0;
|
||||
|
||||
buffer = malloc(BUFFER_SIZE);
|
||||
if (buffer == NULL)
|
||||
return (errno);
|
||||
while (1) {
|
||||
rdsz = read(src, buffer, BUFFER_SIZE);
|
||||
if (rdsz <= 0) {
|
||||
free(buffer);
|
||||
return ((rdsz < 0) ? errno : 0);
|
||||
}
|
||||
if (count != NULL)
|
||||
*count += rdsz;
|
||||
wrsz = (ofs == -1) ?
|
||||
write(dst, buffer, rdsz) :
|
||||
sparse_write(dst, buffer, rdsz);
|
||||
if (wrsz < 0)
|
||||
break;
|
||||
}
|
||||
free(buffer);
|
||||
return (errno);
|
||||
}
|
||||
|
||||
static void
|
||||
mkimg(int bfd)
|
||||
mkimg(void)
|
||||
{
|
||||
FILE *fp;
|
||||
struct part *part;
|
||||
@ -326,10 +257,6 @@ mkimg(int bfd)
|
||||
off_t bytesize;
|
||||
int error, fd;
|
||||
|
||||
error = scheme_bootcode(bfd);
|
||||
if (error)
|
||||
errc(EX_DATAERR, error, "boot code");
|
||||
|
||||
/* First check partition information */
|
||||
STAILQ_FOREACH(part, &partlist, link) {
|
||||
error = scheme_check_part(part);
|
||||
@ -386,8 +313,11 @@ mkimg(int bfd)
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int bcfd, outfd;
|
||||
int c, error;
|
||||
|
||||
bcfd = -1;
|
||||
outfd = 1; /* Write to stdout by default */
|
||||
while ((c = getopt(argc, argv, "b:o:p:s:vH:P:S:T:")) != -1) {
|
||||
switch (c) {
|
||||
case 'b': /* BOOT CODE */
|
||||
@ -398,7 +328,7 @@ main(int argc, char *argv[])
|
||||
err(EX_UNAVAILABLE, "%s", optarg);
|
||||
break;
|
||||
case 'o': /* OUTPUT FILE */
|
||||
if (outfd != 0)
|
||||
if (outfd != 1)
|
||||
usage("multiple output files given");
|
||||
outfd = open(optarg, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
|
||||
@ -471,15 +401,12 @@ main(int argc, char *argv[])
|
||||
errx(EX_DATAERR, "%d partitions supported; %d given",
|
||||
scheme_max_parts(), nparts);
|
||||
|
||||
if (outfd == 0) {
|
||||
if (atexit(cleanup) == -1)
|
||||
err(EX_OSERR, "cannot register cleanup function");
|
||||
outfd = 1;
|
||||
tmpfd = mkstemp(tmpfname);
|
||||
if (tmpfd == -1)
|
||||
err(EX_OSERR, "cannot create temporary file");
|
||||
} else
|
||||
tmpfd = outfd;
|
||||
if (bcfd != -1) {
|
||||
error = scheme_bootcode(bcfd);
|
||||
close(bcfd);
|
||||
if (error)
|
||||
errc(EX_DATAERR, error, "boot code");
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
fprintf(stderr, "Logical sector size: %u\n", secsz);
|
||||
@ -488,16 +415,18 @@ main(int argc, char *argv[])
|
||||
fprintf(stderr, "Number of heads: %u\n", nheads);
|
||||
}
|
||||
|
||||
mkimg(bcfd);
|
||||
error = image_init();
|
||||
if (error)
|
||||
errc(EX_OSERR, error, "cannot initialize");
|
||||
|
||||
mkimg();
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "Number of cylinders: %u\n", ncyls);
|
||||
|
||||
if (tmpfd != outfd) {
|
||||
error = fdcopy(tmpfd, 0, outfd, -1, NULL);
|
||||
if (error)
|
||||
errc(EX_IOERR, error, "writing to stdout");
|
||||
}
|
||||
error = image_copyout(outfd);
|
||||
if (error)
|
||||
errc(EX_IOERR, error, "writing image");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
6
mkimg.h
6
mkimg.h
@ -65,4 +65,10 @@ round_block(lba_t n)
|
||||
return ((n + b - 1) & ~(b - 1));
|
||||
}
|
||||
|
||||
#if !defined(SPARSE_WRITE)
|
||||
#define sparse_write write
|
||||
#else
|
||||
ssize_t sparse_write(int, const char *, size_t);
|
||||
#endif
|
||||
|
||||
#endif /* _MKIMG_MKIMG_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user