LCOV - code coverage report
Current view: top level - strace_git - mmsghdr.c (source / functions) Hit Total Coverage
Test: strace-4.16.0.69.f1ea-dirty Code Coverage Lines: 109 113 96.5 %
Date: 2017-03-18 00:38:52 Functions: 8 8 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 44 48 91.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2010 Andreas Schwab <schwab@linux-m68k.org>
       3                 :            :  * Copyright (c) 2012-2013 Denys Vlasenko <vda.linux@googlemail.com>
       4                 :            :  * Copyright (c) 2014 Masatake YAMATO <yamato@redhat.com>
       5                 :            :  * Copyright (c) 2010-2016 Dmitry V. Levin <ldv@altlinux.org>
       6                 :            :  * All rights reserved.
       7                 :            :  *
       8                 :            :  * Redistribution and use in source and binary forms, with or without
       9                 :            :  * modification, are permitted provided that the following conditions
      10                 :            :  * are met:
      11                 :            :  * 1. Redistributions of source code must retain the above copyright
      12                 :            :  *    notice, this list of conditions and the following disclaimer.
      13                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      14                 :            :  *    notice, this list of conditions and the following disclaimer in the
      15                 :            :  *    documentation and/or other materials provided with the distribution.
      16                 :            :  * 3. The name of the author may not be used to endorse or promote products
      17                 :            :  *    derived from this software without specific prior written permission.
      18                 :            :  *
      19                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      20                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      21                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      22                 :            :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      23                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      24                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      25                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      26                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      27                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      28                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      29                 :            :  */
      30                 :            : 
      31                 :            : #include "defs.h"
      32                 :            : #include "msghdr.h"
      33                 :            : #include <limits.h>
      34                 :            : 
      35                 :            : static int
      36                 :      14622 : fetch_struct_mmsghdr_or_printaddr(struct tcb *const tcp,
      37                 :            :                                   const kernel_ulong_t addr,
      38                 :            :                                   const unsigned int len, void *const mh)
      39                 :            : {
      40 [ +  - ][ +  + ]:      14622 :         if ((entering(tcp) || !syserror(tcp))
      41         [ +  + ]:      14616 :             && fetch_struct_mmsghdr(tcp, addr, mh)) {
      42                 :      14604 :                 return 0;
      43                 :            :         } else {
      44                 :         18 :                 printaddr(addr);
      45                 :         18 :                 return -1;
      46                 :            :         }
      47                 :            : }
      48                 :            : 
      49                 :            : struct print_struct_mmsghdr_config {
      50                 :            :         const int *p_user_msg_namelen;
      51                 :            :         unsigned int msg_len_vlen;
      52                 :            :         unsigned int count;
      53                 :            :         bool use_msg_len;
      54                 :            : };
      55                 :            : 
      56                 :            : static bool
      57                 :      14586 : print_struct_mmsghdr(struct tcb *tcp, void *elem_buf,
      58                 :            :                      size_t elem_size, void *data)
      59                 :            : {
      60                 :      14586 :         const struct mmsghdr *const mmsg = elem_buf;
      61                 :      14586 :         struct print_struct_mmsghdr_config *const c = data;
      62                 :            : 
      63         [ +  + ]:      14586 :         if (!c->count) {
      64                 :         12 :                 tprints("...");
      65                 :         12 :                 return false;
      66                 :            :         }
      67                 :      14574 :         --c->count;
      68                 :            : 
      69                 :      14574 :         tprints("{msg_hdr=");
      70         [ +  + ]:      14574 :         print_struct_msghdr(tcp, &mmsg->msg_hdr, c->p_user_msg_namelen,
      71                 :      16452 :                             c->use_msg_len ? mmsg->msg_len : (kernel_ulong_t) -1);
      72         [ +  + ]:      14574 :         if (c->msg_len_vlen) {
      73                 :       3750 :                 tprintf(", msg_len=%u", mmsg->msg_len);
      74                 :       3750 :                 --c->msg_len_vlen;
      75                 :            :         }
      76                 :      14574 :         tprints("}");
      77                 :            : 
      78         [ +  + ]:      14574 :         if (c->p_user_msg_namelen)
      79                 :       1878 :                 ++c->p_user_msg_namelen;
      80                 :            : 
      81                 :      14574 :         return true;
      82                 :            : }
      83                 :            : 
      84                 :            : static void
      85                 :         30 : free_mmsgvec_data(void *ptr)
      86                 :            : {
      87                 :         30 :         char **pstr = ptr;
      88                 :         30 :         free(*pstr);
      89                 :         30 :         *pstr = 0;
      90                 :            : 
      91                 :         30 :         free(ptr);
      92                 :         30 : }
      93                 :            : 
      94                 :            : struct mmsgvec_data {
      95                 :            :         char *timeout;
      96                 :            :         unsigned int count;
      97                 :            :         int namelen[IOV_MAX];
      98                 :            : };
      99                 :            : 
     100                 :            : static void
     101                 :         30 : save_mmsgvec_namelen(struct tcb *const tcp, kernel_ulong_t addr,
     102                 :            :                      unsigned int len, const char *const timeout)
     103                 :            : {
     104         [ +  + ]:         30 :         if (len > IOV_MAX)
     105                 :         12 :                 len = IOV_MAX;
     106                 :            : 
     107                 :         30 :         const size_t data_size = offsetof(struct mmsgvec_data, namelen)
     108                 :         30 :                                  + sizeof(int) * len;
     109                 :         30 :         struct mmsgvec_data *const data = xmalloc(data_size);
     110                 :         30 :         data->timeout = xstrdup(timeout);
     111                 :            : 
     112                 :            :         unsigned int i, fetched;
     113                 :            : 
     114         [ +  + ]:      12342 :         for (i = 0; i < len; ++i, addr += fetched) {
     115                 :            :                 struct mmsghdr mh;
     116                 :            : 
     117                 :      12312 :                 fetched = fetch_struct_mmsghdr(tcp, addr, &mh);
     118         [ -  + ]:      12312 :                 if (!fetched)
     119                 :          0 :                         break;
     120                 :      12312 :                 data->namelen[i] = mh.msg_hdr.msg_namelen;
     121                 :            :         }
     122                 :         30 :         data->count = i;
     123                 :            : 
     124                 :         30 :         set_tcb_priv_data(tcp, data, free_mmsgvec_data);
     125                 :         30 : }
     126                 :            : 
     127                 :            : static void
     128                 :         72 : decode_mmsgvec(struct tcb *const tcp, const kernel_ulong_t addr,
     129                 :            :                const unsigned int vlen, const unsigned int msg_len_vlen,
     130                 :            :                const bool use_msg_len)
     131                 :            : {
     132                 :            :         struct mmsghdr mmsg;
     133                 :         72 :         struct print_struct_mmsghdr_config c = {
     134                 :            :                 .msg_len_vlen = msg_len_vlen,
     135                 :            :                 .count = IOV_MAX,
     136                 :            :                 .use_msg_len = use_msg_len
     137                 :            :         };
     138                 :         72 :         const struct mmsgvec_data *const data = get_tcb_priv_data(tcp);
     139                 :            : 
     140         [ +  + ]:         72 :         if (data) {
     141         [ +  + ]:         30 :                 if (data->count < c.count)
     142                 :         18 :                         c.count = data->count;
     143                 :         30 :                 c.p_user_msg_namelen = data->namelen;
     144                 :            :         }
     145                 :            : 
     146                 :         72 :         print_array(tcp, addr, vlen, &mmsg, sizeof_struct_mmsghdr(),
     147                 :            :                     fetch_struct_mmsghdr_or_printaddr,
     148                 :            :                     print_struct_mmsghdr, &c);
     149                 :         72 : }
     150                 :            : 
     151                 :            : void
     152                 :         12 : dumpiov_in_mmsghdr(struct tcb *const tcp, kernel_ulong_t addr)
     153                 :            : {
     154                 :         12 :         unsigned int len = tcp->u_rval;
     155                 :            :         unsigned int i, fetched;
     156                 :            :         struct mmsghdr mmsg;
     157                 :            : 
     158         [ +  + ]:         36 :         for (i = 0; i < len; ++i, addr += fetched) {
     159                 :         24 :                 fetched = fetch_struct_mmsghdr(tcp, addr, &mmsg);
     160         [ -  + ]:         24 :                 if (!fetched)
     161                 :          0 :                         break;
     162                 :         24 :                 tprintf(" = %" PRI_klu " buffers in vector %u\n",
     163                 :         24 :                         (kernel_ulong_t) mmsg.msg_hdr.msg_iovlen, i);
     164                 :         24 :                 dumpiov_upto(tcp, mmsg.msg_hdr.msg_iovlen,
     165                 :         24 :                              ptr_to_kulong(mmsg.msg_hdr.msg_iov),
     166                 :         24 :                              mmsg.msg_len);
     167                 :            :         }
     168                 :         12 : }
     169                 :            : 
     170                 :         90 : SYS_FUNC(sendmmsg)
     171                 :            : {
     172         [ +  + ]:         90 :         if (entering(tcp)) {
     173                 :            :                 /* sockfd */
     174                 :         48 :                 printfd(tcp, tcp->u_arg[0]);
     175                 :         48 :                 tprints(", ");
     176         [ +  + ]:         48 :                 if (!verbose(tcp)) {
     177                 :            :                         /* msgvec */
     178                 :          6 :                         printaddr(tcp->u_arg[1]);
     179                 :            :                         /* vlen */
     180                 :          6 :                         tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
     181                 :            :                         /* flags */
     182                 :          6 :                         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
     183                 :          6 :                         return RVAL_DECODED;
     184                 :            :                 }
     185                 :            :         } else {
     186         [ +  + ]:         42 :                 const unsigned int msg_len_vlen =
     187                 :         60 :                         syserror(tcp) ? 0 : tcp->u_rval;
     188                 :            :                 /* msgvec */
     189                 :         42 :                 temporarily_clear_syserror(tcp);
     190                 :         42 :                 decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_arg[2],
     191                 :            :                                msg_len_vlen, false);
     192                 :         42 :                 restore_cleared_syserror(tcp);
     193                 :            :                 /* vlen */
     194                 :         42 :                 tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
     195                 :            :                 /* flags */
     196                 :         42 :                 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
     197                 :            :         }
     198                 :         84 :         return 0;
     199                 :            : }
     200                 :            : 
     201                 :         72 : SYS_FUNC(recvmmsg)
     202                 :            : {
     203         [ +  + ]:         72 :         if (entering(tcp)) {
     204                 :         36 :                 printfd(tcp, tcp->u_arg[0]);
     205                 :         36 :                 tprints(", ");
     206         [ +  + ]:         36 :                 if (verbose(tcp)) {
     207                 :         30 :                         save_mmsgvec_namelen(tcp, tcp->u_arg[1], tcp->u_arg[2],
     208                 :         30 :                                              sprint_timespec(tcp, tcp->u_arg[4]));
     209                 :            :                 } else {
     210                 :            :                         /* msgvec */
     211                 :          6 :                         printaddr(tcp->u_arg[1]);
     212                 :            :                         /* vlen */
     213                 :          6 :                         tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
     214                 :            :                         /* flags */
     215                 :          6 :                         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
     216                 :          6 :                         tprints(", ");
     217                 :          6 :                         print_timespec(tcp, tcp->u_arg[4]);
     218                 :            :                 }
     219                 :         36 :                 return 0;
     220                 :            :         } else {
     221         [ +  + ]:         36 :                 if (verbose(tcp)) {
     222                 :            :                         /* msgvec */
     223                 :         30 :                         decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval,
     224                 :         30 :                                        tcp->u_rval, true);
     225                 :            :                         /* vlen */
     226                 :         30 :                         tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
     227                 :            :                         /* flags */
     228                 :         30 :                         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
     229                 :         30 :                         tprints(", ");
     230                 :            :                         /* timeout on entrance */
     231                 :         30 :                         tprints(*(const char **) get_tcb_priv_data(tcp));
     232                 :            :                 }
     233         [ +  + ]:         36 :                 if (syserror(tcp))
     234                 :          6 :                         return 0;
     235         [ -  + ]:         30 :                 if (tcp->u_rval == 0) {
     236                 :          0 :                         tcp->auxstr = "Timeout";
     237                 :          0 :                         return RVAL_STR;
     238                 :            :                 }
     239 [ +  + ][ +  + ]:         30 :                 if (!verbose(tcp) || !tcp->u_arg[4])
     240                 :         24 :                         return 0;
     241                 :            :                 /* timeout on exit */
     242                 :            :                 static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE];
     243                 :          6 :                 snprintf(str, sizeof(str), "left %s",
     244                 :          6 :                          sprint_timespec(tcp, tcp->u_arg[4]));
     245                 :          6 :                 tcp->auxstr = str;
     246                 :          6 :                 return RVAL_STR;
     247                 :            :         }
     248                 :            : }

Generated by: LCOV version 1.12