How can I watch a specific path? - c

Is it possible to 'watch' a specifc path and have the kernel notify me whenever a file or directory of that name is deleted / written / read / created / etc.?
Note: I am looking for an answer in C. I will accept an answer that points me to the underlying implementation in a different language though (provided I could find the C code)

On Linux, the kernel supports inotify, which allows monitoring of specific files and directories. It appears that a similar thing is available for FreeBSD called pnotify which was based on the Linux 'inotify' interface. (I have used inotify; however, I have not used pnotify myself).
inotify does not require you to write a kernel module. All APIs are available in user-space. Once properly initialized, your application simply calls read() with an inotify file descriptor to monitor file and/or directory activity. The read events come in a structure:
struct inotify_event
{
int wd; /* Watch descriptor */
uint32_t mask; /* Mask of events */
uint32_t cookie; /* Unique cookie associating related events */
uint32_t len; /* Size of name field */
char name[]; /* Optional null-terminated name */
};
From what I have read of pnotify, it is very similar.

You should look at the kqueue interface. inotify does not exist on FreeBSD.
kqueue came first and is generally considered a better interface.

Related

How does the libc function isatty() work?

I searched the linux repo and couldn't find a definition for it, so I guess it's something that comes with C or something like that? I'm trying to understand how isatty is able to tell whether a file descriptor is a terminal or not, and what it even means to "be a terminal," in technical language.
I'm not really sure where to find its implementation, and if it's in assembly I won't really be able to follow along with it very easily.
The general strategy for implementing isatty is to attempt a tty-specific ioctl operation on the file descriptor, and check for ENOTTY error result. Traditionally, TCGETS, which is the backend for the tcgetattr function, is used, but this is slightly dangerous since the ioctl number for it on Linux clashes with legacy OSS sound devices, and if the file descriptor actually refers to a certain type of MIDI device, it will make changes to the device. In musl libc, we use TIOCGWINSZ, the "get window size" operation, whose number was not inadvertently reused for any other types of devices and which reliably fails with ENOTTY for non-tty devices.
In theory, you could do it with fstat and check the st_rdev field for the device major number, but this would require a hard-coded list of all device majors which are ttys, and would have broken when new types were added (e.g. USB-serial/ACM devices, uartlite devices, etc.).
isatty(3) is a library function (you won't find anything about in the linux kernel), and is usually implemented by calling tcgetattr(3) and checking its return value.
For example, in the GNU C library (glibc):
/* Return 1 if FD is a terminal, 0 if not. */
int
__isatty (int fd)
{
struct termios term;
return __tcgetattr (fd, &term) == 0;
}
tcgetattr(3) itself will resolve to some ioctl like TCGETA or TCGETS.
Notice that isatty(3) will also return true for a master side of a pseudo-tty, which isn't really a tty -- most tty related ops performed on it will actually apply to its slave side.
On linux, isatty(3) will also return true for /dev/console, which again, isn't a real tty (it cannot be made the controlling tty of a process).
On linux, you can obtain a list of all the tty drivers on your system with their major and minor numbers via cat /proc/tty/drivers. Of course, that only reflects the modules which have been loaded.

how to get a device class specific descriptor with libusb

I'm working with libusb and I need to get the device class specific descriptor for the hardware I'm working on.
I didn't find any function that could help me, does anyone have a clue about how to do this?
Thanks.
I came across the same situation in checking the ways to get class specific descriptors and saw this question was unanswered.
libusb doesn't have any API or Data Structures to retrieve the class specific descriptors. This may be because libusb is designed only to address the basic USB specification. To get the class specific descriptor details using libusb, there are few extra fields added in each descriptor.
Fields: copied from libusb.h
/** Extra descriptors. If libusb encounters unknown endpoint descriptors,
* it will store them here, should you wish to parse them. */
const unsigned char *extra;
/** Length of the extra descriptors, in bytes. */
int extra_length;
Both "extra" and "extra_length" is added in libusb_endpoint_descriptor, libusb_interface_descriptor, libusb_config_descriptor. You have to manually decode this content according to your class codes (either at configuration level or interface level descriptor).
You can refer lsusb.c in usbutils package for better understanding on decoding.
If libusb does not have a specialized function for getting the data that you want, you should be able to use the libusb_control_transfer function (or the asynchronous version of that function) to fetch it. The USB descriptors are all fetched via control transfers, so you can just do the appropriate control transfer using that function.

How to attach to device context in another driver at Linux

Example: I use sensor TMP421 which driver is linux/drivers/hwmon/tmp421.c. It will export to /sys/class/hwmon/hwon0/.... And user can use cat command to read the temperatures. But my is request: I want to read it at kernel space to control some thing when the temperature reach to MAX values (example).
So how I can attach to get the device context to use the function
tmp421_data *tmp421_update_device(struct device *dev)
to read the temperature ?
Or is there another way ?
I don't want to use the cat command at my code.
Thanks
Just do bus_find_device_by_name on an i2c_bus_type. It should give you the correct device pointer relatively easily. You will also have to change the tmp421_update_device function from "static" to "exported" (and move tmp421_data structure to an external header).
If you don't want to alter drivers not of your own, you can still try to emulate the approach sysfs takes when accessing device information. The sysfs dirent will be accessible to you at the dev->kobj.sd field and it's a fairly simple data structure.
Critically, you need to call put_device() on the received device handle after you've finished with it (otherwise you will end up with kernel lock-up down the line because of "unreleasable" objects). If you're using the kobj.sd accessor, then sysfs_get()/sysfs_put() on it will also be required.
As said in https://stackoverflow.com/a/4407051/196561 ("How to use sysfs inside kernel module?") by shodanex
it is a Bad Idea (tm)
with link http://www.linuxjournal.com/article/8110
Driving Me Nuts - Things You Never Should Do in the Kernel - From Issue #133 Linux Journal, 2005 By Greg Kroah-Hartman
The article says that it is possible to use sys_open and sys_read from modules to open and read files:
old_fs = get_fs();
set_fs(KERNEL_DS);
fd = sys_open(filename, O_RDONLY, 0);
if (fd >= 0) {
/* read the file here */
sys_close(fd);
}
set_fs(old_fs);
Don't know will it work with files in /sys or not.
And Greg warns us:
I Never Told You about This.
In conclusion, reading and writing a file from within the kernel is a bad, bad thing to do. Never do it. Ever.
Better way may be to learn inter module communications, possibly with modifying the hwmon/tmp421.c.

What do the Mutex and Cache sqlite3_open_v2 flags mean?

EDIT: If I could navigate documents I'd be dangerous.
http://www.sqlite.org/sharedcache.html
ORIGINAL:
The sqlite3_open_v2 function bears the signature:
int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
const char *zVfs /* Name of VFS module to use */
);
The third argument, int flags, supports a number of options, some of which are self-explanatory:
#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
/* snip */
#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
I'm not having any issues with my database usage (yet), but I'd like to know what the NOMUTEX vs FULLMUTEX and SHAREDCACHE vs PRIVATECACHE options imply. The description from the sqlite.org page I found, for SQLITE_OPEN_NOMUTEX for instance, isn't very helpful.
If the SQLITE_OPEN_NOMUTEX flag is set, then the database connection
opens in the multi-thread threading mode as long as the single-thread
mode has not been set at compile-time or start-time.
What does the mutex flag do, if simultaneous reads/writes are already guarded against according to the documentation?
Also, what goes in the cache, and if I decide to share it, who am I sharing with and how does that affect their reads/writes?
Is it flushed on close() only?
Any insight at all is appreciated, even a link to a better description would be great.
In short
So cumbersome to explain that if you run Single thread you don't have to care
else read below:
That is the most cubersome part of SQLIte.
If it was rev 1, I will even call that "ill conceived", but as it was incremental evolution with some backward compatibility, I understand the path and mind set followed by the developer.
As opposed as what you may feel reading the official documentation: not all combinations work!!!
Also while decision of the mode can be postponed until call to sqlite3_open_v2(,,,) it BETER be chosen once and for all. The good is that you can decide multiple strategy as long as each is on different db file.
That said:
SQLITE_OPEN_NOMUTEX
does compile (or active on sqlite3_open_v2), the usage of SQLite without internal mutex.
Still safe to be use SQLite multithread BUT in my experience work only safely with individual connection open in each thread.
Do NOT try to share a connection between Thread with this mode.
SQLITE_OPEN_FULLMUTEX
SQLite at runtime does create appropriate mutex to lock some atomic operation.
I use it when I share connection between thread. (In fact I ALWAYS use FULLMUTEX)
If you want to see where search sqlite3.c for sqlite3_mutex_enter(db->mutex);
And know that when NOMUTEX the db->mutex == NULL and no lock occurs
Use SQLITE_OPEN_FULLMUTEX always.
Mutex handling are very fast now, no real impact on performance.
Disk/parsing are fare more onerous in cpu and it is unclear what the benefit of NOMUTEX unless you are ready to reverse engineer code of sqlite3.c
However
I successfully experiment NOMUTEX in Multithread using mutiple connection (one open_v2 in each thread) but using this you also need to worry about decision on CACHE (I use SQLITE_OPEN_PRIVATECACHE, not all combination work, also changing the mode once db have and especially the caching systeme once already been open is really looking for trouble)
Choose a MUTEX+CACHE+sync+journal strategy before first open and stick with it.
See also this very good article about
https://dev.yorhel.nl/doc/sqlaccess

How do I add a char device via C w/o resorting to a bash script

I want to add a char device to /devices in my Linux directory via C code. Since I'm creating fictitious drivers that should only exist when I insmod my_module.ko, I want my module to create a device for me. Below is the part of my code which should add the device, but I only initialize my cdev struct and tell the kernel about it.
int start_mod(void){
//Because we are dealing with a fictitious device, I want
//the driver to create my two devices with arbitrarly
//assigned major numbers.
alloc_chrdev_region(&dev_num, FIRST_MINOR, COUNT, DEVICE_NAME); // This assigns my device name
// as well as asign Major # my driver uses
cdev_init(&(my_dev->my_cdev), &fops);// This initializes my cdev struct that the kernel uses to keep track of my device
my_dev->my_cdev.owner = THIS_MODULE;
my_dev->my_cdev.ops = &fops;// fops is my file operations struct
int err = cdev_add(&(my_dev->my_cdev), dev_num, COUNT);// this in theory should give a pointer to the kernel
// to my cdev struct that I have setup to exist in my other structure.
// Now I need to officially add my device to /devices folder.
return 0;
}
I'm not to sure what I need to do to officially add the char device to the kernel.
What you do is you use some of the newer registration functions in the kernel like class_create and device_create. This will allow udev to create your device.
Are you saying you wrote a driver without looking at any other drivers?
Because there is no shortage of examples about how to register a character device.
Look in
drivers/char
Those aforementioned functions are GPL-only, by the way, which has implications if you want to redistribute the code.
The mknod() system call used to be used...but only a root-privileged process can create devices in /dev usually.

Resources