stat.h: remove some big_ types
Change-Id: I84017db3d54edfb823cc52e02d0b07fccb003988
This commit is contained in:
parent
ab19ece134
commit
c1a31d53d9
51 changed files with 1228 additions and 176 deletions
|
@ -456,13 +456,8 @@ ar_close(void)
|
|||
|
||||
/* mimic cpio's block count first */
|
||||
if (frmt && strcmp(NM_CPIO, argv0) == 0) {
|
||||
#ifdef __minix
|
||||
(void)fprintf(listf, "%d blocks\n",
|
||||
(rdcnt ? rdcnt : wrcnt) / 5120);
|
||||
#else
|
||||
(void)fprintf(listf, OFFT_F " blocks\n",
|
||||
(rdcnt ? rdcnt : wrcnt) / 5120);
|
||||
#endif
|
||||
}
|
||||
|
||||
ar_summary(0);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#define CHMOD 15
|
||||
#define CHOWN 16
|
||||
#define BRK 17
|
||||
#define LSEEK 19
|
||||
#define LSEEK_321 19
|
||||
#define MINIX_GETPID 20
|
||||
#define MOUNT 21
|
||||
#define UMOUNT 22
|
||||
|
@ -48,7 +48,7 @@
|
|||
#define FSTAT 52
|
||||
#define LSTAT 53
|
||||
#define IOCTL 54
|
||||
#define FCNTL 55
|
||||
#define FCNTL_321 55
|
||||
#define FS_READY 57
|
||||
#define PIPE2 58
|
||||
#define EXEC 59
|
||||
|
@ -59,6 +59,8 @@
|
|||
#define ITIMER 64
|
||||
#define GETMCONTEXT 67
|
||||
#define SETMCONTEXT 68
|
||||
#define GETDENTS 69
|
||||
#define FTRUNCATE 70
|
||||
|
||||
/* Posix signal handling. */
|
||||
#define SIGACTION 71
|
||||
|
@ -70,7 +72,7 @@
|
|||
#define REBOOT 76
|
||||
#define SVRCTL 77
|
||||
#define SYSUNAME 78
|
||||
#define GETDENTS 80 /* to VFS */
|
||||
#define GETDENTS_321 80 /* to VFS */
|
||||
#define LLSEEK 81 /* to VFS */
|
||||
#define FSTATFS 82 /* to VFS */
|
||||
#define STATVFS 83 /* to VFS */
|
||||
|
@ -83,14 +85,14 @@
|
|||
#define GETTIMEOFDAY 90 /* to PM */
|
||||
#define SETEUID 91 /* to PM */
|
||||
#define SETEGID 92 /* to PM */
|
||||
#define TRUNCATE 93 /* to VFS */
|
||||
#define FTRUNCATE 94 /* to VFS */
|
||||
#define TRUNCATE_321 93 /* to VFS */
|
||||
#define FTRUNCATE_321 94 /* to VFS */
|
||||
#define FCHMOD 95 /* to VFS */
|
||||
#define FCHOWN 96 /* to VFS */
|
||||
#define LSEEK 97
|
||||
#define SPROF 98 /* to PM */
|
||||
#define CPROF 99 /* to PM */
|
||||
|
||||
/* Calls provided by PM and FS that are not part of the API */
|
||||
#define PM_NEWEXEC 100 /* from VFS or RS to PM: new exec */
|
||||
#define SRV_FORK 101 /* to PM: special fork call for RS */
|
||||
#define EXEC_RESTART 102 /* to PM: final part of exec for RS */
|
||||
|
@ -98,6 +100,8 @@
|
|||
#define ISSETUGID 106 /* to PM: ask if process is tainted */
|
||||
#define GETEPINFO_O 107 /* to PM: get pid/uid/gid of an endpoint */
|
||||
#define UTIMENS 108 /* to FS: [f]utimens(); also [fl]utimes */
|
||||
#define FCNTL 109 /* to VFS */
|
||||
#define TRUNCATE 110 /* to VFS */
|
||||
#define SRV_KILL 111 /* to PM: special kill call for RS */
|
||||
|
||||
#define GCOV_FLUSH 112 /* flush gcov data from server to gcov files */
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#define OS_RELEASE "3"
|
||||
#define OS_VERSION "2.1"
|
||||
|
||||
/* Keep these in sync with os_version above for temp version check in VFS */
|
||||
#define OS_VMAJOR 2
|
||||
#define OS_VMINOR 1
|
||||
/* This file sets configuration parameters for the MINIX kernel, FS, and PM.
|
||||
* It is divided up into two main sections. The first section contains
|
||||
* user-settable parameters. In the second section, various internal system
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
#define VFS_FS_PROTO_VERSION(b) (((b) & RES_PROTO_V_MASK) >> RES_PROTO_V_SHIFT)
|
||||
#define VFS_FS_PROTO_PUT_VERSION(b,v) \
|
||||
((b) |= (((v) << RES_PROTO_V_SHIFT) & RES_PROTO_V_MASK))
|
||||
#define VFS_FS_CURRENT_VERSION 0 /* Current version */
|
||||
#define VFS_FS_CURRENT_VERSION 1 /* Current version */
|
||||
|
||||
/* VFS/FS flags */
|
||||
#define REQ_RDONLY 001
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
struct statfs {
|
||||
off_t f_bsize; /* file system block size */
|
||||
int f_bsize; /* file system block size */
|
||||
};
|
||||
|
||||
int fstatfs(int fd, struct statfs *st);
|
||||
|
|
|
@ -18,7 +18,7 @@ struct mapreq
|
|||
struct mapreqvm
|
||||
{
|
||||
int flags; /* reserved, must be 0 */
|
||||
off_t phys_offset;
|
||||
phys_bytes phys_offset;
|
||||
size_t size;
|
||||
int readonly;
|
||||
char reserved[36]; /* reserved, must be 0 */
|
||||
|
|
|
@ -102,7 +102,7 @@ void arch_post_init(void)
|
|||
pg_info(&vm->p_seg.p_ttbr, &vm->p_seg.p_ttbr_v);
|
||||
}
|
||||
|
||||
int libexec_pg_alloc(struct exec_info *execi, off_t vaddr, size_t len)
|
||||
static int libexec_pg_alloc(struct exec_info *execi, vir_bytes vaddr, size_t len)
|
||||
{
|
||||
pg_map(PG_ALLOCATEME, vaddr, vaddr+len, &kinfo);
|
||||
pg_load();
|
||||
|
|
|
@ -376,7 +376,7 @@ void arch_post_init(void)
|
|||
pg_info(&vm->p_seg.p_cr3, &vm->p_seg.p_cr3_v);
|
||||
}
|
||||
|
||||
int libexec_pg_alloc(struct exec_info *execi, off_t vaddr, size_t len)
|
||||
static int libexec_pg_alloc(struct exec_info *execi, vir_bytes vaddr, size_t len)
|
||||
{
|
||||
pg_map(PG_ALLOCATEME, vaddr, vaddr+len, &kinfo);
|
||||
pg_load();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
@ -9,12 +10,78 @@
|
|||
__weak_alias(fcntl, _fcntl)
|
||||
#endif
|
||||
|
||||
static int __fcntl_321(int fd, int cmd, va_list argp);
|
||||
|
||||
int __fcntl_321(int fd, int cmd, va_list argp)
|
||||
{
|
||||
message m;
|
||||
struct flock_321 f_321;
|
||||
struct flock *flock;
|
||||
int r;
|
||||
|
||||
/* Set up for the sensible case where there is no variable parameter. This
|
||||
* covers F_GETFD, F_GETFL and invalid commands.
|
||||
*/
|
||||
m.m1_i3 = 0;
|
||||
m.m1_p1 = NULL;
|
||||
|
||||
/* Adjust for the stupid cases. */
|
||||
switch(cmd) {
|
||||
case F_DUPFD:
|
||||
case F_SETFD:
|
||||
case F_SETFL:
|
||||
m.m1_i3 = va_arg(argp, int);
|
||||
break;
|
||||
case F_GETLK:
|
||||
case F_SETLK:
|
||||
case F_SETLKW:
|
||||
case F_FREESP:
|
||||
/* VFS expects old format, so translate */
|
||||
flock = (struct flock *) va_arg(argp, struct flock *);
|
||||
f_321.l_type = flock->l_type;
|
||||
f_321.l_whence = flock->l_whence;
|
||||
f_321.l_start = flock->l_start;
|
||||
f_321.l_len = flock->l_len;
|
||||
f_321.l_pid = flock->l_pid;
|
||||
m.m1_p1 = (char *) &f_321;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clean up and make the system call. */
|
||||
m.m1_i1 = fd;
|
||||
m.m1_i2 = cmd;
|
||||
|
||||
r = _syscall(VFS_PROC_NR, FCNTL_321, &m);
|
||||
|
||||
if (r == 0) {
|
||||
/* Maybe we need to convert back */
|
||||
|
||||
switch(cmd) {
|
||||
case F_GETLK:
|
||||
case F_SETLK:
|
||||
case F_SETLKW:
|
||||
case F_FREESP:
|
||||
/* VFS expected old format but libc new format, so translate */
|
||||
flock->l_type = f_321.l_type;
|
||||
flock->l_whence = f_321.l_whence;
|
||||
flock->l_start = f_321.l_start;
|
||||
flock->l_len = f_321.l_len;
|
||||
flock->l_pid = f_321.l_pid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int fcntl(int fd, int cmd, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_list argp, argp_321;
|
||||
message m;
|
||||
int r, org_errno;
|
||||
|
||||
va_start(argp, cmd);
|
||||
va_start(argp_321, cmd);
|
||||
|
||||
/* Set up for the sensible case where there is no variable parameter. This
|
||||
* covers F_GETFD, F_GETFL and invalid commands.
|
||||
|
@ -41,5 +108,15 @@ int fcntl(int fd, int cmd, ...)
|
|||
va_end(argp);
|
||||
m.m1_i1 = fd;
|
||||
m.m1_i2 = cmd;
|
||||
return(_syscall(VFS_PROC_NR, FCNTL, &m));
|
||||
org_errno = errno;
|
||||
r = _syscall(VFS_PROC_NR, FCNTL, &m);
|
||||
|
||||
if (r == -1 && errno == ENOSYS) {
|
||||
errno = org_errno;
|
||||
r = __fcntl_321(fd, cmd, argp_321);
|
||||
}
|
||||
|
||||
va_end(argp_321);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <minix/u64.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -9,11 +11,38 @@
|
|||
__weak_alias(ftruncate, _ftruncate)
|
||||
#endif
|
||||
|
||||
int ftruncate(int _fd, off_t _length)
|
||||
static int __ftruncate_321(int _fd, int _length);
|
||||
|
||||
static int __ftruncate_321(int _fd, int _length)
|
||||
{
|
||||
message m;
|
||||
m.m2_l1 = _length;
|
||||
m.m2_i1 = _fd;
|
||||
|
||||
return(_syscall(VFS_PROC_NR, FTRUNCATE, &m));
|
||||
return(_syscall(VFS_PROC_NR, FTRUNCATE_321, &m));
|
||||
}
|
||||
|
||||
int ftruncate(int _fd, off_t _length)
|
||||
{
|
||||
message m;
|
||||
int orig_errno, r;
|
||||
|
||||
m.m2_l1 = ex64lo(_length);
|
||||
m.m2_l2 = ex64hi(_length);
|
||||
m.m2_i1 = _fd;
|
||||
|
||||
orig_errno = errno;
|
||||
r = _syscall(VFS_PROC_NR, FTRUNCATE, &m);
|
||||
if (r == -1 && errno == ENOSYS) {
|
||||
/* Old VFS, no support for new ftruncate */
|
||||
if (_length >= INT_MIN && _length <= INT_MAX) {
|
||||
errno = orig_errno;
|
||||
return __ftruncate_321(_fd, (int) _length);
|
||||
}
|
||||
|
||||
/* Not going to fit */
|
||||
errno = EOVERFLOW;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -3,15 +3,83 @@
|
|||
#include <lib.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static ssize_t __getdents321(int fd, char *buffer, size_t nbytes);
|
||||
|
||||
ssize_t getdents(int fd, char *buffer, size_t nbytes)
|
||||
{
|
||||
message m;
|
||||
int r, orig_errno;
|
||||
|
||||
orig_errno = errno;
|
||||
m.m1_i1 = fd;
|
||||
m.m1_i2 = nbytes;
|
||||
m.m1_p1 = (char *) buffer;
|
||||
return _syscall(VFS_PROC_NR, GETDENTS, &m);
|
||||
r = _syscall(VFS_PROC_NR, GETDENTS, &m);
|
||||
if (r == -1 && errno == ENOSYS) {
|
||||
errno = orig_errno;/* Restore old value so world is still as expected*/
|
||||
r = __getdents321(fd, buffer, nbytes);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t __getdents321(int fd, char *buffer, size_t nbytes)
|
||||
{
|
||||
message m;
|
||||
int r, consumed = 0, newconsumed = 0;
|
||||
char *intermediate = NULL;
|
||||
struct dirent *dent;
|
||||
struct dirent_321 *dent_321;
|
||||
#define DWORD_ALIGN(d) if((d) % sizeof(long)) (d)+=sizeof(long)-(d)%sizeof(long)
|
||||
|
||||
intermediate = malloc(nbytes);
|
||||
if (intermediate == NULL) return EINVAL;
|
||||
|
||||
m.m1_i1 = fd;
|
||||
/* Pretend the buffer is smaller so we know the converted/expanded version
|
||||
* will fit.
|
||||
*/
|
||||
nbytes = nbytes / 2;
|
||||
if (nbytes < (sizeof(struct dirent) + NAME_MAX + 1)) {
|
||||
free(intermediate);
|
||||
return EINVAL; /* This might not fit. Sorry */
|
||||
}
|
||||
|
||||
m.m1_i2 = nbytes;
|
||||
m.m1_p1 = (char *) intermediate;
|
||||
r = _syscall(VFS_PROC_NR, GETDENTS_321, &m);
|
||||
|
||||
if (r <= 0) {
|
||||
free(intermediate);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Provided format is struct dirent_321 and has to be translated to
|
||||
* struct dirent */
|
||||
dent_321 = (struct dirent_321 *) intermediate;
|
||||
dent = (struct dirent *) buffer;
|
||||
|
||||
while (consumed < r && dent_321->d_reclen > 0) {
|
||||
dent->d_ino = (ino_t) dent_321->d_ino;
|
||||
dent->d_off = (off_t) dent_321->d_off;
|
||||
dent->d_reclen = offsetof(struct dirent, d_name) +
|
||||
strlen(dent_321->d_name) + 1;
|
||||
DWORD_ALIGN(dent->d_reclen);
|
||||
strcpy(dent->d_name, dent_321->d_name);
|
||||
consumed += dent_321->d_reclen;
|
||||
newconsumed += dent->d_reclen;
|
||||
dent_321 = (struct dirent_321 *) &intermediate[consumed];
|
||||
dent = (struct dirent *) &buffer[newconsumed];
|
||||
}
|
||||
|
||||
free(intermediate);
|
||||
|
||||
return newconsumed;
|
||||
}
|
||||
|
||||
#if defined(__minix) && defined(__weak_alias)
|
||||
|
|
|
@ -2,22 +2,53 @@
|
|||
#include "namespace.h"
|
||||
#include <lib.h>
|
||||
|
||||
#include <minix/u64.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(lseek, _lseek)
|
||||
#endif
|
||||
|
||||
off_t lseek(fd, offset, whence)
|
||||
int fd;
|
||||
off_t offset;
|
||||
int whence;
|
||||
i32_t __lseek_321(int fd, i32_t offset, int whence);
|
||||
|
||||
i32_t __lseek_321(int fd, i32_t offset, int whence)
|
||||
{
|
||||
message m;
|
||||
|
||||
m.m2_i1 = fd;
|
||||
m.m2_l1 = offset;
|
||||
m.m2_i2 = whence;
|
||||
if (_syscall(VFS_PROC_NR, LSEEK, &m) < 0) return( (off_t) -1);
|
||||
return( (off_t) m.m2_l1);
|
||||
if (_syscall(VFS_PROC_NR, LSEEK_321, &m) < 0) return(-1);
|
||||
return( (i32_t) m.m2_l1);
|
||||
}
|
||||
|
||||
off_t
|
||||
lseek(int fd, off_t offset, int whence)
|
||||
{
|
||||
message m;
|
||||
int orig_errno;
|
||||
|
||||
m.m2_i1 = fd;
|
||||
m.m2_l1 = ex64lo(offset);
|
||||
m.m2_l2 = ex64hi(offset);
|
||||
m.m2_i2 = whence;
|
||||
|
||||
orig_errno = errno;
|
||||
if (_syscall(VFS_PROC_NR, LSEEK, &m) < 0) {
|
||||
if (errno == ENOSYS) {
|
||||
/* Old VFS, no support for new lseek */
|
||||
if (offset >= INT_MIN && offset <= INT_MAX) {
|
||||
/* offset fits in old range, retry */
|
||||
errno = orig_errno;
|
||||
return (off_t) __lseek_321(fd, (i32_t) offset, whence);
|
||||
}
|
||||
|
||||
/* Not going to fit */
|
||||
errno = EOVERFLOW;
|
||||
}
|
||||
|
||||
return( (off_t) -1);
|
||||
}
|
||||
return( (off_t) make64(m.m2_l1, m.m2_l2));
|
||||
}
|
||||
|
|
|
@ -6,16 +6,46 @@
|
|||
__weak_alias(truncate, _truncate)
|
||||
#endif
|
||||
|
||||
#include <minix/u64.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int __truncate_321(const char *_path, int _length);
|
||||
|
||||
int truncate(const char *_path, off_t _length)
|
||||
static int __truncate_321(const char *_path, int _length)
|
||||
{
|
||||
message m;
|
||||
m.m2_p1 = (char *) __UNCONST(_path);
|
||||
m.m2_i1 = strlen(_path)+1;
|
||||
m.m2_l1 = _length;
|
||||
|
||||
return(_syscall(VFS_PROC_NR, TRUNCATE, &m));
|
||||
return(_syscall(VFS_PROC_NR, TRUNCATE_321, &m));
|
||||
}
|
||||
|
||||
int truncate(const char *_path, off_t _length)
|
||||
{
|
||||
message m;
|
||||
int orig_errno, r;
|
||||
|
||||
m.m2_p1 = (char *) __UNCONST(_path);
|
||||
m.m2_i1 = strlen(_path)+1;
|
||||
m.m2_l1 = ex64lo(_length);
|
||||
m.m2_l2 = ex64hi(_length);
|
||||
|
||||
orig_errno = errno;
|
||||
r = _syscall(VFS_PROC_NR, TRUNCATE, &m);
|
||||
|
||||
if (r == -1 && errno == ENOSYS) {
|
||||
/* Old VFS, no support for new truncate */
|
||||
if (_length >= INT_MIN && _length <= INT_MAX) {
|
||||
errno = orig_errno;
|
||||
return __truncate_321(_path, (int) _length);
|
||||
}
|
||||
|
||||
/* Not going to fit */
|
||||
errno = EOVERFLOW;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <sys/mman.h>
|
||||
#include <machine/elf.h>
|
||||
|
||||
int libexec_alloc_mmap_prealloc_junk(struct exec_info *execi, off_t vaddr, size_t len)
|
||||
int libexec_alloc_mmap_prealloc_junk(struct exec_info *execi, vir_bytes vaddr, size_t len)
|
||||
{
|
||||
if(minix_mmap_for(execi->proc_e, (void *) vaddr, len,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC,
|
||||
|
@ -29,7 +29,7 @@ int libexec_alloc_mmap_prealloc_junk(struct exec_info *execi, off_t vaddr, size_
|
|||
return OK;
|
||||
}
|
||||
|
||||
int libexec_alloc_mmap_prealloc_cleared(struct exec_info *execi, off_t vaddr, size_t len)
|
||||
int libexec_alloc_mmap_prealloc_cleared(struct exec_info *execi, vir_bytes vaddr, size_t len)
|
||||
{
|
||||
if(minix_mmap_for(execi->proc_e, (void *) vaddr, len,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC,
|
||||
|
@ -40,7 +40,7 @@ int libexec_alloc_mmap_prealloc_cleared(struct exec_info *execi, off_t vaddr, si
|
|||
return OK;
|
||||
}
|
||||
|
||||
int libexec_alloc_mmap_ondemand(struct exec_info *execi, off_t vaddr, size_t len)
|
||||
int libexec_alloc_mmap_ondemand(struct exec_info *execi, vir_bytes vaddr, size_t len)
|
||||
{
|
||||
if(minix_mmap_for(execi->proc_e, (void *) vaddr, len,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC,
|
||||
|
@ -56,20 +56,20 @@ int libexec_clearproc_vm_procctl(struct exec_info *execi)
|
|||
return vm_procctl(execi->proc_e, VMPPARAM_CLEAR);
|
||||
}
|
||||
|
||||
int libexec_clear_sys_memset(struct exec_info *execi, off_t vaddr, size_t len)
|
||||
int libexec_clear_sys_memset(struct exec_info *execi, vir_bytes vaddr, size_t len)
|
||||
{
|
||||
return sys_memset(execi->proc_e, 0, vaddr, len);
|
||||
}
|
||||
|
||||
int libexec_copy_memcpy(struct exec_info *execi,
|
||||
off_t off, off_t vaddr, size_t len)
|
||||
off_t off, vir_bytes vaddr, size_t len)
|
||||
{
|
||||
assert(off + len <= execi->hdr_len);
|
||||
memcpy((char *) vaddr, (char *) execi->hdr + off, len);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int libexec_clear_memset(struct exec_info *execi, off_t vaddr, size_t len)
|
||||
int libexec_clear_memset(struct exec_info *execi, vir_bytes vaddr, size_t len)
|
||||
{
|
||||
memset((char *) vaddr, 0, len);
|
||||
return OK;
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
struct exec_info;
|
||||
|
||||
typedef int (*libexec_loadfunc_t)(struct exec_info *execi,
|
||||
off_t offset, off_t vaddr, size_t len);
|
||||
off_t offset, vir_bytes vaddr, size_t len);
|
||||
|
||||
typedef int (*libexec_clearfunc_t)(struct exec_info *execi,
|
||||
off_t vaddr, size_t len);
|
||||
vir_bytes vaddr, size_t len);
|
||||
|
||||
typedef int (*libexec_allocfunc_t)(struct exec_info *execi,
|
||||
off_t vaddr, size_t len);
|
||||
vir_bytes vaddr, size_t len);
|
||||
|
||||
typedef int (*libexec_procclearfunc_t)(struct exec_info *execi);
|
||||
|
||||
|
@ -61,12 +61,15 @@ int libexec_pm_newexec(endpoint_t proc_e, struct exec_info *execi);
|
|||
typedef int (*libexec_exec_loadfunc_t)(struct exec_info *execi);
|
||||
int libexec_load_elf(struct exec_info *execi);
|
||||
|
||||
int libexec_copy_memcpy(struct exec_info *execi, off_t offset, off_t vaddr, size_t len);
|
||||
int libexec_clear_memset(struct exec_info *execi, off_t vaddr, size_t len);
|
||||
int libexec_alloc_mmap_prealloc_cleared(struct exec_info *execi, off_t vaddr, size_t len);
|
||||
int libexec_alloc_mmap_prealloc_junk(struct exec_info *execi, off_t vaddr, size_t len);
|
||||
int libexec_alloc_mmap_ondemand(struct exec_info *execi, off_t vaddr, size_t len);
|
||||
/* Default callbacks for kernel. */
|
||||
int libexec_copy_memcpy(struct exec_info *execi, off_t offset, vir_bytes vaddr, size_t len);
|
||||
int libexec_clear_memset(struct exec_info *execi, vir_bytes vaddr, size_t len);
|
||||
|
||||
/* Default callbacks. */
|
||||
int libexec_alloc_mmap_prealloc_cleared(struct exec_info *execi, vir_bytes vaddr, size_t len);
|
||||
int libexec_alloc_mmap_prealloc_junk(struct exec_info *execi, vir_bytes vaddr, size_t len);
|
||||
int libexec_alloc_mmap_ondemand(struct exec_info *execi, vir_bytes vaddr, size_t len);
|
||||
int libexec_clearproc_vm_procctl(struct exec_info *execi);
|
||||
int libexec_clear_sys_memset(struct exec_info *execi, off_t vaddr, size_t len);
|
||||
int libexec_clear_sys_memset(struct exec_info *execi, vir_bytes vaddr, size_t len);
|
||||
|
||||
#endif /* !_LIBEXEC_H_ */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
EXTERN struct fs_hooks *vtreefs_hooks;
|
||||
|
||||
EXTERN int proto_version;
|
||||
EXTERN message fs_m_in;
|
||||
EXTERN message fs_m_out;
|
||||
|
||||
|
|
|
@ -18,6 +18,13 @@ int fs_readsuper(void)
|
|||
if (fs_m_in.REQ_FLAGS & REQ_ISROOT)
|
||||
return EINVAL;
|
||||
|
||||
/* Get VFS-FS protocol version */
|
||||
if (!(fs_m_in.REQ_FLAGS & REQ_HASPROTO)) {
|
||||
proto_version = 0;
|
||||
} else {
|
||||
proto_version = VFS_FS_PROTO_VERSION(fs_m_in.REQ_PROTO);
|
||||
}
|
||||
|
||||
/* Get the root inode and increase its reference count. */
|
||||
root = get_root_inode();
|
||||
ref_inode(root);
|
||||
|
|
|
@ -67,6 +67,153 @@ int fs_read(void)
|
|||
return r;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* fs_getdents_321 *
|
||||
*===========================================================================*/
|
||||
int fs_getdents_321(void)
|
||||
{
|
||||
/* Retrieve directory entries.
|
||||
*/
|
||||
struct inode *node, *child = NULL;
|
||||
struct dirent_321 *dent;
|
||||
char *name;
|
||||
size_t len, off, user_off, user_left;
|
||||
off_t pos;
|
||||
int r, skip, get_next, indexed;
|
||||
static char buf[GETDENTS_BUFSIZ];
|
||||
|
||||
if (fs_m_in.REQ_SEEK_POS_HI != 0)
|
||||
return EIO;
|
||||
|
||||
if ((node = find_inode(fs_m_in.REQ_INODE_NR)) == NULL)
|
||||
return EINVAL;
|
||||
|
||||
off = 0;
|
||||
user_off = 0;
|
||||
user_left = fs_m_in.REQ_MEM_SIZE;
|
||||
indexed = node->i_indexed;
|
||||
get_next = FALSE;
|
||||
child = NULL;
|
||||
|
||||
/* Call the getdents hook, if any, to "refresh" the directory. */
|
||||
if (!is_inode_deleted(node) && vtreefs_hooks->getdents_hook != NULL) {
|
||||
r = vtreefs_hooks->getdents_hook(node, get_inode_cbdata(node));
|
||||
if (r != OK) return r;
|
||||
}
|
||||
|
||||
for (pos = fs_m_in.REQ_SEEK_POS_LO; ; pos++) {
|
||||
/* Determine which inode and name to use for this entry. */
|
||||
if (pos == 0) {
|
||||
/* The "." entry. */
|
||||
child = node;
|
||||
name = ".";
|
||||
}
|
||||
else if (pos == 1) {
|
||||
/* The ".." entry. */
|
||||
child = get_parent_inode(node);
|
||||
if (child == NULL)
|
||||
child = node;
|
||||
name = "..";
|
||||
}
|
||||
else if (pos - 2 < indexed) {
|
||||
/* All indexed entries. */
|
||||
child = get_inode_by_index(node, pos - 2);
|
||||
|
||||
/* If there is no inode with this particular index,
|
||||
* continue with the next index number.
|
||||
*/
|
||||
if (child == NULL) continue;
|
||||
|
||||
name = child->i_name;
|
||||
}
|
||||
else {
|
||||
/* All non-indexed entries. */
|
||||
|
||||
/* If this is the first loop iteration, first get to
|
||||
* the non-indexed child identified by the current
|
||||
* position.
|
||||
*/
|
||||
if (get_next == FALSE) {
|
||||
skip = pos - indexed - 2;
|
||||
child = get_first_inode(node);
|
||||
|
||||
/* Skip indexed children. */
|
||||
while (child != NULL &&
|
||||
child->i_index != NO_INDEX)
|
||||
child = get_next_inode(child);
|
||||
|
||||
/* Skip to the right position. */
|
||||
while (child != NULL && skip-- > 0)
|
||||
child = get_next_inode(child);
|
||||
|
||||
get_next = TRUE;
|
||||
}
|
||||
else {
|
||||
child = get_next_inode(child);
|
||||
}
|
||||
|
||||
/* No more children? Then stop. */
|
||||
if (child == NULL)
|
||||
break;
|
||||
|
||||
assert(!is_inode_deleted(child));
|
||||
|
||||
name = child->i_name;
|
||||
}
|
||||
|
||||
len = DWORD_ALIGN(sizeof(struct dirent_321) + strlen(name));
|
||||
|
||||
/* Is the user buffer too small to store another record? */
|
||||
if (user_off + off + len > user_left) {
|
||||
/* Is the user buffer too small for even a single
|
||||
* record?
|
||||
*/
|
||||
if (user_off == 0 && off == 0)
|
||||
return EINVAL;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* If our own buffer cannot contain the new record, copy out
|
||||
* first.
|
||||
*/
|
||||
if (off + len > sizeof(buf)) {
|
||||
r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT,
|
||||
user_off, (vir_bytes) buf, off);
|
||||
if (r != OK) return r;
|
||||
|
||||
user_off += off;
|
||||
user_left -= off;
|
||||
off = 0;
|
||||
}
|
||||
|
||||
/* Fill in the actual directory entry. */
|
||||
dent = (struct dirent_321 *) &buf[off];
|
||||
dent->d_ino = (u32_t) get_inode_number(child);
|
||||
dent->d_off = (i32_t) pos;
|
||||
dent->d_reclen = len;
|
||||
strcpy(dent->d_name, name);
|
||||
|
||||
off += len;
|
||||
}
|
||||
|
||||
/* If there is anything left in our own buffer, copy that out now. */
|
||||
if (off > 0) {
|
||||
r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT,
|
||||
user_off, (vir_bytes) buf, off);
|
||||
if (r != OK)
|
||||
return r;
|
||||
|
||||
user_off += off;
|
||||
}
|
||||
|
||||
fs_m_out.RES_SEEK_POS_HI = 0;
|
||||
fs_m_out.RES_SEEK_POS_LO = pos;
|
||||
fs_m_out.RES_NBYTES = user_off;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* fs_getdents *
|
||||
*===========================================================================*/
|
||||
|
@ -82,6 +229,9 @@ int fs_getdents(void)
|
|||
int r, skip, get_next, indexed;
|
||||
static char buf[GETDENTS_BUFSIZ];
|
||||
|
||||
if (proto_version == 0)
|
||||
return fs_getdents_321();
|
||||
|
||||
if (fs_m_in.REQ_SEEK_POS_HI != 0)
|
||||
return EIO;
|
||||
|
||||
|
@ -189,8 +339,8 @@ int fs_getdents(void)
|
|||
|
||||
/* Fill in the actual directory entry. */
|
||||
dent = (struct dirent *) &buf[off];
|
||||
dent->d_ino = get_inode_number(child);
|
||||
dent->d_off = pos;
|
||||
dent->d_ino = (ino_t) get_inode_number(child);
|
||||
dent->d_off = (off_t) pos;
|
||||
dent->d_reclen = len;
|
||||
strcpy(dent->d_name, name);
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ extern char dot2[3]; /* meaning to search_dir: no access permission check. */
|
|||
|
||||
extern int(*fs_call_vec[]) (void);
|
||||
|
||||
EXTERN int proto_version;
|
||||
|
||||
EXTERN message fs_m_in;
|
||||
EXTERN message fs_m_out;
|
||||
EXTERN vfs_ucred_t credentials;
|
||||
|
|
|
@ -719,7 +719,7 @@ off_t len;
|
|||
panic("zeroblock_range: no block");
|
||||
offset = pos % rip->i_sp->s_block_size;
|
||||
if (offset + len > rip->i_sp->s_block_size)
|
||||
panic("zeroblock_range: len too long: %d", len);
|
||||
panic("zeroblock_range: len too long: %lld", len);
|
||||
memset(b_data(bp) + offset, 0, len);
|
||||
lmfs_markdirty(bp);
|
||||
put_block(bp, FULL_DATA_BLOCK);
|
||||
|
|
|
@ -39,6 +39,12 @@ int fs_readsuper()
|
|||
readonly = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0;
|
||||
isroot = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0;
|
||||
|
||||
if (!(fs_m_in.REQ_FLAGS & REQ_HASPROTO)) {
|
||||
proto_version = 0;
|
||||
} else {
|
||||
proto_version = VFS_FS_PROTO_VERSION(fs_m_in.REQ_PROTO);
|
||||
}
|
||||
|
||||
if (label_len > sizeof(fs_dev_label))
|
||||
return(EINVAL);
|
||||
|
||||
|
|
|
@ -610,6 +610,159 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
|
|||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* fs_getdents_321 *
|
||||
*===========================================================================*/
|
||||
static int fs_getdents_321(void)
|
||||
{
|
||||
#define GETDENTS_321_BUFSIZE (sizeof(struct dirent_321) + EXT2_NAME_MAX + 1)
|
||||
#define GETDENTS_321_ENTRIES 8
|
||||
static char getdents_buf[GETDENTS_321_BUFSIZE * GETDENTS_321_ENTRIES];
|
||||
struct inode *rip;
|
||||
int o, r, done;
|
||||
unsigned int block_size, len, reclen;
|
||||
pino_t ino;
|
||||
block_t b;
|
||||
cp_grant_id_t gid;
|
||||
size_t size, tmpbuf_off, userbuf_off;
|
||||
off_t pos, off, block_pos, new_pos, ent_pos;
|
||||
struct buf *bp;
|
||||
struct ext2_disk_dir_desc *d_desc;
|
||||
struct dirent *dep;
|
||||
|
||||
ino = (pino_t) fs_m_in.REQ_INODE_NR;
|
||||
gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
|
||||
size = (size_t) fs_m_in.REQ_MEM_SIZE;
|
||||
pos = (off_t) fs_m_in.REQ_SEEK_POS_LO;
|
||||
|
||||
/* Check whether the position is properly aligned */
|
||||
if ((unsigned int) pos % DIR_ENTRY_ALIGN)
|
||||
return(ENOENT);
|
||||
|
||||
if ((rip = get_inode(fs_dev, ino)) == NULL)
|
||||
return(EINVAL);
|
||||
|
||||
block_size = rip->i_sp->s_block_size;
|
||||
off = (pos % block_size); /* Offset in block */
|
||||
block_pos = pos - off;
|
||||
done = FALSE; /* Stop processing directory blocks when done is set */
|
||||
|
||||
memset(getdents_buf, '\0', sizeof(getdents_buf)); /* Avoid leaking any data */
|
||||
tmpbuf_off = 0; /* Offset in getdents_buf */
|
||||
userbuf_off = 0; /* Offset in the user's buffer */
|
||||
|
||||
/* The default position for the next request is EOF. If the user's buffer
|
||||
* fills up before EOF, new_pos will be modified. */
|
||||
new_pos = rip->i_size;
|
||||
|
||||
for (; block_pos < rip->i_size; block_pos += block_size) {
|
||||
off_t temp_pos = block_pos;
|
||||
b = read_map(rip, block_pos, 0); /* get block number */
|
||||
/* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
|
||||
bp = get_block(rip->i_dev, b, NORMAL); /* get a dir block */
|
||||
assert(bp != NULL);
|
||||
|
||||
/* Search a directory block. */
|
||||
d_desc = (struct ext2_disk_dir_desc*) &b_data(bp);
|
||||
|
||||
/* we need to seek to entry at off bytes.
|
||||
* when NEXT_DISC_DIR_POS == block_size it's last dentry.
|
||||
*/
|
||||
for (; temp_pos + conv2(le_CPU, d_desc->d_rec_len) <= pos
|
||||
&& NEXT_DISC_DIR_POS(d_desc, &b_data(bp)) < block_size;
|
||||
d_desc = NEXT_DISC_DIR_DESC(d_desc)) {
|
||||
temp_pos += conv2(le_CPU, d_desc->d_rec_len);
|
||||
}
|
||||
|
||||
for (; CUR_DISC_DIR_POS(d_desc, &b_data(bp)) < block_size;
|
||||
d_desc = NEXT_DISC_DIR_DESC(d_desc)) {
|
||||
if (d_desc->d_ino == 0)
|
||||
continue; /* Entry is not in use */
|
||||
|
||||
#if 0 /* d_nam_len is a uint8_t, so the test is always false. */
|
||||
if (d_desc->d_name_len > NAME_MAX ||
|
||||
d_desc->d_name_len > EXT2_NAME_MAX) {
|
||||
len = min(NAME_MAX, EXT2_NAME_MAX);
|
||||
} else {
|
||||
len = d_desc->d_name_len;
|
||||
}
|
||||
#endif
|
||||
len = d_desc->d_name_len;
|
||||
|
||||
/* Compute record length */
|
||||
reclen = offsetof(struct dirent_321, d_name) + len + 1;
|
||||
o = (reclen % sizeof(long));
|
||||
if (o != 0)
|
||||
reclen += sizeof(long) - o;
|
||||
|
||||
/* Need the position of this entry in the directory */
|
||||
ent_pos = block_pos + ((char *)d_desc - b_data(bp));
|
||||
|
||||
if (userbuf_off + tmpbuf_off + reclen >= size) {
|
||||
/* The user has no space for one more record */
|
||||
done = TRUE;
|
||||
|
||||
/* Record the position of this entry, it is the
|
||||
* starting point of the next request (unless the
|
||||
* position is modified with lseek).
|
||||
*/
|
||||
new_pos = ent_pos;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmpbuf_off + reclen >=
|
||||
GETDENTS_321_BUFSIZE * GETDENTS_321_ENTRIES) {
|
||||
r = sys_safecopyto(VFS_PROC_NR, gid,
|
||||
(vir_bytes) userbuf_off,
|
||||
(vir_bytes) getdents_buf,
|
||||
(size_t) tmpbuf_off);
|
||||
if (r != OK) {
|
||||
put_inode(rip);
|
||||
return(r);
|
||||
}
|
||||
userbuf_off += tmpbuf_off;
|
||||
tmpbuf_off = 0;
|
||||
}
|
||||
|
||||
dep = (struct dirent *) &getdents_buf[tmpbuf_off];
|
||||
dep->d_ino = (u32_t) conv4(le_CPU, d_desc->d_ino);
|
||||
dep->d_off = (i32_t) ent_pos;
|
||||
dep->d_reclen = (unsigned short) reclen;
|
||||
memcpy(dep->d_name, d_desc->d_name, len);
|
||||
dep->d_name[len] = '\0';
|
||||
tmpbuf_off += reclen;
|
||||
}
|
||||
|
||||
put_block(bp, DIRECTORY_BLOCK);
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmpbuf_off != 0) {
|
||||
r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) userbuf_off,
|
||||
(vir_bytes) getdents_buf, (size_t) tmpbuf_off);
|
||||
if (r != OK) {
|
||||
put_inode(rip);
|
||||
return(r);
|
||||
}
|
||||
|
||||
userbuf_off += tmpbuf_off;
|
||||
}
|
||||
|
||||
if (done && userbuf_off == 0)
|
||||
r = EINVAL; /* The user's buffer is too small */
|
||||
else {
|
||||
fs_m_out.RES_NBYTES = userbuf_off;
|
||||
fs_m_out.RES_SEEK_POS_LO = new_pos;
|
||||
rip->i_update |= ATIME;
|
||||
rip->i_dirt = IN_DIRTY;
|
||||
r = OK;
|
||||
}
|
||||
|
||||
put_inode(rip); /* release the inode */
|
||||
return(r);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* fs_getdents *
|
||||
*===========================================================================*/
|
||||
|
@ -629,6 +782,10 @@ int fs_getdents(void)
|
|||
struct ext2_disk_dir_desc *d_desc;
|
||||
struct dirent *dep;
|
||||
|
||||
if (proto_version == 0) {
|
||||
return fs_getdents_321();
|
||||
}
|
||||
|
||||
ino = (pino_t) fs_m_in.REQ_INODE_NR;
|
||||
gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
|
||||
size = (size_t) fs_m_in.REQ_MEM_SIZE;
|
||||
|
@ -729,8 +886,8 @@ int fs_getdents(void)
|
|||
}
|
||||
|
||||
dep = (struct dirent *) &getdents_buf[tmpbuf_off];
|
||||
dep->d_ino = conv4(le_CPU, d_desc->d_ino);
|
||||
dep->d_off = ent_pos;
|
||||
dep->d_ino = (ino_t) conv4(le_CPU, d_desc->d_ino);
|
||||
dep->d_off = (off_t) ent_pos;
|
||||
dep->d_reclen = (unsigned short) reclen;
|
||||
memcpy(dep->d_name, d_desc->d_name, len);
|
||||
dep->d_name[len] = '\0';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
#define GETDENTS_BUFSIZ 257
|
||||
#define GETDENTS_BUFSIZ 261
|
||||
|
||||
#define ISO9660_STANDARD_ID "CD001" /* Standard code for ISO9660 filesystems */
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ EXTERN int FS_STATE;
|
|||
EXTERN uid_t caller_uid;
|
||||
EXTERN gid_t caller_gid;
|
||||
|
||||
EXTERN int proto_version;
|
||||
EXTERN int req_nr; /* request number to the server */
|
||||
|
||||
EXTERN int SELF_E; /* process number */
|
||||
|
|
|
@ -18,6 +18,12 @@ int fs_readsuper() {
|
|||
label_gid = fs_m_in.REQ_GRANT;
|
||||
label_len = fs_m_in.REQ_PATH_LEN;
|
||||
|
||||
if (!(fs_m_in.REQ_FLAGS & REQ_HASPROTO)) {
|
||||
proto_version = 0;
|
||||
} else {
|
||||
proto_version = VFS_FS_PROTO_VERSION(fs_m_in.REQ_PROTO);
|
||||
}
|
||||
|
||||
if (label_len > sizeof(fs_dev_label))
|
||||
return(EINVAL);
|
||||
|
||||
|
|
|
@ -137,9 +137,9 @@ int fs_bread(void)
|
|||
|
||||
|
||||
/*===========================================================================*
|
||||
* fs_getdents *
|
||||
* fs_getdents_321 *
|
||||
*===========================================================================*/
|
||||
int fs_getdents(void) {
|
||||
int fs_getdents_321(void) {
|
||||
struct dir_record *dir;
|
||||
pino_t ino;
|
||||
cp_grant_id_t gid;
|
||||
|
@ -246,7 +246,158 @@ int fs_getdents(void) {
|
|||
/* The standard data structure is created using the
|
||||
* data in the buffer. */
|
||||
dirp = (struct dirent *) &getdents_buf[tmpbuf_offset];
|
||||
dirp->d_ino = (pino_t)(b_data(bp) + block_pos);
|
||||
dirp->d_ino = (u32_t) (b_data(bp) + block_pos);
|
||||
dirp->d_off= (i32_t) cur_pos;
|
||||
dirp->d_reclen= reclen;
|
||||
memcpy(dirp->d_name, name, len);
|
||||
dirp->d_name[len]= '\0';
|
||||
tmpbuf_offset += reclen;
|
||||
|
||||
cur_pos += dir_tmp->length;
|
||||
release_dir_record(dir_tmp);
|
||||
}
|
||||
|
||||
block_pos += dir_tmp->length;
|
||||
}
|
||||
|
||||
put_block(bp); /* release the block */
|
||||
if (done == TRUE) break;
|
||||
|
||||
cur_pos += block_size - cur_pos;
|
||||
block++; /* read the next one */
|
||||
}
|
||||
|
||||
if (tmpbuf_offset != 0) {
|
||||
r = sys_safecopyto(VFS_PROC_NR, gid, userbuf_off,
|
||||
(vir_bytes) getdents_buf, tmpbuf_offset);
|
||||
if (r != OK)
|
||||
panic("fs_getdents: sys_safecopyto failed: %d", r);
|
||||
|
||||
userbuf_off += tmpbuf_offset;
|
||||
}
|
||||
|
||||
fs_m_out.RES_NBYTES = userbuf_off;
|
||||
fs_m_out.RES_SEEK_POS_LO = cur_pos;
|
||||
|
||||
release_dir_record(dir); /* release the inode */
|
||||
return(OK);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* fs_getdents *
|
||||
*===========================================================================*/
|
||||
int fs_getdents(void) {
|
||||
struct dir_record *dir;
|
||||
pino_t ino;
|
||||
cp_grant_id_t gid;
|
||||
size_t block_size;
|
||||
off_t pos, block_pos, block, cur_pos, tmpbuf_offset, userbuf_off;
|
||||
struct buf *bp;
|
||||
struct dir_record *dir_tmp;
|
||||
struct dirent *dirp;
|
||||
int r,done,o,len,reclen;
|
||||
char *cp;
|
||||
char name[NAME_MAX + 1];
|
||||
char name_old[NAME_MAX + 1];
|
||||
|
||||
if (proto_version == 0) {
|
||||
return fs_getdents_321();
|
||||
}
|
||||
|
||||
/* Initialize the tmp arrays */
|
||||
memset(name,'\0',NAME_MAX);
|
||||
memset(name_old,'\0',NAME_MAX);
|
||||
|
||||
/* Get input parameters */
|
||||
ino = fs_m_in.REQ_INODE_NR;
|
||||
gid = fs_m_in.REQ_GRANT;
|
||||
pos = fs_m_in.REQ_SEEK_POS_LO;
|
||||
|
||||
block_size = v_pri.logical_block_size_l;
|
||||
cur_pos = pos; /* The current position */
|
||||
tmpbuf_offset = 0;
|
||||
userbuf_off = 0;
|
||||
memset(getdents_buf, '\0', GETDENTS_BUFSIZ); /* Avoid leaking any data */
|
||||
|
||||
if ((dir = get_dir_record(ino)) == NULL) return(EINVAL);
|
||||
|
||||
block = dir->loc_extent_l; /* First block of the directory */
|
||||
block += pos / block_size; /* Shift to the block where start to read */
|
||||
done = FALSE;
|
||||
|
||||
while (cur_pos<dir->d_file_size) {
|
||||
bp = get_block(block); /* Get physical block */
|
||||
|
||||
if (bp == NULL) {
|
||||
release_dir_record(dir);
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
block_pos = cur_pos % block_size; /* Position where to start read */
|
||||
|
||||
while (block_pos < block_size) {
|
||||
dir_tmp = get_free_dir_record();
|
||||
create_dir_record(dir_tmp,b_data(bp) + block_pos,
|
||||
block*block_size + block_pos);
|
||||
if (dir_tmp->length == 0) { /* EOF. I exit and return 0s */
|
||||
block_pos = block_size;
|
||||
done = TRUE;
|
||||
release_dir_record(dir_tmp);
|
||||
} else { /* The dir record is valid. Copy data... */
|
||||
if (dir_tmp->file_id[0] == 0)
|
||||
strlcpy(name, ".", NAME_MAX + 1);
|
||||
else if (dir_tmp->file_id[0] == 1)
|
||||
strlcpy(name, "..", NAME_MAX + 1);
|
||||
else {
|
||||
/* Extract the name from the field file_id */
|
||||
strncpy(name, dir_tmp->file_id,
|
||||
dir_tmp->length_file_id);
|
||||
name[dir_tmp->length_file_id] = 0;
|
||||
|
||||
/* Tidy up file name */
|
||||
cp = memchr(name, ';', NAME_MAX);
|
||||
if (cp != NULL) name[cp - name] = 0;
|
||||
|
||||
/*If no file extension, then remove final '.'*/
|
||||
if (name[strlen(name) - 1] == '.')
|
||||
name[strlen(name) - 1] = '\0';
|
||||
}
|
||||
|
||||
if (strcmp(name_old, name) == 0) {
|
||||
cur_pos += dir_tmp->length;
|
||||
release_dir_record(dir_tmp);
|
||||
continue;
|
||||
}
|
||||
|
||||
strlcpy(name_old, name, NAME_MAX + 1);
|
||||
|
||||
/* Compute the length of the name */
|
||||
cp = memchr(name, '\0', NAME_MAX);
|
||||
if (cp == NULL) len = NAME_MAX;
|
||||
else len= cp - name;
|
||||
|
||||
/* Compute record length */
|
||||
reclen = offsetof(struct dirent, d_name) + len + 1;
|
||||
o = (reclen % sizeof(long));
|
||||
if (o != 0)
|
||||
reclen += sizeof(long) - o;
|
||||
|
||||
/* If the new record does not fit, then copy the buffer
|
||||
* and start from the beginning. */
|
||||
if (tmpbuf_offset + reclen > GETDENTS_BUFSIZ) {
|
||||
r = sys_safecopyto(VFS_PROC_NR, gid, userbuf_off,
|
||||
(vir_bytes)getdents_buf, tmpbuf_offset);
|
||||
|
||||
if (r != OK)
|
||||
panic("fs_getdents: sys_safecopyto failed: %d", r);
|
||||
userbuf_off += tmpbuf_offset;
|
||||
tmpbuf_offset= 0;
|
||||
}
|
||||
|
||||
/* The standard data structure is created using the
|
||||
* data in the buffer. */
|
||||
dirp = (struct dirent *) &getdents_buf[tmpbuf_offset];
|
||||
dirp->d_ino = (u32_t)(b_data(bp) + (size_t)block_pos);
|
||||
dirp->d_off= cur_pos;
|
||||
dirp->d_reclen= reclen;
|
||||
memcpy(dirp->d_name, name, len);
|
||||
|
|
|
@ -27,6 +27,7 @@ EXTERN uid_t caller_uid;
|
|||
EXTERN gid_t caller_gid;
|
||||
|
||||
EXTERN int req_nr;
|
||||
EXTERN int proto_version;
|
||||
|
||||
EXTERN endpoint_t SELF_E;
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ EXTERN struct inode {
|
|||
|
||||
/* The following items are not present on the disk. */
|
||||
dev_t i_dev; /* which device is the inode on */
|
||||
ino_t i_num; /* inode number on its (minor) device */
|
||||
pino_t i_num; /* inode number on its (minor) device */
|
||||
int i_count; /* # times inode used; 0 means slot is free */
|
||||
unsigned int i_ndzones; /* # direct zones (Vx_NR_DZONES) */
|
||||
unsigned int i_nindirs; /* # indirect zones per indirect block */
|
||||
|
|
|
@ -30,6 +30,12 @@ int fs_readsuper()
|
|||
readonly = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0;
|
||||
isroot = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0;
|
||||
|
||||
if (!(fs_m_in.REQ_FLAGS & REQ_HASPROTO)) {
|
||||
proto_version = 0;
|
||||
} else {
|
||||
proto_version = VFS_FS_PROTO_VERSION(fs_m_in.REQ_PROTO);
|
||||
}
|
||||
|
||||
if (label_len > sizeof(fs_dev_label))
|
||||
return(EINVAL);
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ int search_dir(struct inode *ldir_ptr, char string [MFS_NAME_MAX], pino_t
|
|||
int fs_chmod(void);
|
||||
int fs_chown(void);
|
||||
int fs_getdents(void);
|
||||
int fs_getdents_321(void);
|
||||
int forbidden(struct inode *rip, pmode_t access_desired);
|
||||
int read_only(struct inode *ip);
|
||||
|
||||
|
|
|
@ -604,6 +604,153 @@ unsigned bytes_ahead; /* bytes beyond position for immediate use */
|
|||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* fs_getdents_321 *
|
||||
*===========================================================================*/
|
||||
int fs_getdents_321(void)
|
||||
{
|
||||
#define GETDENTS_321_BUFSIZE (sizeof(struct dirent_321) + MFS_NAME_MAX + 1)
|
||||
#define GETDENTS_321_ENTRIES 8
|
||||
static char getdents_buf[GETDENTS_321_BUFSIZE * GETDENTS_321_ENTRIES];
|
||||
register struct inode *rip;
|
||||
int o, r, done;
|
||||
unsigned int block_size, len, reclen;
|
||||
pino_t ino;
|
||||
block_t b;
|
||||
cp_grant_id_t gid;
|
||||
size_t size, tmpbuf_off, userbuf_off;
|
||||
off_t pos, off, block_pos, new_pos, ent_pos;
|
||||
struct buf *bp;
|
||||
struct direct *dp;
|
||||
struct dirent_321 *dep;
|
||||
char *cp;
|
||||
|
||||
ino = (pino_t) fs_m_in.REQ_INODE_NR;
|
||||
gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
|
||||
size = (size_t) fs_m_in.REQ_MEM_SIZE;
|
||||
pos = (off_t) fs_m_in.REQ_SEEK_POS_LO;
|
||||
|
||||
/* Check whether the position is properly aligned */
|
||||
if ((unsigned int) pos % DIR_ENTRY_SIZE)
|
||||
return(ENOENT);
|
||||
|
||||
if ((rip = get_inode(fs_dev, ino)) == NULL)
|
||||
return(EINVAL);
|
||||
|
||||
block_size = rip->i_sp->s_block_size;
|
||||
off = (pos % block_size); /* Offset in block */
|
||||
block_pos = pos - off;
|
||||
done = FALSE; /* Stop processing directory blocks when done is set */
|
||||
|
||||
tmpbuf_off = 0; /* Offset in getdents_buf */
|
||||
memset(getdents_buf, '\0', sizeof(getdents_buf)); /* Avoid leaking any data */
|
||||
userbuf_off = 0; /* Offset in the user's buffer */
|
||||
|
||||
/* The default position for the next request is EOF. If the user's buffer
|
||||
* fills up before EOF, new_pos will be modified. */
|
||||
new_pos = rip->i_size;
|
||||
|
||||
for(; block_pos < rip->i_size; block_pos += block_size) {
|
||||
b = read_map(rip, block_pos, 0); /* get block number */
|
||||
|
||||
/* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
|
||||
bp = get_block(rip->i_dev, b, NORMAL); /* get a dir block */
|
||||
|
||||
assert(bp != NULL);
|
||||
|
||||
/* Search a directory block. */
|
||||
if (block_pos < pos)
|
||||
dp = &b_dir(bp)[off / DIR_ENTRY_SIZE];
|
||||
else
|
||||
dp = &b_dir(bp)[0];
|
||||
for (; dp < &b_dir(bp)[NR_DIR_ENTRIES(block_size)]; dp++) {
|
||||
if (dp->mfs_d_ino == 0)
|
||||
continue; /* Entry is not in use */
|
||||
|
||||
/* Compute the length of the name */
|
||||
cp = memchr(dp->mfs_d_name, '\0', sizeof(dp->mfs_d_name));
|
||||
if (cp == NULL)
|
||||
len = sizeof(dp->mfs_d_name);
|
||||
else
|
||||
len = cp - (dp->mfs_d_name);
|
||||
|
||||
/* Compute record length */
|
||||
reclen = offsetof(struct dirent_321, d_name) + len + 1;
|
||||
o = (reclen % sizeof(long));
|
||||
if (o != 0)
|
||||
reclen += sizeof(long) - o;
|
||||
|
||||
/* Need the position of this entry in the directory */
|
||||
ent_pos = block_pos + ((char *) dp - (char *) bp->data);
|
||||
|
||||
if (userbuf_off + tmpbuf_off + reclen >= size) {
|
||||
/* The user has no space for one more record */
|
||||
done = TRUE;
|
||||
|
||||
/* Record the position of this entry, it is the
|
||||
* starting point of the next request (unless the
|
||||
* postion is modified with lseek).
|
||||
*/
|
||||
new_pos = ent_pos;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmpbuf_off + reclen >=
|
||||
GETDENTS_321_BUFSIZE * GETDENTS_321_ENTRIES) {
|
||||
r = sys_safecopyto(VFS_PROC_NR, gid,
|
||||
(vir_bytes) userbuf_off,
|
||||
(vir_bytes) getdents_buf,
|
||||
(size_t) tmpbuf_off);
|
||||
if (r != OK) {
|
||||
put_inode(rip);
|
||||
return(r);
|
||||
}
|
||||
|
||||
userbuf_off += tmpbuf_off;
|
||||
tmpbuf_off = 0;
|
||||
}
|
||||
|
||||
dep = (struct dirent_321 *) &getdents_buf[tmpbuf_off];
|
||||
dep->d_ino = (u32_t) dp->mfs_d_ino;
|
||||
dep->d_off = (i32_t) ent_pos;
|
||||
dep->d_reclen = (unsigned short) reclen;
|
||||
memcpy(dep->d_name, dp->mfs_d_name, len);
|
||||
dep->d_name[len] = '\0';
|
||||
tmpbuf_off += reclen;
|
||||
}
|
||||
|
||||
put_block(bp, DIRECTORY_BLOCK);
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmpbuf_off != 0) {
|
||||
r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) userbuf_off,
|
||||
(vir_bytes) getdents_buf, (size_t) tmpbuf_off);
|
||||
if (r != OK) {
|
||||
put_inode(rip);
|
||||
return(r);
|
||||
}
|
||||
|
||||
userbuf_off += tmpbuf_off;
|
||||
}
|
||||
|
||||
if (done && userbuf_off == 0)
|
||||
r = EINVAL; /* The user's buffer is too small */
|
||||
else {
|
||||
fs_m_out.RES_NBYTES = userbuf_off;
|
||||
fs_m_out.RES_SEEK_POS_LO = new_pos;
|
||||
if(!rip->i_sp->s_rd_only) {
|
||||
rip->i_update |= ATIME;
|
||||
IN_MARKDIRTY(rip);
|
||||
}
|
||||
r = OK;
|
||||
}
|
||||
|
||||
put_inode(rip); /* release the inode */
|
||||
return(r);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* fs_getdents *
|
||||
*===========================================================================*/
|
||||
|
@ -624,6 +771,12 @@ int fs_getdents(void)
|
|||
struct dirent *dep;
|
||||
char *cp;
|
||||
|
||||
if (proto_version == 0) {
|
||||
/* VFS-FS protocol version 0 uses 32-bits ino_t and off_t. We need to
|
||||
* use the binary compatible version of this routine */
|
||||
return fs_getdents_321();
|
||||
}
|
||||
|
||||
ino = (pino_t) fs_m_in.REQ_INODE_NR;
|
||||
gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
|
||||
size = (size_t) fs_m_in.REQ_MEM_SIZE;
|
||||
|
@ -706,8 +859,8 @@ int fs_getdents(void)
|
|||
}
|
||||
|
||||
dep = (struct dirent *) &getdents_buf[tmpbuf_off];
|
||||
dep->d_ino = dp->mfs_d_ino;
|
||||
dep->d_off = ent_pos;
|
||||
dep->d_ino = (ino_t) dp->mfs_d_ino;
|
||||
dep->d_off = (off_t) ent_pos;
|
||||
dep->d_reclen = (unsigned short) reclen;
|
||||
memcpy(dep->d_name, dp->mfs_d_name, len);
|
||||
dep->d_name[len] = '\0';
|
||||
|
|
|
@ -66,9 +66,9 @@ static int stat_inode(
|
|||
memset(&statbuf, 0, sizeof(struct stat));
|
||||
|
||||
statbuf.st_dev = rip->i_dev;
|
||||
statbuf.st_ino = rip->i_num;
|
||||
statbuf.st_mode = rip->i_mode;
|
||||
statbuf.st_nlink = rip->i_nlinks;
|
||||
statbuf.st_ino = (ino_t) rip->i_num;
|
||||
statbuf.st_mode = (mode_t) rip->i_mode;
|
||||
statbuf.st_nlink = (nlink_t) rip->i_nlinks;
|
||||
statbuf.st_uid = rip->i_uid;
|
||||
statbuf.st_gid = rip->i_gid;
|
||||
statbuf.st_rdev = (s ? (dev_t) rip->i_zone[0] : NO_DEV);
|
||||
|
|
|
@ -22,14 +22,14 @@
|
|||
*/
|
||||
|
||||
EXTERN struct super_block {
|
||||
pino_t s_ninodes; /* # usable inodes on the minor device */
|
||||
u32_t s_ninodes; /* # usable inodes on the minor device */
|
||||
zone1_t s_nzones; /* total device size, including bit maps etc */
|
||||
short s_imap_blocks; /* # of blocks used by inode bit map */
|
||||
short s_zmap_blocks; /* # of blocks used by zone bit map */
|
||||
zone1_t s_firstdatazone_old; /* number of first data zone (small) */
|
||||
short s_log_zone_size; /* log2 of blocks/zone */
|
||||
unsigned short s_flags; /* FS state flags */
|
||||
off_t s_max_size; /* maximum file size on this device */
|
||||
i32_t s_max_size; /* maximum file size on this device */
|
||||
zone_t s_zones; /* number of zones (replaces s_nzones in V2) */
|
||||
short s_magic; /* magic number to recognize super-blocks */
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ static int do_exec(int proc_e, char *exec, size_t exec_len, char *progname,
|
|||
char *frame, int frame_len);
|
||||
static int exec_restart(int proc_e, int result, vir_bytes pc);
|
||||
static int read_seg(struct exec_info *execi, off_t off,
|
||||
off_t seg_addr, size_t seg_bytes);
|
||||
vir_bytes seg_addr, size_t seg_bytes);
|
||||
static int exec_restart(int proc_e, int result, vir_bytes pc);
|
||||
|
||||
/* Array of loaders for different object formats */
|
||||
|
@ -191,7 +191,7 @@ static int exec_restart(int proc_e, int result, vir_bytes pc)
|
|||
static int read_seg(
|
||||
struct exec_info *execi, /* various data needed for exec */
|
||||
off_t off, /* offset in file */
|
||||
off_t seg_addr, /* address to load segment */
|
||||
vir_bytes seg_addr, /* address to load segment */
|
||||
size_t seg_bytes /* how much is to be transferred? */
|
||||
)
|
||||
{
|
||||
|
|
|
@ -64,7 +64,7 @@ static void clo_exec(struct fproc *rfp);
|
|||
static int stack_prepare_elf(struct vfs_exec_info *execi,
|
||||
char *curstack, size_t *frame_len, vir_bytes *vsp, int *extrabase);
|
||||
static int map_header(struct vfs_exec_info *execi);
|
||||
static int read_seg(struct exec_info *execi, off_t off, off_t seg_addr, size_t seg_bytes);
|
||||
static int read_seg(struct exec_info *execi, off_t off, vir_bytes seg_addr, size_t seg_bytes);
|
||||
|
||||
#define PTRSIZE sizeof(char *) /* Size of pointers in argv[] and envp[]. */
|
||||
|
||||
|
@ -571,7 +571,7 @@ char path[PATH_MAX]; /* path to script file */
|
|||
|
||||
/* Issue request */
|
||||
r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, ((u64_t)(pos)), READING,
|
||||
VFS_PROC_NR, buf, _MAX_BLOCK_SIZE, &new_pos, &cum_io);
|
||||
VFS_PROC_NR, (vir_bytes) buf, _MAX_BLOCK_SIZE, &new_pos, &cum_io);
|
||||
if (r != OK) return(r);
|
||||
|
||||
n = vp->v_size;
|
||||
|
@ -679,7 +679,7 @@ int replace
|
|||
/*===========================================================================*
|
||||
* read_seg *
|
||||
*===========================================================================*/
|
||||
static int read_seg(struct exec_info *execi, off_t off, off_t seg_addr, size_t seg_bytes)
|
||||
static int read_seg(struct exec_info *execi, off_t off, vir_bytes seg_addr, size_t seg_bytes)
|
||||
{
|
||||
/*
|
||||
* The byte count on read is usually smaller than the segment count, because
|
||||
|
@ -696,7 +696,7 @@ static int read_seg(struct exec_info *execi, off_t off, off_t seg_addr, size_t s
|
|||
if ((unsigned long) vp->v_size < off+seg_bytes) return(EIO);
|
||||
|
||||
if ((r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, ((u64_t)(off)), READING,
|
||||
execi->proc_e, (char*)seg_addr, seg_bytes,
|
||||
execi->proc_e, (vir_bytes) seg_addr, seg_bytes,
|
||||
&new_pos, &cum_io)) != OK) {
|
||||
printf("VFS: read_seg: req_readwrite failed (data)\n");
|
||||
return(r);
|
||||
|
@ -742,7 +742,7 @@ static int map_header(struct vfs_exec_info *execi)
|
|||
execi->args.hdr = hdr;
|
||||
|
||||
r = req_readwrite(execi->vp->v_fs_e, execi->vp->v_inode_nr,
|
||||
((u64_t)(pos)), READING, VFS_PROC_NR, hdr,
|
||||
((u64_t)(pos)), READING, VFS_PROC_NR, (vir_bytes) hdr,
|
||||
execi->args.hdr_len, &new_pos, &cum_io);
|
||||
if (r != OK) {
|
||||
printf("VFS: exec: map_header: req_readwrite failed\n");
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <string.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/config.h> /* Remove with version check in do_truncate */
|
||||
#include <minix/vfsif.h>
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
|
@ -306,8 +307,18 @@ int do_truncate(message *UNUSED(m_out))
|
|||
resolve.l_vmnt_lock = VMNT_READ;
|
||||
resolve.l_vnode_lock = VNODE_WRITE;
|
||||
|
||||
length = (off_t) job_m_in.flength;
|
||||
if (length < 0) return(EINVAL);
|
||||
if (job_call_nr == TRUNCATE_321) {
|
||||
length = (off_t) job_m_in.m2_l1;
|
||||
if ((int) job_m_in.flength < 0) return(EINVAL);
|
||||
} else {
|
||||
#if OS_VMAJOR == 2 && OS_VMINOR == 1
|
||||
length = (off_t) make64(job_m_in.m2_l1, 0); /* Ignore higher bits */
|
||||
#else
|
||||
#error "Please remove this version check. Recompile dynamic packages first."
|
||||
length = (off_t) make64(job_m_in.m2_l1, job_m_in.m2_l2);
|
||||
#endif
|
||||
if (length < 0) return(EINVAL);
|
||||
}
|
||||
|
||||
/* Temporarily open file */
|
||||
if (fetch_name(vname, vname_length, fullpath) != OK) return(err_code);
|
||||
|
@ -343,9 +354,20 @@ int do_ftruncate(message *UNUSED(m_out))
|
|||
off_t length;
|
||||
|
||||
scratch(fp).file.fd_nr = job_m_in.fd;
|
||||
length = (off_t) job_m_in.flength;
|
||||
|
||||
if (length < 0) return(EINVAL);
|
||||
if (job_call_nr == FTRUNCATE_321) {
|
||||
length = (off_t) job_m_in.m2_l1;
|
||||
if ((int) job_m_in.flength < 0) return(EINVAL);
|
||||
} else {
|
||||
#if OS_VMAJOR == 2 && OS_VMINOR == 1
|
||||
length = (off_t) make64(job_m_in.m2_l1, 0); /* Ignore higher bits */
|
||||
#else
|
||||
#error "Please remove this version check. Recompile dynamic packages first."
|
||||
length = (off_t) make64(job_m_in.m2_l1, job_m_in.m2_l2);
|
||||
#endif
|
||||
if (length < 0) return(EINVAL);
|
||||
}
|
||||
|
||||
|
||||
/* File is already opened; get a vnode pointer from filp */
|
||||
if ((rfilp = get_filp(scratch(fp).file.fd_nr, VNODE_WRITE)) == NULL)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include "fs.h"
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/u64.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -30,11 +31,26 @@ int req; /* either F_SETLK or F_SETLKW */
|
|||
mode_t mo;
|
||||
off_t first, last;
|
||||
struct flock flock;
|
||||
struct flock_321 fa_321;
|
||||
struct file_lock *flp, *flp2, *empty;
|
||||
|
||||
/* Fetch the flock structure from user space. */
|
||||
r = sys_datacopy(who_e, (vir_bytes) scratch(fp).io.io_buffer, VFS_PROC_NR,
|
||||
(vir_bytes) &flock, sizeof(flock));
|
||||
if (job_call_nr == FCNTL_321) {
|
||||
r = sys_datacopy(who_e, (vir_bytes) scratch(fp).io.io_buffer,
|
||||
VFS_PROC_NR, (vir_bytes) &fa_321, sizeof(fa_321));
|
||||
|
||||
/* Convert old values to new structure */
|
||||
if (r == OK) {
|
||||
flock.l_type = fa_321.l_type;
|
||||
flock.l_whence = fa_321.l_whence;
|
||||
flock.l_start = (off_t) fa_321.l_start;
|
||||
flock.l_len = (off_t) fa_321.l_len;
|
||||
flock.l_pid = fa_321.l_pid;
|
||||
}
|
||||
} else {
|
||||
r = sys_datacopy(who_e, (vir_bytes) scratch(fp).io.io_buffer,
|
||||
VFS_PROC_NR, (vir_bytes) &flock, sizeof(flock));
|
||||
}
|
||||
if (r != OK) return(EINVAL);
|
||||
|
||||
/* Make some error checks. */
|
||||
|
@ -147,8 +163,23 @@ int req; /* either F_SETLK or F_SETLKW */
|
|||
}
|
||||
|
||||
/* Copy the flock structure back to the caller. */
|
||||
r = sys_datacopy(VFS_PROC_NR, (vir_bytes) &flock,
|
||||
who_e, (vir_bytes) scratch(fp).io.io_buffer, sizeof(flock));
|
||||
if (job_call_nr == FCNTL_321) {
|
||||
/* Convert new values to old structure */
|
||||
if (r == OK) {
|
||||
fa_321.l_type = flock.l_type;
|
||||
fa_321.l_whence = flock.l_whence;
|
||||
fa_321.l_start = (i32_t) flock.l_start;
|
||||
fa_321.l_len = (i32_t) flock.l_len;
|
||||
fa_321.l_pid = flock.l_pid;
|
||||
}
|
||||
r = sys_datacopy(VFS_PROC_NR, (vir_bytes) &fa_321,
|
||||
who_e, (vir_bytes) scratch(fp).io.io_buffer,
|
||||
sizeof(fa_321));
|
||||
} else {
|
||||
r = sys_datacopy(VFS_PROC_NR, (vir_bytes) &flock,
|
||||
who_e, (vir_bytes) scratch(fp).io.io_buffer,
|
||||
sizeof(flock));
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
|
|
|
@ -177,23 +177,38 @@ int do_fcntl(message *UNUSED(m_out))
|
|||
case F_FREESP:
|
||||
{
|
||||
/* Free a section of a file */
|
||||
off_t start, end;
|
||||
off_t start, end, offset;
|
||||
struct flock flock_arg;
|
||||
signed long offset;
|
||||
|
||||
/* Check if it's a regular file. */
|
||||
if (!S_ISREG(f->filp_vno->v_mode)) r = EINVAL;
|
||||
else if (!(f->filp_mode & W_BIT)) r = EBADF;
|
||||
else
|
||||
else {
|
||||
/* Copy flock data from userspace. */
|
||||
r = sys_datacopy(who_e, (vir_bytes) scratch(fp).io.io_buffer,
|
||||
SELF, (vir_bytes) &flock_arg,
|
||||
sizeof(flock_arg));
|
||||
if (job_call_nr == FCNTL_321) {
|
||||
struct flock_321 fa_321;
|
||||
r = sys_datacopy(who_e,
|
||||
(vir_bytes) scratch(fp).io.io_buffer, SELF,
|
||||
(vir_bytes) &fa_321, sizeof(fa_321));
|
||||
/* Let's convert the values to the new structure */
|
||||
if (r == OK) {
|
||||
flock_arg.l_type = fa_321.l_type;
|
||||
flock_arg.l_whence = fa_321.l_whence;
|
||||
flock_arg.l_start = (off_t) fa_321.l_start;
|
||||
flock_arg.l_len = (off_t) fa_321.l_len;
|
||||
flock_arg.l_pid = fa_321.l_pid;
|
||||
}
|
||||
} else {
|
||||
r = sys_datacopy(who_e,
|
||||
(vir_bytes) scratch(fp).io.io_buffer, SELF,
|
||||
(vir_bytes) &flock_arg, sizeof(flock_arg));
|
||||
}
|
||||
}
|
||||
|
||||
if (r != OK) break;
|
||||
|
||||
/* Convert starting offset to signed. */
|
||||
offset = (signed long) flock_arg.l_start;
|
||||
offset = (off_t) flock_arg.l_start;
|
||||
|
||||
/* Figure out starting position base. */
|
||||
switch(flock_arg.l_whence) {
|
||||
|
|
|
@ -590,6 +590,9 @@ int do_mkdir(message *UNUSED(m_out))
|
|||
return(r);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* actual_lseek *
|
||||
*===========================================================================*/
|
||||
int actual_lseek(message *m_out, int seekfd, int seekwhence, off_t offset)
|
||||
{
|
||||
/* Perform the lseek(ls_fd, offset, whence) system call. */
|
||||
|
@ -614,19 +617,14 @@ int actual_lseek(message *m_out, int seekfd, int seekwhence, off_t offset)
|
|||
default: unlock_filp(rfilp); return(EINVAL);
|
||||
}
|
||||
|
||||
if (offset >= 0)
|
||||
newpos = pos + offset;
|
||||
else
|
||||
newpos = sub64ul(pos, -offset);
|
||||
|
||||
/* Check for overflow. */
|
||||
if (ex64hi(newpos) != 0) {
|
||||
r = EOVERFLOW;
|
||||
} else if ((off_t) ex64lo(newpos) < 0) { /* no negative file size */
|
||||
if (offset < 0 && -offset > pos) { /* no negative file size */
|
||||
r = EOVERFLOW;
|
||||
} else {
|
||||
newpos = pos + offset;
|
||||
|
||||
/* insert the new position into the output message */
|
||||
m_out->reply_l1 = ex64lo(newpos);
|
||||
m_out->reply_l2 = ex64hi(newpos);
|
||||
|
||||
if (cmp64(newpos, rfilp->filp_pos) != 0) {
|
||||
rfilp->filp_pos = newpos;
|
||||
|
|
|
@ -626,7 +626,7 @@ char ename[NAME_MAX + 1];
|
|||
|
||||
do {
|
||||
r = req_getdents(dirp->v_fs_e, dirp->v_inode_nr, pos, buf, sizeof(buf),
|
||||
&new_pos, 1);
|
||||
&new_pos, 1, 0 /* Not MINIX 3.2.1 format */);
|
||||
|
||||
if (r == 0) {
|
||||
return(ENOENT); /* end of entries -- matching inode !found */
|
||||
|
|
|
@ -167,6 +167,7 @@ void close_reply(void);
|
|||
int common_open(char path[PATH_MAX], int oflags, mode_t omode);
|
||||
int do_creat(void);
|
||||
int do_lseek(message *m_out);
|
||||
int do_lseek321(message *m_out);
|
||||
int do_llseek(message *m_out);
|
||||
int do_mknod(message *m_out);
|
||||
int do_mkdir(message *m_out);
|
||||
|
@ -228,7 +229,7 @@ int rw_pipe(int rw_flag, endpoint_t usr, struct filp *f, char *buf,
|
|||
|
||||
/* request.c */
|
||||
int req_breadwrite(endpoint_t fs_e, endpoint_t user_e, dev_t dev, u64_t pos,
|
||||
unsigned int num_of_bytes, char *user_addr, int rw_flag,
|
||||
unsigned int num_of_bytes, vir_bytes user_addr, int rw_flag,
|
||||
u64_t *new_posp, unsigned int *cum_iop);
|
||||
int req_chmod(endpoint_t fs_e, ino_t inode_nr, mode_t rmode,
|
||||
mode_t *new_modep);
|
||||
|
@ -241,7 +242,7 @@ int req_fstatfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf);
|
|||
int req_statvfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf);
|
||||
int req_ftrunc(endpoint_t fs_e, ino_t inode_nr, off_t start, off_t end);
|
||||
int req_getdents(endpoint_t fs_e, ino_t inode_nr, u64_t pos, char *buf,
|
||||
size_t size, u64_t *new_pos, int direct);
|
||||
size_t size, u64_t *new_pos, int direct, int getdents_321);
|
||||
int req_inhibread(endpoint_t fs_e, ino_t inode_nr);
|
||||
int req_link(endpoint_t fs_e, ino_t link_parent, char *lastc,
|
||||
ino_t linked_file);
|
||||
|
@ -261,7 +262,7 @@ int req_rdlink(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e,
|
|||
int req_readsuper(struct vmnt *vmp, char *driver_name, dev_t dev, int readonly,
|
||||
int isroot, struct node_details *res_nodep);
|
||||
int req_readwrite(endpoint_t fs_e, ino_t inode_nr, u64_t pos, int rw_flag,
|
||||
endpoint_t user_e, char *user_addr, unsigned int num_of_bytes,
|
||||
endpoint_t user_e, vir_bytes user_addr, unsigned int num_of_bytes,
|
||||
u64_t *new_posp, unsigned int *cum_iop);
|
||||
int req_bpeek(endpoint_t fs_e, dev_t dev, u64_t pos, unsigned int num_of_bytes);
|
||||
int req_peek(endpoint_t fs_e, ino_t inode_nr, u64_t pos, unsigned int bytes);
|
||||
|
|
|
@ -194,8 +194,8 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
|
|||
if(rw_flag == PEEKING) {
|
||||
r = req_bpeek(vp->v_bfs_e, vp->v_sdev, position, size);
|
||||
} else {
|
||||
r = req_breadwrite(vp->v_bfs_e, for_e, vp->v_sdev,
|
||||
position, size, buf, rw_flag, &res_pos, &res_cum_io);
|
||||
r = req_breadwrite(vp->v_bfs_e, for_e, vp->v_sdev, position,
|
||||
size, (vir_bytes) buf, rw_flag, &res_pos, &res_cum_io);
|
||||
if (r == OK) {
|
||||
position = res_pos;
|
||||
cum_io += res_cum_io;
|
||||
|
@ -215,7 +215,8 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
|
|||
} else {
|
||||
u64_t new_pos;
|
||||
r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, position,
|
||||
rw_flag, for_e, buf, size, &new_pos, &cum_io_incr);
|
||||
rw_flag, for_e, (vir_bytes) buf, size, &new_pos,
|
||||
&cum_io_incr);
|
||||
|
||||
if (r >= 0) {
|
||||
if (ex64hi(new_pos))
|
||||
|
@ -262,10 +263,11 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
|
|||
int do_getdents(message *UNUSED(m_out))
|
||||
{
|
||||
/* Perform the getdents(fd, buf, size) system call. */
|
||||
int r = OK;
|
||||
int r = OK, getdents_321 = 0;
|
||||
u64_t new_pos;
|
||||
register struct filp *rfilp;
|
||||
|
||||
if (job_call_nr == GETDENTS_321) getdents_321 = 1;
|
||||
scratch(fp).file.fd_nr = job_m_in.fd;
|
||||
scratch(fp).io.io_buffer = job_m_in.buffer;
|
||||
scratch(fp).io.io_nbytes = (size_t) job_m_in.nbytes;
|
||||
|
@ -285,7 +287,7 @@ int do_getdents(message *UNUSED(m_out))
|
|||
|
||||
r = req_getdents(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr,
|
||||
rfilp->filp_pos, scratch(fp).io.io_buffer,
|
||||
scratch(fp).io.io_nbytes, &new_pos,0);
|
||||
scratch(fp).io.io_nbytes, &new_pos, 0, getdents_321);
|
||||
|
||||
if (r > 0) rfilp->filp_pos = new_pos;
|
||||
}
|
||||
|
@ -341,7 +343,7 @@ size_t req_size;
|
|||
panic("unmapped pipe");
|
||||
|
||||
r = req_readwrite(vp->v_mapfs_e, vp->v_mapinode_nr, position, rw_flag, usr_e,
|
||||
buf, size, &new_pos, &cum_io_incr);
|
||||
(vir_bytes) buf, size, &new_pos, &cum_io_incr);
|
||||
|
||||
if (r != OK) {
|
||||
return(r);
|
||||
|
|
|
@ -6,25 +6,29 @@
|
|||
*/
|
||||
|
||||
#include "fs.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statfs.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <minix/vfsif.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/u64.h>
|
||||
#include <minix/vfsif.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statfs.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "fproc.h"
|
||||
#include "param.h"
|
||||
#include "path.h"
|
||||
#include "vmnt.h"
|
||||
#include "vnode.h"
|
||||
#include "path.h"
|
||||
#include "param.h"
|
||||
|
||||
|
||||
static size_t translate_dents(char *src, size_t size, char *dst, int direction);
|
||||
|
||||
/*===========================================================================*
|
||||
* req_breadwrite *
|
||||
*===========================================================================*/
|
||||
|
@ -34,7 +38,7 @@ int req_breadwrite(
|
|||
dev_t dev,
|
||||
u64_t pos,
|
||||
unsigned int num_of_bytes,
|
||||
char *user_addr,
|
||||
vir_bytes user_addr,
|
||||
int rw_flag,
|
||||
u64_t *new_posp,
|
||||
unsigned int *cum_iop
|
||||
|
@ -44,7 +48,7 @@ int req_breadwrite(
|
|||
cp_grant_id_t grant_id;
|
||||
message m;
|
||||
|
||||
grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr, num_of_bytes,
|
||||
grant_id = cpf_grant_magic(fs_e, user_e, user_addr, num_of_bytes,
|
||||
(rw_flag == READING ? CPF_WRITE : CPF_READ));
|
||||
if(grant_id == -1)
|
||||
panic("req_breadwrite: cpf_grant_magic failed");
|
||||
|
@ -300,19 +304,65 @@ int req_getdents(
|
|||
char *buf,
|
||||
size_t size,
|
||||
u64_t *new_pos,
|
||||
int direct
|
||||
int direct,
|
||||
int getdents_321 /* Set to 1 if user land expects old format */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
int fs_getdents_321 = 0, do_translation = 0;
|
||||
message m;
|
||||
cp_grant_id_t grant_id;
|
||||
struct vmnt *vmp;
|
||||
char *indir_buf_src = NULL;
|
||||
char *indir_buf_dst = NULL;
|
||||
|
||||
if (direct) {
|
||||
grant_id = cpf_grant_direct(fs_e, (vir_bytes) buf, size,
|
||||
CPF_WRITE);
|
||||
vmp = find_vmnt(fs_e);
|
||||
assert(vmp != NULL);
|
||||
|
||||
if (VFS_FS_PROTO_VERSION(vmp->m_proto) == 0) {
|
||||
fs_getdents_321 = 1;
|
||||
}
|
||||
|
||||
/* When we have to translate new struct dirent to the old format or vice
|
||||
* versa, we're going to have to ignore the user provided buffer and do only
|
||||
* one entry at a time. We have to do the translation here and allocate
|
||||
* space on the stack. This is a limited resource. Besides, we don't want to
|
||||
* be dependent on crazy buffer sizes provided by user space (i.e., we'd have
|
||||
* to allocate a similarly sized buffer here).
|
||||
*
|
||||
* We need to translate iff:
|
||||
* 1. userland expects old format and FS provides new format
|
||||
* 2. userland expects new format and FS provides old format
|
||||
* We don't need to translate iff
|
||||
* 3. userland expects old format and FS provides old format
|
||||
* 4. userland expects new format and FS provides new format
|
||||
*
|
||||
* Note: VFS expects new format (when doing 'direct'), covered by case 2.
|
||||
*/
|
||||
if (getdents_321 && !fs_getdents_321) { /* case 1 */
|
||||
do_translation = 1;
|
||||
} else if (fs_getdents_321 && !getdents_321) {/* case 2 */
|
||||
do_translation = 1;
|
||||
}
|
||||
|
||||
if (do_translation) {
|
||||
/* We're cutting down the buffer size in two so it's guaranteed we
|
||||
* have enough space for the translation (data structure has become
|
||||
* larger).
|
||||
*/
|
||||
size = size / 2;
|
||||
indir_buf_src = malloc(size);
|
||||
indir_buf_dst = malloc(size * 2); /* dst buffer keeps original size */
|
||||
if (indir_buf_src == NULL || indir_buf_dst == NULL)
|
||||
panic("Couldn't allocate temp buf space\n");
|
||||
|
||||
grant_id = cpf_grant_direct(fs_e, (vir_bytes) indir_buf_src, size,
|
||||
CPF_WRITE);
|
||||
} else if (direct) {
|
||||
grant_id = cpf_grant_direct(fs_e, (vir_bytes) buf, size, CPF_WRITE);
|
||||
} else {
|
||||
grant_id = cpf_grant_magic(fs_e, who_e, (vir_bytes) buf, size,
|
||||
CPF_WRITE);
|
||||
CPF_WRITE);
|
||||
}
|
||||
|
||||
if (grant_id < 0)
|
||||
|
@ -329,14 +379,84 @@ int req_getdents(
|
|||
r = fs_sendrec(fs_e, &m);
|
||||
cpf_revoke(grant_id);
|
||||
|
||||
if (do_translation) {
|
||||
if (r == OK) {
|
||||
m.RES_NBYTES = translate_dents(indir_buf_src, m.RES_NBYTES,
|
||||
indir_buf_dst, getdents_321);
|
||||
if (direct) {
|
||||
memcpy(buf, indir_buf_dst, m.RES_NBYTES);
|
||||
} else {
|
||||
r = sys_vircopy(SELF, (vir_bytes) indir_buf_dst, who_e,
|
||||
(vir_bytes) buf, m.RES_NBYTES);
|
||||
}
|
||||
}
|
||||
free(indir_buf_src);
|
||||
free(indir_buf_dst);
|
||||
}
|
||||
|
||||
if (r == OK) {
|
||||
*new_pos = ((u64_t)(m.RES_SEEK_POS_LO));
|
||||
r = m.RES_NBYTES;
|
||||
*new_pos = ((u64_t)(m.RES_SEEK_POS_LO));
|
||||
r = m.RES_NBYTES;
|
||||
}
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* translate_dents *
|
||||
*===========================================================================*/
|
||||
static size_t
|
||||
translate_dents(char *src, size_t size, char *dst, int to_getdents_321)
|
||||
{
|
||||
/* Convert between 'struct dirent' and 'struct dirent_321' both ways and
|
||||
* return the size of the new buffer.
|
||||
*/
|
||||
int consumed = 0, newconsumed = 0;
|
||||
struct dirent *dent;
|
||||
struct dirent_321 *dent_321;
|
||||
#define DWORD_ALIGN(d) if((d) % sizeof(long)) (d)+=sizeof(long)-(d)%sizeof(long)
|
||||
|
||||
if (to_getdents_321) {
|
||||
/* Provided format is struct dirent and has to be translated
|
||||
* to struct dirent_321 */
|
||||
dent_321 = (struct dirent_321 *) dst;
|
||||
dent = (struct dirent *) src;
|
||||
|
||||
while (consumed < size && dent->d_reclen > 0) {
|
||||
dent_321->d_ino = (u32_t) dent->d_ino;
|
||||
dent_321->d_off = (i32_t) dent->d_off;
|
||||
dent_321->d_reclen = offsetof(struct dirent_321,d_name)+
|
||||
strlen(dent->d_name) + 1;
|
||||
DWORD_ALIGN(dent_321->d_reclen);
|
||||
strcpy(dent_321->d_name, dent->d_name);
|
||||
consumed += dent->d_reclen;
|
||||
newconsumed += dent_321->d_reclen;
|
||||
dent = (struct dirent *) &src[consumed];
|
||||
dent_321 = (struct dirent_321 *) &dst[newconsumed];
|
||||
}
|
||||
} else {
|
||||
/* Provided format is struct dirent_321 and has to be
|
||||
* translated to struct dirent */
|
||||
dent_321 = (struct dirent_321 *) src;
|
||||
dent = (struct dirent *) dst;
|
||||
|
||||
while (consumed < size && dent_321->d_reclen > 0) {
|
||||
dent->d_ino = (ino_t) dent_321->d_ino;
|
||||
dent->d_off = (off_t) dent_321->d_off;
|
||||
dent->d_reclen = offsetof(struct dirent, d_name) +
|
||||
strlen(dent_321->d_name) + 1;
|
||||
DWORD_ALIGN(dent->d_reclen);
|
||||
strcpy(dent->d_name, dent_321->d_name);
|
||||
consumed += dent_321->d_reclen;
|
||||
newconsumed += dent->d_reclen;
|
||||
dent_321 = (struct dirent_321 *) &src[consumed];
|
||||
dent = (struct dirent *) &dst[newconsumed];
|
||||
}
|
||||
}
|
||||
|
||||
return newconsumed;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* req_inhibread *
|
||||
*===========================================================================*/
|
||||
|
@ -762,8 +882,6 @@ int req_readsuper(
|
|||
res_nodep->fs_e = m.m_source;
|
||||
res_nodep->inode_nr = (ino_t) m.RES_INODE_NR;
|
||||
vmp->m_proto = m.RES_PROTO;
|
||||
printf("%d: proto = 0x%x, version=%d conreqs=%d\n", fs_e, vmp->m_proto,
|
||||
VFS_FS_PROTO_VERSION(vmp->m_proto), VFS_FS_PROTO_CONREQS(vmp->m_proto));
|
||||
res_nodep->fmode = (mode_t) m.RES_MODE;
|
||||
res_nodep->fsize = m.RES_FILE_SIZE_LO;
|
||||
res_nodep->uid = (uid_t) m.RES_UID;
|
||||
|
@ -784,7 +902,7 @@ ino_t inode_nr;
|
|||
u64_t pos;
|
||||
int rw_flag;
|
||||
endpoint_t user_e;
|
||||
char *user_addr;
|
||||
vir_bytes user_addr;
|
||||
unsigned int num_of_bytes;
|
||||
u64_t *new_posp;
|
||||
unsigned int *cum_iop;
|
||||
|
@ -796,7 +914,7 @@ unsigned int *cum_iop;
|
|||
if (ex64hi(pos) != 0)
|
||||
panic("req_readwrite: pos too large");
|
||||
|
||||
grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr, num_of_bytes,
|
||||
grant_id = cpf_grant_magic(fs_e, user_e, user_addr, num_of_bytes,
|
||||
(rw_flag==READING ? CPF_WRITE:CPF_READ));
|
||||
if (grant_id == -1)
|
||||
panic("req_readwrite: cpf_grant_magic failed");
|
||||
|
|
|
@ -23,7 +23,7 @@ int (*call_vec[])(message *m_out) = {
|
|||
do_open, /* 5 = open */
|
||||
do_close, /* 6 = close */
|
||||
no_sys, /* 7 = wait */
|
||||
no_sys, /* 8 = unused (was creat) */
|
||||
no_sys, /* 8 = unused */
|
||||
do_link, /* 9 = link */
|
||||
do_unlink, /* 10 = unlink */
|
||||
no_sys, /* 11 = waitpid */
|
||||
|
@ -34,7 +34,7 @@ int (*call_vec[])(message *m_out) = {
|
|||
do_chown, /* 16 = chown */
|
||||
no_sys, /* 17 = break */
|
||||
no_sys, /* 18 = unused (was old stat)*/
|
||||
do_lseek, /* 19 = lseek */
|
||||
no_sys, /* 19 = unused (was lseek_321)*/
|
||||
no_sys, /* 20 = getpid */
|
||||
do_mount, /* 21 = mount */
|
||||
do_umount, /* 22 = umount */
|
||||
|
@ -56,7 +56,7 @@ int (*call_vec[])(message *m_out) = {
|
|||
do_rename, /* 38 = rename */
|
||||
do_mkdir, /* 39 = mkdir */
|
||||
do_unlink, /* 40 = rmdir */
|
||||
no_sys, /* 41 = unused (was dup) */
|
||||
no_sys, /* 41 = unused */
|
||||
do_pipe, /* 42 = pipe */
|
||||
no_sys, /* 43 = times */
|
||||
no_sys, /* 44 = (prof) */
|
||||
|
@ -84,8 +84,8 @@ int (*call_vec[])(message *m_out) = {
|
|||
do_fstat, /* 66 = fstat - badly numbered, being phased out */
|
||||
do_lstat, /* 67 = lstat - badly numbered, being phased out */
|
||||
no_sys, /* 68 = (setmcontext) */
|
||||
no_sys, /* 69 = unused */
|
||||
no_sys, /* 70 = unused */
|
||||
do_getdents, /* 69 = getdents */
|
||||
do_ftruncate, /* 70 = ftruncate */
|
||||
no_sys, /* 71 = (sigaction) */
|
||||
no_sys, /* 72 = (sigsuspend) */
|
||||
no_sys, /* 73 = (sigpending) */
|
||||
|
@ -95,11 +95,11 @@ int (*call_vec[])(message *m_out) = {
|
|||
do_svrctl, /* 77 = svrctl */
|
||||
no_sys, /* 78 = (sysuname) */
|
||||
no_sys, /* 79 = unused */
|
||||
do_getdents, /* 80 = getdents */
|
||||
do_getdents, /* 80 = getdents_321 (to be phased out) */
|
||||
do_llseek, /* 81 = llseek */
|
||||
do_fstatfs, /* 82 = fstatfs */
|
||||
do_statvfs, /* 83 = fstatvfs */
|
||||
do_fstatvfs, /* 84 = statvfs */
|
||||
do_statvfs, /* 83 = fstatvfs */
|
||||
do_fstatvfs, /* 84 = statvfs */
|
||||
do_select, /* 85 = select */
|
||||
do_fchdir, /* 86 = fchdir */
|
||||
do_fsync, /* 87 = fsync */
|
||||
|
@ -108,11 +108,11 @@ int (*call_vec[])(message *m_out) = {
|
|||
no_sys, /* 90 = (gettimeofday) */
|
||||
no_sys, /* 91 = (seteuid) */
|
||||
no_sys, /* 92 = (setegid) */
|
||||
do_truncate, /* 93 = truncate */
|
||||
do_ftruncate, /* 94 = truncate */
|
||||
do_truncate, /* 93 = truncate_321 (to be phased out) */
|
||||
do_ftruncate, /* 94 = ftruncate_321 (to be phased out) */
|
||||
do_chmod, /* 95 = fchmod */
|
||||
do_chown, /* 96 = fchown */
|
||||
no_sys, /* 97 = unused */
|
||||
do_lseek, /* 97 = lseek */
|
||||
no_sys, /* 98 = (sprofile) */
|
||||
no_sys, /* 99 = (cprofile) */
|
||||
no_sys, /* 100 = (newexec) */
|
||||
|
@ -124,8 +124,8 @@ int (*call_vec[])(message *m_out) = {
|
|||
no_sys, /* 106 = unused */
|
||||
no_sys, /* 107 = (getepinfo) */
|
||||
do_utimens, /* 108 = utimens */
|
||||
no_sys, /* 109 = unused */
|
||||
no_sys, /* 110 = unused */
|
||||
do_fcntl, /* 109 = fcntl */
|
||||
do_truncate, /* 110 = unused */
|
||||
no_sys, /* 111 = (srv_kill) */
|
||||
do_gcov_flush, /* 112 = gcov_flush */
|
||||
no_sys, /* 113 = (getsid) */
|
||||
|
|
|
@ -214,7 +214,7 @@ struct vm_exec_info {
|
|||
};
|
||||
|
||||
static int libexec_copy_physcopy(struct exec_info *execi,
|
||||
off_t off, off_t vaddr, size_t len)
|
||||
off_t off, vir_bytes vaddr, size_t len)
|
||||
{
|
||||
vir_bytes end;
|
||||
struct vm_exec_info *ei = execi->opaque;
|
||||
|
@ -237,14 +237,14 @@ static void boot_alloc(struct exec_info *execi, off_t vaddr,
|
|||
}
|
||||
|
||||
static int libexec_alloc_vm_prealloc(struct exec_info *execi,
|
||||
off_t vaddr, size_t len)
|
||||
vir_bytes vaddr, size_t len)
|
||||
{
|
||||
boot_alloc(execi, vaddr, len, MF_PREALLOC);
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int libexec_alloc_vm_ondemand(struct exec_info *execi,
|
||||
off_t vaddr, size_t len)
|
||||
vir_bytes vaddr, size_t len)
|
||||
{
|
||||
boot_alloc(execi, vaddr, len, 0);
|
||||
return OK;
|
||||
|
|
|
@ -38,8 +38,8 @@ typedef char * __caddr_t; /* core address */
|
|||
typedef __uint32_t __gid_t; /* group id */
|
||||
typedef __uint32_t __in_addr_t; /* IP(v4) address */
|
||||
typedef __uint16_t __in_port_t; /* "Internet" port number */
|
||||
typedef __uint16_t __mode_t; /* file permissions */
|
||||
typedef __int32_t __off_t; /* file offset */
|
||||
typedef __uint32_t __mode_t; /* file permissions */
|
||||
typedef __int64_t __off_t; /* file offset */
|
||||
typedef __int32_t __pid_t; /* process id */
|
||||
typedef __uint8_t __sa_family_t; /* socket address family */
|
||||
typedef __int32_t __socklen_t; /* socket-related datum length */
|
||||
|
|
|
@ -17,6 +17,13 @@ struct dirent { /* Largest entry (8 slots) */
|
|||
char d_name[1]; /* Null terminated name */
|
||||
};
|
||||
|
||||
struct dirent_321 { /* Largest entry (8 slots) */
|
||||
u32_t d_ino; /* I-node number */
|
||||
i32_t d_off; /* Offset in directory */
|
||||
unsigned short d_reclen; /* Length of this record */
|
||||
char d_name[1]; /* Null terminated name */
|
||||
};
|
||||
|
||||
#if defined(_NETBSD_SOURCE)
|
||||
#define MAXNAMLEN 511
|
||||
#define d_fileno d_ino
|
||||
|
|
|
@ -153,6 +153,14 @@ struct flock {
|
|||
pid_t l_pid; /* process id of the locks' owner */
|
||||
};
|
||||
|
||||
struct flock_321 {
|
||||
short l_type; /* type: F_RDLCK, F_WRLCK, or F_UNLCK */
|
||||
short l_whence; /* flag for starting offset */
|
||||
i32_t l_start; /* relative offset in bytes */
|
||||
i32_t l_len; /* size; if 0, then until EOF */
|
||||
pid_t l_pid; /* process id of the locks' owner */
|
||||
};
|
||||
|
||||
#if defined(_NETBSD_SOURCE)
|
||||
/* lock operations for flock(2) */
|
||||
#define LOCK_SH F_RDLCK /* Shared lock */
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
#endif
|
||||
|
||||
struct stat {
|
||||
# ifdef AVOID_USING_BIG_TYPES
|
||||
dev_t st_dev; /* inode's device */
|
||||
mode_t st_mode; /* inode protection mode */
|
||||
ino_t st_ino; /* inode's number */
|
||||
|
@ -66,16 +65,6 @@ struct stat {
|
|||
uid_t st_uid; /* user ID of the file's owner */
|
||||
gid_t st_gid; /* group ID of the file's group */
|
||||
dev_t st_rdev; /* device type */
|
||||
# else /* !AVOID_USING_BIG_TYPES */
|
||||
/* XXX For now MINIX is still using big_xxx_t types; just cut this when the day finally comes! */
|
||||
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 */
|
||||
# endif /* AVOID_USING_BIG_TYPES */
|
||||
#if (_POSIX_C_SOURCE - 0) >= 200809L || (_XOPEN_SOURCE - 0) >= 700 || \
|
||||
defined(_NETBSD_SOURCE)
|
||||
struct timespec st_atim; /* time of last access */
|
||||
|
@ -96,11 +85,7 @@ struct stat {
|
|||
off_t st_size; /* file size, in off_t bytes */
|
||||
off_t st_size_rest;
|
||||
#else
|
||||
# ifdef AVOID_USING_BIG_TYPES
|
||||
off_t st_size; /* file size, in bytes */
|
||||
# else /* !AVOID_USING_BIG_TYPES */ /* XXX also cut here */
|
||||
big_off_t st_size; /* file size, in bytes */
|
||||
# endif /* AVOID_USING_BIG_TYPES */
|
||||
#endif
|
||||
blkcnt_t st_blocks; /* blocks allocated for file */
|
||||
blksize_t st_blksize; /* optimal blocksize for I/O */
|
||||
|
|
|
@ -106,15 +106,6 @@ typedef int16_t i16_t;
|
|||
typedef int32_t i32_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;
|
||||
|
||||
|
||||
#ifdef _NETBSD_SOURCE
|
||||
/* some Minix specific types that do not conflict with posix */
|
||||
typedef uint32_t zone_t; /* zone number */
|
||||
|
@ -204,7 +195,7 @@ typedef __gid_t gid_t; /* group id */
|
|||
|
||||
typedef int idtype_t; /* type of the id */
|
||||
typedef uint32_t id_t; /* group id, process id or user id */
|
||||
typedef uint32_t ino_t; /* inode number */
|
||||
typedef uint64_t ino_t; /* inode number */
|
||||
typedef long key_t; /* IPC key (for Sys V IPC) */
|
||||
|
||||
#ifndef mode_t
|
||||
|
@ -212,7 +203,7 @@ typedef __mode_t mode_t; /* permissions */
|
|||
#define mode_t __mode_t
|
||||
#endif
|
||||
|
||||
typedef int16_t nlink_t; /* link count */
|
||||
typedef uint32_t nlink_t; /* link count */
|
||||
|
||||
#ifndef off_t
|
||||
typedef __off_t off_t; /* file offset */
|
||||
|
|
|
@ -66,7 +66,7 @@ __RCSID("$NetBSD: gzip.c,v 1.105 2011/08/30 23:06:00 joerg Exp $");
|
|||
#include <time.h>
|
||||
|
||||
#ifndef PRIdOFF
|
||||
#define PRIdOFF PRId32
|
||||
#define PRIdOFF PRId64
|
||||
#endif
|
||||
|
||||
/* what type of file are we dealing with */
|
||||
|
@ -1276,11 +1276,7 @@ file_compress(char *file, char *outfile, size_t outsize)
|
|||
if (osb.st_size != size) {
|
||||
maybe_warnx("output file: %s wrong size (%" PRIdOFF
|
||||
" != %" PRIdOFF "), deleting",
|
||||
#ifndef __minix
|
||||
outfile, osb.st_size, size);
|
||||
#else
|
||||
outfile, osb.st_size, (big_off_t)size);
|
||||
#endif
|
||||
goto bad_outfile;
|
||||
}
|
||||
|
||||
|
@ -1559,11 +1555,7 @@ file_uncompress(char *file, char *outfile, size_t outsize)
|
|||
if (osb.st_size != size) {
|
||||
maybe_warnx("stat gave different size: %" PRIdOFF
|
||||
" != %" PRIdOFF " (leaving original)",
|
||||
#ifndef __minix
|
||||
size, osb.st_size);
|
||||
#else
|
||||
(big_off_t)size, osb.st_size);
|
||||
#endif
|
||||
close(ofd);
|
||||
unlink(outfile);
|
||||
return -1;
|
||||
|
|
Loading…
Reference in a new issue