isastream system call is used to determine if a descriptor refers to a stream or not.
System Definition:
ubuntu@ip-172-31-23-227:~$ less /usr/include/stropts.h
......
/* Test whether FILDES is associated with a STREAM-based file. */
extern int isastream (int __fildes) __THROW;
......
Example:
stream.c
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<stropts.h>
int main(int argc, char* argv[])
{
int i, fd;
for(i = 1; i < argc; i++) {
if((fd = open(argv[i], O_RDONLY)) < 0) {
printf("%s: can't open\n", argv[i]);
continue;
}
if(isastream(fd) == 0) {
printf("%s: not a stream\n", argv[i]);
}
else {
printf("%s: streams device\n", argv[i]);
}
}
exit(0);
}
shell:
ubuntu@ip-172-31-23-227:~$ ./stream.out /dev/tty /dev/fb /dev/null /etc/mtab
/dev/tty: not a stream
/dev/fb: can't open
/dev/null: not a stream
/etc/mtab: not a stream
2. isastream implementation
isastream merely use ioctl that is valid only on STREAM device. I_CANPUT ioctl command checks if the band specified by the third argument is writable.
ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/bits/stropts.h
......
/* Macros used as `request' argument to `ioctl'. */
#define __SID ('S' << 8)
#define I_NREAD (__SID | 1) /* Counts the number of data bytes in the data
block in the first message. */
#define I_PUSH (__SID | 2) /* Push STREAMS module onto top of the current
STREAM, just below the STREAM head. */
#define I_POP (__SID | 3) /* Remove STREAMS module from just below the
STREAM head. */
......
#define I_CANPUT (__SID |34) /* Check if a certain band is writable. */
......
Example:
stream.c:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<stropts.h>
int isastream(int fd)
{
printf("own isastream test: ");
return(ioctl(fd, I_CANPUT, 0) != -1);
}
int main(int argc, char* argv[])
{
int i, fd;
for(i = 1; i < argc; i++) {
if((fd = open(argv[i], O_RDONLY)) < 0) {
printf("%s: can't open\n", argv[i]);
continue;
}
if(isastream(fd) == 0) {
printf("%s: not a stream\n", argv[i]);
}
else {
printf("%s: streams device\n", argv[i]);
}
}
exit(0);
}
shell:
ubuntu@ip-172-31-23-227:~$ ./stream.out /dev/tty /dev/fb /dev/null /etc/mtab
own isastream test: /dev/tty: not a stream
/dev/fb: can't open
own isastream test: /dev/null: not a stream
own isastream test: /etc/mtab: not a stream
3. Return the modules on the stream
module.c:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<stropts.h>
int main(int argc, char *argv[])
{
int fd, i, nmods;
struct str_list list;
// Open the file descriptor
if((fd = open(argv[1], O_RDONLY)) < 0) {
printf("can't open %s", argv[1]);
exit(1);
}
if(isastream(fd) == 0) {
printf("%s is not a stream", argv[1]);
exit(2);
}
// Return the number of modules in the stream
// With second argument as : I_LIST, third argument 0
if((nmods = ioctl(fd, I_LIST, (void*) 0)) < 0) {
printf("I_LIST error for nmods");
exit(3);
}
printf("#modules = %d\n", nmods);
// Allocate struct str_mlist
list.sl_modlist = calloc(nmods, sizeof(struct str_mlist));
if(list.sl_modlist == NULL) {
printf("calloc error!\n");
exit(4);
}
list.sl_nmods = nmods;
if(ioctl(fd, I_LIST, &list) < 0) {
printf("I_LIST error for list");
exit(4);
}
// Print out all modules
for(i = 1; i <=nmods; i++)
printf(" %s: %s\n", (i == nmods) ? "driver" : "module", list.sl_modlist++->l_name);
exit(0);
}
Definition:
ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/bits/stropts.h
......
struct str_mlist
{
char l_name[FMNAMESZ + 1];
};
struct str_list
{
int sl_nmods;
struct str_mlist *sl_modlist;
};
......
No comments:
Post a Comment