diff --git a/sys/emulation/linux/i386/linux_proto.h b/sys/emulation/linux/i386/linux_proto.h index c95ffc9..84b3e23 100644 --- a/sys/emulation/linux/i386/linux_proto.h +++ b/sys/emulation/linux/i386/linux_proto.h @@ -113,7 +113,7 @@ struct linux_stat_args { struct sysmsg sysmsg; #endif char * path; char path_[PAD_(char *)]; - struct ostat * up; char up_[PAD_(struct ostat *)]; + struct ostat * statbuf; char statbuf_[PAD_(struct ostat *)]; }; struct linux_lseek_args { #ifdef _KERNEL @@ -377,6 +377,13 @@ struct linux_sigpending_args { #endif l_osigset_t * mask; char mask_[PAD_(l_osigset_t *)]; }; +struct linux_sethostname_args { +#ifdef _KERNEL + struct sysmsg sysmsg; +#endif + char * hostname; char hostname_[PAD_(char *)]; + u_int len; char len_[PAD_(u_int)]; +}; struct linux_setrlimit_args { #ifdef _KERNEL struct sysmsg sysmsg; @@ -418,6 +425,13 @@ struct linux_symlink_args { char * path; char path_[PAD_(char *)]; char * to; char to_[PAD_(char *)]; }; +struct linux_ostat_args { +#ifdef _KERNEL + struct sysmsg sysmsg; +#endif + char * path; char path_[PAD_(char *)]; + struct ostat * statbuf; char statbuf_[PAD_(struct ostat *)]; +}; struct linux_readlink_args { #ifdef _KERNEL struct sysmsg sysmsg; @@ -1744,12 +1758,14 @@ int sys_linux_setreuid16 (struct linux_setreuid16_args *); int sys_linux_setregid16 (struct linux_setregid16_args *); int sys_linux_sigsuspend (struct linux_sigsuspend_args *); int sys_linux_sigpending (struct linux_sigpending_args *); +int sys_linux_sethostname (struct linux_sethostname_args *); int sys_linux_setrlimit (struct linux_setrlimit_args *); int sys_linux_old_getrlimit (struct linux_old_getrlimit_args *); int sys_linux_getgroups16 (struct linux_getgroups16_args *); int sys_linux_setgroups16 (struct linux_setgroups16_args *); int sys_linux_old_select (struct linux_old_select_args *); int sys_linux_symlink (struct linux_symlink_args *); +int sys_linux_ostat (struct linux_ostat_args *); int sys_linux_readlink (struct linux_readlink_args *); int sys_linux_uselib (struct linux_uselib_args *); int sys_linux_reboot (struct linux_reboot_args *); diff --git a/sys/emulation/linux/i386/linux_syscall.h b/sys/emulation/linux/i386/linux_syscall.h index 94e8019..7111421 100644 --- a/sys/emulation/linux/i386/linux_syscall.h +++ b/sys/emulation/linux/i386/linux_syscall.h @@ -69,7 +69,7 @@ #define LINUX_SYS_linux_setregid16 71 #define LINUX_SYS_linux_sigsuspend 72 #define LINUX_SYS_linux_sigpending 73 -#define LINUX_SYS_osethostname 74 +#define LINUX_SYS_linux_sethostname 74 #define LINUX_SYS_linux_setrlimit 75 #define LINUX_SYS_linux_old_getrlimit 76 #define LINUX_SYS_getrusage 77 @@ -79,7 +79,7 @@ #define LINUX_SYS_linux_setgroups16 81 #define LINUX_SYS_linux_old_select 82 #define LINUX_SYS_linux_symlink 83 -#define LINUX_SYS_ostat 84 +#define LINUX_SYS_linux_ostat 84 #define LINUX_SYS_linux_readlink 85 #define LINUX_SYS_linux_uselib 86 #define LINUX_SYS_swapon 87 diff --git a/sys/emulation/linux/i386/linux_sysent.c b/sys/emulation/linux/i386/linux_sysent.c index 06ffaf7..c7bac06 100644 --- a/sys/emulation/linux/i386/linux_sysent.c +++ b/sys/emulation/linux/i386/linux_sysent.c @@ -92,7 +92,7 @@ struct sysent linux_sysent[] = { { AS(linux_setregid16_args), (sy_call_t *)sys_linux_setregid16 }, /* 71 = linux_setregid16 */ { AS(linux_sigsuspend_args), (sy_call_t *)sys_linux_sigsuspend }, /* 72 = linux_sigsuspend */ { AS(linux_sigpending_args), (sy_call_t *)sys_linux_sigpending }, /* 73 = linux_sigpending */ - { AS(sethostname_args), (sy_call_t *)sys_osethostname }, /* 74 = osethostname */ + { AS(linux_sethostname_args), (sy_call_t *)sys_linux_sethostname }, /* 74 = linux_sethostname */ { AS(linux_setrlimit_args), (sy_call_t *)sys_linux_setrlimit }, /* 75 = linux_setrlimit */ { AS(linux_old_getrlimit_args), (sy_call_t *)sys_linux_old_getrlimit }, /* 76 = linux_old_getrlimit */ { AS(getrusage_args), (sy_call_t *)sys_getrusage }, /* 77 = getrusage */ @@ -102,7 +102,7 @@ struct sysent linux_sysent[] = { { AS(linux_setgroups16_args), (sy_call_t *)sys_linux_setgroups16 }, /* 81 = linux_setgroups16 */ { AS(linux_old_select_args), (sy_call_t *)sys_linux_old_select }, /* 82 = linux_old_select */ { AS(linux_symlink_args), (sy_call_t *)sys_linux_symlink }, /* 83 = linux_symlink */ - { AS(ostat_args), (sy_call_t *)sys_ostat }, /* 84 = ostat */ + { AS(linux_ostat_args), (sy_call_t *)sys_linux_ostat }, /* 84 = linux_ostat */ { AS(linux_readlink_args), (sy_call_t *)sys_linux_readlink }, /* 85 = linux_readlink */ { AS(linux_uselib_args), (sy_call_t *)sys_linux_uselib }, /* 86 = linux_uselib */ { AS(swapon_args), (sy_call_t *)sys_swapon }, /* 87 = swapon */ diff --git a/sys/emulation/linux/i386/linux_union.h b/sys/emulation/linux/i386/linux_union.h index 0263161..739ce86 100644 --- a/sys/emulation/linux/i386/linux_union.h +++ b/sys/emulation/linux/i386/linux_union.h @@ -62,12 +62,14 @@ union sysunion { struct linux_setregid16_args linux_setregid16; struct linux_sigsuspend_args linux_sigsuspend; struct linux_sigpending_args linux_sigpending; + struct linux_sethostname_args linux_sethostname; struct linux_setrlimit_args linux_setrlimit; struct linux_old_getrlimit_args linux_old_getrlimit; struct linux_getgroups16_args linux_getgroups16; struct linux_setgroups16_args linux_setgroups16; struct linux_old_select_args linux_old_select; struct linux_symlink_args linux_symlink; + struct linux_ostat_args linux_ostat; struct linux_readlink_args linux_readlink; struct linux_uselib_args linux_uselib; struct linux_reboot_args linux_reboot; diff --git a/sys/emulation/linux/i386/syscalls.master b/sys/emulation/linux/i386/syscalls.master index 31c8d0d..a5e9451 100644 --- a/sys/emulation/linux/i386/syscalls.master +++ b/sys/emulation/linux/i386/syscalls.master @@ -59,7 +59,7 @@ 16 STD LINUX { int linux_lchown16(char *path, l_uid16_t uid, \ l_gid16_t gid); } 17 UNIMPL LINUX break -18 STD LINUX { int linux_stat(char *path, struct ostat *up); } +18 STD LINUX { int linux_stat(char *path, struct ostat *statbuf); } 19 STD LINUX { int linux_lseek(l_uint fdes, l_off_t off, \ l_int whence); } 20 STD LINUX { int linux_getpid(void); } @@ -126,8 +126,7 @@ 72 STD LINUX { int linux_sigsuspend(l_int hist0, l_int hist1, \ l_osigset_t mask); } 73 STD LINUX { int linux_sigpending(l_osigset_t *mask); } -74 NOPROTO LINUX { int osethostname(char *hostname, u_int len); } \ - osethostname sethostname_args int +74 STD LINUX { int linux_sethostname(char *hostname, u_int len); } 75 STD LINUX { int linux_setrlimit(l_uint resource, \ struct l_rlimit *rlim); } 76 STD LINUX { int linux_old_getrlimit(l_uint resource, \ @@ -144,7 +143,7 @@ 82 STD LINUX { int linux_old_select(struct l_old_select_argv \ *ptr); } 83 STD LINUX { int linux_symlink(char *path, char *to); } -84 NOPROTO LINUX { int ostat(char *path, struct ostat *up); } +84 STD LINUX { int linux_ostat(char *path, struct ostat *statbuf); } 85 STD LINUX { int linux_readlink(char *name, char *buf, \ l_int count); } 86 STD LINUX { int linux_uselib(char *library); } diff --git a/sys/emulation/linux/linux_misc.c b/sys/emulation/linux/linux_misc.c index beff37b..1d304e4 100644 --- a/sys/emulation/linux/linux_misc.c +++ b/sys/emulation/linux/linux_misc.c @@ -1933,3 +1933,34 @@ sys_linux_getcpu(struct linux_getcpu_args *args) error = copyout(&node, args->pnode, sizeof(node)); return (error); } + +int +sys_linux_sethostname(struct linux_sethostname_args *uap) +{ + struct thread *td = curthread; + size_t len; + char *hostname; + int name[2]; + int error; + + name[0] = CTL_KERN; + name[1] = KERN_HOSTNAME; + error = priv_check_cred(td->td_ucred, PRIV_SETHOSTNAME, 0); + if (error) + return (error); + len = MIN(uap->len, MAXHOSTNAMELEN); + hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK); + + error = copyin(uap->hostname, hostname, len); + if (error) { + kfree(hostname, M_TEMP); + return (error); + } + + get_mplock(); + error = kernel_sysctl(name, 2, NULL, 0, hostname, len, NULL); + rel_mplock(); + + kfree(hostname, M_TEMP); + return (error); +} diff --git a/sys/emulation/linux/linux_stats.c b/sys/emulation/linux/linux_stats.c index 1302e41..4910497 100644 --- a/sys/emulation/linux/linux_stats.c +++ b/sys/emulation/linux/linux_stats.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -78,6 +79,35 @@ newstat_copyout(struct stat *buf, void *ubuf) return (error); } +static int +ostat_copyout(struct stat *st, struct ostat *uaddr) +{ + struct ostat ost; + int error; + + ost.st_dev = st->st_dev; + ost.st_ino = st->st_ino; + ost.st_mode = st->st_mode; + ost.st_nlink = st->st_nlink; + ost.st_uid = st->st_uid; + ost.st_gid = st->st_gid; + ost.st_rdev = st->st_rdev; + if (st->st_size < (quad_t)1 << 32) + ost.st_size = st->st_size; + else + ost.st_size = -2; + ost.st_atime = st->st_atime; + ost.st_mtime = st->st_mtime; + ost.st_ctime = st->st_ctime; + ost.st_blksize = st->st_blksize; + ost.st_blocks = st->st_blocks; + ost.st_flags = st->st_flags; + ost.st_gen = st->st_gen; + + error = copyout(&ost, uaddr, sizeof(ost)); + return (error); +} + /* * MPALMOSTSAFE */ @@ -511,5 +541,32 @@ sys_linux_fstatat64(struct linux_fstatat64_args *args) return (error); } +int +sys_linux_ostat(struct linux_ostat_args *args) +{ + struct nlookupdata nd; + struct stat buf; + char *path; + int error; + + error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS); + if (error) + return (error); +#ifdef DEBUG + if (ldebug(ostat)) + kprintf(ARGS(ostat, "%s, *"), path); +#endif + get_mplock(); + error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); + if (error == 0) { + error = kern_stat(&nd, &buf); + nlookup_done(&nd); + } + rel_mplock(); + if (error == 0) + error = ostat_copyout(&buf, args->statbuf); + linux_free_path(&path); + return (error); +} #endif /* __i386__ */