1

The following is a program that copies the contents of a file (1st argument) to a new file (2nd argument).

I'm testing it on linux, so for instance, copying the contents of user's terminal onto new file also works:

./copy /dev/tty newFile

However, copying the contents of current directory does not work:

./copy . newFile

The latter does not cause an error when opening the 1st argument, but nothing is copied. I thought that the contents of the directory would be copied onto the new file?

EDIT : This happens because linux takes working directory by standard to be ~

copy.c program below:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>


int copy(int inFileDesc,int outFileDesc);

int main (int argc, char** argv)
{
    int inputfd;
    int outputfd;
    if (argc!=3)
    {
        printf("Wrong number of arguments\n");
        exit(1);
    }
    inputfd=open(argv[1],O_RDONLY);
    if(inputfd==-1)
    {
        printf("Cannot open file\n");
        exit(1);
    }
    outputfd=creat(argv[2],0666);
    if(outputfd==-1)
    {
        printf("Cannot create file\n");
        exit(1);
    }
    copy(inputfd,outputfd);
    exit(0);
}

int copy(int inFileDesc,int outFileDesc)
{
    int count;
    char buffer[BUFSIZ];
    while((count=read(inFileDesc,buffer,sizeof(buffer)))>0)
    {
        write(outFileDesc,buffer,count);
    }
}
Davide Spataro
  • 7,319
  • 1
  • 24
  • 36
korppu73
  • 237
  • 1
  • 2
  • 5
  • First of I can't see an flock struct , how do you implement O_RDONLY ? – Tsakiroglou Fotis Nov 26 '18 at 09:50
  • O_RDONLY is defined in fcntl.h, I think (http://pubs.opengroup.org/onlinepubs/7908799/xsh/fcntl.h.html) – korppu73 Nov 26 '18 at 09:55
  • Yes indeed but I think you need to say struct flock my_lock; and lock.l_type = O_RDONLY; – Tsakiroglou Fotis Nov 26 '18 at 09:57
  • @korppu73 What exactly would do you expect `newFile` to contain after `./copy . newFile`? – Jabberwocky Nov 26 '18 at 09:58
  • Do you want me to give you a fcntl.h example – Tsakiroglou Fotis Nov 26 '18 at 09:58
  • Maybe [this SO article](https://stackoverflow.com/questions/4204666/how-to-list-files-in-a-directory-in-a-c-program) could be ineresting for you. – Jabberwocky Nov 26 '18 at 10:03
  • Regarding fcntl this is a man page with examples : http://pubs.opengroup.org/onlinepubs/009604599/functions/fcntl.html – Tsakiroglou Fotis Nov 26 '18 at 10:04
  • @Jabberwocky: the directory content (list of file names), I expected – korppu73 Nov 26 '18 at 10:05
  • 1
    @Tsakioglou: ok thanks I'll look at the examples. Had no idea about flock. – korppu73 Nov 26 '18 at 10:07
  • @Jabberwocky It doesn't seem like a duplicate to me, I understand the question as "Why does this copy program has this behaviour ?" rather than "How to list a directory in C ?" – alamit Nov 26 '18 at 10:22
  • @alamit I must admit it's a corner case if you read just the question, but from his comment "the directory content (list of file names), I expected" I'm pretty sure it's a duplicate. – Jabberwocky Nov 26 '18 at 10:30
  • The aim of my program isn't to list the files of a directory but to make a new copy of any file, and given that in unix everything is treated as a file, this should work (and does) for copying devices, but I thought it would also work for a directory. @Tsakiroglou Fotis: Do I need to create a flock structure only for directories? (ordinary files and devices like user terminal seem to work without flock) – korppu73 Nov 26 '18 at 10:33
  • @korppu73 OK, it's getting clearer what you want, I reopened the question. If you want to copy a whole directory structure, you need to copy each file of the directory separately to the newly created directory. You also need to do this recursively, because your source directory might contain directories etc. – Jabberwocky Nov 26 '18 at 10:58

1 Answers1

2

If you read man 2 open an man 2 read

man 2 open

The named file is opened unless:
...
[EISDIR] The named file is a directory, and the arguments specify that it is to
be opened for writing.

man 2 read

The pread(), read(), and readv() calls will succeed unless:
...
[EISDIR] An attempt is made to read a directory.

Therefore, open will not fail because you specified O_RDONLY and return your file descriptor, however read will fail at first call.

alamit
  • 392
  • 2
  • 10