/* opensize.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

static void usage (void)
{
  puts ("Usage: opensize [-t] <file> <initial_size> <actual_size>");
  exit (1);
}


static long get_size (const char *s)
{
  char *e;
  long n;

  errno = 0;
  n = strtol (s, &e, 0);
  if (n < 0 || errno != 0 || e == s || *e != 0)
    usage ();
  return n;
}


int main (int argc, char *argv[])
{
  const char *fname;
  long isize, asize;
  int i, fd, n, nwritten, trunc;
  static char buf[512];

  i = 1; trunc = 0;
  if (i < argc && strcmp (argv[i], "-t") == 0)
    trunc = 1, ++i;

  if (argc - i != 3)
    usage ();
  fname = argv[i+0];
  isize = get_size (argv[i+1]);
  asize = get_size (argv[i+2]);

  fd = open (fname, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY | O_SIZE,
             S_IREAD | S_IWRITE, (unsigned long)isize);
  if (fd == -1)
    {
      perror (fname);
      exit (2);
    }

  memset (buf, 0x55, sizeof (buf));
  while (asize != 0)
    {
      n = ((size_t)asize < sizeof (buf) ? (int)asize : (int)sizeof (buf));
      nwritten = write (fd, buf, n);
      if (nwritten == -1)
        {
          perror (fname);
          exit (2);
        }
      if (nwritten != n)
        abort ();
      asize -= nwritten;
    }

  if (trunc && ftruncate (fd, tell (fd)) != 0)
    {
      perror ("ftruncate()");
      exit (2);
    }
  if (close (fd) != 0)
    {
      perror ("close()");
      exit (2);
    }

  return 0;
}
