I am trying to implement the caesar cipher with mmap. I think the cipher works so fine but the problem is, the mmap. The idea of it is to update the file, if there was a change. So far it isn't working. I can just read the memory mapped file and print it. But if I make any modificaiton, I get a segmentation fault. Unfortunately, I couldn't solve the problem myself. So, I would appreciate it, if you could help me with it.
Here is the code.
int main (int argc, char *argv[]) {
if(argc != 5)
fprintf(stdeer, "usage: ./cipher (encrypt|decrypt) <file name> (casar| vigenere) <key>\n");
// (encrypt / decrypt) can be found in argv[1]
// filename in argv[2]
// encryption method in argv[3]
// key in argv[4]
int fd = open(argv[2], O_RDWR, S_IWRITE | S_IREAD);
if (fd < 0)
hanle_error("open");
off_t len = lseek(fd, 0, SEEK_END);
if (len == (off_t)-1)
handle_error("lseek");
unsigned char* data = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // Add PROT_WRITE
if (data == MAP_FAILED)
handle_error("mmap");
char c = *argv[4];
int key = 0;
if(strcmp(argv[3], "caesar") == 0) {
key = c - 48;
if(strcmp(argv[1], "decrpyt") == 0)
key = -key;
int num = 0;
for(int size_t i = 0; i < (size_t)len; i++) {
if(data[i] >= 97 && data[i] <= 122) {
num = data[i];
num +=key;
if(num > 'z') {
num -= 26;
data[i] = num + '0';
} else if (num < 'a') {
num += 26;
data[i] = num + '0';
} else {
data[i] = num + '0';
}
} else {
continue;
}
}
}
return 0;
}
A possible input can be anything e.g.
SsWd asdas
qwmkfd aw.
The algorithm above should just modify the lower case letters and leave the rest as it is.
I hope someone might be able to help me.
Also, I only implemented the caesar cipher.
EDIT: The seg fault is gone after I added PROT_WRITE. But know I get weird question marks for the modified lower case letters. Does anyone know why?
If you want to write to the file too, then
should be
That may not be the only issue, but would explain the seg fault.
The reason is self explanatory!