Skip to content

Conversation

@mgutt
Copy link
Contributor

@mgutt mgutt commented Jan 11, 2026

  • Use fixed filename 'file.manager.terminal.sh' instead of timestamp-based names
  • Remove temporary script after terminal is opened
  • Use user's shell from posix_getpwuid() instead of hardcoded bash
  • Add sed_escape() function similar to preg_quote() with optional delimiter
  • Prevents accumulation of /var/tmp/File_Manager_*.run.sh files

Fixes #2515

Summary by CodeRabbit

  • Bug Fixes
    • Standardized the file manager terminal identifier for consistent behavior.
    • Improved terminal startup and cleanup for more reliable launch and teardown of in-app terminals.
    • Added per-session isolation to avoid naming collisions and race conditions during terminal creation.
    • Made startup/launch sequence more robust and safer when invoking user shells.

✏️ Tip: You can customize this high-level summary in your review settings.

- Use fixed filename 'file.manager.terminal.sh' instead of timestamp-based names
- Remove temporary script after terminal is opened (not dependent on script success)
- Use user's shell from posix_getpwuid() instead of hardcoded bash
- Add sed_escape() function similar to preg_quote() with optional delimiter
- Prevents accumulation of /var/tmp/File_Manager_*.run.sh files
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 11, 2026

Walkthrough

Replaces dynamic terminal naming with a static UI identifier and moves terminal startup to per-session script/profile files; adds a sed-escaping helper, determines the target shell via posix_getpwuid(0), and makes startup scripts self-delete and exec the user shell with --norc -i.

Changes

Cohort / File(s) Summary
Browse page
emhttp/plugins/dynamix/Browse.page
Changed terminal launch to use static identifier file.manager.terminal (UI/ttyd name) instead of previously generated File_Manager_<timestamp> names.
Terminal init & helpers
emhttp/plugins/dynamix/include/OpenTerminal.php
Added sed_escape($s); switched to per-session startup script and profile paths (/var/tmp/file.manager.terminal.<id>.sh, /tmp/file.manager.terminal.<id>.profile); obtain shell via posix_getpwuid(0)['shell']; startup script now sources profile, unlinks the profile, deletes itself, and execs the user shell with --norc -i.

Sequence Diagram(s)

sequenceDiagram
    participant Browser
    participant PHP as OpenTerminal.php
    participant FS as Filesystem
    participant ttyd
    participant Shell

    Browser->>PHP: Request "Open terminal here"
    PHP->>FS: write /tmp/file.manager.terminal.<id>.profile
    PHP->>FS: write /var/tmp/file.manager.terminal.<id>.sh
    PHP->>ttyd: spawn ttyd (name: file.manager.terminal) running the startup script
    ttyd->>FS: execute /var/tmp/file.manager.terminal.<id>.sh
    /var/tmp/...sh->>FS: source profile, remove profile, unlink self
    /var/tmp/...sh->>Shell: exec <user_shell> --norc -i
    Shell->>Browser: interactive session via ttyd
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I dug a script and left no trace,
A tidy path for each terminal's place.
Sed-safe lines and shells that start,
Self-cleaning hops, a careful art.
Click, connect — a cleaner space.

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing issue #2515 by cleaning up temporary terminal files with fixed filenames instead of timestamp-based names.
Linked Issues check ✅ Passed All three objectives from issue #2515 are addressed: fixed filename scheme adopted (file.manager.terminal), temporary script removal implemented, and timestamp-based accumulation prevented.
Out of Scope Changes check ✅ Passed All changes directly support the linked objectives. The sed_escape() function addition, shell retrieval via posix_getpwuid(), and script self-deletion are all necessary implementations for the stated goals.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e14b54 and 484f091.

📒 Files selected for processing (1)
  • emhttp/plugins/dynamix/include/OpenTerminal.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • emhttp/plugins/dynamix/include/OpenTerminal.php

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Jan 11, 2026

🔧 PR Test Plugin Available

A test plugin has been generated for this PR that includes the modified files.

Version: 2026.01.12.0005
Build: View Workflow Run

📥 Installation Instructions:

Install via Unraid Web UI:

  1. Go to Plugins → Install Plugin
  2. Copy and paste this URL:
https://preview.dl.unraid.net/pr-plugins/pr-2517/webgui-pr-2517.plg
  1. Click Install

Alternative: Direct Download

⚠️ Important Notes:

  • Testing only: This plugin is for testing PR changes
  • Backup included: Original files are automatically backed up
  • Easy removal: Files are restored when plugin is removed
  • Conflicts: Remove this plugin before installing production updates

📝 Modified Files:

Click to expand file list
emhttp/plugins/dynamix/Browse.page
emhttp/plugins/dynamix/include/OpenTerminal.php

🔄 To Remove:

Navigate to Plugins → Installed Plugins and remove webgui-pr-2517, or run:

plugin remove webgui-pr-2517

🤖 This comment is automatically generated and will be updated with each new push to this PR.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @emhttp/plugins/dynamix/include/OpenTerminal.php:
- Around line 43-51: The sed_escape() function currently only escapes BRE
pattern metacharacters but not the replacement-context special character '&',
which leads to unintended substitution when used in the sed replacement; update
sed_escape (or create sed_replacement_escape) to also escape '&' for replacement
context (e.g., add '&' to the preg_replace pattern or perform an additional
str_replace to replace '&' with '\&') so paths like "Tom & Jerry" are safe, and
optionally rename the function and update its comment to indicate it escapes for
sed replacements.
- Around line 77-78: The fixed file paths for the terminal script/profile
(variables like $exec = "/var/tmp/file.manager.terminal.sh" and the profile file
"/tmp/file.manager.terminal.profile") create a race where concurrent terminals
can overwrite each other; change these to include a unique suffix (e.g.,
getmypid() or a random token/uniqid()) when you create the filenames and use the
same generated name for all reads/writes in OpenTerminal.php so each session has
its own script/profile; ensure the code that writes the script, writes the
profile, and invokes/cleans up the script/profile all reference the generated
filename variable.
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 94f8272 and e6dd72c.

📒 Files selected for processing (2)
  • emhttp/plugins/dynamix/Browse.page
  • emhttp/plugins/dynamix/include/OpenTerminal.php
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ljm42
Repo: unraid/webgui PR: 2414
File: etc/rc.d/rc.nginx:374-376
Timestamp: 2025-10-03T02:57:29.994Z
Learning: Repo unraid/webgui: In etc/rc.d/rc.nginx, maintainers prefer not to add explicit mv-failure checks or EXIT trap clearing around atomic writes in build_servers(), build_locations(), and build_ini(); treat mv failures (e.g., disk full/permissions) as non-recoverable and keep the implementation simple.
📚 Learning: 2025-10-26T12:07:25.907Z
Learnt from: mgutt
Repo: unraid/webgui PR: 2429
File: emhttp/plugins/dynamix/nchan/file_manager:248-249
Timestamp: 2025-10-26T12:07:25.907Z
Learning: Unraid defaults to bash as the shell and does not have dash available. Process substitution syntax `>(...)` used with PHP's `exec()` function (which calls `/bin/sh`) is safe on Unraid because `/bin/sh` is bash.

Applied to files:

  • emhttp/plugins/dynamix/include/OpenTerminal.php
📚 Learning: 2025-12-28T15:54:58.673Z
Learnt from: mgutt
Repo: unraid/webgui PR: 2496
File: emhttp/plugins/dynamix/Browse.page:901-906
Timestamp: 2025-12-28T15:54:58.673Z
Learning: In the unraid/webgui codebase, CSRF validation is centralized in the global auto_prepend_file (local_prepend.php) which runs before every PHP request. Do not add per-script CSRF checks in individual files like Browse.page or Control.php. If a script relies on global validation, ensure it does not duplicate CSRF logic; otherwise extend the central preface to cover the needed checks.

Applied to files:

  • emhttp/plugins/dynamix/include/OpenTerminal.php
🔇 Additional comments (3)
emhttp/plugins/dynamix/Browse.page (1)

1391-1396: LGTM!

The change to use a static identifier 'file.manager.terminal' aligns with the consolidated terminal script approach in OpenTerminal.php. This properly addresses the PR objective of preventing accumulation of temporary files.

emhttp/plugins/dynamix/include/OpenTerminal.php (2)

82-83: Good improvement: Dynamic shell detection.

Using posix_getpwuid(0)['shell'] instead of hardcoding /bin/bash is a solid improvement that respects the system configuration and aligns with the standard terminal path (line 105).


95-101: LGTM: Self-deletion mechanism is correctly implemented.

The grouped command { rm -f '$exec'; exec $user_shell --norc -i; } ensures cleanup happens before exec replaces the process. Since bash loads the script into memory before execution, this pattern is safe.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @emhttp/plugins/dynamix/include/OpenTerminal.php:
- Around line 43-51: Remove the unused function bre_escape from
OpenTerminal.php: locate the function definition named bre_escape (the block
starting with function bre_escape($s, $delimiter = null)) and delete it along
with its doc/comments, ensuring no other code references bre_escape remain; run
a quick project-wide search to confirm it's not used before committing.
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6dd72c and 6e14b54.

📒 Files selected for processing (1)
  • emhttp/plugins/dynamix/include/OpenTerminal.php
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: ljm42
Repo: unraid/webgui PR: 2414
File: etc/rc.d/rc.nginx:374-376
Timestamp: 2025-10-03T02:57:29.994Z
Learning: Repo unraid/webgui: In etc/rc.d/rc.nginx, maintainers prefer not to add explicit mv-failure checks or EXIT trap clearing around atomic writes in build_servers(), build_locations(), and build_ini(); treat mv failures (e.g., disk full/permissions) as non-recoverable and keep the implementation simple.
📚 Learning: 2025-09-03T08:33:04.940Z
Learnt from: Squidly271
Repo: unraid/webgui PR: 2352
File: emhttp/plugins/dynamix.plugin.manager/include/PluginHelpers.php:0-0
Timestamp: 2025-09-03T08:33:04.940Z
Learning: In the unraid/webgui codebase, Squidly271 prefers file locking to be handled centrally within the file_put_contents_atomic function rather than in individual functions that use it. This maintains cleaner architecture by centralizing the locking mechanism.

Applied to files:

  • emhttp/plugins/dynamix/include/OpenTerminal.php
📚 Learning: 2025-06-03T21:27:15.912Z
Learnt from: zackspear
Repo: unraid/webgui PR: 2230
File: emhttp/plugins/dynamix/include/Templates.php:63-74
Timestamp: 2025-06-03T21:27:15.912Z
Learning: In the Unraid WebGUI codebase (emhttp/plugins/dynamix/include/Templates.php), there are known duplicate ID issues in checkbox templates across multiple template instances that the maintainers are aware of but have chosen not to address due to the effort required for legacy code improvements.

Applied to files:

  • emhttp/plugins/dynamix/include/OpenTerminal.php
📚 Learning: 2025-10-03T02:57:29.994Z
Learnt from: ljm42
Repo: unraid/webgui PR: 2414
File: etc/rc.d/rc.nginx:374-376
Timestamp: 2025-10-03T02:57:29.994Z
Learning: Repo unraid/webgui: In etc/rc.d/rc.nginx, maintainers prefer not to add explicit mv-failure checks or EXIT trap clearing around atomic writes in build_servers(), build_locations(), and build_ini(); treat mv failures (e.g., disk full/permissions) as non-recoverable and keep the implementation simple.

Applied to files:

  • emhttp/plugins/dynamix/include/OpenTerminal.php
📚 Learning: 2025-10-26T12:07:25.907Z
Learnt from: mgutt
Repo: unraid/webgui PR: 2429
File: emhttp/plugins/dynamix/nchan/file_manager:248-249
Timestamp: 2025-10-26T12:07:25.907Z
Learning: Unraid defaults to bash as the shell and does not have dash available. Process substitution syntax `>(...)` used with PHP's `exec()` function (which calls `/bin/sh`) is safe on Unraid because `/bin/sh` is bash.

Applied to files:

  • emhttp/plugins/dynamix/include/OpenTerminal.php
📚 Learning: 2025-12-28T15:54:58.673Z
Learnt from: mgutt
Repo: unraid/webgui PR: 2496
File: emhttp/plugins/dynamix/Browse.page:901-906
Timestamp: 2025-12-28T15:54:58.673Z
Learning: In the unraid/webgui codebase, CSRF validation is centralized in the global auto_prepend_file (local_prepend.php) which runs before every PHP request. Do not add per-script CSRF checks in individual files like Browse.page or Control.php. If a script relies on global validation, ensure it does not duplicate CSRF logic; otherwise extend the central preface to cover the needed checks.

Applied to files:

  • emhttp/plugins/dynamix/include/OpenTerminal.php
🔇 Additional comments (3)
emhttp/plugins/dynamix/include/OpenTerminal.php (3)

52-55: LGTM!

The sed_escape function correctly escapes both backslashes and ampersands in the proper order for sed replacement strings.


81-87: Good approach using fixed filename and dynamic shell detection.

Using a fixed path eliminates temp file accumulation, and posix_getpwuid(0)['shell'] is more robust than hardcoding /bin/bash.

Minor consideration: the fixed filename could cause issues if multiple File Manager terminals are opened simultaneously (second invocation would overwrite the script). Given Unraid's single-user nature, this is likely acceptable, but worth noting.


106-111: LGTM!

Good consistency using posix_getpwuid(0)['shell'] in both the path-specific terminal and the standard login shell branches.

@mgutt mgutt marked this pull request as ready for review January 12, 2026 00:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File Manager: "Open terminal here" feature does not clean up temporary files

1 participant