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:
@@ -1,14 +1,35 @@
|
||||
#include <lib.h>
|
||||
#define fstat _fstat
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
PUBLIC int fstat(fd, buffer)
|
||||
int fd;
|
||||
struct stat *buffer;
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
struct minix_prev_stat old_sb;
|
||||
|
||||
m.m1_i1 = fd;
|
||||
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>
|
||||
#define lstat _lstat
|
||||
#define stat _stat
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -10,11 +9,29 @@ struct stat *buffer;
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
struct minix_prev_stat old_sb;
|
||||
|
||||
m.m1_i1 = strlen(name) + 1;
|
||||
m.m1_p1 = (char *) name;
|
||||
m.m1_p2 = (char *) buffer;
|
||||
|
||||
if((r = _syscall(VFS_PROC_NR, LSTAT, &m)) >= 0 || errno != ENOSYS)
|
||||
return r;
|
||||
return _stat(name, buffer);
|
||||
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));
|
||||
COPY_PREV_STAT_TO_NEW(buffer, &old_sb);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -8,9 +8,30 @@ _CONST char *name;
|
||||
struct stat *buffer;
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
struct minix_prev_stat old_sb;
|
||||
|
||||
m.m1_i1 = strlen(name) + 1;
|
||||
m.m1_p1 = (char *) name;
|
||||
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 <sys/statfs.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <string.h>
|
||||
|
||||
/*===========================================================================*
|
||||
* fs_stat *
|
||||
@@ -22,6 +23,8 @@ PUBLIC int fs_stat(void)
|
||||
if ((node = find_inode(fs_m_in.REQ_INODE_NR)) == NULL)
|
||||
return EINVAL;
|
||||
|
||||
memset(&statbuf, 0, sizeof(struct stat));
|
||||
|
||||
/* Fill in the basic info. */
|
||||
statbuf.st_dev = fs_dev;
|
||||
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) {
|
||||
#ifdef __minix
|
||||
b.psize = MINIX_ST_BLKSIZE;
|
||||
#else
|
||||
b.psize = sb.st_blksize;
|
||||
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;
|
||||
} else
|
||||
#endif
|
||||
b.psize = sb.st_blksize;
|
||||
|
||||
if (b.psize < MINPSIZE)
|
||||
b.psize = MINPSIZE;
|
||||
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))
|
||||
return (NULL);
|
||||
#ifdef __minix
|
||||
hashp->BSIZE = MIN(MINIX_ST_BLKSIZE, MAX_BSIZE);
|
||||
#else
|
||||
hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE);
|
||||
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);
|
||||
} else
|
||||
#endif
|
||||
hashp->BSIZE = MIN(statbuf.st_blksize, MAX_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
|
||||
--- nbsdsrc/src/lib/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.
|
||||
*/
|
||||
if (b.psize == 0) {
|
||||
- b.psize = sb.st_blksize;
|
||||
+#ifdef __minix
|
||||
+ b.psize = MINIX_ST_BLKSIZE;
|
||||
+#else
|
||||
b.psize = sb.st_blksize;
|
||||
+ 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;
|
||||
+ } else
|
||||
+#endif
|
||||
+ b.psize = sb.st_blksize;
|
||||
+
|
||||
if (b.psize < MINPSIZE)
|
||||
b.psize = MINPSIZE;
|
||||
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
|
||||
--- nbsdsrc/src/lib/libc/db/hash/hash.c
|
||||
+++ lib/nbsd_libc/db/hash/hash.c
|
||||
@@ -301,7 +301,11 @@
|
||||
@@ -301,7 +301,16 @@
|
||||
if (file != NULL) {
|
||||
if (stat(file, &statbuf))
|
||||
return (NULL);
|
||||
- hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE);
|
||||
+#ifdef __minix
|
||||
+ hashp->BSIZE = MIN(MINIX_ST_BLKSIZE, MAX_BSIZE);
|
||||
+#else
|
||||
hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE);
|
||||
+ 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);
|
||||
+ } else
|
||||
+#endif
|
||||
+ hashp->BSIZE = MIN(statbuf.st_blksize, MAX_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
|
||||
--- nbsdsrc/src/lib/libc/resolv/res_init.c
|
||||
+++ lib/nbsd_libc/resolv/res_init.c
|
||||
@@ -70,6 +70,10 @@
|
||||
* 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 @@
|
||||
@@ -88,7 +88,9 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.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 <arpa/inet.h>
|
||||
@@ -348,7 +354,9 @@
|
||||
@@ -348,7 +350,9 @@
|
||||
nserv = 0;
|
||||
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
|
||||
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 */
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
@@ -502,6 +510,7 @@
|
||||
@@ -502,6 +506,7 @@
|
||||
if (fstat(statp->_u._ext.ext->resfd, &st) != -1)
|
||||
__res_conf_time = statp->_u._ext.ext->res_conf_time =
|
||||
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();
|
||||
(void)fcntl(statp->_u._ext.ext->kq, 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|
|
||||
NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE, 0, 0);
|
||||
(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 {
|
||||
statp->_u._ext.ext->kq = -1;
|
||||
statp->_u._ext.ext->resfd = -1;
|
||||
@@ -565,7 +577,13 @@
|
||||
@@ -565,7 +573,13 @@
|
||||
int
|
||||
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
|
||||
* was a kevent related to resolv.conf and reload.
|
||||
* If the times are not equal, then we don't bother
|
||||
@@ -593,6 +611,7 @@
|
||||
@@ -593,6 +607,7 @@
|
||||
if (mtime)
|
||||
*mtime = __res_conf_time;
|
||||
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
|
||||
--- nbsdsrc/src/lib/libc/stdio/fseeko.c
|
||||
+++ lib/nbsd_libc/stdio/fseeko.c
|
||||
@@ -150,7 +150,11 @@
|
||||
@@ -150,7 +150,16 @@
|
||||
fp->_flags |= __SNPT;
|
||||
goto dumb;
|
||||
}
|
||||
- fp->_blksize = st.st_blksize;
|
||||
+#ifdef __minix
|
||||
+ fp->_blksize = MINIX_ST_BLKSIZE;
|
||||
+#else
|
||||
fp->_blksize = st.st_blksize;
|
||||
+ 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;
|
||||
+ } else
|
||||
+#endif
|
||||
+ fp->_blksize = st.st_blksize;
|
||||
+
|
||||
fp->_flags |= __SOPT;
|
||||
}
|
||||
|
||||
diff -ru nbsdsrc/src/lib/libc/stdio/makebuf.c lib/nbsd_libc/stdio/makebuf.c
|
||||
--- nbsdsrc/src/lib/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 */
|
||||
*couldbetty = S_ISCHR(st.st_mode);
|
||||
+#ifndef __minix
|
||||
if (st.st_blksize == 0) {
|
||||
*bufsize = BUFSIZ;
|
||||
return (__SNPT);
|
||||
}
|
||||
+#endif
|
||||
- if (st.st_blksize == 0) {
|
||||
- *bufsize = BUFSIZ;
|
||||
- return (__SNPT);
|
||||
- }
|
||||
|
||||
/*
|
||||
* Optimise fseek() only if it is a regular file. (The test for
|
||||
* __sseek is mainly paranoia.) It is safe to set _blksize
|
||||
* unconditionally; it will only be used if __SOPT is also set.
|
||||
*/
|
||||
- *bufsize = st.st_blksize;
|
||||
- fp->_blksize = st.st_blksize;
|
||||
+#ifdef __minix
|
||||
+ *bufsize = MINIX_ST_BLKSIZE;
|
||||
+ fp->_blksize = MINIX_ST_BLKSIZE;
|
||||
+#else
|
||||
*bufsize = st.st_blksize;
|
||||
fp->_blksize = st.st_blksize;
|
||||
+ if (st.st_blksize == 0) {
|
||||
+ /* 0 in 2 cases: upgrade from old to new struct stat or
|
||||
+ * there is a bug in underlying fs.
|
||||
+ */
|
||||
+ *bufsize = fp->_blksize = MINIX_ST_BLKSIZE;
|
||||
+ } else
|
||||
+#endif
|
||||
+ *bufsize = fp->_blksize = st.st_blksize;
|
||||
+
|
||||
return ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek ?
|
||||
__SOPT : __SNPT);
|
||||
}
|
||||
|
||||
@@ -70,10 +70,6 @@
|
||||
* 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
|
||||
|
||||
@@ -151,10 +151,15 @@ fseeko(FILE *fp, off_t offset, int whence)
|
||||
goto dumb;
|
||||
}
|
||||
#ifdef __minix
|
||||
fp->_blksize = MINIX_ST_BLKSIZE;
|
||||
#else
|
||||
fp->_blksize = st.st_blksize;
|
||||
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;
|
||||
} else
|
||||
#endif
|
||||
fp->_blksize = st.st_blksize;
|
||||
|
||||
fp->_flags |= __SOPT;
|
||||
}
|
||||
|
||||
|
||||
@@ -114,12 +114,6 @@ __swhatbuf(fp, bufsize, couldbetty)
|
||||
|
||||
/* could be a tty iff it is a character device */
|
||||
*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
|
||||
@@ -127,12 +121,15 @@ __swhatbuf(fp, bufsize, couldbetty)
|
||||
* unconditionally; it will only be used if __SOPT is also set.
|
||||
*/
|
||||
#ifdef __minix
|
||||
*bufsize = MINIX_ST_BLKSIZE;
|
||||
fp->_blksize = MINIX_ST_BLKSIZE;
|
||||
#else
|
||||
*bufsize = st.st_blksize;
|
||||
fp->_blksize = st.st_blksize;
|
||||
if (st.st_blksize == 0) {
|
||||
/* 0 in 2 cases: upgrade from old to new struct stat or
|
||||
* there is a bug in underlying fs.
|
||||
*/
|
||||
*bufsize = fp->_blksize = MINIX_ST_BLKSIZE;
|
||||
} else
|
||||
#endif
|
||||
*bufsize = fp->_blksize = st.st_blksize;
|
||||
|
||||
return ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek ?
|
||||
__SOPT : __SNPT);
|
||||
}
|
||||
|
||||
@@ -5,101 +5,126 @@
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __MINIX_EMULATE_NETBSD_STAT
|
||||
#error __MINIX_EMULATE_NETBSD_STAT is set.
|
||||
#endif
|
||||
|
||||
int __orig_minix_stat(name, buffer)
|
||||
const char *name;
|
||||
struct __minix_stat *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)
|
||||
{
|
||||
message m;
|
||||
|
||||
m.m1_i1 = strlen(name) + 1;
|
||||
m.m1_p1 = (char *) name;
|
||||
m.m1_p2 = (char *) buffer;
|
||||
return(_syscall(VFS_PROC_NR, STAT, &m));
|
||||
/* 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 __orig_minix_fstat(fd, buffer)
|
||||
int fd;
|
||||
struct __minix_stat *buffer;
|
||||
{
|
||||
message m;
|
||||
|
||||
m.m1_i1 = fd;
|
||||
m.m1_p1 = (char *) buffer;
|
||||
return(_syscall(VFS_PROC_NR, FSTAT, &m));
|
||||
}
|
||||
|
||||
int __orig_minix_lstat(name, buffer)
|
||||
int _stat(name, buffer)
|
||||
const char *name;
|
||||
struct __minix_stat *buffer;
|
||||
struct stat *buffer;
|
||||
{
|
||||
message m;
|
||||
int r;
|
||||
struct minix_prev_stat old_sb;
|
||||
|
||||
m.m1_i1 = strlen(name) + 1;
|
||||
m.m1_p1 = (char *) name;
|
||||
m.m1_p2 = (char *) buffer;
|
||||
if((r = _syscall(VFS_PROC_NR, LSTAT, &m)) >= 0 || errno != ENOSYS)
|
||||
return r;
|
||||
return __orig_minix_stat(name, buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
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 __emu_netbsd_fstat(fd, buffer)
|
||||
int _fstat(fd, buffer)
|
||||
int fd;
|
||||
struct __netbsd_stat *buffer;
|
||||
struct stat *buffer;
|
||||
{
|
||||
int r;
|
||||
r = __orig_minix_fstat(fd, (struct __minix_stat *)buffer);
|
||||
if ( r < 0 )
|
||||
return r;
|
||||
__emulate_netbsd_fields(buffer);
|
||||
message m;
|
||||
int r;
|
||||
struct minix_prev_stat old_sb;
|
||||
|
||||
m.m1_i1 = fd;
|
||||
m.m1_p1 = (char *) buffer;
|
||||
|
||||
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 __emu_netbsd_lstat(name, buffer)
|
||||
int _lstat(name, buffer)
|
||||
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);
|
||||
if ( r < 0 )
|
||||
return r;
|
||||
__emulate_netbsd_fields(buffer);
|
||||
m.m1_i1 = strlen(name) + 1;
|
||||
m.m1_p1 = (char *) name;
|
||||
m.m1_p2 = (char *) buffer;
|
||||
|
||||
if((r = _syscall(VFS_PROC_NR, LSTAT, &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_LSTAT, &m)) < 0)
|
||||
return r;
|
||||
|
||||
memset(buffer, 0, sizeof(struct stat));
|
||||
prev_stat2new_stat(buffer, &old_sb);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user