mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:58:11 +00:00
Make stat() work on device files again.
FileDescriptor will now keep a pointer to the original inode even after opening it resolves to a character device. Fixed up /bin/ls to display major and minor device numbers instead of size for device files.
This commit is contained in:
parent
c3cc318028
commit
c4fce9b3f9
8 changed files with 25 additions and 10 deletions
|
@ -360,7 +360,7 @@ InodeMetadata Ext2FSInode::metadata() const
|
||||||
if (isBlockDevice(m_raw_inode.i_mode) || isCharacterDevice(m_raw_inode.i_mode)) {
|
if (isBlockDevice(m_raw_inode.i_mode) || isCharacterDevice(m_raw_inode.i_mode)) {
|
||||||
unsigned dev = m_raw_inode.i_block[0];
|
unsigned dev = m_raw_inode.i_block[0];
|
||||||
metadata.majorDevice = (dev & 0xfff00) >> 8;
|
metadata.majorDevice = (dev & 0xfff00) >> 8;
|
||||||
metadata.minorDevice= (dev & 0xff) | ((dev >> 12) & 0xfff00);
|
metadata.minorDevice = (dev & 0xff) | ((dev >> 12) & 0xfff00);
|
||||||
}
|
}
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,10 +59,11 @@ RetainPtr<FileDescriptor> FileDescriptor::clone()
|
||||||
? FileDescriptor::create_pipe_reader(*m_fifo)
|
? FileDescriptor::create_pipe_reader(*m_fifo)
|
||||||
: FileDescriptor::create_pipe_writer(*m_fifo);
|
: FileDescriptor::create_pipe_writer(*m_fifo);
|
||||||
} else {
|
} else {
|
||||||
if (m_inode)
|
if (m_device) {
|
||||||
descriptor = FileDescriptor::create(m_inode.copyRef());
|
|
||||||
else {
|
|
||||||
descriptor = FileDescriptor::create(m_device.copyRef());
|
descriptor = FileDescriptor::create(m_device.copyRef());
|
||||||
|
descriptor->m_inode = m_inode.copyRef();
|
||||||
|
} else {
|
||||||
|
descriptor = FileDescriptor::create(m_inode.copyRef());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!descriptor)
|
if (!descriptor)
|
||||||
|
@ -90,7 +91,7 @@ int FileDescriptor::fstat(stat* buffer)
|
||||||
if (!metadata.isValid())
|
if (!metadata.isValid())
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
buffer->st_dev = 0; // FIXME
|
buffer->st_dev = encodedDevice(metadata.majorDevice, metadata.minorDevice);
|
||||||
buffer->st_ino = metadata.inode.index();
|
buffer->st_ino = metadata.inode.index();
|
||||||
buffer->st_mode = metadata.mode;
|
buffer->st_mode = metadata.mode;
|
||||||
buffer->st_nlink = metadata.linkCount;
|
buffer->st_nlink = metadata.linkCount;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
#include <AK/CircularQueue.h>
|
#include <AK/CircularQueue.h>
|
||||||
#include <AK/Retainable.h>
|
#include <AK/Retainable.h>
|
||||||
|
#include <AK/Badge.h>
|
||||||
|
|
||||||
class TTY;
|
class TTY;
|
||||||
class MasterPTY;
|
class MasterPTY;
|
||||||
|
@ -68,6 +69,8 @@ public:
|
||||||
|
|
||||||
ByteBuffer& generator_cache() { return m_generator_cache; }
|
ByteBuffer& generator_cache() { return m_generator_cache; }
|
||||||
|
|
||||||
|
void set_original_inode(Badge<VFS>, RetainPtr<Inode>&& inode) { m_inode = move(inode); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class VFS;
|
friend class VFS;
|
||||||
explicit FileDescriptor(RetainPtr<Inode>&&);
|
explicit FileDescriptor(RetainPtr<Inode>&&);
|
||||||
|
|
|
@ -1215,7 +1215,7 @@ int Process::sys$lstat(const char* path, stat* statbuf)
|
||||||
if (!validate_write_typed(statbuf))
|
if (!validate_write_typed(statbuf))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
int error;
|
int error;
|
||||||
auto descriptor = VFS::the().open(move(path), error, O_NOFOLLOW_NOERROR, 0, cwd_inode()->identifier());
|
auto descriptor = VFS::the().open(move(path), error, O_NOFOLLOW_NOERROR | O_DONT_OPEN_DEVICE, 0, cwd_inode()->identifier());
|
||||||
if (!descriptor)
|
if (!descriptor)
|
||||||
return error;
|
return error;
|
||||||
descriptor->fstat(statbuf);
|
descriptor->fstat(statbuf);
|
||||||
|
@ -1227,7 +1227,7 @@ int Process::sys$stat(const char* path, stat* statbuf)
|
||||||
if (!validate_write_typed(statbuf))
|
if (!validate_write_typed(statbuf))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
int error;
|
int error;
|
||||||
auto descriptor = VFS::the().open(move(path), error, 0, 0, cwd_inode()->identifier());
|
auto descriptor = VFS::the().open(move(path), error, O_DONT_OPEN_DEVICE, 0, cwd_inode()->identifier());
|
||||||
if (!descriptor)
|
if (!descriptor)
|
||||||
return error;
|
return error;
|
||||||
descriptor->fstat(statbuf);
|
descriptor->fstat(statbuf);
|
||||||
|
|
|
@ -146,13 +146,15 @@ RetainPtr<FileDescriptor> VFS::open(const String& path, int& error, int options,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto metadata = inode->metadata();
|
auto metadata = inode->metadata();
|
||||||
if (metadata.isCharacterDevice()) {
|
if (!(options & O_DONT_OPEN_DEVICE) && metadata.isCharacterDevice()) {
|
||||||
auto it = m_character_devices.find(encodedDevice(metadata.majorDevice, metadata.minorDevice));
|
auto it = m_character_devices.find(encodedDevice(metadata.majorDevice, metadata.minorDevice));
|
||||||
if (it == m_character_devices.end()) {
|
if (it == m_character_devices.end()) {
|
||||||
kprintf("VFS::open: no such character device %u,%u\n", metadata.majorDevice, metadata.minorDevice);
|
kprintf("VFS::open: no such character device %u,%u\n", metadata.majorDevice, metadata.minorDevice);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return (*it).value->open(error, options);
|
auto descriptor = (*it).value->open(error, options);
|
||||||
|
descriptor->set_original_inode(Badge<VFS>(), move(inode));
|
||||||
|
return descriptor;
|
||||||
}
|
}
|
||||||
return FileDescriptor::create(move(inode));
|
return FileDescriptor::create(move(inode));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#define O_NOFOLLOW 00400000
|
#define O_NOFOLLOW 00400000
|
||||||
#define O_CLOEXEC 02000000
|
#define O_CLOEXEC 02000000
|
||||||
#define O_NOFOLLOW_NOERROR 0x4000000
|
#define O_NOFOLLOW_NOERROR 0x4000000
|
||||||
|
#define O_DONT_OPEN_DEVICE 0x8000000
|
||||||
|
|
||||||
class CharacterDevice;
|
class CharacterDevice;
|
||||||
class FileDescriptor;
|
class FileDescriptor;
|
||||||
|
|
|
@ -9,4 +9,8 @@ mode_t umask(mode_t);
|
||||||
int chmod(const char* pathname, mode_t);
|
int chmod(const char* pathname, mode_t);
|
||||||
int mkdir(const char* pathname, mode_t);
|
int mkdir(const char* pathname, mode_t);
|
||||||
|
|
||||||
|
inline dev_t makedev(unsigned int major, unsigned int minor) { return (minor & 0xffu) | (major << 8u) | ((minor & ~0xffu) << 12u); }
|
||||||
|
inline unsigned int major(dev_t dev) { return (dev & 0xfff00u) >> 8u; }
|
||||||
|
inline unsigned int minor(dev_t dev) { return (dev & 0xffu) | ((dev >> 12u) & 0xfff00u); }
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <AK/AKString.h>
|
#include <AK/AKString.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
|
@ -150,7 +151,10 @@ int do_dir(const char* path)
|
||||||
|
|
||||||
printf(" %4u %4u", st.st_uid, st.st_gid);
|
printf(" %4u %4u", st.st_uid, st.st_gid);
|
||||||
|
|
||||||
printf(" %10u ", st.st_size);
|
if (S_ISCHR(st.st_mode))
|
||||||
|
printf(" %4u,%4u ", major(st.st_dev), minor(st.st_dev));
|
||||||
|
else
|
||||||
|
printf(" %10u ", st.st_size);
|
||||||
|
|
||||||
printf(" %10u ", st.st_mtime);
|
printf(" %10u ", st.st_mtime);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue