unixsystems-programming

Trouble with creating an empty file using C programming language in UNIX environment


I have recently started programming in UNIX environment. I need to write a program which creates an empty file with name and size given in the terminal using this commands

gcc foo.c -o foo.o 
./foo.o result.txt 1000

Here result.txt means the name of the newly created file, and 1000 means the size of the file in bytes.

I know for sure that lseek function moves the file offset, but the trouble is that whenever I run the program it creates a file with a given name, however the size of the file is 0.

Here is the code of my small program.

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
int main(int  argc, char **argv)
{
    int fd;
    char *file_name;
    off_t bytes;
    mode_t mode;

    if (argc < 3)
    {
        perror("There is not enough command-line arguments.");
        //return 1;
    }

    file_name = argv[1];
    bytes = atoi(argv[2]);
    mode = S_IWUSR | S_IWGRP | S_IWOTH;

    if ((fd = creat(file_name, mode)) < 0)
    {
        perror("File creation error.");
        //return 1;
    }
    if (lseek(fd, bytes, SEEK_SET) == -1)
    {
        perror("Lseek function error.");
        //return 1;
    }
    close(fd);
    return 0;
}

Solution

  • If you aren't allowed to use any other functions to assist in creating a "blank" text file, why not change your file mode on creat() then loop-and-write:

    int fd = creat(file_name, 0666);
    
    for (int i=0; i < bytes; i++) {
        int wbytes = write(fd, " ", 1);
        if (wbytes < 0) {
            perror("write error")
            return 1;
        }
    }
    

    You'll want to have some additional checks here but, that would be the general idea.

    I don't know whats acceptable in your situation but, possibly adding just the write() call after lseek() even:

    // XXX edit to include write
    if ((fd = creat(file_name, 0666)) < 0) {
        perror("File creation error");
        //return 1;
    }
    
    // XXX seek to bytes - 1
    if (lseek(fd, bytes - 1, SEEK_SET) == -1) {
        perror("lseek() error");
        //return 1;
    }
    
    // add this call to write a single byte @ position set by lseek
    if (write(fd, " ", 1) == -1) {
        perror("write() error");
        //return 1;
    }
    
    close(fd);
    return 0;