C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 07-24-2007, 03:43 AM   #1
Linux is where it's at
 
movl0x1's Avatar
 
Join Date: May 2007
Posts: 72
help with stat() and fopen()

Code:
/* a very simple copy command for unix */
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{
         struct stat flinfo;                   /* structure holding file info read by stat() */

         if (argc != 3) 
                display_usage(1);
         

         /* we're doing a copy, so we want to see the permissions of file a */
         errno = 0;
         if ( (stat(argv[1],  flinfo)) == -1) {
              fprintf(stderr, "copy: %s: %s\n", argv[1], strerror(errno));
              exit(1);
         }

         /* open argv[1] for reading */
         fd = open(argv[1], O_RDONLY);

        /* now open argv[2] with same permissions as argv[1], so that the resulting
            copied file has same permissions    */
        errno = 0;
        if ( (fd2 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, flinfo.st_mode)) == -1)
              fprintf(stderr, "copy: %s: %s\n", argv[2], strerro(errno));
              exit(1);
        }


        /* then here I'd do the actual copy with read() and write() */

}

I'm doing the above with low level (OS specific) functions and wish to do them with
fopen, fgetc, etc. My problem is with using the 'mode' argument with fopen() so that the
resulting file will be of the same permissions (executable, etc). The above worked fine
using the above code (plus the rest, not shown) to make a simple 'copy' command. You can
pass the st_mode of the first file you open read with stat(), to open(). Can I do the same
with the fopen() function? I tried fopen() and then did a stat(), and then used umask() to
set the mode of the 2nd file I wanted to create with fopen() for the copy, but it didn't
seem to work. Can anyone give some suggestions?

thanks
__________________
Remember that all that code you write turns into this:

0100100100110010010011100100111001001
0010100100100001001111100010010010010 ....
movl0x1 is offline   Reply With Quote
Old 07-24-2007, 04:09 AM   #2
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,647
There is no standard way to set the permissions on a file.
So you can use fopen() etc to copy the file, but you still need to "stat" to find its real permissions.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Old 07-24-2007, 04:30 AM   #3
Linux is where it's at
 
movl0x1's Avatar
 
Join Date: May 2007
Posts: 72
Thanks, but how do I pass the st_mode (permissions) read by stat() to fopen?

with open I do:
Code:
    open(filename, O_WRONLY | O_CREAT | O_TRUNC, fl.st_mode);
That creates a new file with the same permissions as the first file that I stat()'d
such as for a copy.

But how do I pass the st_mode element of struct stat fl (first file's info) to fopen()?
Doesn't fopen() only take fopen(filename, "w") ?

Thanks
__________________
Remember that all that code you write turns into this:

0100100100110010010011100100111001001
0010100100100001001111100010010010010 ....
movl0x1 is offline   Reply With Quote
Old 07-24-2007, 05:13 AM   #4
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,647
You have to do a chmod() after the file has been created.

Or if you want to make sure that the file has the right permissions thoughout, create it with the right permissions, then fopen() it later using one of the "update" modes.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Old 07-24-2007, 09:42 AM   #5
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,754
Quote:
Originally Posted by movl0x1 View Post
Thanks, but how do I pass the st_mode (permissions) read by stat() to fopen?
You can't directly. First, open the file with open() and then turn it into a FILE object with fdopen:

Code:
FILE *fp;
int fd;

umask(0); /* See below */
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, fl.st_mode);
if(fd < 0)
{
    /* Error */
}
else
{
    fp = fdopen(fd, "wb");
}
There is a problem here, though. The st_mode you pass to open() will be combined with the current umask to form the real permissions. For a copy program, you do NOT want this -- you want the permissions to be exactly as passed. So, you need to clear the umask before calling open() -- as highlighted in blue in the code.

The change to the umask only affects your program, not the shell or any other process.
brewbuck is offline   Reply With Quote
Old 07-25-2007, 05:08 AM   #6
Linux is where it's at
 
movl0x1's Avatar
 
Join Date: May 2007
Posts: 72
Thanks guys. But what I did was do a stat() on the first file (the one I want to copy) to
get its permissions (st_mode). Then I did an fopen() on the 2nd file (the one I want to create
and copy file a to) and used chmod() on the 2nd file I just created and it works every time.

Code:
      struct stat fl;

      /* open first file (1 I want to copy) */
      in = fopen(argv[1], "r");

      /* get the first file's info into fl */
      stat(argv[1], &fl);

     /* open the file we want to create and copy to */
      out = fopen(argv[2], "w");

     /* Now we want to set our new file to the same
         permissions as argv[1]  */
     chmod(argv[2], fl.st_mode);
The above of course excludes all error checks, etc. which I have
in the real program.


So I basically just open the 2nd file with fopen() and copy the mode of the first
open file with chmod() to the new file.

thanks
__________________
Remember that all that code you write turns into this:

0100100100110010010011100100111001001
0010100100100001001111100010010010010 ....

Last edited by movl0x1; 07-25-2007 at 05:15 AM.
movl0x1 is offline   Reply With Quote
Old 07-25-2007, 05:28 AM   #7
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,647
> fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, fl.st_mode);
Will this allow you to copy a file which is read-only?
IE, will the file you're trying to create be read-only at the point you create it?
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump


All times are GMT -6. The time now is 10:33 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22