Our teacher has a web server and we are allowed to test some things. I connected to the server with Putty and tried following command:
echo "i 4 r 255 g 0 b 0." > /dev/ttyACM0
ttyACM0
is a virtual file redirecting the stream to a serial interface. This specific command changes the color of a rgb led. But the same command doesn't work in php with exec
or shell_exec
:
<?php
// Script saved at /home/STUDENT_NAME/public_html/blink.php
echo shell_exec("echo \"i 4 r 255 g 0 b 0.\" > /dev/ttyACM0"); // Doesn't work
echo shell_exec("echo \"Hello\""); // Returns "Hello"
?>
I know that exec
and shell_exec
aren't disabled, because the second call to shell_exec
works. My next idea was to use fopen("php://memory", "a");
, but I don't know how to use these wrappers. So my questions:
- How to use these wrappers correctly? (Maybe like
"php://memory/dev/ttyACM0"
) - Is there a better solution?
When you work on the file through the web, all file accesses are performed through the user the web server is running as, which is likely different from the user you login as through PuTTY. Thus you might be encountering a permission issue. Check the permissions on the tty device:
I guess it will be group-writable, so take note of the group and check if your user is part of that group:
Then check if the user the HTTP server is running as has the same right:
This should show a list of all processes containing http in their name, and the web server will likely be among them. Identify it, and the first column of the corresponding line will tell you the user the web server is using. Let's suppose it is apache. Now run:
(Or whatever you discovered in the previous step) This will show you the groups the user belongs to, and I bet the group ttyACM0 belongs to will not be among those. You will need to ask the sysadmin to add the user to the group.
Anyway using
shell_exec
in that context is very bad practice. I think you can just open the serial device and write to it:Of course this won't work if the HTTP server user does not have the permission to write to the device. Also, make sure to pay attention to the line termination in the
fwrite()
, you might need it or not, or even need a different one (\r
or\r\n
);