/* ****************************************************
 * This program demos how to detach from the controlling terminal on Linux.
 * 
 * It was written by Konrad Rosenbaum, see the article on
 * http://silmor.de/notty.php
 * 
 * This source is in the public domain.
 * **************************************************** */

#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

/* some additional magic that is not in the article */

/* set this to 1 if you want debug output per default */
static int verbose=0;

void init_verbose()
{
  char*env=getenv("NOTTYVERBOSE");
  if(env)
    verbose=atoi(env);
}


/* *********************
 * Part 1: detach from the CTTY
 */


/* our detach-from-tty function */
void detach_tty()
{
  /* try to open the controlling TTY */
  int fd=open("/dev/tty",O_RDWR);
  if(fd<0){
    /* failed: we do not need to detach */
    if(verbose)fprintf(stderr,"No controlling TTY to begin with. No need to detach.\n");
    return;
  }

  /* try to detach */
  if(ioctl(fd,TIOCNOTTY))
          fprintf(stderr,"Warning: unable to detach from controlling TTY.\n");
  else
          if(verbose)fprintf(stderr,"Info: Detached from controlling TTY.\n");

  /* close the handle, it is not needed anymore */
  close(fd);
}

/* *********************
 * Part 2: wrapper for another program
 */


int main(int argc,char**argv)
{
  /* do we have something to do? */
  if(argc<2){
    fprintf(stderr,"Usage: %s command [arguments...]\n set NOTTYVERBOSE=1 for debug output\n",argv[0]);
    return 1;
  }
  /* Verbose? */
  init_verbose();
  /* detach controlling TTY */
  detach_tty();
  /* call original program */
  execvp(argv[1],argv+1);
  /* normally execvp does not return*/
  /* the call failed for some reason */
  fprintf(stderr,"Unable to execute: %s.\n", strerror(errno));
  return 1;
}
