Skip to content

Commit

Permalink
axis: copy gcode to temporary file before opening (fixes #2418)
Browse files Browse the repository at this point in the history
The issue here is that if you open a gcode file, and then change the
file on disk, you'll think your changes are completely inert because
they don't show up in the GUI, but actually LinuxCNC has its own
separate file handle behind-the-scenes, and your machine can do scary
and unpredictable things.

With this fix, the code being executed by LinuxCNC always matches what
is displayed in the AXIS GUI even if you subsequently change the file.
  • Loading branch information
jes committed Apr 6, 2023
1 parent 2df5e87 commit 3db3507
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/emc/usr_intf/axis/scripts/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ def open_file_guts(f, filtered=False, addrecent=True):
loaded_file = f
program_filter = get_filter(f)
if program_filter:
tempfile = os.path.join(tempdir, os.path.basename(f))
tempfile = os.path.join(tempdir, "filtered-" + os.path.basename(f))
exitcode, stderr = filter_program(program_filter, f, tempfile)
if exitcode:
root_window.tk.call("nf_dialog", (".error", "-ext", stderr),
Expand Down Expand Up @@ -1900,9 +1900,14 @@ def reload_file(refilter=True):
o.set_highlight_line(None)

if refilter or not get_filter(loaded_file):
open_file_guts(loaded_file, False, False)
else:
# we copy the file to a temporary file so that even if it subsequently
# changes on disk, LinuxCNC is parsing the file contents from the time
# the user opened the file
tempfile = os.path.join(tempdir, os.path.basename(loaded_file))
shutil.copyfile(loaded_file, tempfile)
open_file_guts(tempfile, False, False)
else:
tempfile = os.path.join(tempdir, "filtered-" + os.path.basename(loaded_file))
open_file_guts(tempfile, True, False)
if line:
o.set_highlight_line(line)
Expand Down

2 comments on commit 3db3507

@sundtek
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not good, it just broke a tool on my side because I expected it to reload and there was some tool changing involved (and I did not notice that it did not reload the g-code)

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.7/tkinter/init.py", line 1705, in call
return self.func(*args)
File "/home/sundtek/devel/linuxcnc/bin/axis", line 2796, in touch_off_system
reload_file(False)
File "/home/sundtek/devel/linuxcnc/bin/axis", line 1911, in reload_file
shutil.copyfile(loaded_file, tempfile)
File "/usr/lib/python3.7/shutil.py", line 104, in copyfile
raise SameFileError("{!r} and {!r} are the same file".format(src, dst))
shutil.SameFileError: '/tmp/tmp3d2pd26j/sidewall.nc' and '/tmp/tmp3d2pd26j/sidewall.nc' are the same file

now this will cause that loaded_file will be overwritten with the tmp name, any reload on the tmp name will just raise this exception.
The patch is missing a loaded_file backup.

@sundtek
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the open dialog should set a global variable to the new filename, reloading the filename should then use this variable for copying the g-code.

rmu> the interpreter always re-opens the file when starting, so if you write the file and don't reload, axis won't show what will be
executed if you start the program

#2762

my patch is incomplete it just disables your code, according to rmu's information.

Please sign in to comment.