@@ -292,66 +292,98 @@ static int do_debug_cmd(const std::string &value) {
292292 }
293293}
294294
295- struct ReadError : std::exception {};
296- struct WriteError : std::exception {};
295+ static bool send_result (int fd, int result) {
296+ ssize_t res = send (fd, &result, sizeof (int ), 0 );
297+ return res == sizeof (int );
298+ }
297299
298- static int read_number (int fd) {
299- int r = 0 , neg = 1 ;
300- char ch;
300+ static bool recv_result (int fd, int *result) {
301+ ssize_t res = recv (fd, result, sizeof (int ), 0 );
302+ return res == sizeof (int );
303+ }
301304
302- while (1 ) {
303- int res = read (fd, &ch, 1 );
304- if (res != 1 )
305- return -1 ;
306- if (ch == ' -' )
307- neg = -1 ;
308- else if (ch == ' ' )
309- return r * neg;
310- else
311- r = 10 * r + ch - ' 0' ;
312- }
313- }
314-
315- static std::string read_string (int fd) {
316- int len = read_number (fd);
317- if (len < 0 )
318- throw ReadError ();
319- if (!len)
320- return std::string ();
321- std::string str (len, 0 );
322- if (read (fd, str.data (), len) != len)
323- throw ReadError ();
324- return str;
325- }
326-
327- static std::vector<std::string> read_strings (int fd) {
328- std::vector<std::string> result;
329- int count = read_number (fd);
330- if (count < 0 )
331- return result;
332- for (int i = 0 ; i < count; i++) {
333- result.push_back (read_string (fd));
334- }
335- return result;
305+ static void set_uint16 (std::vector<char > &buf, uint16_t value, size_t idx) {
306+ buf[idx] = 0xff & (value >> 0 );
307+ buf[idx + 1 ] = 0xff & (value >> 8 );
336308}
337309
338- static void write_number (std::string &buf, int num ) {
339- buf = buf + fmt::format ( " {} " , num );
310+ static uint16_t get_uint16 (std::vector< char > &buf, size_t idx ) {
311+ return (( uint16_t ) buf[idx] << 0 ) | (( uint16_t ) buf[idx + 1 ] << 8 );
340312}
341313
342- static void write_string (std::string &buf, const std::string &s) {
343- write_number (buf, s.size ());
344- buf += s;
314+ static bool recv_args (int fd, std::vector<std::string> &args) {
315+ // Get size
316+ uint16_t tmp;
317+ ssize_t res = recv (fd, &tmp, sizeof (uint16_t ), 0 );
318+ if (res != sizeof (uint16_t )) {
319+ return false ;
320+ }
321+ size_t buff_size = tmp;
322+
323+ // Get data
324+ std::vector<char > buf (buff_size);
325+ res = recv (fd, buf.data (), buff_size, 0 );
326+ if (res != (ssize_t )buff_size) {
327+ return false ;
328+ }
329+
330+ // Deserialize
331+ size_t idx = 0 ;
332+ size_t n_args = get_uint16 (buf, idx);
333+ idx += sizeof (uint16_t );
334+ for (size_t i = 0 ; i < n_args; i++) {
335+ size_t arg_size = get_uint16 (buf, idx);
336+ idx += sizeof (uint16_t );
337+ args.push_back (std::string (buf.begin () + idx, buf.begin () + idx + arg_size));
338+ idx += arg_size;
339+ }
340+ if (idx + sizeof (uint16_t ) != buff_size) {
341+ rtapi_print_msg (RTAPI_MSG_ERR, " rtapi_app: Bug recv_args: idx %li != buff_size %li\n " , idx, buff_size);
342+ return false ;
343+ }
344+
345+ return true ;
345346}
346347
347- static void write_strings (int fd, const std::vector<std::string> &strings) {
348- std::string buf;
349- write_number (buf, strings.size ());
350- for (unsigned int i = 0 ; i < strings.size (); i++) {
351- write_string (buf, strings[i]);
348+ static bool send_args (int fd, const std::vector<std::string> &args) {
349+ // Calculate size
350+ size_t buff_size = 0 ;
351+ buff_size += 2 * sizeof (uint16_t );
352+ for (size_t i = 0 ; i < args.size (); i++) {
353+ buff_size += sizeof (uint16_t );
354+ buff_size += args[i].size ();
352355 }
353- if (write (fd, buf.data (), buf.size ()) != (ssize_t )buf.size ())
354- throw WriteError ();
356+
357+ // This is the largest value set by set_int16()
358+ if (buff_size > std::numeric_limits<uint16_t >::max ()) {
359+ rtapi_print_msg (RTAPI_MSG_ERR, " rtapi_app: Bug send_args: args to big, size = %li!\n " , buff_size);
360+ return false ;
361+ }
362+
363+ // Serialize
364+ std::vector<char > buf (buff_size);
365+ size_t idx = 0 ;
366+ set_uint16 (buf, buff_size, idx);
367+ idx += sizeof (uint16_t );
368+ set_uint16 (buf, args.size (), idx);
369+ idx += sizeof (uint16_t );
370+ for (size_t i = 0 ; i < args.size (); i++) {
371+ set_uint16 (buf, args[i].size (), idx);
372+ idx += sizeof (uint16_t );
373+ buf.insert (buf.begin () + idx, args[i].begin (), args[i].end ());
374+ idx += args[i].size ();
375+ }
376+ if (idx != buff_size) {
377+ rtapi_print_msg (RTAPI_MSG_ERR, " rtapi_app: Bug send_args: idx %li != buff_size %li\n " , idx, buff_size);
378+ return false ;
379+ }
380+
381+ // Send
382+ ssize_t res = send (fd, buf.data (), buf.size (), 0 );
383+ if (res != (ssize_t )buf.size ()) {
384+ return false ;
385+ }
386+ return true ;
355387}
356388
357389static int handle_command (std::vector<std::string> args) {
@@ -380,14 +412,18 @@ static int handle_command(std::vector<std::string> args) {
380412}
381413
382414static int slave (int fd, const std::vector<std::string> &args) {
383- try {
384- write_strings (fd, args);
385- } catch (WriteError &e) {
415+ if (!send_args (fd, args)) {
386416 rtapi_print_msg (RTAPI_MSG_ERR, " rtapi_app: failed to write to master: %s\n " , strerror (errno));
417+ return -1 ;
387418 }
388419
389- int result = read_number (fd);
390- return result;
420+ int result = -1 ;
421+ if (!recv_result (fd, &result)) {
422+ rtapi_print_msg (RTAPI_MSG_ERR, " rtapi_app: failed to read from master: %s\n " , strerror (errno));
423+ return -1 ;
424+ } else {
425+ return result;
426+ }
391427}
392428
393429static int callback (int fd) {
@@ -400,18 +436,18 @@ static int callback(int fd) {
400436 return -1 ;
401437 } else {
402438 int result;
403- try {
404- result = handle_command (read_strings (fd1));
405- } catch (ReadError &e) {
439+ std::vector<std::string> args;
440+ if (!recv_args (fd1, args)) {
406441 rtapi_print_msg (RTAPI_MSG_ERR, " rtapi_app: failed to read from slave: %s\n " , strerror (errno));
407442 close (fd1);
408443 return -1 ;
409444 }
410- std::string buf;
411- write_number (buf, result);
412- if (write (fd1, buf.data (), buf.size ()) != (ssize_t )buf.size ()) {
445+
446+ result = handle_command (args);
447+
448+ if (!send_result (fd1, result)) {
413449 rtapi_print_msg (RTAPI_MSG_ERR, " rtapi_app: failed to write to slave: %s\n " , strerror (errno));
414- };
450+ }
415451 close (fd1);
416452 }
417453 return !force_exit && instance_count > 0 ;
0 commit comments