/* Test concurrent fork, getline, and fflush (NULL).
   Copyright (C) 2016-2018 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; see the file COPYING.LIB.  If
   not, see <http://www.gnu.org/licenses/>.  */

#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>
#include <string.h>
#include <signal.h>

#include <support/xthread.h>
#include <support/temp_file.h>
#include <support/test-driver.h>

enum {
  /* Number of threads which call fork.  */
  fork_thread_count = 4,
  /* Number of threads which call getline (and, indirectly,
     malloc).  */
  read_thread_count = 8,
};

static bool termination_requested;

static void *
fork_thread_function (void *closure)
{
  while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED))
    {
      pid_t pid = fork ();
      if (pid < 0)
        {
          printf ("error: fork: %m\n");
          abort ();
        }
      else if (pid == 0)
        _exit (17);

      int status;
      if (waitpid (pid, &status, 0) < 0)
        {
          printf ("error: waitpid: %m\n");
          abort ();
        }
      if (!WIFEXITED (status) || WEXITSTATUS (status) != 17)
        {
          printf ("error: waitpid returned invalid status: %d\n", status);
          abort ();
        }
    }
  return NULL;
}

static char *file_to_read;

static void *
read_thread_function (void *closure)
{
  FILE *f = fopen (file_to_read, "r");
  if (f == NULL)
    {
      printf ("error: fopen (%s): %m\n", file_to_read);
      abort ();
    }

  while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED))
    {
      rewind (f);
      char *line = NULL;
      size_t line_allocated = 0;
      ssize_t ret = getline (&line, &line_allocated, f);
      if (ret < 0)
        {
          printf ("error: getline: %m\n");
          abort ();
        }
      free (line);
    }
  fclose (f);

  return NULL;
}

static void *
flushall_thread_function (void *closure)
{
  while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED))
    if (fflush (NULL) != 0)
      {
        printf ("error: fflush (NULL): %m\n");
        abort ();
      }
  return NULL;
}

static void
create_threads (pthread_t *threads, size_t count, void *(*func) (void *))
{
  for (size_t i = 0; i < count; ++i)
    threads[i] = xpthread_create (NULL, func, NULL);
}

static void
join_threads (pthread_t *threads, size_t count)
{
  for (size_t i = 0; i < count; ++i)
    xpthread_join (threads[i]);
}

/* Create a file which consists of a single long line, and assigns
   file_to_read.  The hope is that this triggers an allocation in
   getline which needs a lock.  */
static void
create_file_with_large_line (void)
{
  int fd = create_temp_file ("bug19431-large-line", &file_to_read);
  if (fd < 0)
    {
      printf ("error: create_temp_file: %m\n");
      abort ();
    }
  FILE *f = fdopen (fd, "w+");
  if (f == NULL)
    {
      printf ("error: fdopen: %m\n");
      abort ();
    }
  for (int i = 0; i < 50000; ++i)
    fputc ('x', f);
  fputc ('\n', f);
  if (ferror (f))
    {
      printf ("error: fputc: %m\n");
      abort ();
    }
  if (fclose (f) != 0)
    {
      printf ("error: fclose: %m\n");
      abort ();
    }
}

static int
do_test (void)
{
  /* Make sure that we do not exceed the arena limit with the number
     of threads we configured.  */
  if (mallopt (M_ARENA_MAX, 400) == 0)
    {
      printf ("error: mallopt (M_ARENA_MAX) failed\n");
      return 1;
    }

  /* Leave some room for shutting down all threads gracefully.  */
  int timeout = 3;
  if (timeout > DEFAULT_TIMEOUT)
    timeout = DEFAULT_TIMEOUT - 1;

  create_file_with_large_line ();

  pthread_t fork_threads[fork_thread_count];
  create_threads (fork_threads, fork_thread_count, fork_thread_function);
  pthread_t read_threads[read_thread_count];
  create_threads (read_threads, read_thread_count, read_thread_function);
  pthread_t flushall_threads[1];
  create_threads (flushall_threads, 1, flushall_thread_function);

  struct timespec ts = {timeout, 0};
  if (nanosleep (&ts, NULL))
    {
      printf ("error: error: nanosleep: %m\n");
      abort ();
    }

  __atomic_store_n (&termination_requested, true, __ATOMIC_RELAXED);

  join_threads (flushall_threads, 1);
  join_threads (read_threads, read_thread_count);
  join_threads (fork_threads, fork_thread_count);

  free (file_to_read);

  return 0;
}

#include <support/test-driver.c>
