check parent dir dependency before copy
[mizunara.git] / mizucp / main.c
index 5fb1e8b..77b23ea 100644 (file)
@@ -423,11 +423,36 @@ void* copy_run(void *data) {
             to[to_len-1] = 0;
         }
         
+        if(file->depends_on) {
+            SrcFile *dep = file->depends_on;
+            // check first without lock
+            if(dep->status == 0) {
+                if(dep->lock) {
+                    pthread_mutex_lock(&dep->lock->mutex);
+                    if(file->depends_on->status == 0) {
+                        pthread_cond_wait(&dep->lock->cond, &dep->lock->mutex);
+                    }
+                    pthread_mutex_unlock(&dep->lock->mutex);
+                } else {
+                    // locking disabled (because we have only one thread)
+                    // but in that case the file status can't be 0
+                    // therefore this case here should not happen
+                    file->status = -1;
+                }
+            }
+            // check again
+            if(dep->status == -1) {
+                file->status = -1;
+            }
+        }
+        
         int ret;
-        if(file->isdir) {
+        if(file->status == 0) {
+            if(file->isdir) {
             ret = mz_copy_dir(settings, file, from, to);
-        } else {
-            ret = mz_copy_file(settings, file, from, to, buffer, bufsize);
+            } else {
+                ret = mz_copy_file(settings, file, from, to, buffer, bufsize);
+            }
         }
         
         free(to);
@@ -439,15 +464,39 @@ void* copy_run(void *data) {
     return NULL;
 }
 
+static void file_set_status(SrcFile *file, int status) {
+    if(file->lock) {
+        pthread_mutex_lock(&file->lock->mutex);
+        file->status = status;
+        pthread_cond_broadcast(&file->lock->cond);
+        pthread_mutex_unlock(&file->lock->mutex);
+    } else {
+        file->status = status;
+    }
+}
+
 int mz_copy_dir(CPSettings *settings, SrcFile *file, const char *from, const char *to) {
     printf("mkdir %s\n", to);
-    return mkdir(to, file->mode);
+    int ret = mkdir(to, file->mode);
+    if(ret) {
+        if(errno == EEXIST) {
+            struct stat s;
+            if(!stat(to, &s)) {
+                if(S_ISDIR(s.st_mode)) {
+                    ret = 0;
+                }
+            }
+        }
+    }
+    file_set_status(file, !ret ? 1 : -1);
+    return ret;
 }
 
 int mz_copy_file(CPSettings *settings, SrcFile *file, const char *from, const char *to, char *buffer, size_t bufsize) {
     printf("cp %s %s\n", from, to);
     int fin = open(from, O_RDONLY);
     if(fin < 0) {
+        file_set_status(file, -1);
         return 1;
     }
     
@@ -457,6 +506,7 @@ int mz_copy_file(CPSettings *settings, SrcFile *file, const char *from, const ch
     if(fout < 0) {
         perror("open");
         close(fin);
+        file_set_status(file, -1);
         return 1;
     }
     
@@ -471,5 +521,7 @@ int mz_copy_file(CPSettings *settings, SrcFile *file, const char *from, const ch
     close(fin);
     close(fout);
     
+    file_set_status(file, !ret ? 1 : -1);
+    
     return ret;
 }