create_dir_work_item.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/file_util.h"
6#include "base/logging.h"
7#include "chrome/installer/util/create_dir_work_item.h"
8#include "chrome/installer/util/logging_installer.h"
9
10CreateDirWorkItem::~CreateDirWorkItem() {
11}
12
13CreateDirWorkItem::CreateDirWorkItem(const base::FilePath& path)
14    : path_(path),
15      rollback_needed_(false) {
16}
17
18void CreateDirWorkItem::GetTopDirToCreate() {
19  if (file_util::PathExists(path_)) {
20    top_path_ = base::FilePath();
21    return;
22  }
23
24  base::FilePath parent_dir(path_);
25  do {
26    top_path_ = parent_dir;
27    parent_dir = parent_dir.DirName();
28  } while ((parent_dir != top_path_) && !file_util::PathExists(parent_dir));
29  return;
30}
31
32bool CreateDirWorkItem::Do() {
33  VLOG(1) << "creating directory " << path_.value();
34  GetTopDirToCreate();
35  if (top_path_.empty())
36    return true;
37
38  VLOG(1) << "top directory that needs to be created: " << top_path_.value();
39  bool result = file_util::CreateDirectory(path_);
40  VLOG(1) << "directory creation result: " << result;
41
42  rollback_needed_ = true;
43
44  return result;
45}
46
47void CreateDirWorkItem::Rollback() {
48  if (!rollback_needed_)
49    return;
50
51  // Delete all the directories we created to rollback.
52  // Note we can not recusively delete top_path_ since we don't want to
53  // delete non-empty directory. (We may have created a shared directory).
54  // Instead we walk through path_ to top_path_ and delete directories
55  // along the way.
56  base::FilePath path_to_delete(path_);
57
58  while (1) {
59    if (file_util::PathExists(path_to_delete)) {
60      if (!RemoveDirectory(path_to_delete.value().c_str()))
61        break;
62    }
63    if (path_to_delete == top_path_)
64      break;
65    path_to_delete = path_to_delete.DirName();
66  }
67
68  return;
69}
70