In Linux we have 'mode' for each file/folder
if we do:
struct stat buf;
fstat("file_or_folder_name", &buf);
Then fstat function will fill the buf with lots of info including st_mode;
As I know this st_mode contains information about permission and the file type(tells if it is a file or a folder)
So I want to know If I have to generate/make/cook an st_mode from scratch, how can I make sure that it will tell it's
a file and some other time it will tell that it is a folder? That type I will know by doing: S_ISDIR(buf.st_mode)
ex:
mode_t my_file_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
but that only tells about permission.
I want to make it to tell the file type also.
Also I have to fill other members of: struct stat
So what data I can assign to st_dev and st_ino etc any idea?
Actually the file does not exist on disk, I will be reading the objects from cloud, and I will tell the caller if its a file or a folder along with other info.
I think you are looking for S_IFMT
Its available in mode_t.
Predefined values are:
S_IFBLK Block special.
S_IFCHR Character special.
S_IFIFO FIFO special.
S_IFREG Regular.
S_IFDIR Directory.
S_IFLNK Symbolic link.
S_IFSOCK Socket.
Reference
Related
I want to check the content of a file from Linux Kernel v3.0.8 knowing only struct inode *. I only need to read the beginning of a file pointed by this inode, then close and return. I don't care about additional information like filename/mountpoint etc.. In fact, the file may not have the name (like deleted but still open). Is it possible?
I finally did it like this:
This is needed.
struct path root;
struct file *filerd;
Get the init task fs root.
task_lock(&init_task);
get_fs_root(init_task.fs, &root);
task_unlock(&init_task);
Change dentry to this file:
root.dentry = d_find_alias(inode);
Open file:
filerd = file_open_root(root.dentry->d_parent, root.mnt,
root.dentry->d_name.name, O_RDONLY);
It worked for every process I tested and for different mount points, which surprised me.
First, a little background information to provide some motivation for this question: I've got a program that runs on a headless Linux server and reads/writes files on several removable external hard drives, each of which is formatted with ext4 filesystem. Very occasionally, the filesystem metadata on one of these drives gets corrupted for whatever reason (ext4 journalling notwithstanding), which can cause the ext4 filesystem drive to detect a problem and remount the partition as read-only, presumably as a precaution against cascading errors corrupting the drive further.
Okay, fair enough; but what I'd like to do now is add a function to my program that can detect when the drive is in this remounted-read-only state, so that it can pro-actively notify the user that his drive is in trouble.
My question is, what is an elegant/supported way to query a filesystem to find out if it is mounted read-only?
Attempting to write a file to the filesystem isn't good enough, because that could fail for other reasons, and also because I don't want to write to the filesystem if I don't have to.
My program could fopen("/proc/mounts", "r") and parse the lines of text that it generates (grepping for the "rw," token on the line corresponding to my partition), and I will if I have to, but that solution seems a bit hacky (too much like screen-scraping, liable to break if the text format ever changes).
So, is there some lightweight/purpose-built Linux system call that I could use that would tell me whether a given filesystem mount point (e.g. "/dev/sda1") is currently mounted read-only? It seems like stat() might be able to do it, but I can't see how.
The getmntent() family should meet your needs.
NAME
getmntent, setmntent, addmntent, endmntent, hasmntopt, getmntent_r -
get filesystem descriptor file entry
SYNOPSIS
#include <stdio.h>
#include <mntent.h>
FILE *setmntent(const char *filename, const char *type);
struct mntent *getmntent(FILE *stream);
int addmntent(FILE *stream, const struct mntent *mnt);
int endmntent(FILE *streamp);
char *hasmntopt(const struct mntent *mnt, const char *opt);
/* GNU extension */
#include <mntent.h>
struct mntent *getmntent_r(FILE *streamp, struct mntent *mntbuf,
char *buf, int buflen);
DESCRIPTION
These routines are used to access the filesystem description file
/etc/fstab and the mounted filesystem description file /etc/mtab.
The setmntent() function opens the filesystem description file
filename and returns a file pointer which can be used by getmntent().
The argument type is the type of access required and can take the same
values as the mode argument of fopen(3).
The getmntent() function reads the next line of the filesystem
description file from stream and returns a pointer to a structure
containing the broken out fields from a line in the file. The pointer
points to a static area of memory which is overwritten by subsequent
calls to getmntent().
The addmntent() function adds the mntent structure mnt to the end of
the open stream.
The endmntent() function closes the stream associated with the
filesystem description file.
The hasmntopt() function scans the mnt_opts field (see below) of the
mntent structure mnt for a substring that matches opt. See
and mount(8) for valid mount options.
The reentrant getmntent_r() function is similar to getmntent(), but
stores the struct mount in the provided *mntbuf and stores the strings
pointed to by the entries in that struct in the provided array buf of
size buflen.
The mntent structure is defined in as follows:
struct mntent {
char *mnt_fsname; /* name of mounted filesystem */
char *mnt_dir; /* filesystem path prefix */
char *mnt_type; /* mount type (see mntent.h) */
char *mnt_opts; /* mount options (see mntent.h) */
int mnt_freq; /* dump frequency in days */
int mnt_passno; /* pass number on parallel fsck */
};
...
The easiest way to check that the filesystem of an open file for writing has become mounted read-only is to check the errno variable for EROFS error.
If you don't have the possibility of having a writable directory or file in that filesystem, you cannot get a portable way of checking if the filesystem has become read only (more if it has become so due to device errors)
Another way is to ask the administrator to check, or try to read the /proc/mounts file yourself. But this is linux specific only.
I'm reading "The C Progamming Language" and practice a code to print out the file names inside a folder. Here's the snippet of code from the author for the UNIX system:
#ifndef DIRSIZ
#define DIRSIZ 14
#endif
struct direct /* directory entry */
{
ino_t d_ino; /* inode number */
char d_name[DIRSIZ];
} direct
...
struct direct dirbuf;
while(read(afiledescriptor, (char*) &dirbuf, sizeof(dirbuf))
== sizeof(dirbuf)){/* do sth with dirbuf */}
The problem is I don't know how directory file descriptors in Windows are constructed and thus can't specify the third parameter (the bytes to read parameter,DIRSIZE) in_read. Anyone can help? Thank you.
In general, file system function calls are very different between Linux/Unix and Windows. You simply cannot apply your Unix/Linux compatible C code on Windows. For everything regarding the file system in the Windows world, refer to MSDN.
To list files in directories for instance, there's a nice example on MSDN here.
In general, you will be working with FindFirstFile and FindNextFile. Read the documentation on MSDN, the examples and so on.
When coming from the Unix world you will have to get used to how things work on Windows. That takes some time, but it's worth the effort I guess.
I am trying to make a simple program that handles files and directories, but I have two major problems:
how can I check whether a file or directory exists or not, and
how do I know if it is a file, directory, symbolic link, device, named pipe etc.? Mainly file and directories matter for now, but I'd like to know the others too.
EDIT: Too all of those who are suggesting to use stat() or a similar function, I have already looked into that, and while it might answer my first question, I can't figure out how it would answer the second...
Since you're inquiring about named pipes/symlinks etc, you're probably on *nix, so use the
lstat() function
struct stat info;
if(lstat(name,&info) != 0) {
if(errno == ENOENT) {
// doesn't exist
} else if(errno == EACCES) {
// we don't have permission to know if
// the path/file exists.. impossible to tell
} else {
//general error handling
}
return;
}
//so, it exists.
if(S_ISDIR(info.st_mode)) {
//it's a directory
} else if(S_ISFIFO(info.st_mode)) {
//it's a named pipe
} else if(....) {
}
Se docs here for the S_ISXXX macros you can use.
The stat() function should give you everything you are looking for (or more specifically lstat() since stat() will follow the link).
Use stat (or if you wish to get information about a symbolic link instead of following it and getting information about the destination, lstat)
NAME
stat - get file status
SYNOPSIS
#include <sys/stat.h>
int stat(const char *restrict path, struct stat *restrict buf);
DESCRIPTION
The stat() function shall obtain information about the named file and write it to the area pointed to by the buf argument. The path argument points to a pathname naming a file. Read, write, or execute permission of the named file is not required. An implementation that provides additional or alternate file access control mechanisms may, under implementation-defined conditions, cause stat() to fail. In particular, the system may deny the existence of the file specified by path.
If the named file is a symbolic link, the stat() function shall continue pathname resolution using the contents of the symbolic link, and shall return information pertaining to the resulting file if the file exists.
The buf argument is a pointer to a stat structure, as defined in the header, into which information is placed concerning the file.
Is there a way to retrieve path information from a file descriptor or FILE pointer?
I'm aware that this data may not always be relevant/useful for case where the file descriptor is a socket, pipe, etc.
I don't believe there's any portable way, but e.g. on Linux you can call readlink on "/proc/self/fd/fileno" and the kernel will give you a path if it can, or one of various kinds of funny-looking strings if not.
If you're lucky enough to be using Mac OS X you can use the following code:
#define _DARWIN_C_SOURCE
#include <sys/fcntl.h>
.
.
.
char pathbuf[PATH_MAX];
if (fcntl(fd, F_GETPATH, pathbuf) >= 0) {
// pathbuf now contains *a* path to the open file descriptor
}
Note that the path you get back is not necessarily the one used to open the file... If there are hard links, especially, the path you get back will be a valid path to the file.
There can be one or many names for a file, so no std way.
I am not sure if there can be something OS specific.