Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Permission denied" in open() function in C

Tags:

c

file-access

I am new to C programming. I am having problem writing to a file using the open() function in C, here is my code for clarity

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

void usage(char *prog_name, char *filename){
    printf("Usage: %s <data to add to %s> \n",prog_name, filename);
    exit(0);
}

void fatal(char *);                          
void *errchck_malloc(unsigned int);     

int main(int argc, char *argv[]){
    int fd; // File descriptor
    char *buffer, *datafile;

    buffer = (char *) errchck_malloc(100);
    datafile = (char *) errchck_malloc(20);
    strcpy(datafile, "./simplenote.txt");

    if (argc < 2)
        usage(argv[0], datafile);

    strcpy(buffer, argv[1]);

    printf("[DEBUG] buffer @ %p: \'%s\'\n", buffer, buffer);
    printf("[DEBUG] datafile @ %p: \'%s\'\n", datafile, datafile);

    strncat(buffer, "\n", 1);

    // Open file 
    fd = open(datafile, O_CREAT|O_RDWR,O_APPEND, S_IRUSR, S_IWUSR);
    if(fd == -1)
        fatal("in main() while opening file");
    printf("[DEBUG] file descriptor is %d\n", fd);

    // Writing data to file
    if(write(fd, buffer, strlen(buffer))==-1)
        fatal("in main() while writing buffer to file");

    // Closing file
    if(close(fd) == -1)
        fatal("in main() while closing file");

    printf("Note saved\n");
    free(buffer);
    free(datafile);
}

// fatal(): Function to display error message then exit
void fatal(char *message){
    char err_msg[100];

    strcpy(err_msg, "[!!] Fatal Error ");
    strncat(err_msg, message, 83);
    perror(err_msg);
    exit(-1);
}

// errchck_malloc(): An error check malloc wrapper function
void *errchck_malloc(unsigned int size){
    void *ptr;
    ptr = malloc(size);
    if(ptr == NULL)
        fatal("in errchck_malloc() on memory allocation");
    return ptr;
}

When I execute the program on the first try, the program runs as expected.

first run:

user: ./simplenote "Hello, again"
[DEBUG] buffer @ 0x7fafcb4017a0: 'Hello again'
[DEBUG] datafile @ 0x7fafcb401810: './simplenote.txt'
[DEBUG] file descriptor is 3
Note saved

when I try to open the file and view the text, I get a permission denied error. when I try to open the file with sudo, it opens and the text is in the file. When I run the program a second time, I get an error while opening the file because of permission issues.

second run:

user: ./simplenote "just checking if it is still working"                                                           
[DEBUG] buffer @ 0x7face4c017a0: 'just checking if it is still working'
[DEBUG] datafile @ 0x7face4c01810: './simplenote.txt'
[!!] Fatal Error in main() while opening file: Permission denied

How do I fix the permission issues with the file creation?

like image 815
Tijani Avatar asked Jan 27 '26 01:01

Tijani


2 Answers

File created when program run for first time has permissions that does not allows you to append

stat simplenote.txt 
  File: simplenote.txt
  Size: 5           Blocks: 8          IO Block: 4096   regular file
Device: 2fh/47d Inode: 32810078    Links: 1
Access: (2000/------S---)  Uid: ( 1000/ user)   Gid: ( 1000/ user)
Access: 2020-01-05 19:29:34.317872734 +0100
Modify: 2020-01-05 19:29:34.317872734 +0100
Change: 2020-01-05 19:29:34.317872734 +0100

You should combine mode using | like this:

fd = open(datafile, O_CREAT|O_RDWR|O_APPEND, S_IRUSR | S_IWUSR);

You can check what arguments you should pass to open using man open, on my system it show something like this (trimmed to important parts):

   int open(const char *pathname, int flags);
   int open(const char *pathname, int flags, mode_t mode);

   int creat(const char *pathname, mode_t mode);

   int openat(int dirfd, const char *pathname, int flags);
   int openat(int dirfd, const char *pathname, int flags, mode_t mode);
like image 194
rkosegi Avatar answered Jan 29 '26 18:01

rkosegi


The arguments of open() are not correct. The documentation of open() says:

int open(const char *pathname, int flags, mode_t mode);

O_APPEND is a flag, it should be OR-ed with the other two to produce the flags argument.

S_IRUSR and S_IWUSR are permissions. They should be OR-ed to produce the mode argument.

All in all, the call to open() should be:

fd = open(datafile, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR);
like image 32
axiac Avatar answered Jan 29 '26 17:01

axiac



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!