Annotation of embedaddon/mtr/packet/command_unix.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:     mtr  --  a network diagnostic tool
                      3:     Copyright (C) 2016  Matt Kimball
                      4: 
                      5:     This program is free software; you can redistribute it and/or modify
                      6:     it under the terms of the GNU General Public License version 2 as
                      7:     published by the Free Software Foundation.
                      8: 
                      9:     This program is distributed in the hope that it will be useful,
                     10:     but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12:     GNU General Public License for more details.
                     13: 
                     14:     You should have received a copy of the GNU General Public License
                     15:     along with this program; if not, write to the Free Software
                     16:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17: */
                     18: 
                     19: #include "command.h"
                     20: 
                     21: #include <errno.h>
                     22: #include <fcntl.h>
                     23: #include <string.h>
                     24: #include <stdio.h>
                     25: #include <stdlib.h>
                     26: #include <unistd.h>
                     27: 
                     28: /*
                     29:     Initialize the command buffer and put the command stream in
                     30:     non-blocking mode.
                     31: */
                     32: void init_command_buffer(
                     33:     struct command_buffer_t *command_buffer,
                     34:     int command_stream)
                     35: {
                     36:     int flags;
                     37: 
                     38:     memset(command_buffer, 0, sizeof(struct command_buffer_t));
                     39:     command_buffer->command_stream = command_stream;
                     40: 
                     41:     /*  Get the current command stream flags  */
                     42:     flags = fcntl(command_stream, F_GETFL, 0);
                     43:     if (flags == -1) {
                     44:         perror("Unexpected command stream error");
                     45:         exit(EXIT_FAILURE);
                     46:     }
                     47: 
                     48:     /*  Set the O_NONBLOCK bit  */
                     49:     if (fcntl(command_stream, F_SETFL, flags | O_NONBLOCK)) {
                     50:         perror("Unexpected command stream error");
                     51:         exit(EXIT_FAILURE);
                     52:     }
                     53: }
                     54: 
                     55: /*  Read currently available data from the command stream  */
                     56: int read_commands(
                     57:     struct command_buffer_t *buffer)
                     58: {
                     59:     int space_remaining =
                     60:         COMMAND_BUFFER_SIZE - buffer->incoming_read_position - 1;
                     61:     char *read_position =
                     62:         &buffer->incoming_buffer[buffer->incoming_read_position];
                     63:     int read_count;
                     64:     int command_stream = buffer->command_stream;
                     65: 
                     66:     read_count = read(command_stream, read_position, space_remaining);
                     67: 
                     68:     /*  If the command stream has been closed, read will return zero.  */
                     69:     if (read_count == 0) {
                     70:         errno = EPIPE;
                     71:         return -1;
                     72:     }
                     73: 
                     74:     if (read_count > 0) {
                     75:         /*  Account for the newly read data  */
                     76:         buffer->incoming_read_position += read_count;
                     77:     }
                     78: 
                     79:     if (read_count < 0) {
                     80:         /*  EAGAIN simply means there is no available data to read  */
                     81:         /*  EINTR indicates we received a signal during read  */
                     82:         if (errno != EINTR && errno != EAGAIN) {
                     83:             perror("Unexpected command buffer read error");
                     84:             exit(EXIT_FAILURE);
                     85:         }
                     86:     }
                     87: 
                     88:     return 0;
                     89: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>