diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_descrip.c | 31 | ||||
-rw-r--r-- | sys/kern/uipc_sem.c | 19 | ||||
-rw-r--r-- | sys/sys/ksem.h | 8 | ||||
-rw-r--r-- | sys/sys/user.h | 4 |
4 files changed, 60 insertions, 2 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index a9795ca..c0ecf15 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include <sys/filio.h> #include <sys/jail.h> #include <sys/kernel.h> +#include <sys/ksem.h> #include <sys/limits.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -111,6 +112,7 @@ MALLOC_DECLARE(M_FADVISE); static uma_zone_t file_zone; +void (*ksem_info)(struct ksem *ks, char *path, size_t size, uint32_t *value); static int closefp(struct filedesc *fdp, int fd, struct file *fp, struct thread *td, int holdleaders); @@ -123,6 +125,7 @@ static int fill_pipe_info(struct pipe *pi, struct kinfo_file *kif); static int fill_procdesc_info(struct procdesc *pdp, struct kinfo_file *kif); static int fill_pts_info(struct tty *tp, struct kinfo_file *kif); +static int fill_sem_info(struct file *fp, struct kinfo_file *kif); static int fill_shm_info(struct file *fp, struct kinfo_file *kif); static int fill_socket_info(struct socket *so, struct kinfo_file *kif); static int fill_vnode_info(struct vnode *vp, struct kinfo_file *kif); @@ -2968,6 +2971,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS) struct shmfd *shmfd; struct socket *so; struct vnode *vp; + struct ksem *ks; struct file *fp; struct proc *p; struct tty *tp; @@ -2996,6 +3000,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS) continue; bzero(kif, sizeof(*kif)); kif->kf_structsize = sizeof(*kif); + ks = NULL; vp = NULL; so = NULL; tp = NULL; @@ -3041,6 +3046,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS) case DTYPE_SEM: kif->kf_type = KF_TYPE_SEM; + ks = fp->f_data; break; case DTYPE_PTS: @@ -3150,6 +3156,8 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS) } if (shmfd != NULL) shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path)); + if (ks != NULL && ksem_info != NULL) + ksem_info(ks, kif->kf_path, sizeof(kif->kf_path), NULL); error = SYSCTL_OUT(req, kif, sizeof(*kif)); if (error) break; @@ -3220,6 +3228,9 @@ export_fd_to_sb(void *data, int type, int fd, int fflags, int refcnt, case KF_TYPE_PROCDESC: error = fill_procdesc_info((struct procdesc *)data, kif); break; + case KF_TYPE_SEM: + error = fill_sem_info((struct file *)data, kif); + break; case KF_TYPE_SHM: error = fill_shm_info((struct file *)data, kif); break; @@ -3387,6 +3398,7 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen) case DTYPE_SEM: type = KF_TYPE_SEM; + data = fp; break; case DTYPE_PTS: @@ -3621,6 +3633,25 @@ fill_procdesc_info(struct procdesc *pdp, struct kinfo_file *kif) } static int +fill_sem_info(struct file *fp, struct kinfo_file *kif) +{ + struct thread *td; + struct stat sb; + + td = curthread; + if (fp->f_data == NULL) + return (1); + if (fo_stat(fp, &sb, td->td_ucred, td) != 0) + return (1); + if (ksem_info == NULL) + return (1); + ksem_info(fp->f_data, kif->kf_path, sizeof(kif->kf_path), + &kif->kf_un.kf_sem.kf_sem_value); + kif->kf_un.kf_sem.kf_sem_mode = sb.st_mode; + return (0); +} + +static int fill_shm_info(struct file *fp, struct kinfo_file *kif) { struct thread *td; diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c index 509f32e..a9f60f1 100644 --- a/sys/kern/uipc_sem.c +++ b/sys/kern/uipc_sem.c @@ -71,7 +71,6 @@ FEATURE(p1003_1b_semaphores, "POSIX P1003.1B semaphores support"); * TODO * * - Resource limits? - * - Update fstat(1) * - Replace global sem_lock with mtx_pool locks? * - Add a MAC check_create() hook for creating new named semaphores. */ @@ -407,6 +406,7 @@ ksem_insert(char *path, Fnv32_t fnv, struct ksem *ks) map->km_path = path; map->km_fnv = fnv; map->km_ksem = ksem_hold(ks); + ks->ks_path = path; LIST_INSERT_HEAD(KSEM_HASH(fnv), map, km_link); } @@ -428,6 +428,7 @@ ksem_remove(char *path, Fnv32_t fnv, struct ucred *ucred) error = ksem_access(map->km_ksem, ucred); if (error) return (error); + map->km_ksem->ks_path = NULL; LIST_REMOVE(map, km_link); ksem_drop(map->km_ksem); free(map->km_path, M_KSEM); @@ -439,6 +440,20 @@ ksem_remove(char *path, Fnv32_t fnv, struct ucred *ucred) return (ENOENT); } +static void +ksem_info_impl(struct ksem *ks, char *path, size_t size, uint32_t *value) +{ + + if (ks->ks_path == NULL) + return; + sx_slock(&ksem_dict_lock); + if (ks->ks_path != NULL) + strlcpy(path, ks->ks_path, size); + if (value != NULL) + *value = ks->ks_value; + sx_sunlock(&ksem_dict_lock); +} + static int ksem_create_copyout_semid(struct thread *td, semid_t *semidp, int fd, int compat32) @@ -1014,6 +1029,7 @@ ksem_module_init(void) p31b_setcfg(CTL_P1003_1B_SEMAPHORES, 200112L); p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX); p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX); + ksem_info = ksem_info_impl; error = syscall_helper_register(ksem_syscalls); if (error) @@ -1035,6 +1051,7 @@ ksem_module_destroy(void) #endif syscall_helper_unregister(ksem_syscalls); + ksem_info = NULL; p31b_setcfg(CTL_P1003_1B_SEMAPHORES, 0); hashdestroy(ksem_dictionary, M_KSEM, ksem_hash); sx_destroy(&ksem_dict_lock); diff --git a/sys/sys/ksem.h b/sys/sys/ksem.h index da868fa..c11c865 100644 --- a/sys/sys/ksem.h +++ b/sys/sys/ksem.h @@ -29,7 +29,7 @@ #ifndef _POSIX4_KSEM_H_ #define _POSIX4_KSEM_H_ -#ifndef _KERNEL +#if !defined(_KERNEL) && !defined(_WANT_FILE) #error "no user-servicable parts inside" #endif @@ -57,9 +57,15 @@ struct ksem { struct timespec ks_birthtime; struct label *ks_label; /* MAC label */ + const char *ks_path; }; #define KS_ANONYMOUS 0x0001 /* Anonymous (unnamed) semaphore. */ #define KS_DEAD 0x0002 /* No new waiters allowed. */ +#ifdef _KERNEL +extern void (*ksem_info)(struct ksem *ks, char *path, size_t size, + uint32_t *value); +#endif + #endif /* !_POSIX4_KSEM_H_ */ diff --git a/sys/sys/user.h b/sys/sys/user.h index 2f6514b..aa81dc9 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -365,6 +365,10 @@ struct kinfo_file { uint32_t kf_file_pad1; } kf_file; struct { + uint32_t kf_sem_value; + uint16_t kf_sem_mode; + } kf_sem; + struct { uint64_t kf_pipe_addr; uint64_t kf_pipe_peer; uint32_t kf_pipe_buffer_cnt; |