/* This testcase is part of GDB, the GNU debugger.

   Copyright 2011, 2012 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/msg.h>
#include <stdio.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/socket.h>

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *
thread_proc (void *args)
{
  pthread_mutex_lock (&mutex);
  pthread_mutex_unlock (&mutex);
}

int
main (void)
{
  const int flags = IPC_CREAT | 0666;
  key_t shmkey = 3925, semkey = 7428, msgkey = 5294;
  int shmid, semid, msqid;
  FILE *fd;
  pthread_t thread;
  struct sockaddr_in sock_addr;
  int sock;
  unsigned short port;
  socklen_t size;
  int status, try, retries = 1000;

  for (try = 0; try < retries; ++try)
    {
      shmid = shmget (shmkey, 4096, flags | IPC_EXCL);
      if (shmid >= 0)
	break;

      ++shmkey;
    }

  if (shmid < 0)
    {
      printf ("Cannot create shared-memory region after %d tries.\n", retries);
      return 1;
    }

  for (try = 0; try < retries; ++try)
    {
      semid = semget (semkey, 1, flags | IPC_EXCL);
      if (semid >= 0)
	break;

      ++semkey;
    }

  if (semid < 0)
    {
      printf ("Cannot create semaphore after %d tries.\n", retries);
      return 1;
    }

  for (try = 0; try < retries; ++try)
    {
      msqid = msgget (msgkey, flags | IPC_EXCL);
      if (msqid >= 0)
	break;

      ++msgkey;
    }

  if (msqid < 0)
    {
      printf ("Cannot create message queue after %d tries.\n", retries);
      return 1;
    }

  fd = fopen ("/dev/null", "r");

  /* Lock the mutex to prevent the new thread from finishing immediately.  */
  pthread_mutex_lock (&mutex);
  pthread_create (&thread, NULL, thread_proc, 0);
 
  sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sock < 0)
    {
      printf ("Cannot create socket.\n");
      return 1;
    }
 
  sock_addr.sin_family = AF_INET;
  sock_addr.sin_port = 0; /* Bind to a free port.  */
  sock_addr.sin_addr.s_addr = htonl (INADDR_ANY);

  status = bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr));
  if (status < 0)
    {
      printf ("Cannot bind socket.\n");
      return 1;
    }

  /* Find the assigned port number of the socket.  */
  size = sizeof (sock_addr);
  status = getsockname (sock, (struct sockaddr *) &sock_addr, &size);
  if (status < 0)
    {
      printf ("Cannot find name of socket.\n");
      return 1;
    }
  port = ntohs (sock_addr.sin_port);

  status = listen (sock, 1);
  if (status < 0)
    {
      printf ("Cannot listen on socket.\n");
      return 1;
    }

  /* Set breakpoint here.  */

  shmctl (shmid, IPC_RMID, NULL);
  semctl (semid, 0, IPC_RMID, NULL);
  msgctl (msqid, IPC_RMID, NULL);
  fclose (fd);
  close (sock);

  pthread_mutex_unlock (&mutex);
  pthread_join (thread, NULL);

  return 0;
}
