LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-28-2004, 08:10 PM   #1
akin81
LQ Newbie
 
Registered: Mar 2004
Posts: 13

Rep: Reputation: 0
Problem in copying a file in C


How to copy a regular file in C using open(), read() and write()?
It seems i have program creating the new file using open().
How can i make the permission to be the same with the old file?

I am a newbie in Linux programming
 
Old 03-28-2004, 08:52 PM   #2
zekko
Member
 
Registered: Aug 2003
Location: Canada
Distribution: Slackware, debian
Posts: 76

Rep: Reputation: 15
Let's see the code you already got.

I'm not sure how to copy the file with same permissions, I always have to chmod +x if its a executable, I would like to know this too.
 
Old 03-28-2004, 09:27 PM   #3
rkef
Member
 
Registered: Mar 2004
Location: bursa
Posts: 110

Rep: Reputation: 15
$ man 2 stat
Code:
struct stat {
        [...]
        mode_t        st_mode;     /* protection */
        [...]
};
 
Old 03-28-2004, 09:58 PM   #4
akin81
LQ Newbie
 
Registered: Mar 2004
Posts: 13

Original Poster
Rep: Reputation: 0
so far i have the following code in my function
working with just copying the content first
but i dont know why the new file is still empty after i run this
is there any problem in "write(dest_file,buffer,size);"?

Code:
void copy_file(char *source, char *dest)
{
  int source_file, dest_file;
  char buffer[128];
  struct stat buf;
  
  if ( lstat(source,&buf)==0 ) {
    if ( !(buf.st_mode & S_IFREG) )
      printf("%s: is not a regular file\n",source);  
  }
  else
    printf("%s: file does not exist\n",source);
    
  source_file = open(source, O_RDONLY);
  if ( source_file!=0 ) {
    printf("%s: error in opening file\n", source);
    return;
  }
 
  dest_file = open(dest, O_CREAT, S_IRWXU);
  if ( dest_file!=0 ) {
    printf("%s: error in creating file\n", dest);
    return;
  }
    
  int size;
  while( (size=read(source_file, buffer, 128)) > 0 ) {
      write(dest_file,buffer,size);
  }
  
  close(source_file);
  close(dest_file);
    
  return;
}

Last edited by akin81; 03-28-2004 at 10:10 PM.
 
Old 03-28-2004, 10:35 PM   #5
rkef
Member
 
Registered: Mar 2004
Location: bursa
Posts: 110

Rep: Reputation: 15
That's odd. open should return unique file descriptors; your tests of (fd != 0) should always succeed, unless your implementation defines stdin, stdout, stderr to something other than 0, 1, and 2.

You should be testing that they aren't -1 or, in general, < 0.
 
Old 03-28-2004, 10:42 PM   #6
zekko
Member
 
Registered: Aug 2003
Location: Canada
Distribution: Slackware, debian
Posts: 76

Rep: Reputation: 15
I havent test this, but maybe it'll work ...

Code:
void copy_file(char *source, char *dest) {
     int source_file, dest_file, read_size;
     char buffer[128];
     struct stat buf;

     if ( lstat(source,&buf)==0 ) {
        if ( !(buf.st_mode & S_IFREG) )
        printf("%s: is not a regular file\n",source);  
    }
    else
        printf("%s: file does not exist\n",source);
        return;
    }
    if ((source_file = open(source, O_RDONLY)) < 0) {
        fprintf(stderr, "%s: Can't open file\n", source);
        return;
    }
    if ((dest_file = open(dest, O_CREAT, S_IRWXU)) < 0) {
        fprintf(stderr, "%s: error creating file\n", dest);
        return;
    }
    while (1) {
        read_size = read(source_file, buffer, sizeof(buffer));
        if (read_size == 0)
           break;
        if (read_size < 0) {
           fputs("Error while reading file\n", stderr);
           return;
        }
        if (write(dest_file, buffer, read_size) < 0) {
           fputs("Error while writing to file\n", stderr);
           return;
       }
    }
    close(source_file);
    close(dest_file);
}

Last edited by zekko; 03-28-2004 at 10:44 PM.
 
Old 03-29-2004, 01:19 AM   #7
akin81
LQ Newbie
 
Registered: Mar 2004
Posts: 13

Original Poster
Rep: Reputation: 0
Thanks to both of you, for correcting my mistakes.

The problem now i got is "Error while writing to file".
I guess there is a problem in "dest_file = open(dest, O_CREAT, S_IRWXU)".
Is that ok to write into the file using O_CREAT?

I tried "close(dest_file);" and open it again by "dest_file = open(dest, O_WRONLY);".
Then i can write into it without writing error, but this way looks clumsy.

I read "man open" but i don't quite understand about O_CREAT.

If i create a file using "open(dest, O_CREAT, S_IRWXU)" but the file already exists, how can i overwrite it?
If i delete the existing file and create a new one with the same name, it looks clumsy again.

Last edited by akin81; 03-29-2004 at 02:38 AM.
 
Old 03-29-2004, 02:42 AM   #8
rkef
Member
 
Registered: Mar 2004
Location: bursa
Posts: 110

Rep: Reputation: 15
Quote:
If i create a file using "open(dest, O_CREAT, S_IRWXU)" but the file already exists, how can i overwrite it?
Quote:
O_TRUNC
If the file already exists and is a regular file and the open mode allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0.
Quote:
"Error while writing to file"
That looks like it's from your code. Try altering your error message to print the system error message, with something like: printf("Error while writing to file: %s\n", strerror(errno));

Last edited by rkef; 03-29-2004 at 02:45 AM.
 
Old 03-29-2004, 12:18 PM   #9
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 110Reputation: 110
Code:
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>

#define BUFFERSIZE 128

int copy_file(char *source, char *dest)
{
	 int source_file, dest_file;
	 char buffer[BUFFERSIZE];
	 struct stat fstatus;
	 mode_t permissions;
	 ssize_t bytesread;

	 /* Opening source file */
	 source_file = open(source, O_RDONLY);
	 if (source_file < 0) {
		  perror("Opening source file");
		  return 0;
	 }

	 /* Get permissions of source file */
	 if (fstat(source_file, &fstatus) < 0) {
		  perror("Getting permissions of source file");
		  return 0;
	 }
	 permissions = fstatus.st_mode;    /* store permissions */

	 /* 
	  * Opening destination file for writing.
	  * We will set the same permissions as the source file later,
	  * because the umask will be in effect here.
	  */
	 dest_file = open(dest, O_WRONLY|O_CREAT|O_TRUNC,  S_IRUSR|S_IWUSR);
	 if (source_file < 0) {
		  perror("Opening destination file");
		  return 0;
	 }

	 /* Do the copying */
	 do {
		  bytesread = read(source_file, buffer, BUFFERSIZE);
		  if (bytesread < 0) {
			   perror("Copying");
			   return 0;
		  }
		  write(dest_file, buffer, bytesread);
	 } while (bytesread > 0);

	 /* Set permissions as stored from the source file */
	 if (fchmod(dest_file, permissions) < 0) {
		  perror("Setting permissions");
		  return 0;
	 }
	 close(source_file);
	 close(dest_file);
	 return 1;   /* Succesfull! */	 
}


int main(int argc, char *argv[])
{
	 if (argc != 3) {
		  fprintf(stderr, "Usage: %s <source> <destination>\n", argv[0]);
		  return 1;
	 }
	 if (!copy_file(argv[1], argv[2])) {
		  return 2;
	 }
	 printf("done\n");
	 return 0;
}

Last edited by Hko; 03-29-2004 at 03:40 PM.
 
Old 04-01-2004, 07:15 AM   #10
worldmagic
Member
 
Registered: Oct 2003
Location: Europe/Sweden
Distribution: RedHat
Posts: 78

Rep: Reputation: 15
For you copying.. this function might be intresting..
Parts taken from its manpage..

--
#include <sys/sendfile.h>
--
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
--
Because this copying is done within the kernel, sendfile() does not
need to spend time transferring data to and from user space.
--
 
Old 04-02-2004, 01:31 AM   #11
akin81
LQ Newbie
 
Registered: Mar 2004
Posts: 13

Original Poster
Rep: Reputation: 0
Thank you everyone. That really helps.



Quote:
Originally posted by worldmagic
For you copying.. this function might be intresting..
Parts taken from its manpage..

--
#include <sys/sendfile.h>
--
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
--
Because this copying is done within the kernel, sendfile() does not
need to spend time transferring data to and from user space.
--
For my project it is not allowed to use function like this.
But thanks for telling, it may help in the future.
 
Old 04-06-2004, 09:06 AM   #12
worldmagic
Member
 
Registered: Oct 2003
Location: Europe/Sweden
Distribution: RedHat
Posts: 78

Rep: Reputation: 15
You can always say you found it 'grep'ing the kernel.. ;-)
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
File copying problem bubble SUSE / openSUSE 2 12-05-2004 11:12 PM
copying a file enrique_arong Linux - Newbie 5 07-29-2004 01:21 PM
Question on File System and File Copying hey_joe Linux - Newbie 2 11-05-2003 11:30 AM
Copying a file tgonetwork Linux - Newbie 3 01-16-2002 11:08 AM
Copying file problem! Lloyd Linux - Newbie 1 07-30-2001 10:08 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:15 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration