1 /* 2 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr (at) gmail.com> 3 * Copyright (c) 2016-2018 The strace developers. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "tests.h" 30 #include <stdio.h> 31 32 enum sprintrc_fmt { 33 SPRINTRC_FMT_RAW, 34 SPRINTRC_FMT_GREP, 35 }; 36 37 /** 38 * Provides pointer to static string buffer with printed return code in format 39 * used by strace - with errno and error message. 40 * 41 * @param rc Return code. 42 * @param fmt Output format. Currently, raw (used for diff matching) and grep 43 * (for extended POSIX regex-based pattern matching) formats are 44 * supported. 45 * @return Pointer to (statically allocated) buffer containing decimal 46 * representation of return code and errno/error message in case @rc 47 * is equal to -1. 48 */ 49 static inline const char * 50 sprintrc_ex(long rc, enum sprintrc_fmt fmt) 51 { 52 static const char *formats[] = { 53 [SPRINTRC_FMT_RAW] = "-1 %s (%m)", 54 [SPRINTRC_FMT_GREP] = "-1 %s \\(%m\\)", 55 }; 56 static char buf[4096]; 57 58 if (rc == 0) 59 return "0"; 60 61 int ret = (rc == -1) 62 ? snprintf(buf, sizeof(buf), formats[fmt], errno2name()) 63 : snprintf(buf, sizeof(buf), "%ld", rc); 64 65 if (ret < 0) 66 perror_msg_and_fail("snprintf"); 67 if ((size_t) ret >= sizeof(buf)) 68 error_msg_and_fail("snprintf overflow: got %d, expected" 69 " no more than %zu", ret, sizeof(buf)); 70 71 return buf; 72 } 73 74 const char * 75 sprintrc(long rc) 76 { 77 return sprintrc_ex(rc, SPRINTRC_FMT_RAW); 78 } 79 80 const char * 81 sprintrc_grep(long rc) 82 { 83 return sprintrc_ex(rc, SPRINTRC_FMT_GREP); 84 } 85