[PATCH rtems-libbsd] ipsec-tools: Fix copying fd_set prior to select
Chris Johns
chrisj at rtems.org
Tue May 23 06:53:24 UTC 2023
On 23/5/2023 4:25 pm, Christian MAUDERER wrote:
> Hello Chris,
>
> On 2023-05-23 03:36, Chris Johns wrote:
>> Hi,
>>
>> I have been resolving this by adding:
>>
>> #define preset_mask *preset_mask_prealloc
>> #define active_mask *active_mask_prealloc
>>
>> as the assignment logic works as is. It does not catch FD_ZERO which is a shame
>> but is helps avoid us adding a special case.
>
> Thanks for the suggestion. I used that solution already in the file during the
> initial port. But it doesn't work in this case (and maybe we should check other
> cases in libbsd too). It only copies the first element of the array of fd_sets.
>
> The variables / defines are (in the patched version - see [1]):
>
> static fd_set *allocated_preset_mask, *allocated_active_mask;
> static struct fd_monitor *allocated_fd_monitors;
> #define preset_mask (*allocated_preset_mask)
> #define active_mask (*allocated_active_mask)
> #define fd_monitors (allocated_fd_monitors)
>
> They are allocated as follows (see [2]):
>
> allocated_preset_mask = calloc(sizeof(fd_set),
> howmany(rtems_libio_number_iops, sizeof(fd_set) * 8));
> allocated_active_mask = calloc(sizeof(fd_set),
> howmany(rtems_libio_number_iops, sizeof(fd_set) * 8));
> allocated_fd_monitors = calloc(
> rtems_libio_number_iops, sizeof(struct fd_monitor));
>
> So basically it's a bunch of arrays of fd_sets. If I now use the following
> (unpatched) assignment:
>
> active_mask = preset_mask;
>
> After the preprocessor the line will be
>
> (*allocated_active_mask) = (*allocated_preset_mask);
>
> Which copies only the first element. That's why I had to add the memcpy. Did I
> miss some better solution?
I am using this in ntpd which I checked yesterday:
#ifdef __rtems__
#include <rtems/libio_.h>
static size_t rtems_ntpd_fds_size;
static int rtems_fd_set_alloc(fd_set **setp) {
if (*setp == NULL) {
rtems_ntpd_fds_size = sizeof(fd_set) *
(howmany(rtems_libio_number_iops, sizeof(fd_set) * 8));
*setp = malloc(rtems_ntpd_fds_size);
if (*setp == NULL) {
errno = ENOMEM;
return -1;
}
memset(*setp, 0, rtems_ntpd_fds_size);
}
return 0;
}
#define activefds (*activefds_prealloc)
static fd_set *activefds_prealloc;
#define rtems_activefds_alloc() rtems_fd_set_alloc(&activefds_prealloc)
#else /* __rtems__ */
static fd_set activefds;
#endif /* __rtems__ */
and:
#if __rtems__
#define rdfdes (*rdfdes_prealloc)
static fd_set *rdfdes_prealloc;
#else /* __rtems__ */
fd_set rdfdes;
#endif /* __rtems__ */
int nfound;
#if __rtems__
if (rtems_fd_set_alloc(&rdfdes_prealloc) < 0) {
return;
}
memset(rdfdes_prealloc, 0, rtems_ntpd_fds_size);
#else /* __rtems__ */
FD_ZERO(&set);
#endif /* __rtems__ */
with:
++handler_calls;
rdfdes = activefds;
Stepping:
Thread 9 hit Breakpoint 1, _ntp_io_handler () at
../../bsd/freebsd/contrib/ntp/ntpd/ntp_io.c:3727
3727 rdfdes = activefds;
(gdb) x /8bx activefds_prealloc
0x1083e650: 0x20 0x44 0x05 0x20 0x00 0x40 0x00 0x00
(gdb) x /8bx rdfdes_prealloc
0x108353a0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
(gdb) n
3736 t1.tv_usec = 0;
(gdb) x /8bx rdfdes_prealloc
0x108353a0: 0x20 0x44 0x05 0x20 0x00 0x40 0x00 0x00
Looks ok to me.
Chris
More information about the devel
mailing list