GRASS Programmer's Manual  6.4.1(2011)
gets.c
Go to the documentation of this file.
00001 #include <grass/gis.h>
00002 #include <unistd.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include <signal.h>
00007 
00008 /**********************************************************
00009  * G_gets (buf)
00010  *    char *buf      buffer to receive data
00011  *
00012  *  does a gets() from stdin. exits upon EOF.
00013  *  if stdin is a tty (ie, not a pipe or redirected)
00014  *  then ctrl-z is detected
00015  *
00016  * returns
00017  *  1 read ok
00018  *  0 ctrl-z entered. calling routine should re-print a prompt
00019  *    and call G_gets() again
00020  *
00021  * note: This is very useful for allowing a program to 
00022  *       reprompt after the program is restarted after
00023  *       being stopped with a ctrl-Z.
00024  *
00025  * sample use:
00026  *   do {
00027  *      fprintf (stderr, "Enter some input:  ") ;
00028  *   } while ( ! G_gets(buff) )  ;
00029  *
00030  *   If the user suspends the process at this prompt G_gets will return
00031  *   "0" causing the reprompting.
00032  ***********************************************************/
00033 
00034 static int ctrlz = 0;
00035 static void catch_ctrlz(int);
00036 static void catch_int(int);
00037 
00038 
00039 int G_gets(char *buf)
00040 {
00041 #ifdef SIGTSTP
00042     RETSIGTYPE(*sigtstp) ();
00043     int tty;
00044 #endif
00045     char p[128];
00046     char *eof;
00047 
00048     ctrlz = 0;
00049 #ifdef SIGTSTP
00050     if ((tty = isatty(0))) {
00051         sigtstp = signal(SIGTSTP, catch_ctrlz);
00052         if (sigtstp != (RETSIGTYPE(*)())SIG_DFL)
00053             signal(SIGTSTP, sigtstp);
00054     }
00055 #endif
00056     eof = fgets(p, 100, stdin);
00057     /* strip the EOL character      */
00058     if (strlen(p) > 1 && p[strlen(p) - 1] == '\n' && p[strlen(p) - 2] == '\r')
00059         p[strlen(p) - 2] = '\0';        /* Handles DOS/Windows "\r\n" */
00060     else
00061         p[strlen(p) - 1] = '\0';        /* Handles Unix "\n" or old Mac "\r" */
00062     /*      buf could be any length.  Any overflow will occur here. */
00063     strcpy(buf, p);
00064 
00065 #ifdef SIGTSTP
00066     if (tty)
00067         signal(SIGTSTP, sigtstp);
00068 #endif
00069     if (eof)
00070         return 1;
00071     if (ctrlz)
00072         return 0;
00073 
00074     exit(EXIT_SUCCESS);
00075 }
00076 
00077 static void catch_ctrlz(int n)
00078 {
00079 #ifdef __MINGW32__
00080     G_warning("catch_ctrlz: ignored Ctrl-z");
00081 #else
00082 
00083     RETSIGTYPE(*sigint) ();
00084 
00085     /* having caught ctrlz - effect a ctrl-z using kill */
00086     ctrlz = 1;
00087     signal(n, SIG_DFL);
00088     kill(0, n);
00089 
00090     /* for berkley systems, ctrlz will not cause eof on read */
00091     sigint = signal(SIGINT, catch_int);
00092     kill(getpid(), SIGINT);
00093     signal(SIGINT, sigint);
00094 #endif
00095 }
00096 
00097 static void catch_int(int n)
00098 {
00099 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines