I've written a simple C program.
It takes four command line parameters: file name, start position, length and byte value; opens the specified file for writing and, starting at the specified position, fills a segment of the specified length in the file with the specified byte value.
It writes in blocks (the block size is 4 bytes now for debugging purposes).
/* fill_file_w_byte_val.c */
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int block_size = 4;
void error_handling(int res, const char *file_name)
{
if (res == -1) {
perror(file_name);
exit(1);
}
}
void write_n_blocks_of_bytes_to_file(
const char *file_name, int fd, void *mem,
int block_size, int num_of_blocks, int byte_val
)
{
int i, res;
mem = malloc(sizeof(char) * block_size);
memset(mem, byte_val, block_size);
for (i=num_of_blocks; i > 0; i--) {
res = write(fd, mem, block_size);
error_handling(res, file_name);
}
free(mem);
}
int main(int argc, char **argv)
{
char *file_name, *mem = NULL;
int len, byte_val, num_of_blocks, fd, res, reminder;
long start_pos;
if (argc != 5) {
printf("Wrong number of arguments: %d. It must be %d", argc-1, 4);
return 1;
}
file_name = argv[1];
fd = open(file_name, O_WRONLY);
error_handling(fd, file_name);
start_pos = atoi(argv[2]);
res = lseek(fd, start_pos, SEEK_SET);
error_handling(res, file_name);
len = atoi(argv[3]);
byte_val = atoi(argv[4]);
if ((byte_val < 0) || (byte_val > 255)) {
printf("Wrong value of byte: %d. It must be from 0 to 255.", byte_val);
return 1;
}
num_of_blocks = len / block_size;
if (num_of_blocks > 0)
write_n_blocks_of_bytes_to_file(
file_name, fd, mem, block_size, num_of_blocks, byte_val
);
reminder = len % block_size;
if (reminder != 0)
write_n_blocks_of_bytes_to_file(
file_name, fd, mem, reminder, 1, byte_val
);
res = close(fd);
error_handling(res, file_name);
return 0;
}
Here is the working session:
fedor@fedor-Latitude-E7250:~/c$ hexdump test.bin
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
000001c
fedor@fedor-Latitude-E7250:~/c$ ./fill_file_w_byte_val test.bin 1 2 255
fedor@fedor-Latitude-E7250:~/c$ hexdump test.bin
0000000 ff00 00ff 0000 0000 0000 0000 0000 0000
0000010 0000 0000 0000 0000 0000 0000
000001c
Why does my program write the 0th and 3rd bytes instead of the 1st and 2nd?
As requested, my comments in the form of an answer. Those are the 1st and 2nd positions (on a linux intel PC. And, roughly, on almost all modern machines).
hexdump
default behavior is to show unsigned short int
s values, in hex. Your file contains (as you wanted) 0 255 255 0 0 0....
The first unsigned short int
in that file is therefore the one made of bytes 0
and 255
. That is, in little endian 65280
aka 0xff00
. The second unsigned short
in the file is the one made of 255
and 0
, that is, in little endian 255
aka 0x00ff
.
Which is exactly what hexdump
shows.
Try hexdump -C test.bin