Merge lp:~widelands-dev/widelands/bug-1509172-map-saving-paths into lp:widelands

Proposed by GunChleoc
Status: Merged
Merged at revision: 7852
Proposed branch: lp:~widelands-dev/widelands/bug-1509172-map-saving-paths
Merge into: lp:widelands
Diff against target: 150 lines (+23/-30)
5 files modified
src/editor/ui_menus/editor_main_menu_save_map.cc (+15/-24)
src/graphic/animation.cc (+1/-1)
src/io/filesystem/disk_filesystem.cc (+5/-1)
src/logic/map_objects/tribes/production_program.cc (+1/-1)
src/logic/save_handler.cc (+1/-3)
To merge this branch: bzr merge lp:~widelands-dev/widelands/bug-1509172-map-saving-paths
Reviewer Review Type Date Requested Status
GunChleoc Approve
Tino Needs Resubmitting
Review via email: mp+286067@code.launchpad.net

Description of the change

I hope that this will fix the map saving bug in Windows. I can reproduce the original bug, but I need the AppVeyor build to check if this fixes it.

To post a comment you must log in.
Revision history for this message
Tino (tino79) wrote :
review: Needs Fixing
Revision history for this message
GunChleoc (gunchleoc) wrote :

I can't download the linked build - do you have the error message?

Revision history for this message
GunChleoc (gunchleoc) wrote :

Nevermind, the link worked on the 2nd try.

Revision history for this message
Tino (tino79) wrote :

Probably i was still uploading...

I've done some debugging, but did not find a solution as of now:
- Click ok in save dialog
- The first string which arrives in ensure_dir_exists is "C:\data\wl_x64\src\maps" (my binary dir + maps)
- Then the drive letter "C:" get extracted
- Canonalize_name() makes "C:\\Users\\mit\\.widelands\\C:" from this.
- This seems to be done because is_path_absolute("C:") gives false
- This is because path_size < root_size => "C:" < "C:\\Users\\mit\\.widelands\\"

But why is a path relative just because it is shorter than your widelands home directory?

Revision history for this message
GunChleoc (gunchleoc) wrote :

In the error message I got, the path was missing all \. I need to add some more log output so we can get more information as to at what point the path gets messed up.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 709. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/109475085.
Appveyor build 558. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1509172_map_saving_paths-558.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 731. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/110103559.
Appveyor build 578. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1509172_map_saving_paths-578.

Revision history for this message
Tino (tino79) wrote :

Ok, it does work again on windows.
But i've really no clue what i've done with the last commit. No the file lock on the tmp save is gone and it can be renamed correctly.

If this does not break anything on linux i would remove the NOCOMs and merge.

review: Needs Resubmitting
Revision history for this message
GunChleoc (gunchleoc) wrote :

That broke it for Linus, but I have added an #ifndef that should fix it for everybody. I have tested with the zip option on and off. COuld you please test for Windows again to make sure that it's still working?

review: Approve
Revision history for this message
bunnybot (widelandsofficial) wrote :

Bunnybot encountered an error while working on this merge proposal:

Running 'bzr pull --overwrite' failed. Output:

ssh_exchange_identification: Connection closed by remote host
ConnectionReset reading response for 'BzrDir.open_2.1', retrying
ssh_exchange_identification: Connection closed by remote host
bzr: ERROR: Connection closed: Unexpected end of message. Please check connectivity and permissions, and report a bug if problems persist.
Using saved parent location: bzr+ssh://bazaar.launchpad.net/~widelands-dev/widelands/bug-1509172-map-saving-paths/

Revision history for this message
bunnybot (widelandsofficial) wrote :

Bunnybot encountered an error while working on this merge proposal:

Running 'bzr pull --overwrite' failed. Output:

ssh_exchange_identification: Connection closed by remote host
ConnectionReset reading response for 'BzrDir.open_2.1', retrying
ssh_exchange_identification: Connection closed by remote host
bzr: ERROR: Connection closed: Unexpected end of message. Please check connectivity and permissions, and report a bug if problems persist.
Using saved parent location: bzr+ssh://bazaar.launchpad.net/~widelands-dev/widelands/bug-1509172-map-saving-paths/

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 758. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/110807105.
Appveyor build 604. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1509172_map_saving_paths-604.

Revision history for this message
GunChleoc (gunchleoc) wrote :

This now works in Windows for the Zip Filesystem, but not for the normal file system.

review: Needs Fixing
Revision history for this message
Tino (tino79) wrote :

I would really like to avoid using different code pathes for windows and linux.
The current version does work for directory saves on windows.

But if fails on the second save for a zip save:
If you start the editor and save the map "abc" and "abc" already exists it gets overwritten correctly.
But you can't save again "abc" without restarting the editor (or save once under another name).

So the editor itself does put also a lock on the save file after the first save.

Why does creating a MapSaver object with new not work on linux?

Revision history for this message
GunChleoc (gunchleoc) wrote :

I'll test your changes :)

> Why does creating a MapSaver object with new not work on linux?

Why do we need this to be a pointer anyway? It only adds an extra line of code.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Now I get it - it's because of file locks.

Everything works on Ubuntu now, so I am in favour of merging. Let's solve the problem with not being able to save twice in a new branch.

review: Approve
Revision history for this message
GunChleoc (gunchleoc) wrote :

> The current version does work for directory saves on windows.
>
> But if fails on the second save for a zip save:
> If you start the editor and save the map "abc" and "abc" already exists it
> gets overwritten correctly.
> But you can't save again "abc" without restarting the editor (or save once
> under another name).
>
> So the editor itself does put also a lock on the save file after the first
> save.
>

I can confirm this problem - I have created a new bug report so that we can merge this branch:

https://bugs.launchpad.net/widelands/+bug/1548932

Revision history for this message
GunChleoc (gunchleoc) wrote :

@bunnybot merge

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/editor/ui_menus/editor_main_menu_save_map.cc'
2--- src/editor/ui_menus/editor_main_menu_save_map.cc 2016-01-31 10:57:58 +0000
3+++ src/editor/ui_menus/editor_main_menu_save_map.cc 2016-02-22 10:26:20 +0000
4@@ -126,7 +126,7 @@
5 if (filename == "" && table_.has_selection()) { // Maybe a directory is selected.
6 complete_filename = filename = maps_data_[table_.get_selected()].filename;
7 } else {
8- complete_filename = curdir_ + "/" + filename;
9+ complete_filename = curdir_ + g_fs->file_separator() + filename;
10 }
11
12 if (g_fs->is_directory(complete_filename.c_str()) &&
13@@ -155,9 +155,7 @@
14 if (md.run<UI::Panel::Returncodes>() == UI::Panel::Returncodes::kOk) {
15 g_fs->ensure_directory_exists(curdir_);
16 // create directory
17- std::string fullname = curdir_;
18- fullname += "/";
19- fullname += md.get_dirname();
20+ std::string fullname = curdir_ + g_fs->file_separator() + md.get_dirname();
21 g_fs->make_directory(fullname);
22 fill_table();
23 }
24@@ -234,9 +232,7 @@
25 filename += WLMF_SUFFIX;
26
27 // append directory name
28- std::string complete_filename = curdir_;
29- complete_filename += "/";
30- complete_filename += filename;
31+ const std::string complete_filename = curdir_ + g_fs->file_separator() + filename;
32
33 // Check if file exists. If so, show a warning.
34 if (g_fs->file_exists(complete_filename)) {
35@@ -250,7 +246,7 @@
36
37 // save to a tmp file/dir first, rename later
38 // (important to keep script files in the script directory)
39- std::string tmp_name = complete_filename + ".tmp";
40+ const std::string tmp_name = complete_filename + ".tmp";
41 if (g_fs->file_exists(tmp_name)) {
42 const std::string s = (boost::format(_
43 ("A file with the name ‘%s.tmp’ already exists. You have to remove it manually."))
44@@ -266,9 +262,7 @@
45
46 { // fs scope
47 std::unique_ptr<FileSystem> fs
48- (g_fs->create_sub_file_system(tmp_name.empty() ? complete_filename : tmp_name,
49- binary ? FileSystem::ZIP : FileSystem::DIR));
50- Widelands::MapSaver wms(*fs, egbase);
51+ (g_fs->create_sub_file_system(tmp_name, binary ? FileSystem::ZIP : FileSystem::DIR));
52
53 // Recompute seafaring tag
54 if (map.allows_seafaring()) {
55@@ -284,17 +278,16 @@
56 }
57
58 try {
59- wms.save();
60+ Widelands::MapSaver* wms = new Widelands::MapSaver(*fs, egbase);
61+ wms->save();
62+ delete wms;
63+ //reset filesystem to avoid file locks on saves
64+ fs.reset();
65 eia().set_need_save(false);
66-
67- // if saved to a tmp file earlier, rename now
68- if (!tmp_name.empty()) {
69- g_fs->fs_unlink(complete_filename);
70- g_fs->fs_rename(tmp_name, complete_filename);
71- // also change fs, as we assign it to the map below
72- fs.reset(g_fs->make_sub_file_system(complete_filename));
73- }
74-
75+ g_fs->fs_unlink(complete_filename);
76+ g_fs->fs_rename(tmp_name, complete_filename);
77+ // also change fs, as we assign it to the map below
78+ fs.reset(g_fs->make_sub_file_system(complete_filename));
79 // set the filesystem of the map to the current save file / directory
80 map.swap_filesystem(fs);
81 // DONT use fs as of here, its garbage now!
82@@ -310,9 +303,7 @@
83 mbox.run<UI::Panel::Returncodes>();
84
85 // cleanup tmp file if it was created
86- if (!tmp_name.empty()) {
87- g_fs->fs_unlink(tmp_name);
88- }
89+ g_fs->fs_unlink(tmp_name);
90 }
91 } // end fs scope, dont use it
92
93
94=== modified file 'src/graphic/animation.cc'
95--- src/graphic/animation.cc 2016-02-13 12:15:29 +0000
96+++ src/graphic/animation.cc 2016-02-22 10:26:20 +0000
97@@ -114,7 +114,7 @@
98
99 const std::string name = sound_effects->get_string("name");
100 const std::string directory = sound_effects->get_string("directory");
101- sound_effect_ = directory + "/" + name;
102+ sound_effect_ = directory + g_fs->file_separator() + name;
103 g_sound_handler.load_fx_if_needed(directory, name, sound_effect_);
104 }
105
106
107=== modified file 'src/io/filesystem/disk_filesystem.cc'
108--- src/io/filesystem/disk_filesystem.cc 2016-02-15 20:37:29 +0000
109+++ src/io/filesystem/disk_filesystem.cc 2016-02-22 10:26:20 +0000
110@@ -447,7 +447,11 @@
111 {
112 const std::string fullname1 = canonicalize_name(old_name);
113 const std::string fullname2 = canonicalize_name(new_name);
114- rename(fullname1.c_str(), fullname2.c_str());
115+ if (rename(fullname1.c_str(), fullname2.c_str()) != 0)
116+ throw wexception("DiskFileSystem: unable to rename %s to %s: %s",
117+ fullname1.c_str(),
118+ fullname1.c_str(),
119+ strerror(errno));
120 }
121
122
123
124=== modified file 'src/logic/map_objects/tribes/production_program.cc'
125--- src/logic/map_objects/tribes/production_program.cc 2016-02-18 08:42:46 +0000
126+++ src/logic/map_objects/tribes/production_program.cc 2016-02-22 10:26:20 +0000
127@@ -1524,7 +1524,7 @@
128 bool reached_end;
129 const std::string& filepath = next_word(parameters, reached_end);
130 const std::string& filename = next_word(parameters, reached_end);
131- name = filepath + "/" + filename;
132+ name = filepath + g_fs->file_separator() + filename;
133
134 if (!reached_end) {
135 char * endp;
136
137=== modified file 'src/logic/save_handler.cc'
138--- src/logic/save_handler.cc 2016-02-18 18:12:48 +0000
139+++ src/logic/save_handler.cc 2016-02-22 10:26:20 +0000
140@@ -162,9 +162,7 @@
141 std::string SaveHandler::create_file_name(const std::string& dir, const std::string& filename) const
142 {
143 // Append directory name
144- std::string complete_filename = dir;
145- complete_filename += "/";
146- complete_filename += filename;
147+ std::string complete_filename = dir + g_fs->file_separator() + filename;
148
149 // Now check if the extension matches (ignoring case)
150 if (!boost::iends_with(filename, WLGF_SUFFIX)) {

Subscribers

People subscribed via source and target branches

to status/vote changes: