File creation problem

I am creating a file to store data, but the file does not get created at all.

#include <unistd.h>
#define DEFAULT_ID 0

int main()
{
    int d, n=0;
    int sz, data=0;
    char fn[256];
    char *bv;
    snprintf(fn, 256, "bv", DEFAULT_ID);
    bv=fn;
    printf("%s\n", bv);
    if ((d = open(bv, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) {
        printf("\n\nconfig_write::file error\n\n");
        return;
    }

    if ((n = write(d,(char*) data, sz)) != sz) {
        printf("\n\nconfig_write::  written successfully\n\n");
        close(d);
        unlink(fn);
        return;
    }
    printf("\n\nconfig_write:: (%d)\n\n", n);
    close(d);
}
output::
{245}: cc te.c
{246}: ./a.out
bv


config_write::  written successfully

{247}: 
{247}: ls -lrt | tail
-rwxrwxr-x   1 team   4232329 Dec  3 02:22 iswitchd.bv.n
-rw-r--r--   1 team     29471 Dec  3 20:44 config.txt
drwxrwxr-x   2 team      4096 Dec  4 01:14 ConfigSpecs.bak
drwxrwxr-x  28 team      4096 Dec  4 02:47 dist.config.up.dow
-rw-r--r--   1 team     29667 Dec  4 02:59 config.new
-rw-r--r--   1 team     29667 Dec  4 21:00 config2
-rw-r--r--   1 team     29667 Dec  4 22:59 config3
-rw-r--r--   1 team     33293 Dec  5 00:10 fc
-rw-rw-r--   1 team       603 Dec  9 22:04 te.c
-rwxrwxr-x   1 team      5480 Dec  9 22:05 a.out

the ls -lrt command also does not give the file create:confused:

There's quite a bit wrong with that program. Surely you received warnings about what you wrote.

You need to provide prototypes for the POSIX functions you're using, stdio.h for snprintf, ...

When you write to the file, you have two serious problems.

  1. sz is uninitialised.
  2. You're treating the content of data as a pointer to the data to be written to the file. As data is zero, the program should segfault, but it doesn't for some reason.

You should have:

sz = sizeof(data);
write(d, &data, sz);

Note that I have added some color to your C code above. Then note that the text in red shows that sz is allocated but not initialized. It is then used to specify how many bytes write() is supposed to transfer. And when the number of bytes to be transferred does not match the return code from write() we know that write failed. When write() fails you execute the printf() printing the green text saying that the data was written successfully (even though we know it was not written successfully). And, after write() fails you also unlink() the file (as shown in blue text). Since you removed the file, ls won't find it. And as has already been pointed out, if you want to write the contents of data, you need to use &data instead of (char *) data in the call to write().

Also note that the 3rd argument to write() has type size_t, not int and that the return value of write() is a ssize_t. So, sz should be declared to be a size_t instead of an int and the if statement should typecast sz to a ssize_t for the comparison to the return value from write(). After changing the declaration of sz, if you add the statement:

sz = sizeof(data);

before your call to write(), you'll probably have better luck.

Since you're calling snprintf() and printf() as shown in magenta, you should add:

#include <stdio.h>

as the 1st or 2nd line of your code. And, since your snprintf() statement's format string doesn't contain any conversion specifiers, the integer argument in orange after the format string is ignored and can be removed. And since this is the only place it is used, the #define that defines DEFAULT_ID can also be removed.

New program after alteration:
questions::
1) Is this way of writing integer to the file is correct?
if correct the why i am getting an empty file?
if wrong means how should i write an integer? because i am able to write and string easilt in to the file. the problem comes when the value is an integer.

#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#define DEFAULT_ID 0

int main()
{
    int data, d;
    size_t sz;
    data=0;
    if ((d = open("bv", O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) {
        printf("\n\nconfig_write::file error\n\n");
        return;
    }
    printf("sizeof(sz)%d-sizeof(data)%d\n",sizeof(sz), sizeof(data));
    if (write(d, &data, sz)) {
        printf("\n\nconfig_write::  written successfully\n\n");
        close(d);
        return;
    }
    printf("\nexiting...");
    close(d);
}
sample output:
{319}: vi te.c
{320}: cc te.c
{321}: ./a.out
sizeof(sz)4-sizeof(data)4


config_write::  written successfully

{322}: cat bv
{323}

No! You can't use an uninitialized value to specify the number of bytes to write. You shouldn't use functions without providing their function prototypes. You shouldn't use cat to write binary data to a terminal.

The problem is not that you're writing an integer; the problem is that you're telling it to write a random number of bytes because you never set the value of sz AND if data has been written to the file, you're expecting null bytes written to a terminal to be visible.

  1. Add
    text #include <stdio.h>
    as a new line at the start of te.c.
  2. Change:
    text if (write(d, &data, sz)) {
    to:
    text sz = sizeof(data); if (write(d, &data, sz) == (ssize_t)sz) {
  3. Delete the lines:
    text close(d); return;
  4. Change:
    text printf("\nexiting...");
    to:
    text printf("exiting...\n");
  5. If it completes successfully, use:
    text ls -l bv od -t cdI bv
    instead of:
    text cat bv
    to display the contents of the file.
1 Like