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:
Evgeniy Ivanov 2011-07-01 23:35:54 +04:00 committed by Ben Gras
parent 48331843ea
commit ef0a265086
34 changed files with 533 additions and 417 deletions

View file

@ -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 },
}; };

View file

@ -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.
*/ */

View file

@ -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 */

View file

@ -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

View file

@ -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 short nlink_t; /* number of links to a file */ typedef u32_t big_mode_t; /* file type and permissions bits */
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) );

View file

@ -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 */

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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);

View file

@ -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
b.psize = MINIX_ST_BLKSIZE; if (sb.st_blksize == 0) {
#else /* 0 in 2 cases: upgrade from old to new struct stat or
b.psize = sb.st_blksize; * there is a bug in underlying fs.
*/
b.psize = MINIX_ST_BLKSIZE;
} else
#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)

View file

@ -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
hashp->BSIZE = MIN(MINIX_ST_BLKSIZE, MAX_BSIZE); if (statbuf.st_blksize == 0) {
#else /* 0 in 2 cases: upgrade from old to new struct stat or
hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE); * there is a bug in underlying fs.
*/
hashp->BSIZE = MIN(MINIX_ST_BLKSIZE, MAX_BSIZE);
} else
#endif #endif
hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE);
hashp->BSHIFT = __log2((uint32_t)hashp->BSIZE); hashp->BSHIFT = __log2((uint32_t)hashp->BSIZE);
} }

View file

@ -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
+ b.psize = MINIX_ST_BLKSIZE; + if (sb.st_blksize == 0) {
+#else + /* 0 in 2 cases: upgrade from old to new struct stat or
b.psize = sb.st_blksize; + * there is a bug in underlying fs.
+ */
+ b.psize = MINIX_ST_BLKSIZE;
+ } else
+#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
+ hashp->BSIZE = MIN(MINIX_ST_BLKSIZE, MAX_BSIZE); + if (statbuf.st_blksize == 0) {
+#else + /* 0 in 2 cases: upgrade from old to new struct stat or
hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE); + * there is a bug in underlying fs.
+ */
+ hashp->BSIZE = MIN(MINIX_ST_BLKSIZE, MAX_BSIZE);
+ } else
+#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
+ fp->_blksize = MINIX_ST_BLKSIZE; + if (st.st_blksize == 0) {
+#else + /* 0 in 2 cases: upgrade from old to new struct stat or
fp->_blksize = st.st_blksize; + * there is a bug in underlying fs.
+ */
+ fp->_blksize = MINIX_ST_BLKSIZE;
+ } else
+#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);
} }

View file

@ -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

View file

@ -151,10 +151,15 @@ fseeko(FILE *fp, off_t offset, int whence)
goto dumb; goto dumb;
} }
#ifdef __minix #ifdef __minix
fp->_blksize = MINIX_ST_BLKSIZE; if (st.st_blksize == 0) {
#else /* 0 in 2 cases: upgrade from old to new struct stat or
fp->_blksize = st.st_blksize; * there is a bug in underlying fs.
*/
fp->_blksize = MINIX_ST_BLKSIZE;
} else
#endif #endif
fp->_blksize = st.st_blksize;
fp->_flags |= __SOPT; fp->_flags |= __SOPT;
} }

View file

@ -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);
} }

View file

@ -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,
const char *name; * because of minix_prev_stat
struct __minix_stat *buffer; */
#undef st_atime
#undef st_ctime
#undef st_mtime
static void prev_stat2new_stat(struct stat *new, struct minix_prev_stat *prev)
{ {
message m; /* Copy field by field because of st_gid type mismath and
* difference in order after atime.
m.m1_i1 = strlen(name) + 1; */
m.m1_p1 = (char *) name; new->st_dev = prev->st_dev;
m.m1_p2 = (char *) buffer; new->st_ino = prev->st_ino;
return(_syscall(VFS_PROC_NR, STAT, &m)); 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 __orig_minix_fstat(fd, buffer)
int fd;
struct __minix_stat *buffer;
{
message m;
m.m1_i1 = fd; int _stat(name, buffer)
m.m1_p1 = (char *) buffer;
return(_syscall(VFS_PROC_NR, FSTAT, &m));
}
int __orig_minix_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)
return r;
return __orig_minix_stat(name, buffer);
}
/* if((r = _syscall(VFS_PROC_NR, STAT, &m)) >= 0 || errno != ENOSYS)
* NetBSD Fields Emulation.
*/
static void __emulate_netbsd_fields(struct __netbsd_stat *buffer)
{
/* 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;
__emulate_netbsd_fields(buffer);
return r; 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 __emu_netbsd_fstat(fd, buffer) int _fstat(fd, buffer)
int fd; int fd;
struct __netbsd_stat *buffer; struct stat *buffer;
{ {
int r; message m;
r = __orig_minix_fstat(fd, (struct __minix_stat *)buffer); int r;
if ( r < 0 ) struct minix_prev_stat old_sb;
return r;
__emulate_netbsd_fields(buffer); m.m1_i1 = fd;
m.m1_p1 = (char *) buffer;
if((r = _syscall(VFS_PROC_NR, FSTAT, &m)) >= 0 || errno != ENOSYS)
return r; 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 __emu_netbsd_lstat(name, buffer) int _lstat(name, buffer)
const char *name; const char *name;
struct __netbsd_stat *buffer; struct stat *buffer;
{ {
int r; message m;
int r;
struct minix_prev_stat old_sb;
r = __orig_minix_lstat(name, (struct __minix_stat *)buffer); m.m1_i1 = strlen(name) + 1;
if ( r < 0 ) m.m1_p1 = (char *) name;
return r; m.m1_p2 = (char *) buffer;
__emulate_netbsd_fields(buffer);
if((r = _syscall(VFS_PROC_NR, LSTAT, &m)) >= 0 || errno != ENOSYS)
return r; 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_LSTAT, &m)) < 0)
return r;
memset(buffer, 0, sizeof(struct stat));
prev_stat2new_stat(buffer, &old_sb);
return r;
} }

View file

@ -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

View file

@ -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).

View file

@ -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 { struct stat {
dev_t st_dev; /* major/minor device number */ big_dev_t st_dev; /* inode's device */
ino_t st_ino; /* i-node number */ big_mode_t st_mode; /* inode protection mode */
mode_t st_mode; /* file mode, protection bits, etc. */ big_ino_t st_ino; /* inode's number */
nlink_t st_nlink; /* # links; */ big_nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* uid of the file's owner */ big_uid_t st_uid; /* user ID of the file's owner */
gid_t st_gid; /* gid */ big_gid_t st_gid; /* group ID of the file's group */
dev_t st_rdev; big_dev_t st_rdev; /* device type */
off_t st_size; /* file size */ #if defined(_NETBSD_SOURCE)
time_t st_atime; /* time of last access */ struct timespec st_atimespec;/* time of last access */
time_t st_mtime; /* time of last data modification */ struct timespec st_mtimespec;/* time of last data modification */
time_t st_ctime; /* time of last file status change */ 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
big_off_t st_size; /* file size, in bytes */
blkcnt_t st_blocks; /* blocks allocated for file */
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 */
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) #if defined(_NETBSD_SOURCE)
struct __netbsd_stat { /* XXX after updating stat struct we don't want to update all the code */
dev_t st_dev; /* major/minor device number */ #define st_atime st_atimespec.tv_sec
ino_t st_ino; /* i-node number */ #define st_mtime st_mtimespec.tv_sec
mode_t st_mode; /* file mode, protection bits, etc. */ #define st_ctime st_ctimespec.tv_sec
nlink_t st_nlink; /* # links; */ #define st_birthtime st_birthtimespec.tv_sec
uid_t st_uid; /* uid of the file's owner */ #define st_atimensec st_atimespec.tv_nsec
gid_t st_gid; /* gid */ #define st_mtimensec st_mtimespec.tv_nsec
dev_t st_rdev; #define st_ctimensec st_ctimespec.tv_nsec
off_t st_size; /* file size */ #define st_birthtimensec st_birthtimespec.tv_nsec
time_t st_atime; /* time of last access */ #endif
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_mtimespec;/* time of last data modification */
struct timespec st_ctimespec;/* time of last file status change */
struct timespec st_birthtimespec; /* time of creation */
blkcnt_t st_blocks; /* blocks allocated for file */
blksize_t st_blksize; /* optimal blocksize for I/O */
};
#ifdef __MINIX_EMULATE_NETBSD_STAT
#define st_atimensec st_atimespec.tv_nsec
#define st_mtimensec st_mtimespec.tv_nsec
#define st_ctimensec st_ctimespec.tv_nsec
#define st_birthtime st_birthtimespec.tv_sec
#define st_birthtimensec st_birthtimespec.tv_nsec
#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

View file

@ -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 */

View file

@ -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,

View file

@ -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.

View file

@ -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;

View file

@ -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,

View file

@ -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,

View file

@ -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) */

View file

@ -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);

View file

@ -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);

View file

@ -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) );

View file

@ -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,11 +959,51 @@ 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))
sb.st_size -= pos; return(r);
r = sys_vircopy(SELF, D, (vir_bytes) &sb, who_e, D, (vir_bytes) buf,
sizeof(struct stat)); if (pos != 0)
sb.st_size -= pos;
if (stat_version == 0) {
r = sys_vircopy(SELF, D, (vir_bytes) &sb, who_e, D, (vir_bytes) buf,
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);
} }

View file

@ -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);

View file

@ -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 */

View file

@ -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)