New stat structure.
* VFS and installed MFSes must be in sync before and after this change * Use struct stat from NetBSD. It requires adding new STAT, FSTAT and LSTAT syscalls. Libc modification is both backward and forward compatible. Also new struct stat uses modern field sizes to avoid ABI incompatibility, when we update uid_t, gid_t and company. Exceptions are ino_t and off_t in old libc (though paddings added).
This commit is contained in:
parent
48331843ea
commit
ef0a265086
34 changed files with 533 additions and 417 deletions
|
@ -76,10 +76,8 @@ struct field {
|
||||||
{ "mtime", addr(st_mtime), size(st_mtime), 0 },
|
{ "mtime", addr(st_mtime), size(st_mtime), 0 },
|
||||||
{ "Ctime", addr(st_ctime), size(st_ctime), 0 },
|
{ "Ctime", addr(st_ctime), size(st_ctime), 0 },
|
||||||
{ "ctime", addr(st_ctime), size(st_ctime), 0 },
|
{ "ctime", addr(st_ctime), size(st_ctime), 0 },
|
||||||
# ifdef BSD
|
|
||||||
{ "blksize", addr(st_blksize), size(st_blksize), 0 },
|
{ "blksize", addr(st_blksize), size(st_blksize), 0 },
|
||||||
{ "blocks", addr(st_blocks), size(st_blocks), 0 },
|
{ "blocks", addr(st_blocks), size(st_blocks), 0 },
|
||||||
# endif
|
|
||||||
{ NULL, 0, 0, 0 },
|
{ NULL, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#define CHMOD 15
|
#define CHMOD 15
|
||||||
#define CHOWN 16
|
#define CHOWN 16
|
||||||
#define BRK 17
|
#define BRK 17
|
||||||
#define STAT 18
|
#define PREV_STAT 18
|
||||||
#define LSEEK 19
|
#define LSEEK 19
|
||||||
#define MINIX_GETPID 20
|
#define MINIX_GETPID 20
|
||||||
#define MOUNT 21
|
#define MOUNT 21
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
#define STIME 25
|
#define STIME 25
|
||||||
#define PTRACE 26
|
#define PTRACE 26
|
||||||
#define ALARM 27
|
#define ALARM 27
|
||||||
#define FSTAT 28
|
#define PREV_FSTAT 28
|
||||||
#define PAUSE 29
|
#define PAUSE 29
|
||||||
#define UTIME 30
|
#define UTIME 30
|
||||||
#define ACCESS 33
|
#define ACCESS 33
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
#define GETGID 47
|
#define GETGID 47
|
||||||
#define SIGNAL 48
|
#define SIGNAL 48
|
||||||
#define RDLNK 49
|
#define RDLNK 49
|
||||||
#define LSTAT 50
|
#define PREV_LSTAT 50
|
||||||
#define IOCTL 54
|
#define IOCTL 54
|
||||||
#define FCNTL 55
|
#define FCNTL 55
|
||||||
#define FS_READY 57
|
#define FS_READY 57
|
||||||
|
@ -115,6 +115,11 @@
|
||||||
|
|
||||||
#define GCOV_FLUSH 112 /* flush gcov data from server to gcov files */
|
#define GCOV_FLUSH 112 /* flush gcov data from server to gcov files */
|
||||||
|
|
||||||
|
/* Numbers reused intentionally */
|
||||||
|
#define STAT 65
|
||||||
|
#define FSTAT 66
|
||||||
|
#define LSTAT 67
|
||||||
|
|
||||||
#define TASK_REPLY 121 /* to VFS: reply code from drivers, not
|
#define TASK_REPLY 121 /* to VFS: reply code from drivers, not
|
||||||
* really a standalone call.
|
* really a standalone call.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -167,7 +167,7 @@ struct exec_newmem
|
||||||
int is_elf; /* Is ELF exe? */
|
int is_elf; /* Is ELF exe? */
|
||||||
dev_t st_dev; /* Device holding executable file */
|
dev_t st_dev; /* Device holding executable file */
|
||||||
ino_t st_ino; /* Inode of executable file */
|
ino_t st_ino; /* Inode of executable file */
|
||||||
time_t st_ctime; /* Last changed time of executable file */
|
time_t enst_ctime; /* Last changed time of executable file */
|
||||||
uid_t new_uid; /* Process UID after exec */
|
uid_t new_uid; /* Process UID after exec */
|
||||||
gid_t new_gid; /* Process GID after exec */
|
gid_t new_gid; /* Process GID after exec */
|
||||||
char progname[16]; /* Should be at least PROC_NAME_LEN */
|
char progname[16]; /* Should be at least PROC_NAME_LEN */
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
20110708
|
||||||
|
* VFS and installed MFSes must be in sync before and after this change *
|
||||||
|
|
||||||
|
You must update the GNU headers.
|
||||||
|
# cd /usr/src
|
||||||
|
# make gnu-includes
|
||||||
|
|
||||||
|
You must rebuild both MFS and VFS (including those one in the image).
|
||||||
|
Either make world or do the following:
|
||||||
|
# cd /usr/src/servers/mfs
|
||||||
|
# make install
|
||||||
|
# cd /usr/src/servers/vfs
|
||||||
|
# make install
|
||||||
|
# cd /usr/src/tools
|
||||||
|
# make hdboot
|
||||||
|
# shutdown -r now
|
||||||
|
|
||||||
20110701:
|
20110701:
|
||||||
# rm -rf /usr/include /usr/netbsd
|
# rm -rf /usr/include /usr/netbsd
|
||||||
# make etcfiles includes cleandepend depend gnu-includes
|
# make etcfiles includes cleandepend depend gnu-includes
|
||||||
|
|
|
@ -99,17 +99,28 @@ typedef long key_t;
|
||||||
typedef long useconds_t; /* Time in microseconds */
|
typedef long useconds_t; /* Time in microseconds */
|
||||||
|
|
||||||
typedef short dev_t; /* holds (major|minor) device pair */
|
typedef short dev_t; /* holds (major|minor) device pair */
|
||||||
|
typedef u32_t big_dev_t;
|
||||||
|
|
||||||
/* Types used in disk, inode, etc. data structures. */
|
/* Types used in disk, inode, etc. data structures.
|
||||||
|
* Some u64_t should be i64_t, but anyway with old libc we use .lo only.
|
||||||
|
*/
|
||||||
typedef char gid_t; /* group id */
|
typedef char gid_t; /* group id */
|
||||||
|
typedef u32_t big_gid_t; /* group id */
|
||||||
typedef unsigned long ino_t; /* i-node number (V3 filesystem) */
|
typedef unsigned long ino_t; /* i-node number (V3 filesystem) */
|
||||||
|
typedef u64_t big_ino_t; /* i-node number (V3 filesystem) */
|
||||||
typedef unsigned short mode_t; /* file type and permissions bits */
|
typedef unsigned short mode_t; /* file type and permissions bits */
|
||||||
|
typedef u32_t big_mode_t; /* file type and permissions bits */
|
||||||
typedef short nlink_t; /* number of links to a file */
|
typedef short nlink_t; /* number of links to a file */
|
||||||
|
typedef u32_t big_nlink_t;/* number of links to a file */
|
||||||
typedef long off_t; /* offset within a file */
|
typedef long off_t; /* offset within a file */
|
||||||
|
typedef u64_t big_off_t; /* offset within a file */
|
||||||
typedef int pid_t; /* process id (must be signed) */
|
typedef int pid_t; /* process id (must be signed) */
|
||||||
typedef short uid_t; /* user id */
|
typedef short uid_t; /* user id */
|
||||||
|
typedef u32_t big_uid_t; /* user id */
|
||||||
typedef unsigned long fsblkcnt_t; /* File system block count */
|
typedef unsigned long fsblkcnt_t; /* File system block count */
|
||||||
typedef unsigned long fsfilcnt_t; /* File system file count */
|
typedef unsigned long fsfilcnt_t; /* File system file count */
|
||||||
|
typedef u32_t blkcnt_t; /* File system block count */
|
||||||
|
typedef unsigned long blksize_t; /* File system block size */
|
||||||
|
|
||||||
/* Signal handler type, e.g. SIG_IGN */
|
/* Signal handler type, e.g. SIG_IGN */
|
||||||
typedef void _PROTOTYPE( (*sighandler_t), (int) );
|
typedef void _PROTOTYPE( (*sighandler_t), (int) );
|
||||||
|
|
|
@ -10,7 +10,43 @@
|
||||||
#include <minix/types.h>
|
#include <minix/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct stat {
|
struct stat {
|
||||||
|
big_dev_t st_dev; /* inode's device */
|
||||||
|
big_mode_t st_mode; /* inode protection mode */
|
||||||
|
ino_t st_ino; /* inode's number */
|
||||||
|
u32_t padding; /* inode's padding */
|
||||||
|
big_nlink_t st_nlink; /* number of hard links */
|
||||||
|
big_uid_t st_uid; /* user ID of the file's owner */
|
||||||
|
big_gid_t st_gid; /* group ID of the file's group */
|
||||||
|
big_dev_t st_rdev; /* device type */
|
||||||
|
#if defined(_NETBSD_SOURCE)
|
||||||
|
struct timespec st_atimespec;/* time of last access */
|
||||||
|
struct timespec st_mtimespec;/* time of last data modification */
|
||||||
|
struct timespec st_ctimespec;/* time of last file status change */
|
||||||
|
struct timespec st_birthtimespec; /* time of creation */
|
||||||
|
#else
|
||||||
|
time_t st_atime; /* time of last access */
|
||||||
|
long st_atimensec; /* nsec of last access */
|
||||||
|
time_t st_mtime; /* time of last data modification */
|
||||||
|
long st_mtimensec; /* nsec of last data modification */
|
||||||
|
time_t st_ctime; /* time of last file status change */
|
||||||
|
long st_ctimensec; /* nsec of last file status change */
|
||||||
|
time_t st_birthtime; /* time of creation */
|
||||||
|
long st_birthtimensec; /* nsec of time of creation */
|
||||||
|
#endif
|
||||||
|
off_t st_size; /* file size, in bytes */
|
||||||
|
u32_t padding2; /* size padding */
|
||||||
|
blkcnt_t st_blocks; /* blocks allocated for file */
|
||||||
|
u32_t padding3; /* blocks padding */
|
||||||
|
blksize_t st_blksize; /* optimal blocksize for I/O */
|
||||||
|
u32_t st_flags; /* user defined flags for file */
|
||||||
|
u32_t st_gen; /* file generation number */
|
||||||
|
u32_t st_spare[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct minix_prev_stat {
|
||||||
dev_t st_dev; /* major/minor device number */
|
dev_t st_dev; /* major/minor device number */
|
||||||
ino_t st_ino; /* i-node number */
|
ino_t st_ino; /* i-node number */
|
||||||
mode_t st_mode; /* file mode, protection bits, etc. */
|
mode_t st_mode; /* file mode, protection bits, etc. */
|
||||||
|
@ -24,6 +60,25 @@ struct stat {
|
||||||
time_t st_ctime; /* time of last file status change */
|
time_t st_ctime; /* time of last file status change */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy field by field because of st_gid type mismath and
|
||||||
|
* difference in order after atime.
|
||||||
|
*/
|
||||||
|
#define COPY_PREV_STAT_TO_NEW(dest, src)\
|
||||||
|
(dest)->st_dev = (src)->st_dev;\
|
||||||
|
(dest)->st_ino = (src)->st_ino;\
|
||||||
|
(dest)->st_mode = (src)->st_mode;\
|
||||||
|
(dest)->st_nlink = (src)->st_nlink;\
|
||||||
|
(dest)->st_uid = (src)->st_uid;\
|
||||||
|
(dest)->st_gid = (src)->st_gid;\
|
||||||
|
(dest)->st_rdev = (src)->st_rdev;\
|
||||||
|
(dest)->st_size = (src)->st_size;\
|
||||||
|
(dest)->st_atime = (src)->st_atime;\
|
||||||
|
(dest)->st_mtime = (src)->st_mtime;\
|
||||||
|
(dest)->st_ctime = (src)->st_ctime
|
||||||
|
|
||||||
|
#define S_BLKSIZE 512 /* block size used in the stat struct */
|
||||||
|
|
||||||
/* Traditional mask definitions for st_mode. */
|
/* Traditional mask definitions for st_mode. */
|
||||||
#define S_IFMT 0170000 /* type of file */
|
#define S_IFMT 0170000 /* type of file */
|
||||||
#define S_IFSOCK 0140000 /* socket */
|
#define S_IFSOCK 0140000 /* socket */
|
||||||
|
|
|
@ -1,14 +1,35 @@
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
#define fstat _fstat
|
#define fstat _fstat
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
PUBLIC int fstat(fd, buffer)
|
PUBLIC int fstat(fd, buffer)
|
||||||
int fd;
|
int fd;
|
||||||
struct stat *buffer;
|
struct stat *buffer;
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
int r;
|
||||||
|
struct minix_prev_stat old_sb;
|
||||||
|
|
||||||
m.m1_i1 = fd;
|
m.m1_i1 = fd;
|
||||||
m.m1_p1 = (char *) buffer;
|
m.m1_p1 = (char *) buffer;
|
||||||
return(_syscall(VFS_PROC_NR, FSTAT, &m));
|
|
||||||
|
if((r = _syscall(VFS_PROC_NR, FSTAT, &m)) >= 0 || errno != ENOSYS)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* ENOSYS: new binary and old VFS, fallback to PREV_STAT.
|
||||||
|
* User has struct stat (buffer), VFS still fills minix_prev_stat.
|
||||||
|
*/
|
||||||
|
m.m1_i1 = fd;
|
||||||
|
m.m1_p1 = (char *) &old_sb;
|
||||||
|
|
||||||
|
if((r = _syscall(VFS_PROC_NR, PREV_FSTAT, &m)) < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(struct stat));
|
||||||
|
COPY_PREV_STAT_TO_NEW(buffer, &old_sb);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
#define lstat _lstat
|
#define lstat _lstat
|
||||||
#define stat _stat
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -10,11 +9,29 @@ struct stat *buffer;
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
int r;
|
int r;
|
||||||
|
struct minix_prev_stat old_sb;
|
||||||
|
|
||||||
m.m1_i1 = strlen(name) + 1;
|
m.m1_i1 = strlen(name) + 1;
|
||||||
m.m1_p1 = (char *) name;
|
m.m1_p1 = (char *) name;
|
||||||
m.m1_p2 = (char *) buffer;
|
m.m1_p2 = (char *) buffer;
|
||||||
|
|
||||||
if((r = _syscall(VFS_PROC_NR, LSTAT, &m)) >= 0 || errno != ENOSYS)
|
if((r = _syscall(VFS_PROC_NR, LSTAT, &m)) >= 0 || errno != ENOSYS)
|
||||||
return r;
|
return r;
|
||||||
return _stat(name, buffer);
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* ENOSYS: new binary and old VFS, fallback to PREV_STAT.
|
||||||
|
* User has struct stat (buffer), VFS still fills minix_prev_stat.
|
||||||
|
*/
|
||||||
|
m.m1_i1 = strlen(name) + 1;
|
||||||
|
m.m1_p1 = (char *) name;
|
||||||
|
m.m1_p2 = (char *) &old_sb;
|
||||||
|
|
||||||
|
if((r = _syscall(VFS_PROC_NR, PREV_LSTAT, &m)) < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(struct stat));
|
||||||
|
COPY_PREV_STAT_TO_NEW(buffer, &old_sb);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,30 @@ _CONST char *name;
|
||||||
struct stat *buffer;
|
struct stat *buffer;
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
int r;
|
||||||
|
struct minix_prev_stat old_sb;
|
||||||
|
|
||||||
m.m1_i1 = strlen(name) + 1;
|
m.m1_i1 = strlen(name) + 1;
|
||||||
m.m1_p1 = (char *) name;
|
m.m1_p1 = (char *) name;
|
||||||
m.m1_p2 = (char *) buffer;
|
m.m1_p2 = (char *) buffer;
|
||||||
return(_syscall(VFS_PROC_NR, STAT, &m));
|
|
||||||
|
if((r = _syscall(VFS_PROC_NR, STAT, &m)) >= 0 || errno != ENOSYS)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* ENOSYS: new binary and old VFS, fallback to PREV_STAT.
|
||||||
|
* User has struct stat (buffer), VFS still fills minix_prev_stat.
|
||||||
|
*/
|
||||||
|
m.m1_i1 = strlen(name) + 1;
|
||||||
|
m.m1_p1 = (char *) name;
|
||||||
|
m.m1_p2 = (char *) &old_sb;
|
||||||
|
|
||||||
|
if((r = _syscall(VFS_PROC_NR, PREV_STAT, &m)) < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(struct stat));
|
||||||
|
COPY_PREV_STAT_TO_NEW(buffer, &old_sb);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/statfs.h>
|
#include <sys/statfs.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* fs_stat *
|
* fs_stat *
|
||||||
|
@ -22,6 +23,8 @@ PUBLIC int fs_stat(void)
|
||||||
if ((node = find_inode(fs_m_in.REQ_INODE_NR)) == NULL)
|
if ((node = find_inode(fs_m_in.REQ_INODE_NR)) == NULL)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
|
memset(&statbuf, 0, sizeof(struct stat));
|
||||||
|
|
||||||
/* Fill in the basic info. */
|
/* Fill in the basic info. */
|
||||||
statbuf.st_dev = fs_dev;
|
statbuf.st_dev = fs_dev;
|
||||||
statbuf.st_ino = get_inode_number(node);
|
statbuf.st_ino = get_inode_number(node);
|
||||||
|
|
|
@ -263,10 +263,15 @@ __bt_open(const char *fname, int flags, mode_t mode, const BTREEINFO *openinfo,
|
||||||
*/
|
*/
|
||||||
if (b.psize == 0) {
|
if (b.psize == 0) {
|
||||||
#ifdef __minix
|
#ifdef __minix
|
||||||
|
if (sb.st_blksize == 0) {
|
||||||
|
/* 0 in 2 cases: upgrade from old to new struct stat or
|
||||||
|
* there is a bug in underlying fs.
|
||||||
|
*/
|
||||||
b.psize = MINIX_ST_BLKSIZE;
|
b.psize = MINIX_ST_BLKSIZE;
|
||||||
#else
|
} else
|
||||||
b.psize = sb.st_blksize;
|
|
||||||
#endif
|
#endif
|
||||||
|
b.psize = sb.st_blksize;
|
||||||
|
|
||||||
if (b.psize < MINPSIZE)
|
if (b.psize < MINPSIZE)
|
||||||
b.psize = MINPSIZE;
|
b.psize = MINPSIZE;
|
||||||
if (b.psize > MAX_PAGE_OFFSET + 1)
|
if (b.psize > MAX_PAGE_OFFSET + 1)
|
||||||
|
|
|
@ -302,10 +302,15 @@ init_hash(HTAB *hashp, const char *file, const HASHINFO *info)
|
||||||
if (stat(file, &statbuf))
|
if (stat(file, &statbuf))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
#ifdef __minix
|
#ifdef __minix
|
||||||
|
if (statbuf.st_blksize == 0) {
|
||||||
|
/* 0 in 2 cases: upgrade from old to new struct stat or
|
||||||
|
* there is a bug in underlying fs.
|
||||||
|
*/
|
||||||
hashp->BSIZE = MIN(MINIX_ST_BLKSIZE, MAX_BSIZE);
|
hashp->BSIZE = MIN(MINIX_ST_BLKSIZE, MAX_BSIZE);
|
||||||
#else
|
} else
|
||||||
hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE);
|
|
||||||
#endif
|
#endif
|
||||||
|
hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE);
|
||||||
|
|
||||||
hashp->BSHIFT = __log2((uint32_t)hashp->BSIZE);
|
hashp->BSHIFT = __log2((uint32_t)hashp->BSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -280,15 +280,21 @@ diff -ru nbsdsrc/src/lib/libc/compat-43/Makefile.inc lib/nbsd_libc/compat-43/Mak
|
||||||
diff -ru nbsdsrc/src/lib/libc/db/btree/bt_open.c lib/nbsd_libc/db/btree/bt_open.c
|
diff -ru nbsdsrc/src/lib/libc/db/btree/bt_open.c lib/nbsd_libc/db/btree/bt_open.c
|
||||||
--- nbsdsrc/src/lib/libc/db/btree/bt_open.c
|
--- nbsdsrc/src/lib/libc/db/btree/bt_open.c
|
||||||
+++ lib/nbsd_libc/db/btree/bt_open.c
|
+++ lib/nbsd_libc/db/btree/bt_open.c
|
||||||
@@ -262,7 +262,11 @@
|
@@ -262,7 +262,16 @@
|
||||||
* Don't overflow the page offset type.
|
* Don't overflow the page offset type.
|
||||||
*/
|
*/
|
||||||
if (b.psize == 0) {
|
if (b.psize == 0) {
|
||||||
|
- b.psize = sb.st_blksize;
|
||||||
+#ifdef __minix
|
+#ifdef __minix
|
||||||
|
+ if (sb.st_blksize == 0) {
|
||||||
|
+ /* 0 in 2 cases: upgrade from old to new struct stat or
|
||||||
|
+ * there is a bug in underlying fs.
|
||||||
|
+ */
|
||||||
+ b.psize = MINIX_ST_BLKSIZE;
|
+ b.psize = MINIX_ST_BLKSIZE;
|
||||||
+#else
|
+ } else
|
||||||
b.psize = sb.st_blksize;
|
|
||||||
+#endif
|
+#endif
|
||||||
|
+ b.psize = sb.st_blksize;
|
||||||
|
+
|
||||||
if (b.psize < MINPSIZE)
|
if (b.psize < MINPSIZE)
|
||||||
b.psize = MINPSIZE;
|
b.psize = MINPSIZE;
|
||||||
if (b.psize > MAX_PAGE_OFFSET + 1)
|
if (b.psize > MAX_PAGE_OFFSET + 1)
|
||||||
|
@ -314,15 +320,21 @@ diff -ru nbsdsrc/src/lib/libc/db/db/db.c lib/nbsd_libc/db/db/db.c
|
||||||
diff -ru nbsdsrc/src/lib/libc/db/hash/hash.c lib/nbsd_libc/db/hash/hash.c
|
diff -ru nbsdsrc/src/lib/libc/db/hash/hash.c lib/nbsd_libc/db/hash/hash.c
|
||||||
--- nbsdsrc/src/lib/libc/db/hash/hash.c
|
--- nbsdsrc/src/lib/libc/db/hash/hash.c
|
||||||
+++ lib/nbsd_libc/db/hash/hash.c
|
+++ lib/nbsd_libc/db/hash/hash.c
|
||||||
@@ -301,7 +301,11 @@
|
@@ -301,7 +301,16 @@
|
||||||
if (file != NULL) {
|
if (file != NULL) {
|
||||||
if (stat(file, &statbuf))
|
if (stat(file, &statbuf))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
- hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE);
|
||||||
+#ifdef __minix
|
+#ifdef __minix
|
||||||
|
+ if (statbuf.st_blksize == 0) {
|
||||||
|
+ /* 0 in 2 cases: upgrade from old to new struct stat or
|
||||||
|
+ * there is a bug in underlying fs.
|
||||||
|
+ */
|
||||||
+ hashp->BSIZE = MIN(MINIX_ST_BLKSIZE, MAX_BSIZE);
|
+ hashp->BSIZE = MIN(MINIX_ST_BLKSIZE, MAX_BSIZE);
|
||||||
+#else
|
+ } else
|
||||||
hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE);
|
|
||||||
+#endif
|
+#endif
|
||||||
|
+ hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE);
|
||||||
|
+
|
||||||
hashp->BSHIFT = __log2((uint32_t)hashp->BSIZE);
|
hashp->BSHIFT = __log2((uint32_t)hashp->BSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2184,18 +2196,7 @@ diff -ru nbsdsrc/src/lib/libc/resolv/res_comp.c lib/nbsd_libc/resolv/res_comp.c
|
||||||
diff -ru nbsdsrc/src/lib/libc/resolv/res_init.c lib/nbsd_libc/resolv/res_init.c
|
diff -ru nbsdsrc/src/lib/libc/resolv/res_init.c lib/nbsd_libc/resolv/res_init.c
|
||||||
--- nbsdsrc/src/lib/libc/resolv/res_init.c
|
--- nbsdsrc/src/lib/libc/resolv/res_init.c
|
||||||
+++ lib/nbsd_libc/resolv/res_init.c
|
+++ lib/nbsd_libc/resolv/res_init.c
|
||||||
@@ -70,6 +70,10 @@
|
@@ -88,7 +88,9 @@
|
||||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
+#ifdef __minix
|
|
||||||
+#define __MINIX_EMULATE_NETBSD_STAT
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
#if defined(LIBC_SCCS) && !defined(lint)
|
|
||||||
#ifdef notdef
|
|
||||||
@@ -88,7 +92,9 @@
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -2205,7 +2206,7 @@ diff -ru nbsdsrc/src/lib/libc/resolv/res_init.c lib/nbsd_libc/resolv/res_init.c
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@@ -348,7 +354,9 @@
|
@@ -348,7 +350,9 @@
|
||||||
nserv = 0;
|
nserv = 0;
|
||||||
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
|
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -2215,7 +2216,7 @@ diff -ru nbsdsrc/src/lib/libc/resolv/res_init.c lib/nbsd_libc/resolv/res_init.c
|
||||||
|
|
||||||
/* read the config file */
|
/* read the config file */
|
||||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||||
@@ -502,6 +510,7 @@
|
@@ -502,6 +506,7 @@
|
||||||
if (fstat(statp->_u._ext.ext->resfd, &st) != -1)
|
if (fstat(statp->_u._ext.ext->resfd, &st) != -1)
|
||||||
__res_conf_time = statp->_u._ext.ext->res_conf_time =
|
__res_conf_time = statp->_u._ext.ext->res_conf_time =
|
||||||
st.st_mtimespec;
|
st.st_mtimespec;
|
||||||
|
@ -2223,7 +2224,7 @@ diff -ru nbsdsrc/src/lib/libc/resolv/res_init.c lib/nbsd_libc/resolv/res_init.c
|
||||||
statp->_u._ext.ext->kq = kqueue();
|
statp->_u._ext.ext->kq = kqueue();
|
||||||
(void)fcntl(statp->_u._ext.ext->kq, F_SETFD, FD_CLOEXEC);
|
(void)fcntl(statp->_u._ext.ext->kq, F_SETFD, FD_CLOEXEC);
|
||||||
(void)fcntl(statp->_u._ext.ext->resfd, F_SETFD, FD_CLOEXEC);
|
(void)fcntl(statp->_u._ext.ext->resfd, F_SETFD, FD_CLOEXEC);
|
||||||
@@ -509,6 +518,9 @@
|
@@ -509,6 +514,9 @@
|
||||||
EV_ADD|EV_ENABLE|EV_CLEAR, NOTE_DELETE|NOTE_WRITE| NOTE_EXTEND|
|
EV_ADD|EV_ENABLE|EV_CLEAR, NOTE_DELETE|NOTE_WRITE| NOTE_EXTEND|
|
||||||
NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE, 0, 0);
|
NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE, 0, 0);
|
||||||
(void)kevent(statp->_u._ext.ext->kq, &kc, 1, NULL, 0, &ts);
|
(void)kevent(statp->_u._ext.ext->kq, &kc, 1, NULL, 0, &ts);
|
||||||
|
@ -2233,7 +2234,7 @@ diff -ru nbsdsrc/src/lib/libc/resolv/res_init.c lib/nbsd_libc/resolv/res_init.c
|
||||||
} else {
|
} else {
|
||||||
statp->_u._ext.ext->kq = -1;
|
statp->_u._ext.ext->kq = -1;
|
||||||
statp->_u._ext.ext->resfd = -1;
|
statp->_u._ext.ext->resfd = -1;
|
||||||
@@ -565,7 +577,13 @@
|
@@ -565,7 +573,13 @@
|
||||||
int
|
int
|
||||||
res_check(res_state statp, struct timespec *mtime)
|
res_check(res_state statp, struct timespec *mtime)
|
||||||
{
|
{
|
||||||
|
@ -2247,7 +2248,7 @@ diff -ru nbsdsrc/src/lib/libc/resolv/res_init.c lib/nbsd_libc/resolv/res_init.c
|
||||||
* If the times are equal, then we check if there
|
* If the times are equal, then we check if there
|
||||||
* was a kevent related to resolv.conf and reload.
|
* was a kevent related to resolv.conf and reload.
|
||||||
* If the times are not equal, then we don't bother
|
* If the times are not equal, then we don't bother
|
||||||
@@ -593,6 +611,7 @@
|
@@ -593,6 +607,7 @@
|
||||||
if (mtime)
|
if (mtime)
|
||||||
*mtime = __res_conf_time;
|
*mtime = __res_conf_time;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2258,44 +2259,53 @@ diff -ru nbsdsrc/src/lib/libc/resolv/res_init.c lib/nbsd_libc/resolv/res_init.c
|
||||||
diff -ru nbsdsrc/src/lib/libc/stdio/fseeko.c lib/nbsd_libc/stdio/fseeko.c
|
diff -ru nbsdsrc/src/lib/libc/stdio/fseeko.c lib/nbsd_libc/stdio/fseeko.c
|
||||||
--- nbsdsrc/src/lib/libc/stdio/fseeko.c
|
--- nbsdsrc/src/lib/libc/stdio/fseeko.c
|
||||||
+++ lib/nbsd_libc/stdio/fseeko.c
|
+++ lib/nbsd_libc/stdio/fseeko.c
|
||||||
@@ -150,7 +150,11 @@
|
@@ -150,7 +150,16 @@
|
||||||
fp->_flags |= __SNPT;
|
fp->_flags |= __SNPT;
|
||||||
goto dumb;
|
goto dumb;
|
||||||
}
|
}
|
||||||
|
- fp->_blksize = st.st_blksize;
|
||||||
+#ifdef __minix
|
+#ifdef __minix
|
||||||
|
+ if (st.st_blksize == 0) {
|
||||||
|
+ /* 0 in 2 cases: upgrade from old to new struct stat or
|
||||||
|
+ * there is a bug in underlying fs.
|
||||||
|
+ */
|
||||||
+ fp->_blksize = MINIX_ST_BLKSIZE;
|
+ fp->_blksize = MINIX_ST_BLKSIZE;
|
||||||
+#else
|
+ } else
|
||||||
fp->_blksize = st.st_blksize;
|
|
||||||
+#endif
|
+#endif
|
||||||
|
+ fp->_blksize = st.st_blksize;
|
||||||
|
+
|
||||||
fp->_flags |= __SOPT;
|
fp->_flags |= __SOPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
diff -ru nbsdsrc/src/lib/libc/stdio/makebuf.c lib/nbsd_libc/stdio/makebuf.c
|
diff -ru nbsdsrc/src/lib/libc/stdio/makebuf.c lib/nbsd_libc/stdio/makebuf.c
|
||||||
--- nbsdsrc/src/lib/libc/stdio/makebuf.c
|
--- nbsdsrc/src/lib/libc/stdio/makebuf.c
|
||||||
+++ lib/nbsd_libc/stdio/makebuf.c
|
+++ lib/nbsd_libc/stdio/makebuf.c
|
||||||
@@ -114,18 +114,25 @@
|
@@ -114,18 +114,22 @@
|
||||||
|
|
||||||
/* could be a tty iff it is a character device */
|
/* could be a tty iff it is a character device */
|
||||||
*couldbetty = S_ISCHR(st.st_mode);
|
*couldbetty = S_ISCHR(st.st_mode);
|
||||||
+#ifndef __minix
|
- if (st.st_blksize == 0) {
|
||||||
if (st.st_blksize == 0) {
|
- *bufsize = BUFSIZ;
|
||||||
*bufsize = BUFSIZ;
|
- return (__SNPT);
|
||||||
return (__SNPT);
|
- }
|
||||||
}
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optimise fseek() only if it is a regular file. (The test for
|
* Optimise fseek() only if it is a regular file. (The test for
|
||||||
* __sseek is mainly paranoia.) It is safe to set _blksize
|
* __sseek is mainly paranoia.) It is safe to set _blksize
|
||||||
* unconditionally; it will only be used if __SOPT is also set.
|
* unconditionally; it will only be used if __SOPT is also set.
|
||||||
*/
|
*/
|
||||||
|
- *bufsize = st.st_blksize;
|
||||||
|
- fp->_blksize = st.st_blksize;
|
||||||
+#ifdef __minix
|
+#ifdef __minix
|
||||||
+ *bufsize = MINIX_ST_BLKSIZE;
|
+ if (st.st_blksize == 0) {
|
||||||
+ fp->_blksize = MINIX_ST_BLKSIZE;
|
+ /* 0 in 2 cases: upgrade from old to new struct stat or
|
||||||
+#else
|
+ * there is a bug in underlying fs.
|
||||||
*bufsize = st.st_blksize;
|
+ */
|
||||||
fp->_blksize = st.st_blksize;
|
+ *bufsize = fp->_blksize = MINIX_ST_BLKSIZE;
|
||||||
|
+ } else
|
||||||
+#endif
|
+#endif
|
||||||
|
+ *bufsize = fp->_blksize = st.st_blksize;
|
||||||
|
+
|
||||||
return ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek ?
|
return ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek ?
|
||||||
__SOPT : __SNPT);
|
__SOPT : __SNPT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,10 +70,6 @@
|
||||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __minix
|
|
||||||
#define __MINIX_EMULATE_NETBSD_STAT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#if defined(LIBC_SCCS) && !defined(lint)
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
|
|
|
@ -151,10 +151,15 @@ fseeko(FILE *fp, off_t offset, int whence)
|
||||||
goto dumb;
|
goto dumb;
|
||||||
}
|
}
|
||||||
#ifdef __minix
|
#ifdef __minix
|
||||||
|
if (st.st_blksize == 0) {
|
||||||
|
/* 0 in 2 cases: upgrade from old to new struct stat or
|
||||||
|
* there is a bug in underlying fs.
|
||||||
|
*/
|
||||||
fp->_blksize = MINIX_ST_BLKSIZE;
|
fp->_blksize = MINIX_ST_BLKSIZE;
|
||||||
#else
|
} else
|
||||||
fp->_blksize = st.st_blksize;
|
|
||||||
#endif
|
#endif
|
||||||
|
fp->_blksize = st.st_blksize;
|
||||||
|
|
||||||
fp->_flags |= __SOPT;
|
fp->_flags |= __SOPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,12 +114,6 @@ __swhatbuf(fp, bufsize, couldbetty)
|
||||||
|
|
||||||
/* could be a tty iff it is a character device */
|
/* could be a tty iff it is a character device */
|
||||||
*couldbetty = S_ISCHR(st.st_mode);
|
*couldbetty = S_ISCHR(st.st_mode);
|
||||||
#ifndef __minix
|
|
||||||
if (st.st_blksize == 0) {
|
|
||||||
*bufsize = BUFSIZ;
|
|
||||||
return (__SNPT);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optimise fseek() only if it is a regular file. (The test for
|
* Optimise fseek() only if it is a regular file. (The test for
|
||||||
|
@ -127,12 +121,15 @@ __swhatbuf(fp, bufsize, couldbetty)
|
||||||
* unconditionally; it will only be used if __SOPT is also set.
|
* unconditionally; it will only be used if __SOPT is also set.
|
||||||
*/
|
*/
|
||||||
#ifdef __minix
|
#ifdef __minix
|
||||||
*bufsize = MINIX_ST_BLKSIZE;
|
if (st.st_blksize == 0) {
|
||||||
fp->_blksize = MINIX_ST_BLKSIZE;
|
/* 0 in 2 cases: upgrade from old to new struct stat or
|
||||||
#else
|
* there is a bug in underlying fs.
|
||||||
*bufsize = st.st_blksize;
|
*/
|
||||||
fp->_blksize = st.st_blksize;
|
*bufsize = fp->_blksize = MINIX_ST_BLKSIZE;
|
||||||
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
*bufsize = fp->_blksize = st.st_blksize;
|
||||||
|
|
||||||
return ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek ?
|
return ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek ?
|
||||||
__SOPT : __SNPT);
|
__SOPT : __SNPT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,101 +5,126 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef __MINIX_EMULATE_NETBSD_STAT
|
|
||||||
#error __MINIX_EMULATE_NETBSD_STAT is set.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int __orig_minix_stat(name, buffer)
|
/* XXX until that st_Xtime macroses used, we have to undefine them,
|
||||||
|
* because of minix_prev_stat
|
||||||
|
*/
|
||||||
|
#undef st_atime
|
||||||
|
#undef st_ctime
|
||||||
|
#undef st_mtime
|
||||||
|
|
||||||
|
static void prev_stat2new_stat(struct stat *new, struct minix_prev_stat *prev)
|
||||||
|
{
|
||||||
|
/* Copy field by field because of st_gid type mismath and
|
||||||
|
* difference in order after atime.
|
||||||
|
*/
|
||||||
|
new->st_dev = prev->st_dev;
|
||||||
|
new->st_ino = prev->st_ino;
|
||||||
|
new->st_mode = prev->st_mode;
|
||||||
|
new->st_nlink = prev->st_nlink;
|
||||||
|
new->st_uid = prev->st_uid;
|
||||||
|
new->st_gid = prev->st_gid;
|
||||||
|
new->st_rdev = prev->st_rdev;
|
||||||
|
new->st_size = prev->st_size;
|
||||||
|
new->st_atimespec.tv_sec = prev->st_atime;
|
||||||
|
new->st_mtimespec.tv_sec = prev->st_mtime;
|
||||||
|
new->st_ctimespec.tv_sec = prev->st_ctime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int _stat(name, buffer)
|
||||||
const char *name;
|
const char *name;
|
||||||
struct __minix_stat *buffer;
|
struct stat *buffer;
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
int r;
|
||||||
|
struct minix_prev_stat old_sb;
|
||||||
|
|
||||||
m.m1_i1 = strlen(name) + 1;
|
m.m1_i1 = strlen(name) + 1;
|
||||||
m.m1_p1 = (char *) name;
|
m.m1_p1 = (char *) name;
|
||||||
m.m1_p2 = (char *) buffer;
|
m.m1_p2 = (char *) buffer;
|
||||||
return(_syscall(VFS_PROC_NR, STAT, &m));
|
|
||||||
|
if((r = _syscall(VFS_PROC_NR, STAT, &m)) >= 0 || errno != ENOSYS)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* ENOSYS: new binary and old VFS, fallback to PREV_STAT.
|
||||||
|
* User has struct stat (buffer), VFS still fills minix_prev_stat.
|
||||||
|
*/
|
||||||
|
m.m1_i1 = strlen(name) + 1;
|
||||||
|
m.m1_p1 = (char *) name;
|
||||||
|
m.m1_p2 = (char *) &old_sb;
|
||||||
|
|
||||||
|
if((r = _syscall(VFS_PROC_NR, PREV_STAT, &m)) < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(struct stat));
|
||||||
|
prev_stat2new_stat(buffer, &old_sb);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __orig_minix_fstat(fd, buffer)
|
int _fstat(fd, buffer)
|
||||||
int fd;
|
int fd;
|
||||||
struct __minix_stat *buffer;
|
struct stat *buffer;
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
int r;
|
||||||
|
struct minix_prev_stat old_sb;
|
||||||
|
|
||||||
m.m1_i1 = fd;
|
m.m1_i1 = fd;
|
||||||
m.m1_p1 = (char *) buffer;
|
m.m1_p1 = (char *) buffer;
|
||||||
return(_syscall(VFS_PROC_NR, FSTAT, &m));
|
|
||||||
|
if((r = _syscall(VFS_PROC_NR, FSTAT, &m)) >= 0 || errno != ENOSYS)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* ENOSYS: new binary and old VFS, fallback to PREV_STAT.
|
||||||
|
* User has struct stat (buffer), VFS still fills minix_prev_stat.
|
||||||
|
*/
|
||||||
|
m.m1_i1 = fd;
|
||||||
|
m.m1_p1 = (char *) &old_sb;
|
||||||
|
|
||||||
|
if((r = _syscall(VFS_PROC_NR, PREV_FSTAT, &m)) < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(struct stat));
|
||||||
|
prev_stat2new_stat(buffer, &old_sb);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __orig_minix_lstat(name, buffer)
|
int _lstat(name, buffer)
|
||||||
const char *name;
|
const char *name;
|
||||||
struct __minix_stat *buffer;
|
struct stat *buffer;
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
int r;
|
int r;
|
||||||
|
struct minix_prev_stat old_sb;
|
||||||
|
|
||||||
m.m1_i1 = strlen(name) + 1;
|
m.m1_i1 = strlen(name) + 1;
|
||||||
m.m1_p1 = (char *) name;
|
m.m1_p1 = (char *) name;
|
||||||
m.m1_p2 = (char *) buffer;
|
m.m1_p2 = (char *) buffer;
|
||||||
|
|
||||||
if((r = _syscall(VFS_PROC_NR, LSTAT, &m)) >= 0 || errno != ENOSYS)
|
if((r = _syscall(VFS_PROC_NR, LSTAT, &m)) >= 0 || errno != ENOSYS)
|
||||||
return r;
|
return r;
|
||||||
return __orig_minix_stat(name, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
errno = 0;
|
||||||
* NetBSD Fields Emulation.
|
|
||||||
|
/* ENOSYS: new binary and old VFS, fallback to PREV_STAT.
|
||||||
|
* User has struct stat (buffer), VFS still fills minix_prev_stat.
|
||||||
*/
|
*/
|
||||||
|
m.m1_i1 = strlen(name) + 1;
|
||||||
|
m.m1_p1 = (char *) name;
|
||||||
|
m.m1_p2 = (char *) &old_sb;
|
||||||
|
|
||||||
static void __emulate_netbsd_fields(struct __netbsd_stat *buffer)
|
if((r = _syscall(VFS_PROC_NR, PREV_LSTAT, &m)) < 0)
|
||||||
{
|
|
||||||
/* Emulated NetBSD fields. */
|
|
||||||
buffer->st_atimespec.tv_sec = buffer->st_atime;
|
|
||||||
buffer->st_atimespec.tv_nsec = 0;
|
|
||||||
buffer->st_mtimespec.tv_sec = buffer->st_mtime;
|
|
||||||
buffer->st_mtimespec.tv_nsec = 0;
|
|
||||||
buffer->st_ctimespec.tv_sec = buffer->st_ctime;
|
|
||||||
buffer->st_ctimespec.tv_nsec = 0;
|
|
||||||
buffer->st_birthtimespec.tv_sec = 0;
|
|
||||||
buffer->st_birthtimespec.tv_nsec = 0;
|
|
||||||
buffer->st_blocks = (buffer->st_size / S_BLKSIZE) + 1;
|
|
||||||
buffer->st_blksize = MINIX_ST_BLKSIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int __emu_netbsd_stat(name, buffer)
|
|
||||||
const char *name;
|
|
||||||
struct __netbsd_stat *buffer;
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = __orig_minix_stat(name, (struct __minix_stat *)buffer);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
return r;
|
||||||
__emulate_netbsd_fields(buffer);
|
|
||||||
return r;
|
memset(buffer, 0, sizeof(struct stat));
|
||||||
}
|
prev_stat2new_stat(buffer, &old_sb);
|
||||||
|
|
||||||
int __emu_netbsd_fstat(fd, buffer)
|
|
||||||
int fd;
|
|
||||||
struct __netbsd_stat *buffer;
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
r = __orig_minix_fstat(fd, (struct __minix_stat *)buffer);
|
|
||||||
if ( r < 0 )
|
|
||||||
return r;
|
|
||||||
__emulate_netbsd_fields(buffer);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int __emu_netbsd_lstat(name, buffer)
|
|
||||||
const char *name;
|
|
||||||
struct __netbsd_stat *buffer;
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = __orig_minix_lstat(name, (struct __minix_stat *)buffer);
|
|
||||||
if ( r < 0 )
|
|
||||||
return r;
|
|
||||||
__emulate_netbsd_fields(buffer);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ MAN= accept.2 access.2 alarm.2 bind.2 brk.2 chdir.2 chmod.2 chown.2 \
|
||||||
read.2 readlink.2 reboot.2 recv.2 recvfrom.2 recvmsg.2 rename.2 \
|
read.2 readlink.2 reboot.2 recv.2 recvfrom.2 recvmsg.2 rename.2 \
|
||||||
rmdir.2 select.2 send.2 sendmsg.2 sendto.2 setsid.2 \
|
rmdir.2 select.2 send.2 sendmsg.2 sendto.2 setsid.2 \
|
||||||
setsockopt.2 setuid.2 shutdown.2 sigaction.2 sigpending.2 \
|
setsockopt.2 setuid.2 shutdown.2 sigaction.2 sigpending.2 \
|
||||||
sigprocmask.2 sigsuspend.2 socket.2 socketpair.2 stat.2 \
|
sigprocmask.2 sigsuspend.2 socket.2 socketpair.2 \
|
||||||
statvfs.2 svrctl.2 symlink.2 sync.2 time.2 times.2 truncate.2 \
|
statvfs.2 svrctl.2 symlink.2 sync.2 time.2 times.2 truncate.2 \
|
||||||
umask.2 uname.2 unlink.2 utime.2 wait.2 write.2
|
umask.2 uname.2 unlink.2 utime.2 wait.2 write.2
|
||||||
|
|
||||||
|
|
179
man/man2/stat.2
179
man/man2/stat.2
|
@ -1,179 +0,0 @@
|
||||||
.\" Copyright (c) 1980 Regents of the University of California.
|
|
||||||
.\" All rights reserved. The Berkeley software License Agreement
|
|
||||||
.\" specifies the terms and conditions for redistribution.
|
|
||||||
.\"
|
|
||||||
.\" @(#)stat.2 6.5 (Berkeley) 5/12/86
|
|
||||||
.\"
|
|
||||||
.TH STAT 2 "May 12, 1986"
|
|
||||||
.UC 4
|
|
||||||
.SH NAME
|
|
||||||
stat, lstat, fstat \- get file status
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.nf
|
|
||||||
.ft B
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
.ta +54n
|
|
||||||
int stat(const char *\fIpath\fP, struct stat *\fIbuf\fP)
|
|
||||||
int lstat(const char *\fIpath\fP, struct stat *\fIbuf\fP)
|
|
||||||
int fstat(int \fIfd\fP, struct stat *\fIbuf\fP)
|
|
||||||
.fi
|
|
||||||
.ft R
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.B Stat
|
|
||||||
obtains information about the file
|
|
||||||
.IR path .
|
|
||||||
Read, write or execute
|
|
||||||
permission of the named file is not required, but all directories
|
|
||||||
listed in the path name leading to the file must be reachable.
|
|
||||||
.PP
|
|
||||||
.B Lstat
|
|
||||||
is like \fBstat\fP except in the case where the named file is a symbolic link,
|
|
||||||
in which case
|
|
||||||
.B lstat
|
|
||||||
returns information about the link,
|
|
||||||
while
|
|
||||||
.B stat
|
|
||||||
returns information about the file the link references.
|
|
||||||
.PP
|
|
||||||
.B Fstat
|
|
||||||
obtains the same information about an open file
|
|
||||||
referenced by the argument descriptor, such as would
|
|
||||||
be obtained by an \fBopen\fP call. Pipe descriptors
|
|
||||||
look like named pipes with a link count of zero. The
|
|
||||||
st_size field of pipes or named pipes shows the amount of
|
|
||||||
bytes currently buffered in the pipe.
|
|
||||||
.PP
|
|
||||||
.I Buf
|
|
||||||
is a pointer to a
|
|
||||||
.B stat
|
|
||||||
structure into which information is placed concerning the file.
|
|
||||||
The contents of the structure pointed to by
|
|
||||||
.I buf
|
|
||||||
is as follows:
|
|
||||||
.PP
|
|
||||||
.if t .RS
|
|
||||||
.nf
|
|
||||||
.ta +0.4i +0.8i +1i
|
|
||||||
struct stat {
|
|
||||||
dev_t st_dev; /* device inode resides on */
|
|
||||||
ino_t st_ino; /* this inode's number */
|
|
||||||
mode_t st_mode; /* file mode, protection bits, etc. */
|
|
||||||
nlink_t st_nlink; /* number or hard links to the file */
|
|
||||||
uid_t st_uid; /* user-id of the file's owner */
|
|
||||||
gid_t st_gid; /* group-id of the file's owner */
|
|
||||||
dev_t st_rdev; /* the device type, for inode that is device */
|
|
||||||
off_t st_size; /* total size of file */
|
|
||||||
time_t st_atime; /* time of last access */
|
|
||||||
time_t st_mtime; /* time of last data modification */
|
|
||||||
time_t st_ctime; /* time of last file status change */
|
|
||||||
};
|
|
||||||
.fi
|
|
||||||
.if t .RE
|
|
||||||
.DT
|
|
||||||
.PP
|
|
||||||
.TP 12
|
|
||||||
st_atime
|
|
||||||
Time when file data was last read or modified. Changed by the following system
|
|
||||||
calls:
|
|
||||||
.BR mknod (2),
|
|
||||||
.BR utime (2),
|
|
||||||
.BR read (2),
|
|
||||||
and
|
|
||||||
.BR write (2).
|
|
||||||
For reasons of efficiency,
|
|
||||||
st_atime is not set when a directory
|
|
||||||
is searched, although this would be more logical.
|
|
||||||
.TP 12
|
|
||||||
st_mtime
|
|
||||||
Time when data was last modified.
|
|
||||||
It is not set by changes of owner, group, link count, or mode.
|
|
||||||
Changed by the following system calls:
|
|
||||||
.BR mknod (2),
|
|
||||||
.BR utime (2),
|
|
||||||
.BR write (2).
|
|
||||||
.TP 12
|
|
||||||
st_ctime
|
|
||||||
Time when file status was last changed.
|
|
||||||
It is set both both by writing and changing the i-node.
|
|
||||||
Changed by the following system calls:
|
|
||||||
.BR chmod (2)
|
|
||||||
.BR chown (2),
|
|
||||||
.BR link (2),
|
|
||||||
.BR mknod (2),
|
|
||||||
.BR rename (2),
|
|
||||||
.BR unlink (2),
|
|
||||||
.BR utime (2),
|
|
||||||
.BR write (2).
|
|
||||||
.PP
|
|
||||||
The file type information in \fBst_mode\fP has bits:
|
|
||||||
.PP
|
|
||||||
.nf
|
|
||||||
.in +5n
|
|
||||||
.ta 1.6i 2.5i 3i
|
|
||||||
#define S_IFMT 0170000 /* type of file */
|
|
||||||
#define\ \ \ \ S_IFIFO 0010000 /* named pipe */
|
|
||||||
#define\ \ \ \ S_IFCHR 0020000 /* character special */
|
|
||||||
#define\ \ \ \ S_IFDIR 0040000 /* directory */
|
|
||||||
#define\ \ \ \ S_IFBLK 0060000 /* block special */
|
|
||||||
#define\ \ \ \ S_IFREG 0100000 /* regular */
|
|
||||||
#define\ \ \ \ S_IFLNK 0120000 /* symbolic link */
|
|
||||||
.fi
|
|
||||||
.in -5n
|
|
||||||
.PP
|
|
||||||
The mode bits 0007777 encode set-uid/gid bits and
|
|
||||||
permission bits (see
|
|
||||||
.BR chmod (2)).
|
|
||||||
.SH "RETURN VALUE
|
|
||||||
Upon successful completion a value of 0 is returned.
|
|
||||||
Otherwise, a value of \-1 is returned and
|
|
||||||
.B errno
|
|
||||||
is set to indicate the error.
|
|
||||||
.SH "ERRORS
|
|
||||||
.B Stat
|
|
||||||
and
|
|
||||||
.B lstat
|
|
||||||
will fail if one or more of the following are true:
|
|
||||||
.TP 15
|
|
||||||
[ENOTDIR]
|
|
||||||
A component of the path prefix is not a directory.
|
|
||||||
.TP 15
|
|
||||||
[ENAMETOOLONG]
|
|
||||||
The path name exceeds PATH_MAX characters.
|
|
||||||
.TP 15
|
|
||||||
[ENOENT]
|
|
||||||
The named file does not exist.
|
|
||||||
.TP 15
|
|
||||||
[EACCES]
|
|
||||||
Search permission is denied for a component of the path prefix.
|
|
||||||
.TP 15
|
|
||||||
[ELOOP]
|
|
||||||
Too many symbolic links were encountered in translating the pathname.
|
|
||||||
.TP 15
|
|
||||||
[EFAULT]
|
|
||||||
.I Buf
|
|
||||||
or
|
|
||||||
.I name
|
|
||||||
points to an invalid address.
|
|
||||||
.TP 15
|
|
||||||
[EIO]
|
|
||||||
An I/O error occurred while reading from or writing to the file system.
|
|
||||||
.PP
|
|
||||||
.B Fstat
|
|
||||||
will fail if one or both of the following are true:
|
|
||||||
.TP 15
|
|
||||||
[EBADF]
|
|
||||||
.I Fildes
|
|
||||||
is not a valid open file descriptor.
|
|
||||||
.TP 15
|
|
||||||
[EFAULT]
|
|
||||||
.I Buf
|
|
||||||
points to an invalid address.
|
|
||||||
.TP 15
|
|
||||||
[EIO]
|
|
||||||
An I/O error occurred while reading from or writing to the file system.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
.BR chmod (2),
|
|
||||||
.BR chown (2),
|
|
||||||
.BR utime (2).
|
|
|
@ -8,62 +8,66 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* __MINIX_EMULATE_NETBSD_STAT
|
|
||||||
*
|
|
||||||
* Userspace flag to emulate netbsd stat structure.
|
|
||||||
*/
|
|
||||||
#ifdef __MINIX_EMULATE_NETBSD_STAT
|
|
||||||
#define __netbsd_stat stat
|
|
||||||
#else
|
|
||||||
#define __minix_stat stat
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct __minix_stat {
|
|
||||||
dev_t st_dev; /* major/minor device number */
|
|
||||||
ino_t st_ino; /* i-node number */
|
|
||||||
mode_t st_mode; /* file mode, protection bits, etc. */
|
|
||||||
nlink_t st_nlink; /* # links; */
|
|
||||||
uid_t st_uid; /* uid of the file's owner */
|
|
||||||
gid_t st_gid; /* gid */
|
|
||||||
dev_t st_rdev;
|
|
||||||
off_t st_size; /* file size */
|
|
||||||
time_t st_atime; /* time of last access */
|
|
||||||
time_t st_mtime; /* time of last data modification */
|
|
||||||
time_t st_ctime; /* time of last file status change */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
struct stat {
|
||||||
|
big_dev_t st_dev; /* inode's device */
|
||||||
|
big_mode_t st_mode; /* inode protection mode */
|
||||||
|
big_ino_t st_ino; /* inode's number */
|
||||||
|
big_nlink_t st_nlink; /* number of hard links */
|
||||||
|
big_uid_t st_uid; /* user ID of the file's owner */
|
||||||
|
big_gid_t st_gid; /* group ID of the file's group */
|
||||||
|
big_dev_t st_rdev; /* device type */
|
||||||
#if defined(_NETBSD_SOURCE)
|
#if defined(_NETBSD_SOURCE)
|
||||||
struct __netbsd_stat {
|
|
||||||
dev_t st_dev; /* major/minor device number */
|
|
||||||
ino_t st_ino; /* i-node number */
|
|
||||||
mode_t st_mode; /* file mode, protection bits, etc. */
|
|
||||||
nlink_t st_nlink; /* # links; */
|
|
||||||
uid_t st_uid; /* uid of the file's owner */
|
|
||||||
gid_t st_gid; /* gid */
|
|
||||||
dev_t st_rdev;
|
|
||||||
off_t st_size; /* file size */
|
|
||||||
time_t st_atime; /* time of last access */
|
|
||||||
time_t st_mtime; /* time of last data modification */
|
|
||||||
time_t st_ctime; /* time of last file status change */
|
|
||||||
|
|
||||||
/* XXX: Currently not supported by Minix, and here are just emulated. */
|
|
||||||
struct timespec st_atimespec;/* time of last access */
|
struct timespec st_atimespec;/* time of last access */
|
||||||
struct timespec st_mtimespec;/* time of last data modification */
|
struct timespec st_mtimespec;/* time of last data modification */
|
||||||
struct timespec st_ctimespec;/* time of last file status change */
|
struct timespec st_ctimespec;/* time of last file status change */
|
||||||
struct timespec st_birthtimespec; /* time of creation */
|
struct timespec st_birthtimespec; /* time of creation */
|
||||||
|
#else
|
||||||
|
time_t st_atime; /* time of last access */
|
||||||
|
long st_atimensec; /* nsec of last access */
|
||||||
|
time_t st_mtime; /* time of last data modification */
|
||||||
|
long st_mtimensec; /* nsec of last data modification */
|
||||||
|
time_t st_ctime; /* time of last file status change */
|
||||||
|
long st_ctimensec; /* nsec of last file status change */
|
||||||
|
time_t st_birthtime; /* time of creation */
|
||||||
|
long st_birthtimensec; /* nsec of time of creation */
|
||||||
|
#endif
|
||||||
|
big_off_t st_size; /* file size, in bytes */
|
||||||
blkcnt_t st_blocks; /* blocks allocated for file */
|
blkcnt_t st_blocks; /* blocks allocated for file */
|
||||||
blksize_t st_blksize; /* optimal blocksize for I/O */
|
blksize_t st_blksize; /* optimal blocksize for I/O */
|
||||||
|
u32_t st_flags; /* user defined flags for file */
|
||||||
|
u32_t st_gen; /* file generation number */
|
||||||
|
u32_t st_spare[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __MINIX_EMULATE_NETBSD_STAT
|
|
||||||
|
struct minix_prev_stat {
|
||||||
|
dev_t st_dev; /* major/minor device number */
|
||||||
|
ino_t st_ino; /* i-node number */
|
||||||
|
mode_t st_mode; /* file mode, protection bits, etc. */
|
||||||
|
nlink_t st_nlink; /* # links; */
|
||||||
|
uid_t st_uid; /* uid of the file's owner */
|
||||||
|
short int st_gid; /* gid; TEMPORARY HACK: should be gid_t */
|
||||||
|
dev_t st_rdev;
|
||||||
|
off_t st_size; /* file size */
|
||||||
|
time_t st_atime; /* time of last access */
|
||||||
|
time_t st_mtime; /* time of last data modification */
|
||||||
|
time_t st_ctime; /* time of last file status change */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_NETBSD_SOURCE)
|
||||||
|
/* XXX after updating stat struct we don't want to update all the code */
|
||||||
|
#define st_atime st_atimespec.tv_sec
|
||||||
|
#define st_mtime st_mtimespec.tv_sec
|
||||||
|
#define st_ctime st_ctimespec.tv_sec
|
||||||
|
#define st_birthtime st_birthtimespec.tv_sec
|
||||||
#define st_atimensec st_atimespec.tv_nsec
|
#define st_atimensec st_atimespec.tv_nsec
|
||||||
#define st_mtimensec st_mtimespec.tv_nsec
|
#define st_mtimensec st_mtimespec.tv_nsec
|
||||||
#define st_ctimensec st_ctimespec.tv_nsec
|
#define st_ctimensec st_ctimespec.tv_nsec
|
||||||
#define st_birthtime st_birthtimespec.tv_sec
|
|
||||||
#define st_birthtimensec st_birthtimespec.tv_nsec
|
#define st_birthtimensec st_birthtimespec.tv_nsec
|
||||||
#endif
|
#endif
|
||||||
#endif /* _NETBSD_SOURCE */
|
|
||||||
|
|
||||||
#define S_ISUID 0004000 /* set user id on execution */
|
#define S_ISUID 0004000 /* set user id on execution */
|
||||||
#define S_ISGID 0002000 /* set group id on execution */
|
#define S_ISGID 0002000 /* set group id on execution */
|
||||||
|
@ -153,21 +157,12 @@ __BEGIN_DECLS
|
||||||
int chmod(const char *, mode_t);
|
int chmod(const char *, mode_t);
|
||||||
int mkdir(const char *, mode_t);
|
int mkdir(const char *, mode_t);
|
||||||
int mkfifo(const char *, mode_t);
|
int mkfifo(const char *, mode_t);
|
||||||
#ifdef __MINIX_EMULATE_NETBSD_STAT
|
int stat(const char *, struct stat *) __RENAME(_stat);
|
||||||
int stat(const char *, struct stat *) __RENAME(__emu_netbsd_stat);
|
int fstat(int, struct stat *) __RENAME(_fstat);
|
||||||
int fstat(int, struct stat *) __RENAME(__emu_netbsd_fstat);
|
int lstat(const char *, struct stat *) __RENAME(_lstat);
|
||||||
#else
|
|
||||||
int stat(const char *, struct stat *) __RENAME(__orig_minix_stat);
|
|
||||||
int fstat(int, struct stat *) __RENAME(__orig_minix_fstat);
|
|
||||||
#endif
|
|
||||||
mode_t umask(mode_t);
|
mode_t umask(mode_t);
|
||||||
#if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE)
|
#if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE)
|
||||||
int fchmod(int, mode_t);
|
int fchmod(int, mode_t);
|
||||||
#ifdef __MINIX_EMULATE_NETBSD_STAT
|
|
||||||
int lstat(const char *, struct stat *) __RENAME(__emu_netbsd_lstat);
|
|
||||||
#else
|
|
||||||
int lstat(const char *, struct stat *) __RENAME(__orig_minix_lstat);
|
|
||||||
#endif
|
|
||||||
int mknod(const char *, mode_t, dev_t) __RENAME(__mknod50);
|
int mknod(const char *, mode_t, dev_t) __RENAME(__mknod50);
|
||||||
#endif /* defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE) */
|
#endif /* defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE) */
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
|
@ -105,6 +105,14 @@ typedef int16_t i16_t;
|
||||||
typedef int32_t i32_t;
|
typedef int32_t i32_t;
|
||||||
typedef int64_t i64_t;
|
typedef int64_t i64_t;
|
||||||
|
|
||||||
|
typedef uint64_t big_ino_t;
|
||||||
|
typedef int64_t big_off_t;
|
||||||
|
typedef u32_t big_dev_t;
|
||||||
|
typedef u32_t big_gid_t;
|
||||||
|
typedef u32_t big_mode_t;
|
||||||
|
typedef u32_t big_nlink_t;
|
||||||
|
typedef u32_t big_uid_t;
|
||||||
|
|
||||||
|
|
||||||
/* some Minix specific types that do not conflict with posix */
|
/* some Minix specific types that do not conflict with posix */
|
||||||
typedef u32_t zone_t; /* zone number */
|
typedef u32_t zone_t; /* zone number */
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/statfs.h>
|
#include <sys/statfs.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
@ -35,6 +36,8 @@ PRIVATE int stat_inode(
|
||||||
/* true iff special */
|
/* true iff special */
|
||||||
s = (mo == I_CHAR_SPECIAL || mo == I_BLOCK_SPECIAL);
|
s = (mo == I_CHAR_SPECIAL || mo == I_BLOCK_SPECIAL);
|
||||||
|
|
||||||
|
memset(&statbuf, 0, sizeof(struct stat));
|
||||||
|
|
||||||
statbuf.st_dev = rip->i_dev;
|
statbuf.st_dev = rip->i_dev;
|
||||||
statbuf.st_ino = rip->i_num;
|
statbuf.st_ino = rip->i_num;
|
||||||
statbuf.st_mode = rip->i_mode;
|
statbuf.st_mode = rip->i_mode;
|
||||||
|
@ -46,6 +49,8 @@ PRIVATE int stat_inode(
|
||||||
statbuf.st_atime = rip->i_atime;
|
statbuf.st_atime = rip->i_atime;
|
||||||
statbuf.st_mtime = rip->i_mtime;
|
statbuf.st_mtime = rip->i_mtime;
|
||||||
statbuf.st_ctime = rip->i_ctime;
|
statbuf.st_ctime = rip->i_ctime;
|
||||||
|
statbuf.st_blksize = rip->i_sp->s_block_size;
|
||||||
|
statbuf.st_blocks = rip->i_blocks;
|
||||||
|
|
||||||
/* Copy the struct to user space. */
|
/* Copy the struct to user space. */
|
||||||
r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf,
|
r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf,
|
||||||
|
|
|
@ -62,6 +62,8 @@ PUBLIC int do_stat()
|
||||||
if ((r = verify_inode(ino, path, &attr)) != OK)
|
if ((r = verify_inode(ino, path, &attr)) != OK)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
memset(&stat, 0, sizeof(struct stat));
|
||||||
|
|
||||||
stat.st_dev = state.dev;
|
stat.st_dev = state.dev;
|
||||||
stat.st_ino = ino_nr;
|
stat.st_ino = ino_nr;
|
||||||
stat.st_mode = get_mode(ino, attr.a_mode);
|
stat.st_mode = get_mode(ino, attr.a_mode);
|
||||||
|
@ -76,6 +78,12 @@ PUBLIC int do_stat()
|
||||||
stat.st_mtime = attr.a_mtime;
|
stat.st_mtime = attr.a_mtime;
|
||||||
stat.st_ctime = attr.a_ctime;
|
stat.st_ctime = attr.a_ctime;
|
||||||
|
|
||||||
|
stat.st_blocks = stat.st_size / S_BLKSIZE;
|
||||||
|
if (stat.st_size % S_BLKSIZE != 0)
|
||||||
|
stat.st_blocks += 1;
|
||||||
|
|
||||||
|
stat.st_blksize = BLOCK_SIZE;
|
||||||
|
|
||||||
/* We could make this more accurate by iterating over directory inodes'
|
/* We could make this more accurate by iterating over directory inodes'
|
||||||
* children, counting how many of those are directories as well.
|
* children, counting how many of those are directories as well.
|
||||||
* It's just not worth it.
|
* It's just not worth it.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "inc.h"
|
#include "inc.h"
|
||||||
|
#include <assert.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/statfs.h>
|
#include <sys/statfs.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
@ -29,6 +30,14 @@ PRIVATE int stat_dir_record(
|
||||||
int r;
|
int r;
|
||||||
struct tm ltime;
|
struct tm ltime;
|
||||||
time_t time1;
|
time_t time1;
|
||||||
|
u32_t blocks;
|
||||||
|
|
||||||
|
blocks = v_pri.volume_space_size_l;
|
||||||
|
/* The unit of blocks should be 512 */
|
||||||
|
assert(v_pri.logical_block_size_l >= 512);
|
||||||
|
blocks = blocks * (v_pri.logical_block_size_l >> 9);
|
||||||
|
|
||||||
|
memset(&statbuf, 0, sizeof(struct stat));
|
||||||
|
|
||||||
statbuf.st_dev = fs_dev; /* the device of the file */
|
statbuf.st_dev = fs_dev; /* the device of the file */
|
||||||
statbuf.st_ino = ID_DIR_RECORD(dir); /* the id of the dir record */
|
statbuf.st_ino = ID_DIR_RECORD(dir); /* the id of the dir record */
|
||||||
|
@ -38,6 +47,8 @@ PRIVATE int stat_dir_record(
|
||||||
statbuf.st_gid = 0; /* group operator */
|
statbuf.st_gid = 0; /* group operator */
|
||||||
statbuf.st_rdev = NO_DEV;
|
statbuf.st_rdev = NO_DEV;
|
||||||
statbuf.st_size = dir->d_file_size; /* size of the file */
|
statbuf.st_size = dir->d_file_size; /* size of the file */
|
||||||
|
statbuf.st_blksize = v_pri.logical_block_size_l;
|
||||||
|
statbuf.st_blocks = blocks;
|
||||||
|
|
||||||
ltime.tm_year = dir->rec_date[0];
|
ltime.tm_year = dir->rec_date[0];
|
||||||
ltime.tm_mon = dir->rec_date[1] - 1;
|
ltime.tm_mon = dir->rec_date[1] - 1;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/statfs.h>
|
#include <sys/statfs.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
@ -21,6 +23,7 @@ PRIVATE int stat_inode(
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
mode_t mo;
|
mode_t mo;
|
||||||
int r, s;
|
int r, s;
|
||||||
|
u32_t blocks; /* The unit of this is 512 */
|
||||||
|
|
||||||
/* Update the atime, ctime, and mtime fields in the inode, if need be. */
|
/* Update the atime, ctime, and mtime fields in the inode, if need be. */
|
||||||
if (rip->i_update) update_times(rip);
|
if (rip->i_update) update_times(rip);
|
||||||
|
@ -31,6 +34,12 @@ PRIVATE int stat_inode(
|
||||||
/* true iff special */
|
/* true iff special */
|
||||||
s = (mo == I_CHAR_SPECIAL || mo == I_BLOCK_SPECIAL);
|
s = (mo == I_CHAR_SPECIAL || mo == I_BLOCK_SPECIAL);
|
||||||
|
|
||||||
|
blocks = rip->i_size / 512;
|
||||||
|
if (rip->i_size % 512 != 0)
|
||||||
|
blocks += 1;
|
||||||
|
|
||||||
|
memset(&statbuf, 0, sizeof(struct stat));
|
||||||
|
|
||||||
statbuf.st_dev = rip->i_dev;
|
statbuf.st_dev = rip->i_dev;
|
||||||
statbuf.st_ino = rip->i_num;
|
statbuf.st_ino = rip->i_num;
|
||||||
statbuf.st_mode = rip->i_mode;
|
statbuf.st_mode = rip->i_mode;
|
||||||
|
@ -42,6 +51,8 @@ PRIVATE int stat_inode(
|
||||||
statbuf.st_atime = rip->i_atime;
|
statbuf.st_atime = rip->i_atime;
|
||||||
statbuf.st_mtime = rip->i_mtime;
|
statbuf.st_mtime = rip->i_mtime;
|
||||||
statbuf.st_ctime = rip->i_ctime;
|
statbuf.st_ctime = rip->i_ctime;
|
||||||
|
statbuf.st_blksize = fs_block_size;
|
||||||
|
statbuf.st_blocks = blocks;
|
||||||
|
|
||||||
/* Copy the struct to user space. */
|
/* Copy the struct to user space. */
|
||||||
r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf,
|
r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "inode.h"
|
#include "inode.h"
|
||||||
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ PRIVATE int stat_inode(
|
||||||
/* Common code for stat and fstat system calls. */
|
/* Common code for stat and fstat system calls. */
|
||||||
mode_t type;
|
mode_t type;
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
u32_t blocks; /* The unit of this is 512 */
|
||||||
int r, s;
|
int r, s;
|
||||||
|
|
||||||
type = rip->i_mode & I_TYPE;
|
type = rip->i_mode & I_TYPE;
|
||||||
|
@ -23,6 +25,12 @@ PRIVATE int stat_inode(
|
||||||
/* Update the atime, ctime, and mtime fields in the inode, if need be. */
|
/* Update the atime, ctime, and mtime fields in the inode, if need be. */
|
||||||
if (rip->i_update) update_times(rip);
|
if (rip->i_update) update_times(rip);
|
||||||
|
|
||||||
|
blocks = rip->i_size / S_BLKSIZE;
|
||||||
|
if (rip->i_size % S_BLKSIZE != 0)
|
||||||
|
blocks += 1;
|
||||||
|
|
||||||
|
memset(&statbuf, 0, sizeof(struct stat));
|
||||||
|
|
||||||
statbuf.st_dev = rip->i_dev;
|
statbuf.st_dev = rip->i_dev;
|
||||||
statbuf.st_ino = rip->i_num;
|
statbuf.st_ino = rip->i_num;
|
||||||
statbuf.st_mode = rip->i_mode;
|
statbuf.st_mode = rip->i_mode;
|
||||||
|
@ -35,6 +43,8 @@ PRIVATE int stat_inode(
|
||||||
statbuf.st_atime = rip->i_atime;
|
statbuf.st_atime = rip->i_atime;
|
||||||
statbuf.st_mtime = rip->i_mtime;
|
statbuf.st_mtime = rip->i_mtime;
|
||||||
statbuf.st_ctime = rip->i_ctime;
|
statbuf.st_ctime = rip->i_ctime;
|
||||||
|
statbuf.st_blksize = PIPE_BUF;
|
||||||
|
statbuf.st_blocks = blocks;
|
||||||
|
|
||||||
/* Copy the struct to user space. */
|
/* Copy the struct to user space. */
|
||||||
r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf,
|
r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf,
|
||||||
|
|
|
@ -61,7 +61,7 @@ _PROTOTYPE (int (*call_vec[]), (void) ) = {
|
||||||
do_get, /* 47 = getgid */
|
do_get, /* 47 = getgid */
|
||||||
no_sys, /* 48 = (signal)*/
|
no_sys, /* 48 = (signal)*/
|
||||||
no_sys, /* 49 = unused */
|
no_sys, /* 49 = unused */
|
||||||
no_sys, /* 50 = unused */
|
no_sys, /* 50 = lstat */
|
||||||
no_sys, /* 51 = (acct) */
|
no_sys, /* 51 = (acct) */
|
||||||
no_sys, /* 52 = (phys) */
|
no_sys, /* 52 = (phys) */
|
||||||
no_sys, /* 53 = (lock) */
|
no_sys, /* 53 = (lock) */
|
||||||
|
|
|
@ -12,7 +12,7 @@ static int exec_newmem(int proc_e, vir_bytes text_addr,
|
||||||
vir_bytes text_bytes, vir_bytes data_addr,
|
vir_bytes text_bytes, vir_bytes data_addr,
|
||||||
vir_bytes data_bytes, vir_bytes tot_bytes,
|
vir_bytes data_bytes, vir_bytes tot_bytes,
|
||||||
vir_bytes frame_len, int sep_id, int is_elf,
|
vir_bytes frame_len, int sep_id, int is_elf,
|
||||||
dev_t st_dev, ino_t st_ino, time_t st_ctime, char *progname,
|
dev_t st_dev, ino_t st_ino, time_t ctime, char *progname,
|
||||||
int new_uid, int new_gid, vir_bytes *stack_topp,
|
int new_uid, int new_gid, vir_bytes *stack_topp,
|
||||||
int *load_textp, int *allow_setuidp);
|
int *load_textp, int *allow_setuidp);
|
||||||
static void patch_ptr(char stack[ARG_MAX], vir_bytes base);
|
static void patch_ptr(char stack[ARG_MAX], vir_bytes base);
|
||||||
|
@ -321,7 +321,7 @@ static int exec_newmem(
|
||||||
int is_elf,
|
int is_elf,
|
||||||
dev_t st_dev,
|
dev_t st_dev,
|
||||||
ino_t st_ino,
|
ino_t st_ino,
|
||||||
time_t st_ctime,
|
time_t ctime,
|
||||||
char *progname,
|
char *progname,
|
||||||
int new_uid,
|
int new_uid,
|
||||||
int new_gid,
|
int new_gid,
|
||||||
|
@ -344,7 +344,7 @@ static int exec_newmem(
|
||||||
e.is_elf= is_elf;
|
e.is_elf= is_elf;
|
||||||
e.st_dev= st_dev;
|
e.st_dev= st_dev;
|
||||||
e.st_ino= st_ino;
|
e.st_ino= st_ino;
|
||||||
e.st_ctime= st_ctime;
|
e.enst_ctime= ctime;
|
||||||
e.new_uid= new_uid;
|
e.new_uid= new_uid;
|
||||||
e.new_gid= new_gid;
|
e.new_gid= new_gid;
|
||||||
strncpy(e.progname, progname, sizeof(e.progname)-1);
|
strncpy(e.progname, progname, sizeof(e.progname)-1);
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
static int exec_newmem(int proc_e, vir_bytes text_addr, vir_bytes text_bytes,
|
static int exec_newmem(int proc_e, vir_bytes text_addr, vir_bytes text_bytes,
|
||||||
vir_bytes data_addr, vir_bytes data_bytes,
|
vir_bytes data_addr, vir_bytes data_bytes,
|
||||||
vir_bytes tot_bytes, vir_bytes frame_len, int sep_id,
|
vir_bytes tot_bytes, vir_bytes frame_len, int sep_id,
|
||||||
int is_elf, dev_t st_dev, ino_t st_ino, time_t st_ctime,
|
int is_elf, dev_t st_dev, ino_t st_ino, time_t ctime,
|
||||||
char *progname, int new_uid, int new_gid,
|
char *progname, int new_uid, int new_gid,
|
||||||
vir_bytes *stack_topp, int *load_textp,
|
vir_bytes *stack_topp, int *load_textp,
|
||||||
int *allow_setuidp);
|
int *allow_setuidp);
|
||||||
|
@ -129,7 +129,7 @@ PUBLIC int pm_exec(int proc_e, char *path, vir_bytes path_len, char *frame,
|
||||||
r = r1;
|
r = r1;
|
||||||
else
|
else
|
||||||
r = req_stat(vp->v_fs_e, vp->v_inode_nr, VFS_PROC_NR,
|
r = req_stat(vp->v_fs_e, vp->v_inode_nr, VFS_PROC_NR,
|
||||||
(char *) &(execi.sb), 0);
|
(char *) &(execi.sb), 0, 0);
|
||||||
if (r != OK) {
|
if (r != OK) {
|
||||||
put_vnode(vp);
|
put_vnode(vp);
|
||||||
return(r);
|
return(r);
|
||||||
|
@ -314,7 +314,7 @@ static int exec_newmem(
|
||||||
int is_elf,
|
int is_elf,
|
||||||
dev_t st_dev,
|
dev_t st_dev,
|
||||||
ino_t st_ino,
|
ino_t st_ino,
|
||||||
time_t st_ctime,
|
time_t ctime,
|
||||||
char *progname,
|
char *progname,
|
||||||
int new_uid,
|
int new_uid,
|
||||||
int new_gid,
|
int new_gid,
|
||||||
|
@ -337,7 +337,7 @@ static int exec_newmem(
|
||||||
e.is_elf = is_elf;
|
e.is_elf = is_elf;
|
||||||
e.st_dev = st_dev;
|
e.st_dev = st_dev;
|
||||||
e.st_ino = st_ino;
|
e.st_ino = st_ino;
|
||||||
e.st_ctime = st_ctime;
|
e.enst_ctime = ctime;
|
||||||
e.new_uid = new_uid;
|
e.new_uid = new_uid;
|
||||||
e.new_gid = new_gid;
|
e.new_gid = new_gid;
|
||||||
strncpy(e.progname, progname, sizeof(e.progname)-1);
|
strncpy(e.progname, progname, sizeof(e.progname)-1);
|
||||||
|
|
|
@ -226,7 +226,7 @@ _PROTOTYPE(int req_slink, (endpoint_t fs_e, ino_t inode_nr, char *lastc,
|
||||||
endpoint_t who_e, char *path_addr,
|
endpoint_t who_e, char *path_addr,
|
||||||
unsigned short path_length, uid_t uid, gid_t gid) );
|
unsigned short path_length, uid_t uid, gid_t gid) );
|
||||||
_PROTOTYPE( int req_stat, (int fs_e, ino_t inode_nr, int who_e,
|
_PROTOTYPE( int req_stat, (int fs_e, ino_t inode_nr, int who_e,
|
||||||
char *buf, int pos) );
|
char *buf, int pos, int stat_version) );
|
||||||
_PROTOTYPE( int req_sync, (endpoint_t fs_e) );
|
_PROTOTYPE( int req_sync, (endpoint_t fs_e) );
|
||||||
_PROTOTYPE( int req_unlink, (endpoint_t fs_e, ino_t inode_nr,
|
_PROTOTYPE( int req_unlink, (endpoint_t fs_e, ino_t inode_nr,
|
||||||
char *lastc) );
|
char *lastc) );
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/statfs.h>
|
#include <sys/statfs.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
@ -925,19 +926,21 @@ PUBLIC int req_slink(
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* req_stat *
|
* req_stat *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC int req_stat(fs_e, inode_nr, who_e, buf, pos)
|
PUBLIC int req_stat(fs_e, inode_nr, who_e, buf, pos, stat_version)
|
||||||
int fs_e;
|
int fs_e;
|
||||||
ino_t inode_nr;
|
ino_t inode_nr;
|
||||||
int who_e;
|
int who_e;
|
||||||
char *buf;
|
char *buf;
|
||||||
int pos;
|
int pos;
|
||||||
|
int stat_version;
|
||||||
{
|
{
|
||||||
cp_grant_id_t grant_id;
|
cp_grant_id_t grant_id;
|
||||||
int r;
|
int r;
|
||||||
message m;
|
message m;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
struct minix_prev_stat old_sb; /* for backward compatibility */
|
||||||
|
|
||||||
if (pos != 0)
|
if (pos != 0 || stat_version != 0)
|
||||||
grant_id = cpf_grant_direct(fs_e, (vir_bytes) &sb,
|
grant_id = cpf_grant_direct(fs_e, (vir_bytes) &sb,
|
||||||
sizeof(struct stat), CPF_WRITE);
|
sizeof(struct stat), CPF_WRITE);
|
||||||
else
|
else
|
||||||
|
@ -956,12 +959,52 @@ int pos;
|
||||||
r = fs_sendrec(fs_e, &m);
|
r = fs_sendrec(fs_e, &m);
|
||||||
cpf_revoke(grant_id);
|
cpf_revoke(grant_id);
|
||||||
|
|
||||||
if (r == OK && pos != 0) {
|
if (r != OK || (pos == 0 && stat_version == 0))
|
||||||
|
return(r);
|
||||||
|
|
||||||
|
if (pos != 0)
|
||||||
sb.st_size -= pos;
|
sb.st_size -= pos;
|
||||||
|
if (stat_version == 0) {
|
||||||
r = sys_vircopy(SELF, D, (vir_bytes) &sb, who_e, D, (vir_bytes) buf,
|
r = sys_vircopy(SELF, D, (vir_bytes) &sb, who_e, D, (vir_bytes) buf,
|
||||||
sizeof(struct stat));
|
sizeof(struct stat));
|
||||||
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* User needs old struct stat.
|
||||||
|
* Just 1 prev version at this moment */
|
||||||
|
assert(stat_version == 1);
|
||||||
|
|
||||||
|
/* XXX until that st_Xtime macroses used, we have to undefine them,
|
||||||
|
* because of minix_prev_stat
|
||||||
|
*/
|
||||||
|
#undef st_atime
|
||||||
|
#undef st_ctime
|
||||||
|
#undef st_mtime
|
||||||
|
|
||||||
|
/* Copy field by field because of st_gid type mismath and
|
||||||
|
* difference in order after atime.
|
||||||
|
*/
|
||||||
|
old_sb.st_dev = sb.st_dev;
|
||||||
|
old_sb.st_ino = sb.st_ino;
|
||||||
|
old_sb.st_mode = sb.st_mode;
|
||||||
|
old_sb.st_nlink = sb.st_nlink;
|
||||||
|
old_sb.st_uid = sb.st_uid;
|
||||||
|
old_sb.st_gid = sb.st_gid;
|
||||||
|
old_sb.st_rdev = sb.st_rdev;
|
||||||
|
old_sb.st_size = sb.st_size;
|
||||||
|
#if defined(_NETBSD_SOURCE)
|
||||||
|
old_sb.st_atime = sb.st_atimespec.tv_sec;
|
||||||
|
old_sb.st_mtime = sb.st_mtimespec.tv_sec;
|
||||||
|
old_sb.st_ctime = sb.st_ctimespec.tv_sec;
|
||||||
|
#else
|
||||||
|
old_sb.st_atime = sb.st_atime;
|
||||||
|
old_sb.st_mtime = sb.st_mtime;
|
||||||
|
old_sb.st_ctime = sb.st_ctime;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
r = sys_vircopy(SELF, D, (vir_bytes) &old_sb, who_e, D, (vir_bytes) buf,
|
||||||
|
sizeof(struct minix_prev_stat));
|
||||||
|
|
||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "fproc.h"
|
#include "fproc.h"
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
#include <minix/vfsif.h>
|
#include <minix/vfsif.h>
|
||||||
|
#include <minix/callnr.h>
|
||||||
#include "vnode.h"
|
#include "vnode.h"
|
||||||
#include "vmnt.h"
|
#include "vmnt.h"
|
||||||
|
|
||||||
|
@ -121,10 +122,14 @@ PUBLIC int do_stat()
|
||||||
/* Perform the stat(name, buf) system call. */
|
/* Perform the stat(name, buf) system call. */
|
||||||
int r;
|
int r;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
|
int old_stat = 0;
|
||||||
|
|
||||||
|
if (call_nr == PREV_STAT)
|
||||||
|
old_stat = 1;
|
||||||
|
|
||||||
if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
|
if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
|
||||||
if ((vp = eat_path(PATH_NOFLAGS, fp)) == NULL) return(err_code);
|
if ((vp = eat_path(PATH_NOFLAGS, fp)) == NULL) return(err_code);
|
||||||
r = req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, m_in.name2, 0);
|
r = req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, m_in.name2, 0, old_stat);
|
||||||
|
|
||||||
put_vnode(vp);
|
put_vnode(vp);
|
||||||
return r;
|
return r;
|
||||||
|
@ -139,6 +144,10 @@ PUBLIC int do_fstat()
|
||||||
/* Perform the fstat(fd, buf) system call. */
|
/* Perform the fstat(fd, buf) system call. */
|
||||||
register struct filp *rfilp;
|
register struct filp *rfilp;
|
||||||
int pipe_pos = 0;
|
int pipe_pos = 0;
|
||||||
|
int old_stat = 0;
|
||||||
|
|
||||||
|
if (call_nr == PREV_FSTAT)
|
||||||
|
old_stat = 1;
|
||||||
|
|
||||||
/* Is the file descriptor valid? */
|
/* Is the file descriptor valid? */
|
||||||
if ((rfilp = get_filp(m_in.fd)) == NULL) return(err_code);
|
if ((rfilp = get_filp(m_in.fd)) == NULL) return(err_code);
|
||||||
|
@ -153,7 +162,7 @@ PUBLIC int do_fstat()
|
||||||
}
|
}
|
||||||
|
|
||||||
return req_stat(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr,
|
return req_stat(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr,
|
||||||
who_e, m_in.buffer, pipe_pos);
|
who_e, m_in.buffer, pipe_pos, old_stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -212,10 +221,14 @@ PUBLIC int do_lstat()
|
||||||
/* Perform the lstat(name, buf) system call. */
|
/* Perform the lstat(name, buf) system call. */
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
int r;
|
int r;
|
||||||
|
int old_stat = 0;
|
||||||
|
|
||||||
|
if (call_nr == PREV_LSTAT)
|
||||||
|
old_stat = 1;
|
||||||
|
|
||||||
if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
|
if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
|
||||||
if ((vp = eat_path(PATH_RET_SYMLINK, fp)) == NULL) return(err_code);
|
if ((vp = eat_path(PATH_RET_SYMLINK, fp)) == NULL) return(err_code);
|
||||||
r = req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, m_in.name2, 0);
|
r = req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, m_in.name2, 0, old_stat);
|
||||||
|
|
||||||
put_vnode(vp);
|
put_vnode(vp);
|
||||||
return(r);
|
return(r);
|
||||||
|
|
|
@ -33,7 +33,7 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = {
|
||||||
do_chmod, /* 15 = chmod */
|
do_chmod, /* 15 = chmod */
|
||||||
do_chown, /* 16 = chown */
|
do_chown, /* 16 = chown */
|
||||||
no_sys, /* 17 = break */
|
no_sys, /* 17 = break */
|
||||||
do_stat, /* 18 = stat */
|
do_stat, /* 18 = stat (prev)*/
|
||||||
do_lseek, /* 19 = lseek */
|
do_lseek, /* 19 = lseek */
|
||||||
no_sys, /* 20 = getpid */
|
no_sys, /* 20 = getpid */
|
||||||
do_mount, /* 21 = mount */
|
do_mount, /* 21 = mount */
|
||||||
|
@ -43,7 +43,7 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = {
|
||||||
no_sys, /* 25 = (stime) */
|
no_sys, /* 25 = (stime) */
|
||||||
no_sys, /* 26 = ptrace */
|
no_sys, /* 26 = ptrace */
|
||||||
no_sys, /* 27 = alarm */
|
no_sys, /* 27 = alarm */
|
||||||
do_fstat, /* 28 = fstat */
|
do_fstat, /* 28 = fstat (prev)*/
|
||||||
no_sys, /* 29 = pause */
|
no_sys, /* 29 = pause */
|
||||||
do_utime, /* 30 = utime */
|
do_utime, /* 30 = utime */
|
||||||
no_sys, /* 31 = (stty) */
|
no_sys, /* 31 = (stty) */
|
||||||
|
@ -65,7 +65,7 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = {
|
||||||
no_sys, /* 47 = getgid */
|
no_sys, /* 47 = getgid */
|
||||||
no_sys, /* 48 = (signal)*/
|
no_sys, /* 48 = (signal)*/
|
||||||
do_rdlink, /* 49 = readlink*/
|
do_rdlink, /* 49 = readlink*/
|
||||||
do_lstat, /* 50 = lstat */
|
do_lstat, /* 50 = lstat (prev)*/
|
||||||
no_sys, /* 51 = (acct) */
|
no_sys, /* 51 = (acct) */
|
||||||
no_sys, /* 52 = (phys) */
|
no_sys, /* 52 = (phys) */
|
||||||
no_sys, /* 53 = (lock) */
|
no_sys, /* 53 = (lock) */
|
||||||
|
@ -80,9 +80,9 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = {
|
||||||
no_sys, /* 62 = (setsid)*/
|
no_sys, /* 62 = (setsid)*/
|
||||||
no_sys, /* 63 = (getpgrp)*/
|
no_sys, /* 63 = (getpgrp)*/
|
||||||
no_sys, /* 64 = (itimer)*/
|
no_sys, /* 64 = (itimer)*/
|
||||||
no_sys, /* 65 = unused */
|
do_stat, /* 65 = stat */
|
||||||
no_sys, /* 66 = unused */
|
do_fstat, /* 66 = fstat */
|
||||||
no_sys, /* 67 = unused */
|
do_lstat, /* 67 = lstat */
|
||||||
no_sys, /* 68 = unused */
|
no_sys, /* 68 = unused */
|
||||||
no_sys, /* 69 = unused */
|
no_sys, /* 69 = unused */
|
||||||
no_sys, /* 70 = unused */
|
no_sys, /* 70 = unused */
|
||||||
|
|
|
@ -113,7 +113,7 @@ SANITYCHECK(SCL_DETAIL);
|
||||||
/* Save file identification to allow it to be shared. */
|
/* Save file identification to allow it to be shared. */
|
||||||
vmp->vm_ino = args.st_ino;
|
vmp->vm_ino = args.st_ino;
|
||||||
vmp->vm_dev = args.st_dev;
|
vmp->vm_dev = args.st_dev;
|
||||||
vmp->vm_ctime = args.st_ctime;
|
vmp->vm_ctime = args.enst_ctime;
|
||||||
|
|
||||||
/* set/clear separate I&D flag */
|
/* set/clear separate I&D flag */
|
||||||
if (args.sep_id)
|
if (args.sep_id)
|
||||||
|
|
Loading…
Reference in a new issue