I'm new to this forum and I would like to ask the experts a question.
I wrote the following program ( part of a bigger thing, but this is the code that causes me trouble)
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd;
fd = open("/dev/watchdog",O_RDONLY);
lseek(fd,0,SEEK_END);
return 0;
}
The thing that bothers me is that after I run this program as root, after 20-30 seconds, the system crashes, and I can't seem to figure out why. This does not happend as a regular user.
Could you please enlighten me regarding this issue?
Thanks!
PS. Yes, I know that /dev/watchdog is a character file and it's not seekable, but this seems really weird.
It looks like /dev/watchdog is doing what its supposed to do. Once you open /dev/watchdog, you have to keep writing to it, otherwise the system reboots. It is probably not the lseek that is crashing it, it is the lack of writing. See the linux manpages for watchdog for more info.
When you ran as a non-root user, your open of /dev/watchdog probably just failed, so the system did not reboot. Your code is not checking for an error from open().
Related
I know this is kind of silly, but I tried to find out online, but couldnt.
What is the full-form of ttwu in the scheduler code of the linux kernel. It can be seen as a number of function prefixes, namely,
ttwu_do_wakeup
ttwu_do_activate
ttwu_queue_remote
ttwu_activate
.. and many more
I would assume it stands for try_to_wake_up. See for example the comment in kernel/sched/sched.h:
981 /* try_to_wake_up() stats */
982 unsigned int ttwu_count;
983 unsigned int ttwu_local;
yes in true *nix philosophy why waste time on extra characters (e.g. you want to know the current working directory? Use pwd for "print working directory") TTWU is indeed "Try To Wake Up" and implemented in the Linux scheduler code, eventually calling activate_task, which actually DOES NOT DO ANYTHING but put the task on the run queue of one of the CPUs. At some point in the future the _schedule function will make it activate (via switch_context.) Pretty cool stuff if you ask me.
This question already has answers here:
Link to a specific inode
(2 answers)
Closed 3 years ago.
On Linux, suppose a process opens a file for writing, something deletes the file (perhaps misconfigured log rotation), but the process keeps running, keeps the file handle open, and keeps writing to it. My understanding is that in this case, the storage used by the file still exists on disk, until the process terminates.
Suppose I want to read that file. Is there any way for another process to open the file pointed to by that file handle, or to otherwise get access to the data written to it?
Yes it can. Via /proc/$pid/fd/$fd.
Example:
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int fd;
if(0>(fd = open("DELETED", O_CREAT|O_RDWR|O_CLOEXEC, 0600))) return perror("open"),1;
static char const msg[]="got me\n";
(void)write(fd, msg, sizeof(msg));
if(0>(unlink("DELETED"))) return perror("unlink"),1;
char buf[128];
sprintf(buf,"cat /proc/%ld/fd/%d", (long)getpid(), fd);
system(buf);
}
(Here I'm accessing it from a(n indirect) child process, but this is not a requirement. It works from unrelated processes as well.)
The /proc/$pid/fd/$fd items appear as symlinks in the filesystem.
They usually point to the name the file was opened as but when the file is deleted, the original link target has a " (deleted)" appended to it as in
lrwx------ 1 petr petr 64 Aug 19 12:45 /proc/32027/fd/3 -> '/home/petr/DELETED (deleted)'
yet in spite of such a target being nonexistent such a proc symlink works (through some dark kernel magic, presumably).
Suppose I want to read that file. Is there any way for another process to open the file pointed to by that file handle, or to otherwise get access to the data written to it?
As long as any process has the file open, its i-node and any other data will remain on disk. It is at least possible in principle to find that i-node and that data, and read them directly from the disk, though that's not exactly the same thing as opening the file. It may even be possible to do that after the last process closes the file -- this is how undeletion utilities work, and these do exist for Linux filesystems.
I have a scientific camera, a USB3Vision device, that I wrote a program to captures images for. No problems when I use it on my desktop, it works fine every time. If I take the exact same application to another (2 other actually) computer it acquires one image but hangs the second time that you try to capture another.
The desktop I'm developing on is Fedora 25 and I am having this problem on clean installs of both Fedora 24 and 25. Also, on both computers the permissions of the USB device have been set to 666 using a udev rule so it's not some permissions error.
If I attach gdb to the process that's hung it shows that it's waiting on a blocking call to poll(), I've tried waiting a really long time but it never completes. This is where I'm at a bit of a loss now, I'm not really sure what to poke at to troubleshoot why that call never finishes on computers that aren't the mine. I'm also not really sure how to determine what's different between the USB buses on the different computers, that would probably be really useful too.
Example code to recreate this issue is irrelevant IMO, but here it is because it may be asked for if not included:
#include <arv.h>
#include <stdlib.h>
#include <stdio.h>
int
main (int argc, char **argv)
{
ArvCamera *camera;
ArvBuffer *buffer;
camera = arv_camera_new (argc > 1 ? argv[1] : NULL);
buffer = arv_camera_acquisition (camera, 0);
if (ARV_IS_BUFFER (buffer))
printf ("Image successfully acquired\n");
else
printf ("Failed to acquire a single image\n");
g_clear_object (&camera);
g_clear_object (&buffer);
return EXIT_SUCCESS;
}
This is just one of the test programs that comes with the Aravis library that works with GenICam type cameras.
AM having a C program which uses system to list /dev/ttyUSB* devices how can I store them in an array and process.
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("ls /dev/ttyUSB*");
printf("Done");
exit(0);
}
Using system for these things is a bad idea.
First of all, you have to Parse the output of ls, which you should avoid.
Apart from that, this will be quite inefficient. starting programs is rather slow, but you are running a program (written in C), that starts another program (written in C) which calculates something and renders this something into a human-readable form, and then you have to parse the human-readable form to find out what the original something was...
A better way is to do the shortcut can "calculate the something" directly:
check out glob
On Linux/NPTL, threads are created as some kind of process.
I can see some of my process have a weird cmdline:
cat /proc/5590/cmdline
hald-addon-storage: polling /dev/scd0 (every 2 sec)
Do you have an idea how I could do that for each thread of my process? That would be very helpful for debugging.
If you want to do this in a portable way, something that will work across multiple Unix variations, there are very few options available.
What you have to do is that your caller process must call exec with the argv [0] argument pointing to the name that you would like to see in the process output, and the filename pointing to the actual executable.
You can try this behavior from the shell by using:
exec -a "This is my cute name" bash
That will replace the current bash process with one named "This is my cute name".
For doing this in C, you can look at the source code of sendmail or any other piece of software that has been ported extensively and find all the variations that are needed across operating systems to support this.
Some operating systems have a setproctitle(3) API, some others allow you to override the contents of argv [0] and show that result.
argv points to writable strings. Just write stuff to them:
#include <string.h>
#include <unistd.h>
int
main(int argc, char** argv)
{
strcpy(argv[0], "Hello, world!");
sleep(10);
return 0;
}
Bah.. the code is not that nice, the trick is to reuse the environ (here argv_buffer) pointer:
memset (argv_buffer[0] + len, 0, argv_size - len);
argv_buffer[1] = NULL;
Any better idea?
Is that working for different threads?