1/*
2 * Copyright 2001-2010 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Ingo Weinhold, bonefish@@users.sf.net
7 *		Axel Dörfler, axeld@pinc-software.de
8 *		Clemens Zeidler <haiku@clemens-zeidler.de>
9 */
10
11
12#include <Messenger.h>
13#include <NodeMonitor.h>
14
15#include <MessengerPrivate.h>
16
17#include <syscalls.h>
18
19#include "node_monitor_private.h"
20
21
22// TODO: Tests!
23
24
25// Subscribes a target to watch node changes on a volume.
26status_t
27watch_volume(dev_t volume, uint32 flags, BMessenger target)
28{
29	if ((flags & (B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR)) == 0)
30		return B_BAD_VALUE;
31
32	flags |= B_WATCH_VOLUME;
33
34	BMessenger::Private messengerPrivate(target);
35	port_id port = messengerPrivate.Port();
36	int32 token = messengerPrivate.Token();
37	return _kern_start_watching(volume, (ino_t)-1, flags, port, token);
38}
39
40
41status_t
42watch_volume(dev_t volume, uint32 flags, const BHandler* handler,
43	const BLooper* looper)
44{
45	return watch_volume(volume, flags, BMessenger(handler, looper));
46}
47
48
49// Subscribes or unsubscribes a target to node and/or mount watching.
50status_t
51watch_node(const node_ref* node, uint32 flags, BMessenger target)
52{
53	if (!target.IsValid())
54		return B_BAD_VALUE;
55
56	BMessenger::Private messengerPrivate(target);
57	port_id port = messengerPrivate.Port();
58	int32 token = messengerPrivate.Token();
59
60	if (flags == B_STOP_WATCHING) {
61		// unsubscribe from node node watching
62		if (node == NULL)
63			return B_BAD_VALUE;
64
65		return _kern_stop_watching(node->device, node->node, port, token);
66	}
67
68	// subscribe to...
69	// mount watching
70	if (flags & B_WATCH_MOUNT) {
71		status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1,
72			B_WATCH_MOUNT, port, token);
73		if (status < B_OK)
74			return status;
75
76		flags &= ~B_WATCH_MOUNT;
77	}
78
79	// node watching
80	if (flags != 0) {
81		if (node == NULL)
82			return B_BAD_VALUE;
83
84		return _kern_start_watching(node->device, node->node, flags, port,
85			token);
86	}
87
88	return B_OK;
89}
90
91
92// Subscribes or unsubscribes a handler or looper to node and/or mount
93// watching.
94status_t
95watch_node(const node_ref* node, uint32 flags, const BHandler* handler,
96	const BLooper* looper)
97{
98	return watch_node(node, flags, BMessenger(handler, looper));
99}
100
101
102// Unsubscribes a target from node and mount monitoring.
103status_t
104stop_watching(BMessenger target)
105{
106	if (!target.IsValid())
107		return B_BAD_VALUE;
108
109	BMessenger::Private messengerPrivate(target);
110	port_id port = messengerPrivate.Port();
111	int32 token = messengerPrivate.Token();
112
113	return _kern_stop_notifying(port, token);
114}
115
116
117// Unsubscribes a target from node and mount monitoring.
118status_t
119stop_watching(const BHandler* handler, const BLooper* looper)
120{
121	return stop_watching(BMessenger(handler, looper));
122}
123
124