-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enhance(main/libusb): Add integration with termux-usb -E
#21620
Conversation
Here's a little program that I made to help testing this library, compile with #include <libusb-1.0/libusb.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int status;
size_t devnum;
struct libusb_device **devlist;
struct libusb_device_handle *devhdl;
libusb_set_debug(NULL, 3);
status = libusb_init(NULL);
if (status < 0) {
puts(libusb_error_name(status));
return 1;
}
devnum = libusb_get_device_list(NULL, &devlist);
printf("Number of device attached: %lu\n", devnum);
if (devnum == 0)
return 1;
status = libusb_open(devlist[0], &devhdl);
if (status < 0) {
puts(libusb_error_name(status));
return 1;
}
status = libusb_detach_kernel_driver(devhdl, 0);
if (status < 0) {
puts(libusb_error_name(status));
return 1;
}
return EXIT_SUCCESS;
} |
@kyufie |
No. Termux does not have any special rights on system, it is a regular Android app and it can not access HID or Mass Storage devices using USB Host API. |
@hansm629 |
But it seems to me that you can access files on a USB device without root, simply by symlinking the directory mounted to termux. Not a good option, but a workaround if you mean it |
@IntinteDAO I really hope it becomes possible. |
It will not be possible without root. |
I was sure it could be done from within Termux directly, however, I actually have a problem with that, so I suspect I may had root. On the other hand, other apps can access the USB flash drive (e.g. Ghost Commander), so it's probably a technically doable issue. |
They do not use usb api for that. They use storage API. |
I assume so. Is there an option for Termux to use Storage API to read data over USB or not? From what I understand, no (no one has implemented it). |
I usually just read the available mount points and figure out the path to the external storage from it. |
For external storage there is support in Termux thanks to termux-setup-storage. Termux, on the other hand, does not have access to USB storage (without root), although it is theoretically possible for it to have (someone would have to implement some “driver” (?) fuse / gvfs. |
Qemu USB passthrough is now possible thanks to this PR.
In theory, this should permit unbounded access to USB devices without root access.
This is probably the "driver" that you need. I'm also thinking about other possibilities this might opens up (obtain root access without PC, arduino, all those things that people have been struggling with). There's still a bit of a problem when the USB device accidentally disconnected from the host. When that happens, the VM must be restarted. Someone seems to have already done it, but it was quite janky (#19635). |
@kyufie Ultimately, I hope that USB storage can be freely mounted in both the Termux XFCE4 desktop environment and PRoot Linux! |
@hansm629 If you're talking about access to the files inside the USB storage, as opposed to raw access, that one-liner I gave also works for USB drive. |
After installing these two packages, which are currently in a pull request, do I just need to add the following environment variables and start XFCE4?
|
@hansm629
In the desktop environment, you should be able to type in the path in the file manager to go straight to that directory.
|
@kyufie
|
@hansm629 |
@kyufie The steps I followed are as follows:
Is there anything wrong or missing from the steps I took? Could the USB storage format also have an effect? |
@hansm629 |
It is displayed as below.
This is my termux information.
|
@hansm629
I'm using Github debug build.
Taking from Apollo's link.
You might need to update the app. |
Also:
|
@kyufie I’ll update you after I’ve done the update and tested it! :) |
You need https://github.com/termux/termux-app/releases/tag/v0.119.0-beta.1 from github/fdroid for the |
@agnostic-apollo I activated the MANAGE_EXTERNAL_STORAGE permission and manually disabled the WRITE_EXTERNAL_STORAGE permission, but is there something else I might be missing? Could it be that it's not working because it's without root? Here is the termux-info:
|
Try granting both permissions. |
@kyufie I'm not sure what I'm missing... 😭 |
From the linked comment above.
You are getting an |
There is also a script given to find the usb drive path properly. |
@agnostic-apollo Are there any parts of the script that need to be added or modified? <~/.bashrc> export LANG=ko_KR.UTF-8
export LC_MONETARY=ko_KR.UTF-8
export LC_PAPER=ko_KR.UTF-8
export LC_NAME=ko_KR.UTF-8
export LC_ADDRESS=ko_KR.UTF-8
export LC_TELEPHONE=ko_KR.UTF-8
export LC_MEASUREMENT=ko_KR.UTF-8
export LC_IDENTIFICATION=ko_KR.UTF-8
export LC_ALL=
export XDG_CONFIG_HOME=/data/data/com.termux/files/home/.config
export XMODIFIERS=@im=fcitx5
export GTK_IM_MODULE=fcitx5
export QT_IM_MODULE=fcitx5
find_most_recent_unreliable_storage_mount() {
local return_value
local i
local storage_mounts_string
local storage_mount
local storage_mount_basename
local unreliable_storage_mount
local android_build_version_sdk
local valid_number_regex='^[0-9]+$'
local -a storage_mounts_array=()
# Find android sdk/os version
# Termux app exports ANDROID__BUILD_VERSION_SDK for `>= v0.119.0`
if [[ ! "$ANDROID__BUILD_VERSION_SDK" =~ $valid_number_regex ]]; then
android_build_version_sdk="$(unset LD_LIBRARY_PATH; unset LD_PRELOAD; getprop "ro.build.version.sdk")"
return_value=$?
if [ $return_value -ne 0 ] || [[ ! "$android_build_version_sdk" =~ $valid_number_regex ]]; then
echo "Failure while finding \"ro.build.version.sdk\" property" 1>&2
echo "ANDROID__BUILD_VERSION_SDK = \"$android_build_version_sdk\"" 1>&2
if [ $return_value -eq 0 ]; then
return_value=1
fi
return $return_value
fi
else
android_build_version_sdk="$ANDROID__BUILD_VERSION_SDK"
fi
# If on Android `< 11`
if [ "$android_build_version_sdk" -lt 30 ]; then
echo "Cannot find unreliable storage mounts on Android sdk version '< 30'. Current sdk version is '$android_build_version_sdk'." 1>&2
return 1
fi
storage_mounts_string="$(grep -E "^[^ ]+ /mnt/media_rw/[A-Z0-9]{4}-[A-Z0-9]{4} " /proc/mounts | cut -d' ' -f2)"
return_value=$?
if [ $return_value -ne 0 ]; then
echo "Failure while finding most recent unreliable storage mount" 1>&2
return $return_value
fi
if [ -z "$storage_mounts_string" ]; then
echo "Failed to find any reliable or unreliable storage mounts" 1>&2
return 1
fi
IFS=$'\n' read -r -d '' -a storage_mounts_array <<< "$storage_mounts_string"
for (( i=${#storage_mounts_array[@]} - 1; i >= 0; i-- )) ; do
storage_mount="${storage_mounts_array[i]}"
storage_mount_basename="${storage_mount##*/}"
grep -qE "^[^ ]+ /storage/$storage_mount_basename " /proc/mounts
return_value=$?
if [ $return_value -eq 1 ]; then
unreliable_storage_mount="$storage_mount"
break
elif [ $return_value -ne 0 ]; then
echo "Failure while finding if storage mount is unreliable" 1>&2
return $return_value
fi
done
if [ -z "$unreliable_storage_mount" ]; then
echo "Failed to find any unreliable storage mounts" 1>&2
return 1
fi
echo "$unreliable_storage_mount"
}
|
This will require updating docs, @agnostic-apollo can you help with this after it gets merged please? |
@kyufie I do not think you need |
@twaik The external Both read and write operations are possible! Although the volume doesn’t automatically appear in the @kyufie @agnostic-apollo |
@twaik |
@agnostic-apollo However, I have one issue I need to ask about. Mount/unmount USB storage via OTG works perfectly, but I can't access the
/dev/block/vold/public:179,1 192219136 29112576 163106560 16% /mnt/media_rw/3232-6230
/dev/block/vold/public:8,97 30013440 6582544 23430896 22% /mnt/media_rw/3EFF-C796
$ ls /mnt/media_rw/3232-6230
"/mnt/media_rw/3232-6230": Permission denied (os error 13)
$ ls /mnt/media_rw/3EFF-C796
.rwxrwx--- 128 root 7 Oct 2021 autorun.inf*
drwxrwx--- - root 21 Jan 2022 boot/
.rwxrwx--- 414k root 7 Oct 2021 bootmgr*
.rwxrwx--- 1.5M root 7 Oct 2021 bootmgr.efi*
.rwxrwx--- 1.1G root 29 Jun 01:19 'COSTA RICA IN 4K@60fps VP9 HDR.webm'*
drwxrwx--- - root 21 Jan 2022 efi/
drwxrwx--- - root 18 Oct 2023 LOST.DIR/
.rwxrwx--- 74k root 7 Oct 2021 setup.exe*
drwxrwx--- - root 21 Jan 2022 sources/
drwxrwx--- - root 21 Jan 2022 support/
drwxrwx--- - root 21 Jan 2022 'System Volume Information'/
drwxrwx--- - root 7 Dec 2023 포트폴리오/ Is there something I might be missing? Below is the script entered in my find_most_recent_unreliable_storage_mount() {
local return_value
local i
local storage_mounts_string
local storage_mount
local storage_mount_basename
local unreliable_storage_mount
local android_build_version_sdk
local valid_number_regex='^[0-9]+$'
local -a storage_mounts_array=()
# Find android sdk/os version
# Termux app exports ANDROID__BUILD_VERSION_SDK for `>= v0.119.0`
if [[ ! "$ANDROID__BUILD_VERSION_SDK" =~ $valid_number_regex ]]; then
android_build_version_sdk="$(unset LD_LIBRARY_PATH; unset LD_PRELOAD; getprop "ro.build.version.sdk")"
return_value=$?
if [ $return_value -ne 0 ] || [[ ! "$android_build_version_sdk" =~ $valid_number_regex ]]; then
echo "Failure while finding \"ro.build.version.sdk\" property" 1>&2
echo "ANDROID__BUILD_VERSION_SDK = \"$android_build_version_sdk\"" 1>&2
if [ $return_value -eq 0 ]; then
return_value=1
fi
return $return_value
fi
else
android_build_version_sdk="$ANDROID__BUILD_VERSION_SDK"
fi
# If on Android `< 11`
if [ "$android_build_version_sdk" -lt 30 ]; then
echo "Cannot find unreliable storage mounts on Android sdk version '< 30'. Current sdk version is '$android_build_version_sdk'." 1>&2
return 1
fi
storage_mounts_string="$(grep -E "^[^ ]+ /mnt/media_rw/[A-Z0-9]{4}-[A-Z0-9]{4} " /proc/mounts | cut -d' ' -f2)"
return_value=$?
if [ $return_value -ne 0 ]; then
echo "Failure while finding most recent unreliable storage mount" 1>&2
return $return_value
fi
if [ -z "$storage_mounts_string" ]; then
echo "Failed to find any reliable or unreliable storage mounts" 1>&2
return 1
fi
IFS=$'\n' read -r -d '' -a storage_mounts_array <<< "$storage_mounts_string"
for (( i=${#storage_mounts_array[@]} - 1; i >= 0; i-- )) ; do
storage_mount="${storage_mounts_array[i]}"
storage_mount_basename="${storage_mount##*/}"
grep -qE "^[^ ]+ /storage/$storage_mount_basename " /proc/mounts
return_value=$?
if [ $return_value -eq 1 ]; then
unreliable_storage_mount="$storage_mount"
break
elif [ $return_value -ne 0 ]; then
echo "Failure while finding if storage mount is unreliable" 1>&2
return $return_value
fi
done
if [ -z "$unreliable_storage_mount" ]; then
echo "Failed to find any unreliable storage mounts" 1>&2
return 1
fi
echo "$unreliable_storage_mount"
}
df | grep vold |
Send a MediaWiki formatted text and I'll upload. |
Welcome. Read my post in the linked issue, external sd cards (reliable storages) are not accessible even with the permission, although some devices may allow access, like samsung. Only external hd (unreliable storages) will be accessible. The |
@agnostic-apollo After checking with the command below, it seems that the USB storage connected via USB OTG is recognized, but the MicroSDXC card installed on the device is not recognized. If it's displayed as shown below, should I assume that even with permissions, it's impossible to access the MicroSDXC card directly installed on the device (as opposed to via OTG)? /dev/block/vold/public:179,1 192219136 29112576 163106560 16% /mnt/media_rw/3232-6230
$ find_most_recent_unreliable_storage_mount
Failed to find any unreliable storage mounts |
@hansm629 |
@kyufie By converting |
That should be it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be good to merge.
I'd like to give it another day for final comments/reviews.
Ah crap it looks like we have a rebase conflict. Edit: manually rebasing did the job. |
This commit adds the ability for `libusb` to access connected USB device through file descriptor given by `termux-usb -E`
Thank you for your contribution @kyufie. To avoid last minute rebasing errors in the future I would suggest periodically resyncing your development fork with the upstream This is how I do that for my fork: # One time setup to add the upstream remote for fetching new commits.
git remote add upstream https://github.com/termux/termux-packages.git
# Then to resync the fork:
# On your fork's master branch
git fetch --all -v && git rebase upstream/master
# and to push that back to your development fork on GitHub:
git push
# You can then switch back to your dev branch and rebase it on top of local master,
# which is now up to date, and force push it to update your PR
git switch branch-name
git rebase master
git push --force-with-lease=branch-name
# --force would also work, but force with lease is preferred to not accidentally clobber anything You can probably set up git aliases or hooks to make this more convenient. |
Thanks, I'll keep that in mind. |
to make that happen by default, here's an excerpt from my [branch]
autosetupmerge = always
autosetuprebase = always
[pull]
rebase = true
[rebase]
autostash = true then |
Did not know about branch |
This commit adds the ability for
libusb
to access connected USB devices through file descriptor given bytermux-usb -E
, extending its usability for non-root users.In the presence of
TERMUX_USB_FD
,libusb
will try to read the fd number given and add it to the list of available devices, disregarding other discovery methods.Otherwise it will try to use the usual
/dev/bus/usb
-based device discovery so that root users can still enjoy the benefits of having root access.To test it, run
termux-usb -r -E -e 'command' device_name
. Make sure thatcommand
useslibusb
.