16f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov/*
2d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
36f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * All rights reserved.
46f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov *
56f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * Redistribution and use in source and binary forms, with or without
66f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * modification, are permitted provided that the following conditions
76f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * are met:
86f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * 1. Redistributions of source code must retain the above copyright
96f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov *    notice, this list of conditions and the following disclaimer.
106f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * 2. Redistributions in binary form must reproduce the above copyright
116f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov *    notice, this list of conditions and the following disclaimer in the
126f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov *    documentation and/or other materials provided with the distribution.
136f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * 3. The name of the author may not be used to endorse or promote products
146f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov *    derived from this software without specific prior written permission.
156f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov *
166f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
176f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
186f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
196f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
206f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
216f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
226f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
246f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
256f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov */
276f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov
286f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov#include "tests.h"
296f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov#include <stdio.h>
306f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov
316d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikovenum sprintrc_fmt {
326d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov	SPRINTRC_FMT_RAW,
336d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov	SPRINTRC_FMT_GREP,
346d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov};
356d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov
366f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov/**
376f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * Provides pointer to static string buffer with printed return code in format
386f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov * used by strace - with errno and error message.
396f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov *
406d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov * @param rc  Return code.
416d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov * @param fmt Output format. Currently, raw (used for diff matching) and grep
426d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov *            (for extended POSIX regex-based pattern matching) formats are
436d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov *            supported.
446d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov * @return    Pointer to (statically allocated) buffer containing decimal
456d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov *            representation of return code and errno/error message in case @rc
466d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov *            is equal to -1.
476f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov */
486d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikovstatic inline const char *
496d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikovsprintrc_ex(long rc, enum sprintrc_fmt fmt)
506f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov{
516d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov	static const char *formats[] = {
526d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov		[SPRINTRC_FMT_RAW] = "-1 %s (%m)",
536d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov		[SPRINTRC_FMT_GREP] = "-1 %s \\(%m\\)",
546d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov	};
556f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov	static char buf[4096];
566f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov
576d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov	if (fmt >= ARRAY_SIZE(formats))
586d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov		perror_msg_and_fail("sprintrc_ex: incorrect format provided");
596d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov
606f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov	if (rc == 0)
616f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov		return "0";
626f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov
636f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov	int ret = (rc == -1)
646d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov		? snprintf(buf, sizeof(buf), formats[fmt], errno2name())
656f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov		: snprintf(buf, sizeof(buf), "%ld", rc);
666f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov
676f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov	if (ret < 0)
686f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov		perror_msg_and_fail("snprintf");
696f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov	if ((size_t) ret >= sizeof(buf))
706f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov		error_msg_and_fail("snprintf overflow: got %d, expected"
716f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov				   " no more than %zu", ret, sizeof(buf));
726f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov
736f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov	return buf;
746f9aefde214b9438551268cf1c9c128b1cef6413Eugene Syromyatnikov}
756d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov
766d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikovconst char *
776d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikovsprintrc(long rc)
786d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov{
796d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov	return sprintrc_ex(rc, SPRINTRC_FMT_RAW);
806d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov}
816d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov
826d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikovconst char *
836d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikovsprintrc_grep(long rc)
846d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov{
856d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov	return sprintrc_ex(rc, SPRINTRC_FMT_GREP);
866d995ae68b974b389a499bd1d0dfe3e0de92905aEugene Syromyatnikov}
87