when I input "./test test.c /home/user1/Desktop/" it doesnt work anything.
I want to make copy file from (now_path) to (other_path).
But, I dont know why it does not work I think it is perfect code. Is it has error or need some more other codes??
char ch;
int src, dst;
if( argc != 3 )
{
printf("argument error\n");
printf("usage: ./a.out src dest\n");
}
src = open( argv[1], O_RDONLY );
dst = open( argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644 );
while( read( src, &ch, 1 ))
write( dst, &ch, 1 );
close( src );
close( dst );
return 0;
It's impossible to figure out unless you start to check return values. The open function returns a negative value on failure, and errno is set to indicate what went wrong.
Same goes for read and write. They returns the number of bytes read/written and a negative value on failure. errno is also set by these functions.
You could use constructs like this:
if ((src = open( argv[1], O_RDONLY )) < 0) {
fprintf(stderr, "Error accessing source file.\n");
fprintf(stderr, "errno: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
Your code is ok but you might want to ensure that the source file is readable before trying to copy it's content. Also you may want to terminate the program if an error occurs.
char ch;
int src, dst;
if( argc != 3 )
{
printf("argument error\n");
printf("usage: ./a.out src dest\n");
exit(1); // Terminate the program
}
if ((src = open( argv[1], O_RDONLY )) == -1)
{
printf("Error accessing source file.\n");
exit(1);
}
if (dst = open( argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644 )) == -1)
{
printf("Error accessing destination file.\n");
exit(1);
}
while( read( src, &ch, 1 ) > 0 )
write( dst, &ch, 1 );
close( src );
close( dst );
return 0;
Also, if the second argument will always be a directory, you'll need to set the open command for the destination file to the combination of the second and first arguments (argv[2] joined with argv[1]).
For this you can use the strcat function which copies the content of the second string into the first. Start by adding #include <string.h> to the header of your program:
char* buffer[BUF_SIZE];
int src, dst;
int bytesRead;
char dstFile[1024];
if (argc != 3)
{
printf("argument error\n");
printf("usage: ./a.out src dest\n");
}
if ((src = open(argv[1], O_RDONLY)) == -1)
{
printf("Error accessing source file.\n");
exit(1);
}
strcat(dstFile, argv[2]);
strcat(dstFile, argv[1]);
if ((dst = open(dstFile, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1)
{
printf("Error accessing destination file. %s\n", dstFile);
exit(1);
}
while ((bytesRead = read(src, buffer, BUF_SIZE)) > 0)
{
write(dst, buffer, bytesRead);
}
close(src);
close(dst);
return 0;
Related
I'm using mmap to read from a file.
The mmap returns errno 22, invalid argument.
The stat.st_size in this case is 400 which I don't think it is "too large".
I don't think I'm encountering "we dont like addr, length or offset".
I'm running this program on Intel Xeon E5(which I dont think its relevant).
What am I missing here?
if( argc > 1 ) {
struct stat stat;
for( int i = 1; i < argc; i++ ) {
if( access(argv[i], R_OK) == -1 ) {
printf("\n Cannot access datatype description file %s\n", argv[i]);
continue;
}
int fd = open(argv[i], O_RDONLY);
if( fd == -1 ) {
printf("\n Cannot open datatype description from file %s\n", argv[i]);
continue;
}
if( fstat(fd, &stat) == -1 ) {
printf("\n Cannot stat the %s file\n", argv[i]);
continue;
}
void* addr = mmap(NULL, stat.st_size, PROT_READ, MAP_FILE, fd, 0);
if( MAP_FAILED == addr ) {
printf("\nCannot map the datatype description file %s\n", argv[i]);
printf("%s %d stat.st_size %d\n", strerror(errno), errno, stat.st_size );
perror("mmap");
close(fd);
continue;
}
munmap(addr, stat.st_size);
free(addr);
close(fd);
}
}
From man 2 mmap:
MAP_FILE
Compatibility flag. Ignored.
...
EINVAL flags contained neither MAP_PRIVATE or MAP_SHARED, or contained
both of these values.
You need to pass one of MAP_PRIVATE or MAP_SHARED, and you should stop passing MAP_FILE. (What did you even think it did?)
I've been trying to do c programming implementation of cp command in unix/linux by using system calls (read(), write(), open(), close()).
But when I run my program through terminal by copying my source code of this program to the same directory with name change (the source code is about 300 lines)
and when I open that output file , it has more character than the original file.
The extra line is the same as 200ish line. Where does it came from?
here's the screenshot when compile
argp.c
123.c
This is the source code near the end of the original file(argp.c). You will see how I use the read write method.
while (count - ind > 1) {
strcpy(cdir, argv[argc-1]);
if (!isFile(cdir)) {
strcat(cdir, basename(arguments.argv[ind]));
}
if (arguments.update) {
stat(cdir,&stDest);
stat(arguments.argv[ind],&stSrc);
if (difftime(stDest.st_mtim.tv_sec, stSrc.st_mtim.tv_sec) > 0 ) {
printf("Destination file is newer\n");
exit(EXIT_FAILURE);
}
}
//open source file
src = open(arguments.argv[ind],O_RDONLY);
//if source file can't be opened
if (src == -1) {
printf("\nError opening file %s errno = %d\n",arguments.argv[ind],errno);
exit(EXIT_FAILURE);
}
//open target file
if (arguments.force) {
//with -f option(default)
tgt = open(cdir, O_WRONLY | O_CREAT | O_TRUNC , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
} else {
//with -n option
tgt = open(cdir, O_WRONLY | O_CREAT | O_EXCL , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
}
//if the target file cannot be read or already exist(with -n option)
if (tgt == -1) {
printf("File exist or it's not a file.\nCan't copy.\n");
exit(EXIT_FAILURE);
}
//read source file
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, BUFFERSIZE) != pos) {
exit(EXIT_FAILURE);
}
}
//if the source file cannot be read
if (pos == -1) {
printf("\nError in reading data from %s\n",arguments.argv[ind]);
}
//close source file
if (close(src) == -1) {
printf("\nError in closing file %s\n",arguments.argv[ind]);
}
//close target file
if (close(tgt) == -1) {
printf("\nError in closing file %s\n",cdir);
}
ind++;
}
if (arguments.verbose) {
printf("Copy successfully!\n");
}
exit(EXIT_SUCCESS);
}
This is the source code near the end of the copy file(123.c)
while (count - ind > 1) {
strcpy(cdir, argv[argc-1]);
if (!isFile(cdir)) {
strcat(cdir, basename(arguments.argv[ind]));
}
if (arguments.update) {
stat(cdir,&stDest);
stat(arguments.argv[ind],&stSrc);
if (difftime(stDest.st_mtim.tv_sec, stSrc.st_mtim.tv_sec) > 0 ) {
printf("Destination file is newer\n");
exit(EXIT_FAILURE);
}
}
//open source file
src = open(arguments.argv[ind],O_RDONLY);
//if source file can't be opened
if (src == -1) {
printf("\nError opening file %s errno = %d\n",arguments.argv[ind],errno);
exit(EXIT_FAILURE);
}
//open target file
if (arguments.force) {
//with -f option(default)
tgt = open(cdir, O_WRONLY | O_CREAT | O_TRUNC , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
} else {
//with -n option
tgt = open(cdir, O_WRONLY | O_CREAT | O_EXCL , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
}
//if the target file cannot be read or already exist(with -n option)
if (tgt == -1) {
printf("File exist or it's not a file.\nCan't copy.\n");
exit(EXIT_FAILURE);
}
//read source file
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, BUFFERSIZE) != pos) {
exit(EXIT_FAILURE);
}
}
//if the source file cannot be read
if (pos == -1) {
printf("\nError in reading data from %s\n",arguments.argv[ind]);
}
//close source file
if (close(src) == -1) {
printf("\nError in closing file %s\n",arguments.argv[ind]);
}
//close target file
if (close(tgt) == -1) {
printf("\nError in closing file %s\n",cdir);
}
ind++;
}
if (arguments.verbose) {
printf("Copy successfully!\n");
}
exit(EXIT_SUCCESS);
}
it(EXIT_FAILURE);
}
//read source file
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, BUFFERSIZE) != pos) {
exit(EXIT_FAILURE);
}
}
//if the source file cannot be read
if (pos == -1) {
printf("\nError in reading data from %s\n",arguments.argv[ind]);
}
//close source file
if (close(src) == -1) {
printf("\nError in closing file %s\n",arguments.argv[ind]);
}
//close target file
if (close(tgt) == -1) {
printf("\nError in closing file %s\n",cdir);
}
ind++;
}
if (arguments.verbose) {
printf("Copy successfully!\n");
}
exit(EXIT_SUCCESS);
}
You always try to read/write BUFFERSIZE bytes. But what happens if the file you want to copy has a size multiple of BUFFERSIZE? You write what have been read last time.
read return the number of bytes read, so each write should try to write this number of bytes:
Instead of:
pos = read(src, buffer, BUFFERSIZE);
//write target file
while (pos > 0) {
write(tgt, buffer, BUFFERSIZE);
pos = read(src, buffer, BUFFERSIZE);
}
Use:
pos = read(src, buffer, BUFFERSIZE);
//write target file
while (pos > 0) {
write(tgt, buffer, pos);
pos = read(src, buffer, BUFFERSIZE);
}
Same here, instead of:
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, BUFFERSIZE) != pos) {
exit(EXIT_FAILURE);
}
}
Use:
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, pos) != pos) {
exit(EXIT_FAILURE);
}
}
You unconditionally write a full buffer, regardless of how much was read:
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, BUFFERSIZE) != pos) {
exit(EXIT_FAILURE);
}
}
should be:
//write target file
while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
if (write(tgt, buffer, pos) != pos) {
exit(EXIT_FAILURE);
}
}
how would you be able to check if the files have the same/different i-node numbers in C?
Because I want the rightly get the source and destination file information, where the files need to be rightly tested if they are the same.
Code:
#define BUFFER 100 // ** increased - file path can get pretty long
#define buffersize 4096
#define copymode 0644
void error(char *, char *);
int file_exist(char *filename)
{
struct stat buffer;
return (stat (filename, &buffer) == 0);
}
int main()
{
int ac;
char *avc[4096];
int in_fd, out_fd, chars_n;
char buf[BUFFERSIZE];
char ch, sourceFile[20], targetFile[20];
FILE *source, *target;
printf("Enter name of file to copy\n");
fgets(source_file, 20, stdin);
source = fopen(sourceFile, "r");
*avc = sourceFile;
if( source == NULL )
{
printf("Press any key to exit...\n");
exit(1);
}
printf("Enter name of target file\n");
fgets(targetFile, 20, stdin);
// open(path, O_WRONLY | O_CREAT | O_TRUNC, mod);
if (file_exist (targetFile))
{
printf("File exists. \n");
}
else
target = fopen(targetFile, "w");
int dFN;
dFN = malloc(strlen(targetFile) + strlen(av[2] + 1));
if( target == NULL )
{
fclose(source);
printf("Press any key to exit...\n");
exit(1);
}
while( ( ch = fgetc(source) ) != EOF )
fputc(ch, target);
printf("File copied successfully.\n");
fclose(source);
fclose(target);
if ( ac != 3 ){
fprintf( stderr, "usage: %s source destination\n", *avc);
exit(1);
}
if ( (in_fd=open(avc[1], O_RDONLY)) == -1 )
error("Cannot open ", avc[1]);
if ( (out_fd=creat( avc[2], copymode)) == -1 )
error( "Cannot creat", avc[2]);
while ( (chars_n = read(in_fd , buf, buffersize)) > 0 )
if ( write( out_fd, buf, chars_n ) != chars_n )
error("Write error to ", av[2]);
if ( chars_n == -1 )
error("Read error from ", avc[1]);
if ( close(in_fd) == -1 || close(out_fd) == -1 )
error("Error closing files","");
return 0;
}
void error(char *s1, char *s2)
{
fprintf(stderr,"Error: %s ", s1);
perror(s2);
exit(1);
}
Use the stat(2) or fstat function call, which returns various informations about a file, including its inode number.
See for example http://pubs.opengroup.org/onlinepubs/009695399/functions/stat.html
im trying to read a file and write the content in other file, but the finish file is empty after program execution.
this is the code:
char buf[80];
int main(int argc, char *argv[])
{
int fd;
int fs;
if( (fd=open("salida.txt",O_CREAT|O_TRUNC|O_WRONLY,S_IRUSR|S_IWUSR))<0) {
printf("\nError %d en open",errno);
perror("\nError en open");
exit(EXIT_FAILURE);
}
if( (fs=open(argv[1],O_CREAT|O_TRUNC|O_RDONLY,S_IRUSR|S_IWUSR))<0) {
printf("\nError %d en open",errno);
perror("\nError en open");
exit(EXIT_FAILURE);
}
int cont = 1;
if(fs=read(fd,&buf,80) < 0){
cont++;
if(write(fd,&buf,80) != 80) {
perror("\nError en el write");
exit(EXIT_FAILURE);
}
}
The condition
if (fs=read(fd,&buf,80) < 0)
doesn't mean
if ((fs = read(fd,&buf,80)) < 0)
it means
if (fs = (read(fd,&buf,80) < 0))
and has the effect of overwriting the file descriptor fs with 0 if the read succeeds, and with 1 if it fails. (read returns the number of bytes read, or -1 on failure.)
You don't want to assign the result to fs in any case, as it means that you're destroying any possibility of writing to the file you opened.
Also, fd is apparently your output file, so it's slightly strange to read from it.
If you want to copy (up to) 80 bytes, you could say something like
int size = 0;
if((size = read(fs, buf, 80)) > 0){
if (write(fd, buf, size) != size) {
perror("\nError en el write");
exit(EXIT_FAILURE);
}
}
Also, truncating the input file (O_TRUNC) may not be the best idea.
You seem to be reading and writing from and to fd. Your code is not very clear, you may want to clean it up. As other answers have pointed out, there are multiple errors in your code and your intentions are not entirely clear.
You should comment your code and indent properly.
int main()
{
char ch;
FILE *source, *target;
source = fopen(source_file, "r");
if( source == NULL )
{
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
target = fopen(target_file, "w");
if( target == NULL )
{
fclose(source);
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
while( ( ch = fgetc(source) ) != EOF )
fputc(ch, target);
printf("File copied successfully.\n");
fclose(source);
fclose(target);
return 0;
}
You never closed the files. Most operating systems don't actually make changes to the files until you close them. Until then your changes are only visible in RAM and not on the hard drive. Just add:
close(fd);
close(fs);
To the end of your code.
There seem to be some other problems too (why are you reading from a write-only file and seemingly attempting to write the same data back to it), and it's very much unclear what you're trying to accomplish.
// the following compiles, but the #include statements do expect linux
// so if your using a different OS, you may have to update them.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#define BUFFER_SIZE (80)
static char buf[ BUFFER_SIZE ]; // static so only visible in this file
// note: file scope variables are set to 0 by the startup code
int main( int argc, char *argv[])
{
int fd = -1; // destination file descriptor
int fs = -1; // source file descriptor
int statusRd = 0; // returned value from read
int statusWr = 0; // returned value from write
if( 2 > argc )
{ // then, file name parameter missing
printf( "\ncalling format: %s <filenametoread>\n", argv[0]);
exit( EXIT_FAILURE );
}
// implied else, proper number of parameters
// note: there should be a call to 'stat()'
// to assure input file exists placed here
// open destination file, uses fixed name
if( (fd = open("salida.txt", O_TRUNC | O_CREAT | O_WRONLY, S_IWRITE) ) <0)
{
printf("\nError %d en open",errno);
perror("open for write failed");
exit(EXIT_FAILURE);
}
// implied else, open of destination file successful
if( (fs=open(argv[1],O_RDONLY,S_IREAD))<0)
{
printf("\nError %d en open",errno);
perror("open for read failed");
close(fd); // cleanup
exit(EXIT_FAILURE);
}
// implied else, open of source file successful
do
{
if( (statusRd = read(fs,&buf, BUFFER_SIZE)) < 0)
{ // then read failed
perror( "read failed" );
close(fs); // cleanup
close(fd); // cleanup
exit( EXIT_FAILURE );
}
// implied else, read successful
if( 0 < statusRd )
{ // then some bytes read
if( ( statusWr = write(fd, buf, statusRd)) < 0)
{ // then, write failed
perror("\nwrite failed");
close(fs); // cleanup
close(fd); // cleanup
exit(EXIT_FAILURE);
}
}
} while( statusRd > 0 ); // exit loop when reach end of file
close(fs);
close(fd);
return(0);
}
i have this code but every time i try to run it it deletes the source file without giving any output, so how can i fix my problem?
note the question is asking me this:
Write a program that takes two file names from the command line, and copies the reverse of the contents of the first file into the second file, assuming that it is able to open the first file for reading and the second one for writing. If it can’t open the first file for reading, it must neither create nor modify (as the case may be) the second file. This program must use the low-level functions
#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
int source, dest, n;
char buf;
int filesize;
int i;
if (argc != 3)
{
fprintf(stderr, "usage %s <source> <dest>\n", argv[0]);
exit(-1);
}
at this par i am trying to use the following format: open("outf", O_WRONLY | O_CREAT | O_TRUNC, 0666)
if ((source = open(argv[1],O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
{ //read permission for user on source
fprintf(stderr, "can't open source\n");
exit(-1);
}
if ((dest = creat(argv[2], 0666)) < 0)
{ //rwx permission for user on dest
fprintf(stderr, "can't create dest");
exit(-1);
}
filesize = lseek(source, (off_t) 0, SEEK_END); //filesize is lastby +offset
printf("Source file size is %d\n", filesize);
for (i = filesize - 1; i >= 0; i--)
{ //read byte by byte from end
lseek(source, (off_t) i, SEEK_SET);
n = read(source, &buf, 1);
if (n != 1)
{
fprintf(stderr, "can't read 1 byte\n");
exit(-1);
}
n = write(dest, &buf, 1);
if (n != 1)
{
fprintf(stderr, "can't write 1 byte\n");
exit(-1);
}
}
write(STDOUT_FILENO, "DONE\n", 5);
close(source);
close(dest);
return 0;
}
thanks
I am sorry to be rude but did you even read the options you are passing to the first open call? O_CREAT | O_TRUNC?
What do you think those options do? Those options are causing your source file to be deleted.
You need to open your input file with the mode O_RDONLY, i.e. ReaD ONLY not O_WRONLY, i.e. WRite ONLY.
Check this:
int checkstatus(ifstream &in)
{
ios::iostate i;
i = in.rdstate();
if(i & ios::eofbit)
return 0;//cout << "EOF encountered\n";
else if(i & ios::failbit)
return 0;//cout<<"Non-Fatal I/O error\n";
else if(i & ios::badbit)
return 0;//cout<<"Fatal I/O error\n";
return 1;
}
int main()
{
ifstream in;
ofstream o;
in.open("test.txt");
o.open("test1.txt",ios::out);
char c;
in.seekg(0,ios::end);
while(checkstatus(in) != 0)
{
in.seekg(-1,ios::cur);
in.get(c);
in.seekg(-1,ios::cur);
if(checkstatus(in) == 0)
break;
cout<<c;
o.put(c);
}
in.close();
o.close();
return 0;
}
i have made some changes here and it worked very decent but not with very large file!!
#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
int source, dest, n;
char buf;
int filesize;
int i;
if (argc != 3)
{
fprintf(stderr, "usage %s <source> <dest>\n", argv[0]);
exit(-1);
}
if ((source = open(argv[1], 0666)) < 0)
{ //read permission for user on source
fprintf(stderr, "can't open source\n");
exit(-1);
}
if ((dest = open(argv[2],O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
{ //rwx permission for user on dest
fprintf(stderr, "can't create dest");
exit(-1);
}
filesize = lseek(source, (off_t) 0, SEEK_END); //filesize is lastby +offset
printf("Source file size is %d\n", filesize);
for (i = filesize - 1; i >= 0; i--)
{ //read byte by byte from end
lseek(source, (off_t) i, SEEK_SET);
n = read(source, &buf, 1);
if (n != 1)
{
fprintf(stderr, "can't read 1 byte\n");
exit(-1);
}
n = write(dest, &buf, 1);
if (n != 1)
{
fprintf(stderr, "can't write 1 byte\n");
exit(-1);
}
}
write(STDOUT_FILENO, "DONE\n", 5);
close(source);
close(dest);
return 0;
}
do i need to do something with lseek()?