mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-11-03 20:53:13 +03:00 
			
		
		
		
	Convert tests to use 'xfmemopen' rather than open-coding error checks with 'fmemopen' or plain missing them, where 'fmemopen' itself is not the scope of testing. Leave 'fmemopen' tests alone. Reviewed-by: Florian Weimer <fweimer@redhat.com>
		
			
				
	
	
		
			585 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			585 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Basic tests for syslog interfaces.
 | 
						|
   Copyright (C) 2022-2025 Free Software Foundation, Inc.
 | 
						|
   This file is part of the GNU C Library.
 | 
						|
 | 
						|
   The GNU C Library is free software; you can redistribute it and/or
 | 
						|
   modify it under the terms of the GNU Lesser General Public
 | 
						|
   License as published by the Free Software Foundation; either
 | 
						|
   version 2.1 of the License, or (at your option) any later version.
 | 
						|
 | 
						|
   The GNU C Library is distributed in the hope that it will be useful,
 | 
						|
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
   Lesser General Public License for more details.
 | 
						|
 | 
						|
   You should have received a copy of the GNU Lesser General Public
 | 
						|
   License along with the GNU C Library; if not, see
 | 
						|
   <https://www.gnu.org/licenses/>.  */
 | 
						|
 | 
						|
#include <array_length.h>
 | 
						|
#include <fcntl.h>
 | 
						|
#include <paths.h>
 | 
						|
#include <netinet/in.h>
 | 
						|
#include <support/capture_subprocess.h>
 | 
						|
#include <support/check.h>
 | 
						|
#include <support/xstdio.h>
 | 
						|
#include <support/xsocket.h>
 | 
						|
#include <support/xunistd.h>
 | 
						|
#include <stdarg.h>
 | 
						|
#include <stdbool.h>
 | 
						|
#include <stddef.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <syslog.h>
 | 
						|
#include <sys/un.h>
 | 
						|
 | 
						|
static const int facilities[] =
 | 
						|
  {
 | 
						|
    LOG_KERN,
 | 
						|
    LOG_USER,
 | 
						|
    LOG_MAIL,
 | 
						|
    LOG_DAEMON,
 | 
						|
    LOG_AUTH,
 | 
						|
    LOG_SYSLOG,
 | 
						|
    LOG_LPR,
 | 
						|
    LOG_NEWS,
 | 
						|
    LOG_UUCP,
 | 
						|
    LOG_CRON,
 | 
						|
    LOG_AUTHPRIV,
 | 
						|
    LOG_FTP,
 | 
						|
    LOG_LOCAL0,
 | 
						|
    LOG_LOCAL1,
 | 
						|
    LOG_LOCAL2,
 | 
						|
    LOG_LOCAL3,
 | 
						|
    LOG_LOCAL4,
 | 
						|
    LOG_LOCAL5,
 | 
						|
    LOG_LOCAL6,
 | 
						|
    LOG_LOCAL7,
 | 
						|
  };
 | 
						|
 | 
						|
static const int priorities[] =
 | 
						|
  {
 | 
						|
    LOG_EMERG,
 | 
						|
    LOG_ALERT,
 | 
						|
    LOG_CRIT,
 | 
						|
    LOG_ERR,
 | 
						|
    LOG_WARNING,
 | 
						|
    LOG_NOTICE,
 | 
						|
    LOG_INFO,
 | 
						|
    LOG_DEBUG
 | 
						|
  };
 | 
						|
 | 
						|
#define IDENT_LENGTH 64
 | 
						|
#define MSG_LENGTH   1024
 | 
						|
 | 
						|
#define SYSLOG_MSG_BASE "syslog_message"
 | 
						|
#define OPENLOG_IDENT   "openlog_ident"
 | 
						|
static char large_message[MSG_LENGTH];
 | 
						|
 | 
						|
struct msg_t
 | 
						|
  {
 | 
						|
    int priority;
 | 
						|
    int facility;
 | 
						|
    char ident[IDENT_LENGTH];
 | 
						|
    char msg[MSG_LENGTH];
 | 
						|
    pid_t pid;
 | 
						|
  };
 | 
						|
 | 
						|
static void
 | 
						|
call_vsyslog (int priority, const char *format, ...)
 | 
						|
{
 | 
						|
  va_list ap;
 | 
						|
  va_start (ap, format);
 | 
						|
  vsyslog (priority, format, ap);
 | 
						|
  va_end (ap);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
send_vsyslog (int options)
 | 
						|
{
 | 
						|
  for (size_t i = 0; i < array_length (facilities); i++)
 | 
						|
    {
 | 
						|
      for (size_t j = 0; j < array_length (priorities); j++)
 | 
						|
        {
 | 
						|
          int facility = facilities[i];
 | 
						|
          int priority = priorities[j];
 | 
						|
          call_vsyslog (facility | priority, "%s %d %d", SYSLOG_MSG_BASE,
 | 
						|
                        facility, priority);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
send_syslog (int options)
 | 
						|
{
 | 
						|
  for (size_t i = 0; i < array_length (facilities); i++)
 | 
						|
    {
 | 
						|
      for (size_t j = 0; j < array_length (priorities); j++)
 | 
						|
        {
 | 
						|
          int facility = facilities[i];
 | 
						|
          int priority = priorities[j];
 | 
						|
          syslog (facility | priority, "%s %d %d", SYSLOG_MSG_BASE, facility,
 | 
						|
                  priority);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
check_syslog_message (const struct msg_t *msg, int msgnum, int options,
 | 
						|
                      pid_t pid)
 | 
						|
{
 | 
						|
  if (msgnum == array_length (facilities) * array_length (priorities) - 1)
 | 
						|
    return false;
 | 
						|
 | 
						|
  int i = msgnum / array_length (priorities);
 | 
						|
  int j = msgnum % array_length (priorities);
 | 
						|
 | 
						|
  int expected_facility = facilities[i];
 | 
						|
  /* With no preceding openlog, syslog default to LOG_USER.  */
 | 
						|
  if (expected_facility == LOG_KERN)
 | 
						|
      expected_facility = LOG_USER;
 | 
						|
  int expected_priority = priorities[j];
 | 
						|
 | 
						|
  TEST_COMPARE (msg->facility, expected_facility);
 | 
						|
  TEST_COMPARE (msg->priority, expected_priority);
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
send_syslog_large (int options)
 | 
						|
{
 | 
						|
  int facility = LOG_USER;
 | 
						|
  int priority = LOG_INFO;
 | 
						|
 | 
						|
  syslog (facility | priority, "%s %d %d", large_message, facility,
 | 
						|
	  priority);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
send_vsyslog_large (int options)
 | 
						|
{
 | 
						|
  int facility = LOG_USER;
 | 
						|
  int priority = LOG_INFO;
 | 
						|
 | 
						|
  call_vsyslog (facility | priority, "%s %d %d", large_message, facility,
 | 
						|
		priority);
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
check_syslog_message_large (const struct msg_t *msg, int msgnum, int options,
 | 
						|
			    pid_t pid)
 | 
						|
{
 | 
						|
  TEST_COMPARE (msg->facility, LOG_USER);
 | 
						|
  TEST_COMPARE (msg->priority, LOG_INFO);
 | 
						|
  TEST_COMPARE_STRING (msg->msg, large_message);
 | 
						|
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
send_openlog (int options)
 | 
						|
{
 | 
						|
  /* Define a non-default IDENT and a not default facility.  */
 | 
						|
  openlog (OPENLOG_IDENT, options, LOG_LOCAL0);
 | 
						|
  for (size_t j = 0; j < array_length (priorities); j++)
 | 
						|
    {
 | 
						|
      int priority = priorities[j];
 | 
						|
      syslog (priority, "%s %d %d", SYSLOG_MSG_BASE, LOG_LOCAL0, priority);
 | 
						|
    }
 | 
						|
  closelog ();
 | 
						|
 | 
						|
  /* Back to the default IDENT with a non default facility.  */
 | 
						|
  openlog (NULL, 0, LOG_LOCAL6);
 | 
						|
  for (size_t j = 0; j < array_length (priorities); j++)
 | 
						|
    {
 | 
						|
      int priority = priorities[j];
 | 
						|
      syslog (LOG_LOCAL7 | priority, "%s %d %d", SYSLOG_MSG_BASE, LOG_LOCAL7,
 | 
						|
        priority);
 | 
						|
    }
 | 
						|
  closelog ();
 | 
						|
 | 
						|
  /* LOG_KERN does not change the internal default facility.  */
 | 
						|
  openlog (NULL, 0, LOG_KERN);
 | 
						|
  for (size_t j = 0; j < array_length (priorities); j++)
 | 
						|
    {
 | 
						|
      int priority = priorities[j];
 | 
						|
      syslog (priority, "%s %d %d", SYSLOG_MSG_BASE, LOG_KERN, priority);
 | 
						|
    }
 | 
						|
  closelog ();
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
send_openlog_large (int options)
 | 
						|
{
 | 
						|
  /* Define a non-default IDENT and a not default facility.  */
 | 
						|
  openlog (OPENLOG_IDENT, options, LOG_LOCAL0);
 | 
						|
 | 
						|
  syslog (LOG_INFO, "%s %d %d", large_message, LOG_LOCAL0, LOG_INFO);
 | 
						|
 | 
						|
  closelog ();
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
check_openlog_message (const struct msg_t *msg, int msgnum,
 | 
						|
                       int options, pid_t pid)
 | 
						|
{
 | 
						|
  if (msgnum == 3 * array_length (priorities) - 1)
 | 
						|
    return false;
 | 
						|
 | 
						|
  int expected_priority = priorities[msgnum % array_length (priorities)];
 | 
						|
  TEST_COMPARE (msg->priority, expected_priority);
 | 
						|
 | 
						|
  char expected_ident[IDENT_LENGTH];
 | 
						|
  snprintf (expected_ident, sizeof (expected_ident), "%s%s%.0d%s:",
 | 
						|
            OPENLOG_IDENT,
 | 
						|
            options & LOG_PID ? "[" : "",
 | 
						|
            options & LOG_PID ? pid : 0,
 | 
						|
            options & LOG_PID ? "]" : "");
 | 
						|
 | 
						|
  if (msgnum < array_length (priorities))
 | 
						|
    {
 | 
						|
      if (options & LOG_PID)
 | 
						|
        TEST_COMPARE (msg->pid, pid);
 | 
						|
      TEST_COMPARE_STRING (msg->ident, expected_ident);
 | 
						|
      TEST_COMPARE (msg->facility, LOG_LOCAL0);
 | 
						|
    }
 | 
						|
  else if (msgnum < 2 * array_length (priorities))
 | 
						|
    TEST_COMPARE (msg->facility, LOG_LOCAL7);
 | 
						|
  else if (msgnum < 3 * array_length (priorities))
 | 
						|
    TEST_COMPARE (msg->facility, LOG_KERN);
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
check_openlog_message_large (const struct msg_t *msg, int msgnum,
 | 
						|
			     int options, pid_t pid)
 | 
						|
{
 | 
						|
  char expected_ident[IDENT_LENGTH];
 | 
						|
  snprintf (expected_ident, sizeof (expected_ident), "%s%s%.0d%s:",
 | 
						|
            OPENLOG_IDENT,
 | 
						|
            options & LOG_PID ? "[" : "",
 | 
						|
            options & LOG_PID ? pid : 0,
 | 
						|
            options & LOG_PID ? "]" : "");
 | 
						|
 | 
						|
  TEST_COMPARE_STRING (msg->ident, expected_ident);
 | 
						|
  TEST_COMPARE_STRING (msg->msg, large_message);
 | 
						|
  TEST_COMPARE (msg->priority, LOG_INFO);
 | 
						|
  TEST_COMPARE (msg->facility, LOG_LOCAL0);
 | 
						|
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
static struct msg_t
 | 
						|
parse_syslog_msg (const char *msg)
 | 
						|
{
 | 
						|
  struct msg_t r = { .pid = -1 };
 | 
						|
  int number;
 | 
						|
  int wsb, wsa;
 | 
						|
 | 
						|
#define STRINPUT(size)  XSTRINPUT(size)
 | 
						|
#define XSTRINPUT(size) "%" # size "s"
 | 
						|
 | 
						|
  /* The message in the form:
 | 
						|
     <179>Apr  8 14:51:19 tst-syslog: message 176 3  */
 | 
						|
  int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d%n %n" STRINPUT(IDENT_LENGTH)
 | 
						|
		       " " STRINPUT(MSG_LENGTH) " %*d %*d",
 | 
						|
                  &number, &wsb, &wsa, r.ident, r.msg);
 | 
						|
  TEST_COMPARE (n, 3);
 | 
						|
  /* It should only one space between timestamp and message.  */
 | 
						|
  TEST_COMPARE (wsa - wsb, 1);
 | 
						|
 | 
						|
  r.facility = number & LOG_FACMASK;
 | 
						|
  r.priority = number & LOG_PRIMASK;
 | 
						|
 | 
						|
  char *pid_start = strchr (r.ident, '[');
 | 
						|
  if (pid_start != NULL)
 | 
						|
    {
 | 
						|
       char *pid_end = strchr (r.ident, ']');
 | 
						|
       if (pid_end != NULL)
 | 
						|
         r.pid = strtoul (pid_start + 1, NULL, 10);
 | 
						|
    }
 | 
						|
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
static struct msg_t
 | 
						|
parse_syslog_console (const char *msg)
 | 
						|
{
 | 
						|
  int priority;
 | 
						|
  int facility;
 | 
						|
  struct msg_t r;
 | 
						|
 | 
						|
  /* The message in the form:
 | 
						|
     openlog_ident: syslog_message 128 0  */
 | 
						|
  int n = sscanf (msg, STRINPUT(IDENT_LENGTH) " " STRINPUT(MSG_LENGTH) " %d %d",
 | 
						|
      r.ident, r.msg, &facility, &priority);
 | 
						|
  TEST_COMPARE (n, 4);
 | 
						|
 | 
						|
  r.facility = facility;
 | 
						|
  r.priority = priority;
 | 
						|
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
check_syslog_udp (void (*syslog_send)(int), int options,
 | 
						|
                  bool (*syslog_check)(const struct msg_t *, int, int,
 | 
						|
                                       pid_t))
 | 
						|
{
 | 
						|
  struct sockaddr_un addr =
 | 
						|
    {
 | 
						|
      .sun_family = AF_UNIX,
 | 
						|
      .sun_path = _PATH_LOG
 | 
						|
    };
 | 
						|
 | 
						|
  socklen_t addrlen = sizeof (addr);
 | 
						|
  int server_udp = xsocket (AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
 | 
						|
  xbind (server_udp, (struct sockaddr *) &addr, addrlen);
 | 
						|
 | 
						|
  pid_t sender_pid = xfork ();
 | 
						|
  if (sender_pid == 0)
 | 
						|
    {
 | 
						|
      syslog_send (options);
 | 
						|
      _exit (0);
 | 
						|
    }
 | 
						|
 | 
						|
  int msgnum = 0;
 | 
						|
  while (1)
 | 
						|
    {
 | 
						|
      char buf[2048];
 | 
						|
      size_t l = xrecvfrom (server_udp, buf, sizeof (buf), 0,
 | 
						|
                            (struct sockaddr *) &addr, &addrlen);
 | 
						|
      buf[l] = '\0';
 | 
						|
 | 
						|
      struct msg_t msg = parse_syslog_msg (buf);
 | 
						|
      if (!syslog_check (&msg, msgnum++, options, sender_pid))
 | 
						|
        break;
 | 
						|
     }
 | 
						|
 | 
						|
  xclose (server_udp);
 | 
						|
 | 
						|
  int status;
 | 
						|
  xwaitpid (sender_pid, &status, 0);
 | 
						|
  TEST_COMPARE (status, 0);
 | 
						|
 | 
						|
  unlink (_PATH_LOG);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
check_syslog_tcp (void (*syslog_send)(int), int options,
 | 
						|
                  bool (*syslog_check)(const struct msg_t *, int, int,
 | 
						|
                                       pid_t))
 | 
						|
{
 | 
						|
  struct sockaddr_un addr =
 | 
						|
    {
 | 
						|
      .sun_family = AF_UNIX,
 | 
						|
      .sun_path = _PATH_LOG
 | 
						|
    };
 | 
						|
  socklen_t addrlen = sizeof (addr);
 | 
						|
 | 
						|
  int server_tcp = xsocket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
 | 
						|
  xbind (server_tcp, (struct sockaddr *) &addr, addrlen);
 | 
						|
  xlisten (server_tcp, 5);
 | 
						|
 | 
						|
  pid_t sender_pid = xfork ();
 | 
						|
  if (sender_pid == 0)
 | 
						|
    {
 | 
						|
      syslog_send (options);
 | 
						|
      _exit (0);
 | 
						|
    }
 | 
						|
 | 
						|
  int client_tcp = xaccept (server_tcp, NULL, NULL);
 | 
						|
 | 
						|
  char buf[2048], *rb = buf;
 | 
						|
  size_t rbl = sizeof (buf);
 | 
						|
  size_t prl = 0;  /* Track the size of the partial record.  */
 | 
						|
  int msgnum = 0;
 | 
						|
 | 
						|
  while (1)
 | 
						|
    {
 | 
						|
      size_t rl = xrecvfrom (client_tcp, rb, rbl - prl, 0, NULL, NULL);
 | 
						|
      if (rl == 0)
 | 
						|
        break;
 | 
						|
 | 
						|
      /* Iterate over the buffer to find and check the record.  */
 | 
						|
      size_t l = rl + prl;
 | 
						|
      char *b = buf;
 | 
						|
      while (1)
 | 
						|
	{
 | 
						|
          /* With TCP each record ends with a '\0'.  */
 | 
						|
          char *e = memchr (b, '\0', l);
 | 
						|
          if (e != NULL)
 | 
						|
            {
 | 
						|
              struct msg_t msg = parse_syslog_msg (b);
 | 
						|
              if (!syslog_check (&msg, msgnum++, options, sender_pid))
 | 
						|
                break;
 | 
						|
 | 
						|
	      /* Advance to the next record.  */
 | 
						|
	      ptrdiff_t diff = e + 1 - b;
 | 
						|
	      b += diff;
 | 
						|
	      l -= diff;
 | 
						|
	    }
 | 
						|
	  else
 | 
						|
	    {
 | 
						|
              /* Move the partial record to the start of the buffer.  */
 | 
						|
	      memmove (buf, b, l);
 | 
						|
	      rb = buf + l;
 | 
						|
	      prl = l;
 | 
						|
	      break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
  xclose (client_tcp);
 | 
						|
  xclose (server_tcp);
 | 
						|
 | 
						|
  int status;
 | 
						|
  xwaitpid (sender_pid, &status, 0);
 | 
						|
  TEST_COMPARE (status, 0);
 | 
						|
 | 
						|
  unlink (_PATH_LOG);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
check_syslog_console_read (FILE *fp)
 | 
						|
{
 | 
						|
  char buf[512];
 | 
						|
  int msgnum = 0;
 | 
						|
  while (fgets (buf, sizeof (buf), fp) != NULL)
 | 
						|
    {
 | 
						|
      struct msg_t msg = parse_syslog_console (buf);
 | 
						|
      TEST_COMPARE_STRING (msg.ident, OPENLOG_IDENT ":");
 | 
						|
      TEST_COMPARE (msg.priority, priorities[msgnum]);
 | 
						|
      TEST_COMPARE (msg.facility, LOG_LOCAL0);
 | 
						|
 | 
						|
      if (++msgnum == array_length (priorities))
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
check_syslog_console_read_large (FILE *fp)
 | 
						|
{
 | 
						|
  char buf[2048];
 | 
						|
  TEST_VERIFY (fgets (buf, sizeof (buf), fp) != NULL);
 | 
						|
  struct msg_t msg = parse_syslog_console (buf);
 | 
						|
 | 
						|
  TEST_COMPARE_STRING (msg.ident, OPENLOG_IDENT ":");
 | 
						|
  TEST_COMPARE_STRING (msg.msg, large_message);
 | 
						|
  TEST_COMPARE (msg.priority, LOG_INFO);
 | 
						|
  TEST_COMPARE (msg.facility, LOG_LOCAL0);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
check_syslog_console (void (*syslog_send)(int),
 | 
						|
		      void (*syslog_check)(FILE *fp))
 | 
						|
{
 | 
						|
  xmkfifo (_PATH_CONSOLE, 0666);
 | 
						|
 | 
						|
  pid_t sender_pid = xfork ();
 | 
						|
  if (sender_pid == 0)
 | 
						|
    {
 | 
						|
      syslog_send (LOG_CONS);
 | 
						|
      _exit (0);
 | 
						|
    }
 | 
						|
 | 
						|
  {
 | 
						|
    FILE *fp = xfopen (_PATH_CONSOLE, "r+");
 | 
						|
    syslog_check (fp);
 | 
						|
    xfclose (fp);
 | 
						|
  }
 | 
						|
 | 
						|
  int status;
 | 
						|
  xwaitpid (sender_pid, &status, 0);
 | 
						|
  TEST_COMPARE (status, 0);
 | 
						|
 | 
						|
  unlink (_PATH_CONSOLE);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
send_openlog_callback (void *clousure)
 | 
						|
{
 | 
						|
  int options = *(int *) clousure;
 | 
						|
  send_openlog (options);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
send_openlog_callback_large (void *clousure)
 | 
						|
{
 | 
						|
  int options = *(int *) clousure;
 | 
						|
  send_openlog_large (options);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
check_syslog_perror (bool large)
 | 
						|
{
 | 
						|
  struct support_capture_subprocess result;
 | 
						|
  result = support_capture_subprocess (large
 | 
						|
				       ? send_openlog_callback_large
 | 
						|
				       : send_openlog_callback,
 | 
						|
                                       &(int){LOG_PERROR});
 | 
						|
 | 
						|
  FILE *mfp = xfmemopen (result.err.buffer, result.err.length, "r");
 | 
						|
  if (large)
 | 
						|
    check_syslog_console_read_large (mfp);
 | 
						|
  else
 | 
						|
    check_syslog_console_read (mfp);
 | 
						|
  xfclose (mfp);
 | 
						|
 | 
						|
  support_capture_subprocess_check (&result, "tst-openlog-child", 0,
 | 
						|
                                    sc_allow_stderr);
 | 
						|
  support_capture_subprocess_free (&result);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
do_test (void)
 | 
						|
{
 | 
						|
  /* Send every combination of facility/priority over UDP and TCP.  */
 | 
						|
  check_syslog_udp (send_syslog, 0, check_syslog_message);
 | 
						|
  check_syslog_tcp (send_syslog, 0, check_syslog_message);
 | 
						|
 | 
						|
  /* Also check vsyslog.  */
 | 
						|
  check_syslog_udp (send_vsyslog, 0, check_syslog_message);
 | 
						|
  check_syslog_tcp (send_vsyslog, 0, check_syslog_message);
 | 
						|
 | 
						|
  /* Run some openlog/syslog/closelog combinations.  */
 | 
						|
  check_syslog_udp (send_openlog, 0, check_openlog_message);
 | 
						|
  check_syslog_tcp (send_openlog, 0, check_openlog_message);
 | 
						|
 | 
						|
  /* Check the LOG_PID option.  */
 | 
						|
  check_syslog_udp (send_openlog, LOG_PID, check_openlog_message);
 | 
						|
  check_syslog_tcp (send_openlog, LOG_PID, check_openlog_message);
 | 
						|
 | 
						|
  /* Check the LOG_CONS option.  */
 | 
						|
  check_syslog_console (send_openlog, check_syslog_console_read);
 | 
						|
 | 
						|
  /* Check the LOG_PERROR option.  */
 | 
						|
  check_syslog_perror (false);
 | 
						|
 | 
						|
  /* Similar tests as before, but with a large message to trigger the
 | 
						|
     syslog path that uses dynamically allocated memory.  */
 | 
						|
  memset (large_message, 'a', sizeof large_message - 1);
 | 
						|
  large_message[sizeof large_message - 1] = '\0';
 | 
						|
 | 
						|
  check_syslog_udp (send_syslog_large, 0, check_syslog_message_large);
 | 
						|
  check_syslog_tcp (send_syslog_large, 0, check_syslog_message_large);
 | 
						|
 | 
						|
  check_syslog_udp (send_vsyslog_large, 0, check_syslog_message_large);
 | 
						|
  check_syslog_tcp (send_vsyslog_large, 0, check_syslog_message_large);
 | 
						|
 | 
						|
  check_syslog_udp (send_openlog_large, 0, check_openlog_message_large);
 | 
						|
  check_syslog_tcp (send_openlog_large, 0, check_openlog_message_large);
 | 
						|
 | 
						|
  check_syslog_udp (send_openlog_large, LOG_PID, check_openlog_message_large);
 | 
						|
  check_syslog_tcp (send_openlog_large, LOG_PID, check_openlog_message_large);
 | 
						|
 | 
						|
  check_syslog_console (send_openlog_large, check_syslog_console_read_large);
 | 
						|
 | 
						|
  check_syslog_perror (true);
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
#include <support/test-driver.c>
 |