-1

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

1 Answers1

0

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.

Chris Turner
  • 8,082
  • 1
  • 14
  • 18
  • thank you for your suggestios. but why multiply n by 8? I get that the second parameter has to be octal, but for example if we take rwxrwxrwx n=511, and shouldn't the second parameter be 0777? I tested this example with the n multiplied by 8 and for owner and group it sets the right permissions (read and write), but for others it appears read-only, when it should also be read and write? – Alexandra_p Dec 14 '17 at 23:53
  • @Alexandra_p if `n` is 511 (decimal) then that is the same as 0777 which is octal. If you multiple by 10, you'd get 777 which is 1411 in octal. – Chris Turner Dec 15 '17 at 10:09
  • The reason why it's not working as you'd expect is because the mode is being affected by your umask - you'd still need to do a `chmod` to get the actual permissions you want. – Chris Turner Dec 15 '17 at 10:12