#include #include #include "mini.h" #if defined(HOST_WIN32) || !defined(HAVE_SYS_IPC_H) || !defined(HAVE_SYS_SEM_H) || (defined(__native_client__) && defined(__GLIBC__)) int mini_wapi_hps (int argc, char **argv) { return 0; } int mini_wapi_semdel (int argc, char **argv) { return 0; } int mini_wapi_seminfo (int argc, char **argv) { return 0; } #else #include #include #include #include #include /* We're digging into handle internals here... */ #include #include #include #include static const gchar *unused_details (struct _WapiHandleShared *handle); static const gchar *unshared_details (struct _WapiHandleShared *handle); #if 0 static const gchar *thread_details (struct _WapiHandleShared *handle); #endif static const gchar *namedmutex_details (struct _WapiHandleShared *handle); static const gchar *namedsem_details (struct _WapiHandleShared *handle); static const gchar *namedevent_details (struct _WapiHandleShared *handle); static const gchar *process_details (struct _WapiHandleShared *handle); /* This depends on the ordering of the enum WapiHandleType in * io-layer/wapi-private.h */ static const gchar * (*details[])(struct _WapiHandleShared *)= { unused_details, unshared_details, /* file */ unshared_details, /* console */ unshared_details, /* thread */ unshared_details, /* sem */ unshared_details, /* mutex */ unshared_details, /* event */ unshared_details, /* socket */ unshared_details, /* find */ process_details, unshared_details, /* pipe */ namedmutex_details, namedsem_details, namedevent_details, unused_details, }; int mini_wapi_hps (int argc, char **argv) { guint32 i; guint32 now; _wapi_shared_layout = _wapi_shm_attach(WAPI_SHM_DATA); if (_wapi_shared_layout == NULL) { g_error ("Failed to attach shared memory!"); exit (-1); } _wapi_fileshare_layout = _wapi_shm_attach(WAPI_SHM_FILESHARE); if (_wapi_fileshare_layout == NULL) { g_error ("Failed to attach fileshare shared memory!"); exit (-1); } if (argc > 1) { _wapi_shm_semaphores_init (); _wapi_collection_init (); _wapi_handle_collect (); } g_print ("collection: %d sem: 0x%x\n", _wapi_shared_layout->collection_count, _wapi_shared_layout->sem_key); now = (guint32)(time(NULL) & 0xFFFFFFFF); for (i = 0; i < _WAPI_HANDLE_INITIAL_COUNT; i++) { struct _WapiHandleShared *shared; shared = &_wapi_shared_layout->handles[i]; if (shared->type != WAPI_HANDLE_UNUSED) { g_print ("%3x (%3d) [%7s] %4u %s (%s)\n", i, shared->handle_refs, _wapi_handle_typename[shared->type], now - shared->timestamp, shared->signalled?"Sg":"Un", details[shared->type](shared)); } } g_print ("Fileshare hwm: %d\n", _wapi_fileshare_layout->hwm); for (i = 0; i <= _wapi_fileshare_layout->hwm; i++) { struct _WapiFileShare *file_share; file_share = &_wapi_fileshare_layout->share_info[i]; if (file_share->handle_refs > 0) { g_print ("dev: 0x%llx ino: %lld open pid: %d share: 0x%x access: 0x%x refs: %d\n", (long long int)file_share->device, (long long int)file_share->inode, file_share->opened_by_pid, file_share->sharemode, file_share->access, file_share->handle_refs); } } exit (0); } static const gchar *unused_details (struct _WapiHandleShared *handle) { return("unused details"); } static const gchar *unshared_details (struct _WapiHandleShared *handle) { return("unshared details"); } #if 0 static const gchar *thread_details (struct _WapiHandleShared *handle) { static gchar buf[80]; struct _WapiHandle_thread *thr=&handle->u.thread; g_snprintf (buf, sizeof(buf), "proc: %d, tid: %ld, state: %d, exit: %u, join: %d", thr->owner_pid, thr->id, thr->state, thr->exitstatus, thr->joined); return(buf); } #endif static const gchar *namedmutex_details (struct _WapiHandleShared *handle) { static gchar buf[80]; gchar *name; struct _WapiHandle_namedmutex *mut=&handle->u.namedmutex; name = mut->sharedns.name; g_snprintf (buf, sizeof(buf), "[%15s] own: %5d:%5ld, count: %5u", name==NULL?(gchar *)"":name, mut->pid, mut->tid, mut->recursion); return(buf); } static const gchar *namedsem_details (struct _WapiHandleShared *handle) { static gchar buf[80]; gchar *name; struct _WapiHandle_namedsem *sem = &handle->u.namedsem; name = sem->sharedns.name; g_snprintf (buf, sizeof(buf), "[%15s] val: %5u, max: %5d", name == NULL?(gchar *)"":name, sem->val, sem->max); return(buf); } static const gchar *namedevent_details (struct _WapiHandleShared *handle) { static gchar buf[80]; gchar *name; struct _WapiHandle_namedevent *event = &handle->u.namedevent; name = event->sharedns.name; g_snprintf (buf, sizeof(buf), "[%15s] %s count: %5u", name == NULL?(gchar *)"":name, event->manual?"Manual":"Auto", event->set_count); return(buf); } static const gchar *process_details (struct _WapiHandleShared *handle) { static gchar buf[80]; gchar *name; struct _WapiHandle_process *proc=&handle->u.process; name = proc->proc_name; g_snprintf (buf, sizeof(buf), "[%25.25s] pid: %5u exit: %u", name==NULL?(gchar *)"":name, proc->id, proc->exitstatus); return(buf); } /* The old handles/semdel.c */ int mini_wapi_semdel (int argc, char **argv) { int sem_id, ret; _wapi_shared_layout = _wapi_shm_attach(WAPI_SHM_DATA); if (_wapi_shared_layout == FALSE || _wapi_shared_layout->sem_key == 0) { exit (0); } sem_id = semget (_wapi_shared_layout->sem_key, _WAPI_SHARED_SEM_COUNT, 0600); if (sem_id != -1) { ret = semctl (sem_id, 0, IPC_RMID); if (ret == -1) { g_message ("Error deleting semaphore: %s", g_strerror (errno)); } } exit (0); } static void sem_explain (int sem_id, ushort *vals, int which) { pid_t pid; g_print ("%d ", vals[which]); if (vals[which] >= 1) { g_print ("(Unlocked)"); } else { pid = semctl (sem_id, which, GETPID); g_print ("(Locked by %d)", pid); } g_print ("\n"); } int mini_wapi_seminfo (int argc, char **argv) { int sem_id, ret; union semun { int val; struct semid_ds *buf; ushort *array; } arg; ushort vals[_WAPI_SHARED_SEM_COUNT]; _wapi_shared_layout = _wapi_shm_attach (WAPI_SHM_DATA); if (_wapi_shared_layout == FALSE || _wapi_shared_layout->sem_key == 0) { exit (0); } sem_id = semget (_wapi_shared_layout->sem_key, _WAPI_SHARED_SEM_COUNT, 0600); if (sem_id != -1) { g_print ("Getting values for sem: 0x%x\n", _wapi_shared_layout->sem_key); arg.array = vals; ret = semctl (sem_id, 0, GETALL, arg); if (ret != -1) { g_print ("Namespace: "); sem_explain (sem_id, vals, _WAPI_SHARED_SEM_NAMESPACE); g_print ("Fileshare: "); sem_explain (sem_id, vals, _WAPI_SHARED_SEM_FILESHARE); g_print ("Handles: "); sem_explain (sem_id, vals, _WAPI_SHARED_SEM_SHARED_HANDLES); g_print ("Count lock: "); sem_explain (sem_id, vals, _WAPI_SHARED_SEM_PROCESS_COUNT_LOCK); g_print ("Count: %d\n", vals[_WAPI_SHARED_SEM_PROCESS_COUNT]); } } exit (0); } #endif