]> git.tdb.fi Git - builder.git/blob - source/copy.cpp
Add comments
[builder.git] / source / copy.cpp
1 #include <errno.h>
2 #include <fstream>
3 #include <iostream>
4 #include <msp/path/utils.h>
5 #include "builder.h"
6 #include "copy.h"
7 #include "package.h"
8
9 using namespace std;
10 using namespace Msp;
11
12 Copy::Copy(Builder &b, const Package &pkg, const Path::Path &s, const Path::Path &d):
13         Action(b),
14         src(s),
15         dest(d),
16         worker(0)
17 {
18         announce(pkg.get_name(), "COPY", dest[-1]);
19         if(builder.get_verbose()>=2)
20                 cout<<s<<" -> "<<d<<'\n';
21         
22         if(!builder.get_dry_run())
23                 worker=new Worker(*this);
24 }
25
26 int Copy::check()
27 {
28         if(!worker)  // True for dry run
29         {
30                 signal_done.emit();
31                 return 0;
32         }
33         
34         if(worker->get_done())
35         {
36                 signal_done.emit();
37                 worker->join();
38                 return worker->get_error()?1:0;
39         }
40         
41         return -1;
42 }
43
44 Copy::~Copy()
45 {
46         delete worker;
47 }
48
49 void Copy::Worker::main()
50 {
51         Path::mkpath(copy.dest.subpath(0, copy.dest.size()-1), 0755);
52         
53         // Remove old file.  Not doing this would cause Bad Stuff when installing libraries.
54         if(unlink(copy.dest.str().c_str())<0 && errno!=ENOENT)
55         {
56                 int err=errno;
57                 cerr<<"Can't unlink "<<copy.dest<<": "<<strerror(err)<<'\n';
58                 done=error=true;
59                 return;
60         }
61
62         ifstream in(copy.src.str().c_str());
63         if(!in)
64         {
65                 cerr<<"Can't open "<<copy.src<<" for reading\n";
66                 done=error=true;
67                 return;
68         }
69
70         ofstream out(copy.dest.str().c_str());
71         if(!out)
72         {
73                 cerr<<"Can't open "<<copy.dest<<" for writing\n";
74                 done=error=true;
75                 return;
76         }
77
78         // Actual transfer loop
79         char buf[16384];
80         while(!in.eof())
81         {
82                 in.read(buf, sizeof(buf));
83                 out.write(buf, in.gcount());
84         }
85
86         // Preserve file permissions
87         struct stat st;
88         Path::stat(copy.src, st);
89         chmod(copy.dest.str().c_str(), st.st_mode&0777);
90
91         done=true;
92 }