I'm logged into an android device via ADB wireless and I'm root. I'm in /sys/devices/platform/musb_hdrc/ trying to modify a file called mode. When I pipe something into the file, it returns without error, but the file is unmodified. And when I pipe something into a new file, I get "directory nonexistent". What's going on?
# ls -l mode
-rwxrwxrwx root root 4096 2012-11-11 14:39 mode
# cat mode
b_peripheral
# echo foobar
foobar
# echo foobar > mode
# cat mode
b_peripheral
# echo foobar > myfile
cannot create myfile: directory nonexistent
#
/sys is not a real directory with real files, it's the convenient interface to the kernel functions, exported as file system. some files are writable, but most of them are read-only and you're not supposed to create any files there yourself because, once again, it's not a real file system.
Related
At my first thought, I should know how to check the permissions of a folder in the Linux system(since the kernel of Android is linux) by C or C++.
Since C++17 is not available for me, so std::filesystem could not be used. And I searched on SO, I found access may be a solution. So I wrote the code snippet below:
if (access(folder_path, W_OK | X_OK) == 0) {
SDK_LOG_ERROR("folder is not writable");
}
But it seems not work as expected, I can manually create new files in a specific folder:
C:\tools>adb root
adbd is already running as root
C:\tools>adb remount
remount succeeded
C:\tools>adb shell
promotion:/system/etc/some_folder/.../config # ls -lhd .
drwxrwxrwx 2 root root 4.0K 2022-05-31 21:14 .
promotion:/system/etc/some_folder/.../config # touch a
promotion:/system/etc/some_folder/.../config # touch b
promotion:/system/etc/some_folder/.../config # ls -lh
total 14K
-rw-rw-rw- 1 root root 0 2022-05-31 21:14 a
-rw-rw-rw- 1 root root 0 2022-05-31 21:14 b
Before running the said code snippet, I call adb root; adb remount first, and then I call whoami in the terminal, the output is root.
But when I run the aforementioned code snippet on Android, the program tells me folder is not writable". What a surprise!
I am building AOSP 11 for emulator x86_64 and trying to run shell script on boot.
Below is my shell script test.sh
#!/vendor/bin/sh
echo "Hello" >> /data/local/tmp/test.txt
created myrc.rc file to create service
service runapp /vendor/bin/test.sh
class main
seclabel u:r:init-myservice:s0
user root
group root
oneshot
disabled
on property:dev.bootcomplete=1
start runapp
In device/generic/goldfish/sepolicy/x86/file_contexts i have file_contexts with
/vendor/bin/test.sh u:object_r:init-myservice_exec:s0
In device/generic/goldfish/sepolicy/x86/init-myservice.te
type init-myservice, domain;
type init-myservice_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(init-myservice)
allow init-myservice vendor_file_type:file { execute getattr map open read };
allow init-myservice vendor_toolbox_exec:file read;
Add myrc.rc and test.sh in device/generic/goldfish/x86_64-vendor.mk file
PRODUCT_COPY_FILES += \
external/service/test.sh:$(TARGET_COPY_OUT_VENDOR)/bin/test.sh \
external/service/myrc.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/myrc.rc \
In build/make/target/board/generic_x86_64/BoardConfig.mk
BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
But I can't see any file test.txt created in /data/local/tmp/
It's look like service not running on boot.
I have checked dmesg logs but there not any logs of "runapp" service which i have
created.
Anyone have idea on this ?
#GNK,for the rooted device below solution is working
No need to define any domain.
create rc file with below configuration
**service runapp /system/bin/test.sh
class main
seclabel u:r:su:s0
user root
group root
oneshot
disabled
on property:dev.bootcomplete=1
start runapp**
Modify your make file to put this files.
Put rc file in /etc/init/
Put test.sh in /system/bin/
I want to run a service on few tablets (VONINO NAVO P) that they will serve as a photo frame for digital ads.
What i'm trying to achieve is to run some commands at boot and i'm stuck.
I have created digitalads.rc in system/etc/init which will execute /system/bin/digitalads.sh from where i need to run some commands like:
svc power stayon true
settings put system screen_brightness 255
pm disable com.android.systemui
settings put system screen_off_timeout 999999999
settings put system accelerometer_rotation 0
settings put global airplane_mode_on 0
svc bluetooth disable
monkey -p my.app -c android.intent.category.LAUNCHER 1
and some other custom commands that they will update the contents of media files
my .rc file:
tulip-f708:/ # cat /system/etc/init/digitalads.rc
service digitalads /system/bin/digitalads.sh
disabled
user root
group root
u:object_r:system_file:s0
on property:sys.boot_completed=1
start digitalads
dmesg output
tulip-f708:/ # dmesg | grep digitalads
[ 6.512868] init: /system/etc/init/digitalads.rc: 5: invalid keyword 'u:object_r:system_file:s0'
[ 6.522694] init: (Parsing /system/etc/init/digitalads.rc took 0.01s.)
[ 44.546434] init: Service digitalads does not have a SELinux domain defined.
SElinux output
tulip-f708:/ # getenforce
Enforcing
tulip-f708:/ # setenforce 0
tulip-f708:/ # getenforce
Permissive
other services run under u:object_r:system_file:s0
tulip-f708:/ # ls -Z /system/bin/
u:object_r:system_file:s0 4d78d2ea-a631-70fb-aaa787c2b5773052.ta
u:object_r:system_file:s0 a98befed-d679-ce4a-a3c827dcd51d21ed.ta
u:object_r:system_file:s0 acpi
u:object_r:system_file:s0 am
u:object_r:system_file:s0 app_process
u:object_r:zygote_exec:s0 app_process32
u:object_r:zygote_exec:s0 app_process64
u:object_r:system_file:s0 applypatch
u:object_r:system_file:s0 appops
u:object_r:system_file:s0 appwidget
u:object_r:system_file:s0 arping
.............................
I also tried to unpack boot.img to modify init.rc but failed when put it back (bricked two of them). Not mention that to root them i had to contact the manufacturer directly...
Some hints would help me! Thx
It seems your .rc files misses the seclabel keyword. Your service declaration should look like this:
service digitalads /system/bin/digitalads.sh
disabled
user root
group root
seclabel u:object_r:system_file:s0
Edit regarding your SE Linux violation: The message says that init cannot start a program labelled with system_file. That means you have to modify the SE Linux rules. The best approach would be to add a new label specific to your service:
Identify the folder where you want to add your policy. This is somewhat specific to your setup, so I cannot give you a definite answer. Check for .te files in your source code. The core Android policies are in system/sepolicy/, but if your setup has special SE policies somewhere in devices/ or vendor/, these location would be better suited for your customization (because it makes it easier for your to update to a new Android version when your customizations are as isolated as possible).
In that folder, create a new policy file, e.g. digitalads.te. Add the following rules:
type digitalads_exec, system_file_type, exec_type, file_type;
type digitalads domain;
init_daemon_domain(digitalads)
In the same folder, there should be a file file_contexts: Add a line like
/system/bin/digitalads u:object_r:digitalads_exec:s0
(When you boot with this change, ls -Z /system/bin/digitalads should show this label.)
For the seclabel in your .rc file, replace system_file with digitalads.
(Check dmesg output and also ps -Z to verify your service has been labelled correctly.)
Story
I take photos and record videos with my phone camera and keep all of them on my internal storage/sdcard. I periodically back them up on my PC, so I keep these camera photos on PC storage in sync with phone storage.
For years, I've been backing up my phone camera photos to my PC in the following way:
Plug in phone into PC and allow access to phone data
Browse phone storage → DCIM → Camera
Wait several minutes for the system to load a list of ALL photos
Copy only several latest photos which haven't been backed up yet
I figured that waiting several minutes for all photos to load is an unnecessary drag so I downloaded adb platform tools. I've added the folder bin to my Path environment variable (i.e. %USERPROFILE%\Tools\adb-platform-tools_r28.0.3) so that I can seamlessly use adb and not write its full path each time.
The script
I wrote the following script for Git Bash for Windows. It is also compatible with Unix if you change the $userprofile variable. Essentially, the script pulls camera photos between two dates from phone storage to PC.
# Attach device and start deamon process
adb devices
# Initialize needed variables
userprofile=$(echo "$USERPROFILE" | tr "\\" "/") # Windows adjustments
srcFolder="//storage/06CB-C9CE/DCIM/Camera" # Remote folder
dstFolder="$userprofile/Desktop/CameraPhotos" # Local folder
lsFile="$dstFolder/camera-ls.txt"
filenameRegex="2019061[5-9]_.*" # Date from 20190615 to 20190619
# Create dst folder if it doesn't exist
mkdir -p "$dstFolder"
# 1. List contents from src folder
# 2. Filter out file names matching regex
# 3. Write these file names line by line into a ls file
adb shell ls "$srcFolder" | grep -E "$filenameRegex" > "$lsFile"
# Pull files listed in ls file from src to dst folder
while read filename; do
if [ -z "$filename" ]; then continue; fi
adb pull "$srcFolder/$filename" "$dstFolder" # adb: error: ...
done < "$lsFile"
# Clean up
rm "$lsFile"
# Inform the user
echo "Done pulling files to $dstFolder"
The problem
When I run the script (bash adb-pull-camera-photos.sh), everything runs smoothly except for the adb pull command in the while-loop. It gives the following error:
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190618_124656.jpg
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190618_204522.jpg
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190619_225739.jpg
I am not sure why the output is broken. Sometimes when I resize the Git Bash window some of the text goes haywire. This is the actual error text:
adb: error: failed to stat remote object '//storage/06CB-C9CE/DCIM/Camera/20190618_124656.jpg': No such file or directory
adb: error: failed to stat remote object '//storage/06CB-C9CE/DCIM/Camera/20190618_204522.jpg': No such file or directory
adb: error: failed to stat remote object '//storage/06CB-C9CE/DCIM/Camera/20190619_225739.jpg': No such file or directory
I am sure that these files exist in the specified directory on the phone. When I manually execute the failing command in bash, it succeeds with the following output:
$ adb pull "//storage/06CB-C9CE/DCIM/Camera/20190618_124656.jpg" "C:/Users/User/Desktop/CameraPhotos/"
//storage/06CB-C9CE/DCIM/Camera/20190618_124656.jpg: 1 file pulled. 15.4 MB/s (1854453 bytes in 0.115s)
The question
I can't figure out what's wrong with the script. I thought the Windows system might be causing a commotion, because I don't see the reason why the same code works when entered manually, but doesn't work when run in a script. How do I fix this error?
Additional info
Note that I had to use // in the beginning of an absolute path on Windows because Git Bash would interpret / as its own root directory (C:\Program Files\Git).
I've echoed all variables inside the script and got all the correct paths that otherwise work via manual method.
camera-ls.txt file contents
20190618_124656.jpg
20190618_204522.jpg
20190619_225739.jpg
Additional questions
Is it possible to navigate to external sdcard without using its name? I had to use /storage/06CB-C9CE/ because /sdcard/ navigates to internal storage.
Why does tr "\\" "/" give me this error: tr: warning: an unescaped backslash at end of string is not portable?
Windows batch script
Here's a .bat script that can be run by Windows Command Prompt or Windows PowerShell. No Git Bash required.
:: Start deamon of the device attached
adb devices
:: Pull camera files starting from date
set srcFolder=/storage/06CB-C9CE/DCIM/Camera
set dstFolder=%USERPROFILE%\Desktop\CameraPhotos
set lsFile=%USERPROFILE%\Desktop\CameraPhotos\camera-ls.txt
set dateRegex=2019061[5-9]_.*
mkdir %dstFolder%
adb shell ls %srcFolder% | adb shell grep %dateRegex% > %lsFile%
for /F "tokens=*" %%A in (%lsFile%) do adb pull %srcFolder%/%%A %dstFolder%
del %lsFile%
echo Done pulling files to %dstFolder%
Just edit the srcFolder to point to your phone camera folder,
plug a pattern into the dateRegex for matching the date interval and
save it as a file with .bat extension, i.e: adb-pull-camera-photos.bat.
Double-click the file and it will pull filtered photos into CameraPhotos folder on Desktop.
Keep in mind that you still need have adb for Windows on your PC.
The problem was with Windows line delimiters.
Easy fix
Just add the IFS=$'\r\n' above the loop so that the read command knows the actual line delimiter.
IFS=$'\r\n'
while read filename; do
if [ -z "$filename" ]; then continue; fi
adb pull "$srcFolder/$filename" "$dstFolder"
done < "$lsFile"
Explanation
I tried plugging the whole while-loop into the console and it failed with the same error:
$ bash adb-pull-camera-photos.sh
List of devices attached
9889db343047534336 device
tr: warning: an unescaped backslash at end of string is not portable
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190618_124656.jpg
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190618_204522.jpg
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190619_225739.jpg
Done pulling files to C:/Users/User/Desktop/CameraPhotos
This time I started investigating why the output was broken. I remembered that windows uses \r\n as newline, which means Carriage Return + Line Feed, (CR+LF), so some text must have been overwritten.
It was because of broken values stored inside the $filename variable.
This is the loop from the script:
while read filename; do
if [ -z "$filename" ]; then continue; fi
adb pull "$srcFolder/$filename" "$dstFolder"
done < "$lsFile"
Since each iteration of the while-loop reads a line from $lsFile in the following form:
exampleFilename.jpg\r\n
It misinterprets the newline symbols as part of the file name, so adb pull tries to read files with these whitespaces in their names, but fails and it additionally writes a broken output.
Adb Photo Sync
This might not be the answer but might be useful for others looking for android photo/files backup solution.
I use this script on my Windows with git bash. This can be easily used for Linux. A common issue with a long backup process is that it might get interrupted and you might have to restart the entire copy process from start.
This script saves you from this trouble. You can restart the script or interrupt in between but it will resume copy operation from the point it left.
Just change the rfolder => android folder, lfolder => local folder
#!/bin/sh
rfolder=sdcard/DCIM/Camera
lfolder=/f/mylocal/s8-backup/Camera
adb shell ls "$rfolder" > android.files
ls -1 "$lfolder" > local.files
rm -f update.files
touch update.files
while IFS= read -r q; do
# Remove non-printable characters (are not visible on console)
l=$(echo ${q} | sed 's/[^[:print:]]//')
# Populate files to update
if ! grep -q "$l" local.files; then
echo "$l" >> update.files
fi
done < android.files
script_dir=$(pwd)
cd $lfolder
while IFS= read -r q; do
# Remove non-printable characters (are not visible on console)
l=$(echo ${q} | sed 's/[^[:print:]]//')
echo "Get file: $l"
adb pull "$rfolder/$l"
done < "${script_dir}"/update.files
I want to replace a system library by one where I made some small changes. Both libraries were compiled with the same version of cyanogenmod source. The one I copied to the sdcard worked on an earlier flash of CM.
Now I try to run the following:
$ adb shell
shell#m0:/ $ su
root#m0:/ # mount -o rw,remount /system
root#m0:/ # chmod 777 /system/lib/libwilhelm.so
root#m0:/ # cp /sdcard/libwilhelm.so /system/lib/libwilhelm.so
root#m0:/ # chmod 644 /system/lib/libwilhelm.so
root#m0:/ # mount -o ro,remount /system
root#m0:/ # reboot
However even after reboot the old libwilhelm.so is used
I know this because I log something in the not-overriden version in
frameworks/wilhelm/src/sl_entry.c:
#include <android/log.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "frameworks/wilhelm/src/sl_entry.c", __VA_ARGS__))
// ...
SL_API SLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
{
LOGI("qqqqqqqqqqqqqqqqqqqq in slCreateEngine");
//... continue original code
This log is then different in the other library that is on the sdcard. So the logcat should display something else once I replaced the library and rebooted but it still prints the original log message.
Also the library doesn't seem to be read from another location:
root#m0:/ # find . -name "libwilhelm*"
./mnt/shell/emulated/0/libwilhelm.so
./system/lib/libwilhelm.so
find: ./proc/1897/task/2088/fd/49: No such file or directory
find: ./proc/1897/task/2088/fd/57: No such file or directory
find: ./proc/1897/task/2100/fd/42: No such file or directory
find: ./proc/2466/task/2471/fd/88: No such file or directory
find: ./proc/2466/task/2741/fd/85: No such file or directory
find: ./proc/2466/task/2741/fd/95: No such file or directory
./data/media/0/libwilhelm.so
What did I miss?
Turns out frameworks/wilhelm/src/sl_entry.c is not part of the libwilhelm.so but the libOpenSLES.so
Moreover it is safer to replace the library by an updater-script that can be executed from a recovery program like TWRP. The script could look like:
ui_print("mounting /system");
mount("ext4", "EMMC", "/dev/block/mmcblk0p9", "/system");
ui_print("/system now mounted");
ui_print("adding new shared library libOpenSLES.so");
package_extract_file("libOpenSLES.so", "/system/lib/libOpenSLES.so");
ui_print("done adding new shared library libOpenSLES.so");
ui_print("unmounting /system");
unmount("/system");
ui_print("/system now unmounted");
ui_print("finished");