Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
M. Stoeckl
Waypipe
Commits
e631a334
Commit
e631a334
authored
May 25, 2019
by
Manuel Stoeckl
Browse files
Extend parsing logic; also run parser remotely
parent
542be9ee
Changes
6
Hide whitespace changes
Inline
Side-by-side
client.c
View file @
e631a334
...
...
@@ -133,8 +133,9 @@ static int run_client_child(int chanfd, const char *socket_path)
untranslate_ids
(
&
fdtransmap
,
nids
,
ids
,
fds
);
if
(
waymsg
)
{
parse_and_prune_messages
(
&
mtracker
,
true
,
waymsg
,
&
waylen
,
fds
,
&
nids
);
parse_and_prune_messages
(
&
mtracker
,
&
fdtransmap
,
true
,
waymsg
,
&
waylen
,
fds
,
&
nids
);
}
if
(
waylen
>
0
)
{
...
...
@@ -173,8 +174,9 @@ static int run_client_child(int chanfd, const char *socket_path)
}
if
(
rc
>
0
)
{
int
nrc
=
(
int
)
rc
;
parse_and_prune_messages
(
&
mtracker
,
false
,
buffer
,
&
nrc
,
fdbuf
,
&
nfds
);
parse_and_prune_messages
(
&
mtracker
,
&
fdtransmap
,
false
,
buffer
,
&
nrc
,
fdbuf
,
&
nfds
);
rc
=
nrc
;
}
if
(
rc
>
0
)
{
...
...
parsing.c
View file @
e631a334
...
...
@@ -71,8 +71,10 @@ struct context {
struct
message_tracker
*
mt
;
struct
wp_object
*
obj
;
bool
drop_this_msg
;
bool
can_buffer_changes_result
;
// unless otherwise indicated by the
// protocol
};
void
event_wl_display_error
(
void
*
data
,
struct
wl_display
*
wl_display
,
static
void
event_wl_display_error
(
void
*
data
,
struct
wl_display
*
wl_display
,
void
*
object_id
,
uint32_t
code
,
const
char
*
message
)
{
struct
context
*
context
=
(
struct
context
*
)
data
;
...
...
@@ -82,7 +84,7 @@ void event_wl_display_error(void *data, struct wl_display *wl_display,
(
void
)
code
;
(
void
)
message
;
}
void
event_wl_display_delete_id
(
static
void
event_wl_display_delete_id
(
void
*
data
,
struct
wl_display
*
wl_display
,
uint32_t
id
)
{
struct
context
*
context
=
(
struct
context
*
)
data
;
...
...
@@ -95,30 +97,31 @@ void event_wl_display_delete_id(
(
void
)
wl_display
;
}
void
request_wl_display_get_registry
(
struct
wl_client
*
client
,
static
void
request_wl_display_get_registry
(
struct
wl_client
*
client
,
struct
wl_resource
*
resource
,
uint32_t
registry
)
{
struct
context
*
context
=
(
struct
context
*
)
client
;
wp_log
(
WP_DEBUG
,
"Getting registry: %lx %lx %d
\n
"
,
(
uint64_t
)
client
,
(
uint64_t
)
resource
,
registry
);
(
void
)
context
;
(
void
)
resource
;
(
void
)
registry
;
}
void
event_wl_registry_global
(
void
*
data
,
struct
wl_registry
*
wl_registry
,
uint32_t
name
,
const
char
*
interface
,
uint32_t
version
)
static
void
event_wl_registry_global
(
void
*
data
,
struct
wl_registry
*
wl_registry
,
uint32_t
name
,
const
char
*
interface
,
uint32_t
version
)
{
struct
context
*
context
=
(
struct
context
*
)
data
;
if
(
!
strcmp
(
interface
,
"wl_drm"
))
{
wp_log
(
WP_DEBUG
,
"Hiding wl_drm advertisement: %lx
\n
"
,
(
uint64_t
)
context
);
wp_log
(
WP_DEBUG
,
"Hiding wl_drm advertisement
\n
"
);
context
->
drop_this_msg
=
true
;
}
if
(
!
strcmp
(
interface
,
"zwp_linux_dmabuf_v1"
))
{
wp_log
(
WP_DEBUG
,
"Hiding zwp_linux_dmabuf_v1 advertisement
\n
"
);
context
->
drop_this_msg
=
true
;
}
if
(
!
strcmp
(
interface
,
"zwlr_export_dmabuf_manager_v1"
))
{
wp_log
(
WP_DEBUG
,
"Hiding zwp_linux_dmabuf_v1 advertisement: %lx
\n
"
,
(
uint64_t
)
context
);
"Hiding zwlr_export_dmabuf_manager_v1 advertisement
\n
"
);
context
->
drop_this_msg
=
true
;
}
...
...
@@ -126,7 +129,7 @@ void event_wl_registry_global(void *data, struct wl_registry *wl_registry,
(
void
)
name
;
(
void
)
version
;
}
void
event_wl_registry_global_remove
(
static
void
event_wl_registry_global_remove
(
void
*
data
,
struct
wl_registry
*
wl_registry
,
uint32_t
name
)
{
struct
context
*
context
=
(
struct
context
*
)
data
;
...
...
@@ -134,30 +137,115 @@ void event_wl_registry_global_remove(
(
void
)
wl_registry
;
(
void
)
name
;
}
static
const
struct
msg_handler
handlers
[];
void
request_wl_registry_bind
(
struct
wl_client
*
client
,
struct
wl_resource
*
resource
,
uint32_t
name
,
const
char
*
interface
,
uint32_t
version
,
uint32_t
id
)
{
struct
context
*
context
=
(
struct
context
*
)
client
;
(
void
)
resource
;
/* Special case handling. This creates a new object matching
* (name,interface,version) with id id */
for
(
int
i
=
0
;
handlers
[
i
].
interface
;
i
++
)
{
if
(
!
strcmp
(
interface
,
handlers
[
i
].
interface
->
name
))
{
struct
wp_object
*
new_obj
=
calloc
(
1
,
sizeof
(
struct
wp_object
));
new_obj
->
obj_id
=
(
int
)
id
;
new_obj
->
type
=
handlers
[
i
].
interface
;
listset_insert
(
&
context
->
mt
->
objects
,
new_obj
);
return
;
}
}
wp_log
(
WP_DEBUG
,
"Binding fail name=%d %s id=%d (v%d)
\n
"
,
name
,
interface
,
id
,
version
);
(
void
)
name
;
(
void
)
interface
;
(
void
)
version
;
(
void
)
id
;
}
static
void
event_wl_buffer_release
(
void
*
data
,
struct
wl_buffer
*
wl_buffer
)
{
struct
context
*
context
=
(
struct
context
*
)
data
;
(
void
)
context
;
(
void
)
wl_buffer
;
}
static
void
request_wl_buffer_destroy
(
struct
wl_client
*
client
,
struct
wl_resource
*
resource
)
{
struct
context
*
context
=
(
struct
context
*
)
client
;
// User requests surface destruction
(
void
)
context
;
(
void
)
resource
;
(
void
)
client
;
}
static
void
request_wl_surface_destroy
(
struct
wl_client
*
client
,
struct
wl_resource
*
resource
)
{
struct
context
*
context
=
(
struct
context
*
)
client
;
// User requests surface destruction
(
void
)
context
;
(
void
)
resource
;
}
static
void
request_wl_surface_damage
(
struct
wl_client
*
client
,
struct
wl_resource
*
resource
,
int32_t
x
,
int32_t
y
,
int32_t
width
,
int32_t
height
)
{
struct
context
*
context
=
(
struct
context
*
)
client
;
// A rectangle of the buffer was damaged, hence backing buffers
// may be updated.
(
void
)
context
;
(
void
)
resource
;
(
void
)
x
;
(
void
)
y
;
(
void
)
width
;
(
void
)
height
;
}
static
void
event_wl_keyboard_keymap
(
void
*
data
,
struct
wl_keyboard
*
wl_keyboard
,
uint32_t
format
,
int32_t
fd
,
uint32_t
size
)
{
struct
context
*
context
=
(
struct
context
*
)
data
;
(
void
)
wl_keyboard
;
// Exception to the default lack of changes.
// (Technically a no-op, since the fd should always be new/dirty;
// but what happens if the file is recycled?)
context
->
can_buffer_changes_result
=
true
;
(
void
)
format
;
(
void
)
fd
;
(
void
)
size
;
}
static
const
struct
wl_display_listener
wl_display_event_handler
=
{
event_wl_display_error
,
event_wl_display_delete_id
};
.
error
=
event_wl_display_error
,
.
delete_id
=
event_wl_display_delete_id
};
// Note that the 'sync' request is entirely unrelated to our task, and our
// implementation of it would do nothing
static
const
struct
wl_display_interface
wl_display_request_handler
=
{
NULL
,
request_wl_display_get_registry
};
.
get_registry
=
request_wl_display_get_registry
// .sync initialized to NULL, due to static storage duration
};
static
const
struct
wl_registry_listener
wl_registry_event_handler
=
{
event_wl_registry_global
,
event_wl_registry_global_remove
};
.
global
=
event_wl_registry_global
,
.
global_remove
=
event_wl_registry_global_remove
};
static
const
struct
wl_registry_interface
wl_registry_request_handler
=
{
request_wl_registry_bind
};
.
bind
=
request_wl_registry_bind
};
static
const
struct
wl_buffer_listener
wl_buffer_event_handler
=
{
.
release
=
event_wl_buffer_release
};
static
const
struct
wl_buffer_interface
wl_buffer_request_handler
=
{
.
destroy
=
request_wl_buffer_destroy
};
static
const
struct
wl_surface_listener
wl_surface_event_handler
=
{
.
enter
=
NULL
,
.
leave
=
NULL
};
static
const
struct
wl_surface_interface
wl_surface_request_handler
=
{
.
destroy
=
request_wl_surface_destroy
,
.
damage
=
request_wl_surface_damage
,
};
static
const
struct
wl_keyboard_listener
wl_keyboard_event_handler
=
{
.
keymap
=
event_wl_keyboard_keymap
};
void
listset_insert
(
struct
obj_list
*
lst
,
struct
wp_object
*
obj
)
{
...
...
@@ -203,7 +291,7 @@ void listset_remove(struct obj_list *lst, struct wp_object *obj)
wp_log
(
WP_ERROR
,
"Object not in list
\n
"
);
return
;
}
struct
wp_object
*
listset_get
(
struct
obj_list
*
lst
,
int
id
)
struct
wp_object
*
listset_get
(
struct
obj_list
*
lst
,
u
int
32_t
id
)
{
for
(
int
i
=
0
;
i
<
lst
->
nobj
;
i
++
)
{
if
(
lst
->
objs
[
i
]
->
obj_id
>
id
)
{
...
...
@@ -215,15 +303,38 @@ struct wp_object *listset_get(struct obj_list *lst, int id)
return
NULL
;
}
static
const
struct
msg_handler
handlers
[]
=
{
{
&
wl_display_interface
,
&
wl_display_event_handler
,
&
wl_display_request_handler
,
FDEFFECT_NEVER
},
{
&
wl_registry_interface
,
&
wl_registry_event_handler
,
&
wl_registry_request_handler
,
FDEFFECT_NEVER
},
{
&
wl_buffer_interface
,
&
wl_buffer_event_handler
,
&
wl_buffer_request_handler
,
FDEFFECT_MAYBE
},
{
&
wl_surface_interface
,
&
wl_surface_event_handler
,
&
wl_surface_request_handler
,
FDEFFECT_MAYBE
},
// List all other known global object interface types
{
&
wl_compositor_interface
,
NULL
,
NULL
,
FDEFFECT_MAYBE
},
{
&
wl_subcompositor_interface
,
NULL
,
NULL
,
FDEFFECT_MAYBE
},
{
&
wl_data_device_manager_interface
,
NULL
,
NULL
,
FDEFFECT_MAYBE
},
{
&
wl_shm_interface
,
NULL
,
NULL
,
FDEFFECT_MAYBE
},
{
&
wl_shm_pool_interface
,
NULL
,
NULL
,
FDEFFECT_MAYBE
},
{
&
xdg_wm_base_interface
,
NULL
,
NULL
,
FDEFFECT_MAYBE
},
{
&
wp_presentation_interface
,
NULL
,
NULL
,
FDEFFECT_MAYBE
},
{
&
wl_seat_interface
,
NULL
,
NULL
,
FDEFFECT_MAYBE
},
{
&
wl_output_interface
,
NULL
,
NULL
,
FDEFFECT_MAYBE
},
// List all interfaces with additional guidance
{
&
wl_pointer_interface
,
NULL
,
NULL
,
FDEFFECT_NEVER
},
{
&
wl_keyboard_interface
,
&
wl_keyboard_event_handler
,
NULL
,
FDEFFECT_NEVER
},
{
&
wl_touch_interface
,
NULL
,
NULL
,
FDEFFECT_NEVER
},
{
NULL
,
NULL
,
NULL
,
FDEFFECT_MAYBE
}};
void
init_message_tracker
(
struct
message_tracker
*
mt
)
{
memset
(
mt
,
0
,
sizeof
(
*
mt
));
mt
->
handlers
[
0
].
interface
=
&
wl_display_interface
;
mt
->
handlers
[
0
].
event_handlers
=
&
wl_display_event_handler
;
mt
->
handlers
[
0
].
request_handlers
=
&
wl_display_request_handler
;
mt
->
handlers
[
1
].
interface
=
&
wl_registry_interface
;
mt
->
handlers
[
1
].
event_handlers
=
&
wl_registry_event_handler
;
mt
->
handlers
[
1
].
request_handlers
=
&
wl_registry_request_handler
;
struct
wp_object
*
display_obj
=
calloc
(
1
,
sizeof
(
struct
wp_object
));
display_obj
->
obj_id
=
1
;
...
...
@@ -238,15 +349,12 @@ void cleanup_message_tracker(struct message_tracker *mt)
free
(
mt
->
objects
.
objs
);
}
struct
msg_handler
*
get_handler_for_interface
(
struct
message_tracker
*
mt
,
const
struct
wl_interface
*
intf
)
const
struct
msg_handler
*
get_handler_for_interface
(
const
struct
wl_interface
*
intf
)
{
for
(
int
i
=
0
;
i
<
50
;
i
++
)
{
if
(
mt
->
handlers
[
i
].
interface
==
intf
)
{
return
&
mt
->
handlers
[
i
];
}
if
(
!
mt
->
handlers
[
i
].
interface
)
{
return
NULL
;
for
(
int
i
=
0
;
handlers
[
i
].
interface
;
i
++
)
{
if
(
handlers
[
i
].
interface
==
intf
)
{
return
&
handlers
[
i
];
}
}
return
NULL
;
...
...
@@ -255,12 +363,19 @@ struct msg_handler *get_handler_for_interface(
struct
uarg
{
union
{
uint32_t
ui
;
char
*
str
;
int32_t
si
;
const
char
*
str
;
struct
wp_object
*
obj
;
wl_fixed_t
fxd
;
// from wayland-util.h
struct
{
struct
wl_array
*
arrptr
;
struct
wl_array
arr
;
// from wayland-util.h
};
};
};
void
invoke_msg_handler
(
const
struct
wl_message
*
msg
,
const
uint32_t
*
payload
,
static
void
invoke_msg_handler
(
const
struct
wl_message
*
msg
,
const
uint32_t
*
const
payload
,
const
int
paylen
,
void
(
*
const
func
)(
void
),
struct
context
*
ctx
,
struct
message_tracker
*
mt
)
{
...
...
@@ -280,54 +395,152 @@ void invoke_msg_handler(const struct wl_message *msg, const uint32_t *payload,
call_args_ptr
[
1
]
=
&
nullptr
;
int
nargs
=
2
;
int
k
=
0
;
int
i
=
0
;
// index in message
int
k
=
0
;
// current argument index
const
char
*
c
=
msg
->
signature
;
// current argument value
// TODO: compensate for version strings
for
(
const
char
*
c
=
msg
->
signature
;
*
c
;
c
++
,
k
++
)
{
// Skip over version data?
while
(
*
c
>=
'0'
&&
*
c
<=
'9'
)
{
for
(;
*
c
;
c
++
,
k
++
)
{
// TODO: truncation safety check, because applications need not
// be protocol-compliant
// Skip over version specifications, and over null object
// permission flags
while
((
*
c
>=
'0'
&&
*
c
<=
'9'
)
||
*
c
==
'?'
)
{
c
++
;
}
if
(
!*
c
)
{
break
;
}
const
struct
wl_interface
*
type
=
msg
->
types
[
k
];
switch
(
*
c
)
{
case
'n'
:
{
// Point directly into source buffer, if
// we can.
uint32_t
v
=
*
payload
++
;
case
'a'
:
{
if
(
i
>=
paylen
)
{
goto
len_overflow
;
}
uint32_t
len
=
payload
[
i
++
];
if
(
i
+
((
int
)
len
+
3
)
/
4
-
1
>=
paylen
)
{
goto
len_overflow
;
}
struct
wp_object
*
new_obj
=
calloc
(
1
,
sizeof
(
struct
wp_object
));
new_obj
->
obj_id
=
v
;
new_obj
->
type
=
type
;
listset_insert
(
&
mt
->
objects
,
new_obj
);
// pass in pointer
call_args_val
[
nargs
].
arr
.
data
=
(
void
*
)
&
payload
[
i
];
call_args_val
[
nargs
].
arr
.
size
=
len
;
// fixed allocation. waypipe won't reallocate anyway
call_args_val
[
nargs
].
arr
.
alloc
=
(
size_t
)
-
1
;
call_args_ptr
[
nargs
]
=
&
call_args_val
[
nargs
].
arr
;
call_types
[
nargs
]
=
&
ffi_type_pointer
;
call_args_val
[
nargs
].
obj
=
new_obj
;
i
+=
((
len
+
3
)
/
4
);
}
break
;
case
'h'
:
{
// Consume an fd; TODO
call_args_val
[
nargs
].
si
=
9999
;
call_args_ptr
[
nargs
]
=
&
call_args_val
[
nargs
].
si
;
call_types
[
nargs
]
=
&
ffi_type_sint32
;
// see typedef
nargs
++
;
}
break
;
case
'f'
:
{
if
(
i
>=
paylen
)
{
goto
len_overflow
;
}
wl_fixed_t
v
=
*
((
const
wl_fixed_t
*
)
&
payload
[
i
++
]);
call_args_val
[
nargs
].
fxd
=
v
;
call_args_ptr
[
nargs
]
=
&
call_args_val
[
nargs
].
fxd
;
call_types
[
nargs
]
=
&
ffi_type_sint32
;
// see typedef
nargs
++
;
}
break
;
case
'i'
:
{
if
(
i
>=
paylen
)
{
goto
len_overflow
;
}
int32_t
v
=
(
int32_t
)
payload
[
i
++
];
call_args_val
[
nargs
].
si
=
v
;
call_args_ptr
[
nargs
]
=
&
call_args_val
[
nargs
].
si
;
call_types
[
nargs
]
=
&
ffi_type_sint32
;
nargs
++
;
}
break
;
case
'o'
:
{
if
(
i
>=
paylen
)
{
goto
len_overflow
;
}
uint32_t
id
=
payload
[
i
++
];
struct
wp_object
*
lo
=
listset_get
(
&
mt
->
objects
,
id
);
// May always be null, in case client messes up
call_args_val
[
nargs
].
obj
=
lo
;
call_args_ptr
[
nargs
]
=
&
call_args_val
[
nargs
].
obj
;
call_types
[
nargs
]
=
&
ffi_type_pointer
;
nargs
++
;
}
break
;
case
'u'
:
{
uint32_t
v
=
*
payload
++
;
call_args_val
[
nargs
].
ui
=
v
;
call_args_ptr
[
nargs
]
=
&
call_args_val
[
nargs
].
ui
;
call_types
[
nargs
]
=
&
ffi_type_uint32
;
nargs
++
;
case
'n'
:
{
if
(
i
>=
paylen
)
{
goto
len_overflow
;
}
uint32_t
v
=
payload
[
i
++
];
if
(
type
)
{
struct
wp_object
*
new_obj
=
calloc
(
1
,
sizeof
(
struct
wp_object
));
new_obj
->
obj_id
=
v
;
new_obj
->
type
=
type
;
listset_insert
(
&
mt
->
objects
,
new_obj
);
call_args_val
[
nargs
].
obj
=
new_obj
;
call_args_ptr
[
nargs
]
=
&
call_args_val
[
nargs
].
obj
;
call_types
[
nargs
]
=
&
ffi_type_pointer
;
nargs
++
;
}
else
{
/* I.e, for wl_registry.bind, an object with
* NULL type is passed in as its object id */
call_args_val
[
nargs
].
ui
=
v
;
call_args_ptr
[
nargs
]
=
&
call_args_val
[
nargs
].
ui
;
call_types
[
nargs
]
=
&
ffi_type_uint32
;
nargs
++
;
}
}
break
;
case
's'
:
{
uint32_t
len
=
*
payload
++
;
char
*
str
=
(
char
*
)
payload
;
if
(
i
>=
paylen
)
{
goto
len_overflow
;
}
uint32_t
len
=
payload
[
i
++
];
if
(
i
+
((
int
)
len
+
3
)
/
4
-
1
>=
paylen
)
{
goto
len_overflow
;
}
const
char
*
str
=
(
const
char
*
)
&
payload
[
i
];
call_args_val
[
nargs
].
str
=
str
;
call_args_ptr
[
nargs
]
=
&
call_args_val
[
nargs
].
str
;
call_types
[
nargs
]
=
&
ffi_type_pointer
;
nargs
++
;
payload
+=
(
len
/
4
);
i
+=
(
(
len
+
3
)
/
4
);
}
break
;
case
'u'
:
{
if
(
i
>=
paylen
)
{
goto
len_overflow
;
}
uint32_t
v
=
payload
[
i
++
];
call_args_val
[
nargs
].
ui
=
v
;
call_args_ptr
[
nargs
]
=
&
call_args_val
[
nargs
].
ui
;
call_types
[
nargs
]
=
&
ffi_type_uint32
;
nargs
++
;
}
break
;
default:
wp_log
(
WP_
ERROR
,
"Unidentified message type %c
\n
"
,
*
c
);
wp_log
(
WP_
DEBUG
,
"Unidentified message type %c
,
\n
"
,
*
c
);
break
;
}
continue
;
len_overflow:
wp_log
(
WP_ERROR
,
"Message parse length overflow, i=%d, len=%d, c=%c
\n
"
,
i
,
paylen
,
*
c
);
return
;
}
if
(
i
!=
paylen
)
{
wp_log
(
WP_ERROR
,
"Parse error length mismatch for %s: used %d expected %d
\n
"
,
msg
->
name
,
i
*
4
,
paylen
*
4
);
}
if
(
func
)
{
...
...
@@ -340,17 +553,18 @@ void invoke_msg_handler(const struct wl_message *msg, const uint32_t *payload,
bool
handle_message
(
struct
message_tracker
*
mt
,
bool
from_client
,
void
*
data
,
int
data_len
,
int
*
consumed_length
,
int
*
fds
,
int
fds_len
,
int
*
n_consumed_fds
)
int
*
n_consumed_fds
,
bool
*
buffer_changes
)
{
const
uint32_t
*
const
header
=
(
uint32_t
*
)
data
;
int
obj
=
(
int
)
header
[
0
];
u
int
32_t
obj
=
header
[
0
];
int
meth
=
(
int
)((
header
[
1
]
<<
16
)
>>
16
);
int
len
=
(
int
)(
header
[
1
]
>>
16
);
*
consumed_length
=
len
;
if
(
len
>
data_len
)
{
wp_log
(
WP_ERROR
,
"Message length overflow: %d claimed vs %d available"
,
"Message length overflow: %d claimed vs %d available
. Keeping message, uninterpreted
"
,
len
,
data_len
);
return
false
;
}
// display: object = 0?
...
...
@@ -378,8 +592,8 @@ bool handle_message(struct message_tracker *mt, bool from_client, void *data,
}
}
if
(
msg
)
{
struct
msg_handler
*
handler
=
get_handler_for_interface
(
mt
,
objh
->
type
);
const
struct
msg_handler
*
handler
=
get_handler_for_interface
(
objh
->
type
);
void
(
*
fn
)(
void
)
=
NULL
;
if
(
handler
)
{
if
(
from_client
&&
handler
->
request_handlers
)
{
...
...
@@ -398,13 +612,30 @@ bool handle_message(struct message_tracker *mt, bool from_client, void *data,
ctx
.
mt
=
mt
;
ctx
.
obj
=
objh
;
ctx
.
drop_this_msg
=
false
;
ctx
.
can_buffer_changes_result
=
true
;
if
(
handler
&&
handler
->
effect
==
FDEFFECT_NEVER
)
{
// Change the default value; handler function
// may yet override
ctx
.
can_buffer_changes_result
=
false
;
}
const
uint32_t
*
payload
=
header
+
2
;
invoke_msg_handler
(
msg
,
payload
,
fn
,
&
ctx
,
mt
);
invoke_msg_handler
(
msg
,
payload
,
len
/
4
-
2
,
fn
,
&
ctx
,
mt
);
// Flag set by the protocol handler function
if
(
ctx
.
drop_this_msg
)
{
return
false
;
// DROP
}
*
buffer_changes
=
ctx
.
can_buffer_changes_result
;
}
else
{
wp_log
(
WP_DEBUG
,
"Unidentified %s from known object
\n
"
,
from_client
?
"request"
:
"event"
);
*
buffer_changes
=
true
;
}
}
else
{
wp_log
(
WP_DEBUG
,
"Unidentified object %d with %s
\n
"
,
obj
,
from_client
?
"request"
:
"event"
);
*
buffer_changes
=
true
;
}
(
void
)
fds
;
(
void
)
fds_len
;
...
...
server.c
View file @
e631a334
...
...
@@ -49,6 +49,8 @@ static int run_server_child(int chanfd, int appfd)
char
*
buffer
=
calloc
(
1
,
maxmsg
+
1
);
struct
fd_translation_map
fdtransmap
=
{
.
local_sign
=
-
1
,
.
list
=
NULL
,
.
max_local_id
=
1
};
struct
message_tracker
mtracker
;
init_message_tracker
(
&
mtracker
);
struct
pollfd
*
pfds
=
NULL
;
while
(
!
shutdown_flag
)
{
int
npoll
=
2
+
count_npipes
(
&
fdtransmap
);
...
...
@@ -113,6 +115,12 @@ static int run_server_child(int chanfd, int appfd)
memset
(
fds
,
0
,
sizeof
(
fds
));
untranslate_ids
(
&
fdtransmap
,
nids
,
ids
,
fds
);
if
(
waymsg
)
{
parse_and_prune_messages
(
&
mtracker
,
&
fdtransmap
,
false
,
waymsg
,
&
waylen
,
fds
,
&
nids
);
}
if
(
waymsg
)
{
ssize_t
wc
=
iovec_write
(
appfd
,
waymsg
,
waylen
,
fds
,
nids
);
...
...
@@ -146,6 +154,13 @@ static int run_server_child(int chanfd, int appfd)
rc
,
strerror
(
errno
));
break
;
}
if
(
rc
>
0
)
{
int
nrc
=
(
int
)
rc
;
parse_and_prune_messages
(
&
mtracker
,
&
fdtransmap
,
true
,
buffer
,
&
nrc
,
fdbuf
,
&
nfds
);
rc
=
nrc
;
}
if
(
rc
>
0
)
{
wp_log
(
WP_DEBUG
,
"appfd: read %ld byte waymsg, %d fds
\n
"
,
...
...
@@ -188,6 +203,7 @@ static int run_server_child(int chanfd, int appfd)
free
(
pfds
);
cleanup_translation_map
(
&
fdtransmap
);
cleanup_message_tracker
(
&
mtracker
);
close
(
chanfd
);
close
(
appfd
);
free
(
buffer
);
...
...
util.c
View file @
e631a334
...
...
@@ -253,6 +253,8 @@ static int translate_fd(struct fd_translation_map *map, int fd)
shadow
->
file_size
=
(
size_t
)
-
1
;
shadow
->
remote_id
=
(
map
->
max_local_id
++
)
*
map
->
local_sign
;
shadow
->
type
=
FDC_UNKNOWN
;
// File changes must be propagated
shadow
->
is_dirty
=
true
;
wp_log
(
WP_DEBUG
,
"Creating new shadow buffer for local fd %d
\n
"
,
fd
);
...
...
@@ -285,8 +287,8 @@ static int translate_fd(struct fd_translation_map *map, int fd)
* connection of the terminal which was acquired with
* forkpty; it probably links to a character device */
wp_log
(
WP_ERROR
,
"The fd %d is neither a pipe nor a regular file. Proceeding under the assumption that it is pipe-like.
\n
"
,
fd
);
"The fd %d
, size %ld, mode %x
is neither a pipe nor a regular file. Proceeding under the assumption that it is pipe-like.
\n
"
,
fd
,
fsdata
.
st_size
,
fsdata
.
st_mode
);
}
int
flags
=
fcntl
(
fd
,
F_GETFL
,
0
);
if
(
flags
==
-
1
)
{
...
...
@@ -428,6 +430,13 @@ void collect_updates(struct fd_translation_map *map, int *ntransfers,
{
for
(
struct
shadow_fd
*
cur
=
map
->
list
;
cur
;
cur
=
cur
->
next
)
{
if
(
cur
->
type
==
FDC_FILE
)
{
if
(
!
cur
->
is_dirty
)
{
// File is clean, we have no reason to believe