Wednesday, April 27, 2022

[SOLVED] create file with given name and permissions in linux using c

Issue

I have to write a function in c create with 2 parameters: file name and permissions for the file. (e.g: create("f","rwxr_xr_x") this function creates file f which will receive "rwxr_xr_x" permissions and will return 0)If the file already exists or it can not be created it will return a number different from 0. Here is the code that I came up with:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

int create(char *name, char *mode)
{
    int fp = fopen(name, "r+");
    if (fp > 0)
    {
        int i, n = 0;
        for (i = 0; i < 9; i = i + 3)
        {
            int nr = 0;
            if (mode[i] == 'r')     nr += 4;
            if (mode[i + 1] == 'w') nr += 2;
            if (mode[i + 2] == 'x') nr += 1;
            n = n * 10 + nr;
        }
        chmod(name, n);
        return 0;
    }
    else
        return -1;
}

int main(int argc, char* argv[])
{
    if (argc != 3) printf("%s\n", "Error: Incomplet number of arguments!");
    int fp;
    fp = create(argv[1], argv[2]);
    if (fp == 0) printf("%s\n", "File successfully created!");
    else printf("%s\n", "Could not create file!");
    return 0;
}

I tried to open the file in r+ mode and then I used chmod to change permissions, {not sure if this is correct). When I compile this, I get the following warning: "initialization makes integer from pointer without a cast for the line int fp=fopen(name, r+) . Can someone please help me solve this and tell me if the code is correct? I am new to linux

UPDATE so I made some changes, as suggested but I think it still does not give the right permissions (as I said I am new to linux, so I might be wrong). Here is how my code looks now:

 #include <stdio.h>
 #include <stdlib.h>
 #include <stdio.h> 
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <fcntl.h>
 int create(char *name, char *mode)
 {
  int i,n=0;
  for(i=0; i<9; i=i+3)
   {
      int nr=0;
      if(mode[i]=='r')   nr+=4;
      if(mode[i+1]=='w') nr+=2;
      if(mode[i+2]=='x') nr+=1;
      n=n*8+nr;
   }   
  int fl=creat(name, n);
  printf("%d\n", n); 
   if(fl>0)
       return 0;
   else return -1;
}

int main(int argc, char* argv[])
{
   if(argc != 3)
      printf("%s\n", "Error: Incomplet number of arguments!");

   int fp;
   fp=create(argv[1], argv[2]);
   if(fp==0) printf("%s\n", "File successfully created!");
   else printf("%s\n", "Could not create file!");
   return 0;
}

Also, how can I check if the file already exists? Because in that case my function has to return a value different from 0 and print an error message


Solution

Firstly your problem with this line:

int fp=fopen(name, "r+");

fopen returns a value of type FILE * not int so that line should be

FILE *fp=fopen(name, "r+");

And that means you need to test if fp is not NULL not > 0.

Having created the file, you should also remember to call fclose(fp) to close the file as well.

Your code handling the permissions is also wrong. The values you normally pass to the chmod command in the shell are octal, not decimal, so this line is wrong.

n=n*10+nr;

You want to multiple n by 8 each time.

Since it's a bit field you could improve the code by using the '|=' operator to change the appropriate bits rather than using addition.

if(mode[i]=='r')   nr |=4;
if(mode[i+1]=='w') nr |=2;
if(mode[i+2]=='x') nr |=1;

Also you should really check to make sure that mode is at least 9 characters long before the loop.



Answered By - Chris Turner
Answer Checked By - Cary Denson (WPSolving Admin)