diff --git a/server/Makefile.in b/server/Makefile.in index 84e78d0aa56..4c4dedcb35a 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -25,6 +25,7 @@ C_SRCS = \ object.c \ process.c \ procfs.c \ + procstat.c \ ptrace.c \ queue.c \ region.c \ @@ -49,6 +50,6 @@ MANPAGES = \ wineserver.fr.UTF-8.man.in \ wineserver.man.in -EXTRALIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) +EXTRALIBS = $(LDEXECFLAGS) $(RT_LIBS) $(INOTIFY_LIBS) $(PROCSTAT_LIBS) unicode_EXTRADEFS = -DNLSDIR="\"${nlsdir}\"" -DBIN_TO_NLSDIR=\"`${MAKEDEP} -R ${bindir} ${nlsdir}`\" diff --git a/server/process.c b/server/process.c index 343ad78270c..76d42f82261 100644 --- a/server/process.c +++ b/server/process.c @@ -1550,9 +1550,9 @@ DECL_HANDLER(get_process_vm_counters) struct process *process = get_process_from_handle( req->handle, PROCESS_QUERY_LIMITED_INFORMATION ); if (!process) return; -#ifdef linux if (process->unix_pid != -1) { +#ifdef linux FILE *f; char proc_path[32], line[256]; unsigned long value; @@ -1579,9 +1579,12 @@ DECL_HANDLER(get_process_vm_counters) fclose( f ); } else set_error( STATUS_ACCESS_DENIED ); +#elif defined(HAVE_LIBPROCSTAT) + unsigned int err = procstat_get_process_vm_counters( process->unix_pid, reply ); + if (err) set_error( err ); +#endif } else set_error( STATUS_ACCESS_DENIED ); -#endif release_object( process ); } diff --git a/server/process.h b/server/process.h index 22ee8178368..b64299f9f8f 100644 --- a/server/process.h +++ b/server/process.h @@ -146,4 +146,8 @@ static inline int is_process_init_done( struct process *process ) static const unsigned int default_session_id = 1; +#ifdef HAVE_LIBPROCSTAT +extern unsigned int procstat_get_process_vm_counters(pid_t pid, struct get_process_vm_counters_reply *reply); +#endif + #endif /* __WINE_SERVER_PROCESS_H */ diff --git a/server/procstat.c b/server/procstat.c new file mode 100644 index 00000000000..a0f882a6029 --- /dev/null +++ b/server/procstat.c @@ -0,0 +1,83 @@ +/* + * libprocstat support for FreeBSD + * + * Copyright (C) 2021 Damjan Jovanovic + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_PARAM_H +# include +#endif +#ifdef HAVE_SYS_QUEUE_H +# include +#endif +#ifdef HAVE_SYS_SYSCTL_H +# include +#endif + +#ifdef HAVE_SYS_USER_H +# include +#endif +#ifdef HAVE_LIBPROCSTAT +# include +#endif + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "winternl.h" + +#include "file.h" +#include "process.h" +/* DO NOT include "thread.h", another "struct thread" is defined in */ + +#ifdef HAVE_LIBPROCSTAT + +unsigned int procstat_get_process_vm_counters(pid_t pid, struct get_process_vm_counters_reply *reply) +{ + struct procstat *procstat; + unsigned int count; + unsigned int ret = 0; + + if ((procstat = procstat_open_sysctl())) + { + struct kinfo_proc *kp = procstat_getprocs( procstat, KERN_PROC_PID, pid, &count ); + if (kp) + { + reply->virtual_size = kp->ki_size; + reply->peak_virtual_size = reply->virtual_size; + reply->working_set_size = kp->ki_rssize << PAGE_SHIFT; + reply->peak_working_set_size = kp->ki_rusage.ru_maxrss * 1024; + procstat_freeprocs( procstat, kp ); + } + else ret = STATUS_ACCESS_DENIED; + procstat_close( procstat ); + } + else ret = STATUS_ACCESS_DENIED; + return ret; +} + +#endif /* HAVE_LIBPROCSTAT */ +