why the device file can not be found in init process after kernel booted? - kernel-module

everyone, I want to execute a script in init process, and I want it auto restart whenever it be terminated.
so I put this line in /etc/inittab
::respawn:/root/test.sh
and the test.sh contains this line(I simplified the script for clarify):
[ -e /dev/ttyUSB0 ] && echo 'hello, USB0' > /root/dump
and then I reboot my system to test the result, unfortunately, I never got a dump file in /root/ contains the line 'hello, USB0', which indicates that the /dev/ttyUSB0 is not exists.
but after I logged in, and type ls /dev/tty* I can see that the /dev/ttyUSB0 was right there.
I use openwrt 3.3.8, and I have installed kmod-usb-serial-pl2303 module so openwrt can recognize my usb device.
what's the problem? Is the usb serial module not loaded when init process running? Sorry for my poorly English, any help will be appreciated.

Related

Allow non-root application modify read-only file in /etc

I am trying to have an almost idiotproof configurator for network and some other stuff for embedded device running on linux. Application is saving to /etc/network/interfaces without problem when run by root, but returns "segmentation fault" when run by standard user. strace returned:
open("/etc/network/interfaces", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 EACCES (Permission denied)
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0} ---
How can I allow it to be launched by anyone and write to /etc/network/interfaces ?
Code for saving to file:
FILE *saveFile;
saveFile = fopen("/etc/network/interfaces","w");
// loopback
fprintf(saveFile, "auto lo \niface lo inet loopback\n\n");
// eth0
fprintf(saveFile, "auto eth0\niface eth0 inet static\n\taddress %s\n\tnetmask %s\n\tgateway %s\n",
address,netmask,gateway);
fclose(saveFile);
How can I allow it to be launched by anyone and write to /etc/network/interfaces ?
Mmmmm... By giving write permissions to anyone on /etc/network/interfaces ?
After your comment, your requirement is to allow a non root user to do a particular administrative tasks that would require root priviledge. The traditional way would be to make the program owned by root and setuid. This is now a throwned upon way, because a setuid program (su or sudo are) should be thoroughly scrutinized for any potential security problem: a buffer overflow or other would allow execution of arbitrary code as root.
For your example, if it is a simple program, it could make sense, but at least the return value of every operation (fopen and fwrite here) should be tested!
The recommended way for that will now be to use sudo and set specific entries in the /etc/sudoers file to allow any user (or a specific list of groups and/or users) to execute that specific command as root. To achieve almost the same that a setuid command but prompt the user for his/her password to notice him/her of an administrative task:
ALL local_host_name = (root) /full/path/to/command
But the sudoers syntax allow much finer grained authorizations.
(Beware: you still have to twice control your code)
you can try something like this :
install sudo
create a new user
Give sudo permission for the new user only on your program.
This way, when people will try to execute any command other than your program,it will be refused.
Now, your program will run with sudo rigth, so make sure that your program cannot be modified or replaced by another program (like chmod 700 and chown root) and make sure your program will not mess /etc/network/interface

How to get PIDs using a mount point before removed by udev on plug out

I want to know mechanism to get processes using any mount point before unmounted and remove by udev on removing the storage device in Debian OS.
When I skip remove directory in udev rule file it get a lot of processes including kernel etc.
I want to implement an alert message on screen if some one remove pen drive from system while uploading or downloading in the pen drive.
Please help me.
You may use lsof command. This command lists which process is using which file. output contains command, PID, USERID, file type, Device, side , file name etc.
You may grep for mount point to find who is using your device.
Syntax :
#lsof | grep <mount point>
OR
#lsof <mount point>
Other option is to use fuser command. It displays process IDs which are using given file/dir
Syntax :
#fuser <mount point >
Thanks for your reply. I am getting it by fuser. My question is how to handle it after removed by user. In my system hot plugging is managed by udev rules. Its show Specified filename
/media/pen-drive does not exist. Remove action is
ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/sh -c '/bin/fuser -m /media/%E{dir_name'", RUN+="/bin/umount -l /media/%E{dir_name}", RUN+="/bin/rmdir /media/%E{dir_name}"

Cannot get mac os x lldb process to read the STDIN

Is it me or lldb for mac os x (replacing gdb) does not allow you to pipe a file into the stdin, to be used by the process being debugged?
reading the instructions there is no reference to it.
I've gone through and installed gnu gdb, but would like to take advantage of what I suppose is improved lldb capability?
(lldb) process launch -i <file>
Should do the trick. Note you can't say:
(lldb) run -i <file>
since run is an alias for process launch -- so all its arguments are passed to the process being launched.
There's a general "help" facility that can show you more about all the lldb commands.
(lldb) help process launch
would have shown you this option.

Cloning command `script` and PTY background job problems: terminal messed up

I'm trying to recode the UNIX command script (as it is on OSX). This is part of an exercise for school to help students learn UNIX APIs. We are only allowed to use system calls, more specifically, only those available on MAN(2) pages on Mac OSX (since that's our OS at school).
I have a 'first version' that kind of works. Running a program such as ls prints the right output to the screen and in an output file.
The problem scenario
I run bash from within the script-clone. First issue is I get the following error:
bash: no job control in this shell
I have tried forcing the bash process into foreground with setpgrp and setpgid but that din't change anything so I concluded that was not the problem.
I also tried to understand why the real script command uses cfmakeraw (at least on Linux), as seen here, but I don't get it. The MAN page is not very helpful.
The real script also dup2s STDIN on the slave, as seen here, but when I do that, it seems like input isn't read anymore.
However, the bash still runs, and I can execute commands inside of it.
But if I run vim inside it, and then hit Ctrl-Z to put vim to the background, the terminal is messed up (which does not happen when I'm in my regular terminal).
So I guess I must have done something wrong. I'd appreciate any advice/help.
Here's the source code:
https://github.com/conradkleinespel/unix-command-script/tree/2587b07e7a36dc74bf6dff0e82c9fdd33cb40411
You can compile by doing: make (it builds on OSX 10.9, hopefully on Linux as well)
And run by doing: ./ft_script
Don't know it it makes more sense to have all the source code in StackOverflow as it would crowd the page with it. If needed, I can replace the Git link with the source.
I don't use OS X, so I can't directly test your code, but I'm currently writing a toy terminal emulator and had similar troubles.
about "bash: no job control in this shell"
In order to perform job control, a shell needs to be a session leader and the controlling process of its terminal. By default, your program inherits the controlling terminal of your own shell which runs your script program and which is also a session leader. Here is how to make your new slave process a session leader after fork:
/* we don't need the inherited master fd */
close(master);
/* discard the previous controlling tty */
ioctl(0, TIOCNOTTY, 0);
/* replace existing stdin/out/err with the slave pts */
dup2(slave, 0);
dup2(slave, 1);
dup2(slave, 2);
/* discard the extra file descriptor for the slave pts */
close(slave);
/* make the pts our controlling terminal */
ioctl(0, TIOCSCTTY, 0);
/* make a new session */
setsid()
At this point, the forked process has stdin/out/err bound to the new pts, the pts became its controlling terminal, and the process is a session leader. The job control should now work.
about raw tty
When you run a program inside a normal terminal, it looks like this:
(term emulator, master side) <=> /dev/pts/42 <=> (program, slave side)
If you press ^Z, the terminal emulator will write the ascii character 0x1A to the pts. It is a control character, so it won't be sent to the program, but instead the kernel will issue SIGSTP to the program and suspend it. The process of transforming characters into something else is called "line cooking" and has various settings that can be adjusted for each tty.
Now let's look at the situation with script:
term emulator <=> /dev/pts/42 <=> script <=> /dev/pts/43 <=> program
With normal line settings, what happens when you press ^Z? It will be transformed into SIGSTP by /dev/pts/42 and script will be suspended. But that's not what we want, instead we'd like the 0x1A character produced by our ^Z to go as-is through /dev/pts/42, then be passed by script to /dev/pts/43 and only then be transformed into SIGSTP to suspend the program.
This is the reason why the pts between your terminal and script must be configured as "raw", so that all control characters reach the pts between script and the program, as if you were directly working with it.

Calling tftp get command from c source code

I'm calling system command
system("tftp -m binary 192.168.1.1 -c get myfile > /dev/null") ;
it works fine when tftp server is running but it makes my c program crashed when tftp server is off.
Is there a way to check whether the server is available or not in c source code ?
I think your problem lies not in the availability of the server, but the fact that tftp (at least on my Ubuntu box) does not support the command-line arguments you've provided. As a matter of fact, the only command-line argument that it does support is the name of the server.
However, you could try piping commands into tftp (simulating an interactive session), like so:
system( "echo -e \"binary\\nget myfile\\nquit\" | tftp 192.168.1.1" );
If the server isn't available, it'll time out after a few seconds and return control to your program.
system("echo -e \"timeout 1\\nget myfile\" | tftp 192.168.1.1");
I used timeout options instead of quit command because actual latency which makes my program watchdog reset is performing on get command execution. So quit can not prevent this.
On the otherhand I decided to call tftp command on a bash script starting my c program.
I think that calling tftp commad on a real time c program is faulty.
Many thanks Ethan .

Resources