LCOV - code coverage report
Current view: top level - src/bin/scripts - pg_isready.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 72.9 % 129 94
Test Date: 2026-07-19 19:15:43 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 50.0 % 64 32

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * pg_isready --- checks the status of the PostgreSQL server
       4                 :             :  *
       5                 :             :  * Copyright (c) 2013-2026, PostgreSQL Global Development Group
       6                 :             :  *
       7                 :             :  * src/bin/scripts/pg_isready.c
       8                 :             :  *
       9                 :             :  *-------------------------------------------------------------------------
      10                 :             :  */
      11                 :             : 
      12                 :             : #include "postgres_fe.h"
      13                 :             : #include "common.h"
      14                 :             : #include "common/logging.h"
      15                 :             : #include "fe_utils/option_utils.h"
      16                 :             : 
      17                 :             : #define DEFAULT_CONNECT_TIMEOUT "3"
      18                 :             : 
      19                 :             : static void
      20                 :             :             help(const char *progname);
      21                 :             : 
      22                 :             : int
      23                 :           8 : main(int argc, char **argv)
      24                 :             : {
      25                 :             :     int         c;
      26                 :             : 
      27                 :             :     const char *progname;
      28                 :             : 
      29                 :           8 :     const char *pghost = NULL;
      30                 :           8 :     const char *pgport = NULL;
      31                 :           8 :     const char *pguser = NULL;
      32                 :           8 :     const char *pgdbname = NULL;
      33                 :           8 :     const char *connect_timeout = DEFAULT_CONNECT_TIMEOUT;
      34                 :             : 
      35                 :           8 :     const char *pghost_str = NULL;
      36                 :           8 :     const char *pghostaddr_str = NULL;
      37                 :           8 :     const char *pgport_str = NULL;
      38                 :             : 
      39                 :             : #define PARAMS_ARRAY_SIZE   7
      40                 :             : 
      41                 :             :     const char *keywords[PARAMS_ARRAY_SIZE];
      42                 :             :     const char *values[PARAMS_ARRAY_SIZE];
      43                 :             : 
      44                 :           8 :     bool        quiet = false;
      45                 :             : 
      46                 :             :     PGPing      rv;
      47                 :           8 :     PQconninfoOption *opts = NULL;
      48                 :           8 :     PQconninfoOption *defs = NULL;
      49                 :             :     PQconninfoOption *opt;
      50                 :             :     PQconninfoOption *def;
      51                 :           8 :     char       *errmsg = NULL;
      52                 :             : 
      53                 :             :     /*
      54                 :             :      * We accept user and database as options to avoid useless errors from
      55                 :             :      * connecting with invalid params
      56                 :             :      */
      57                 :             : 
      58                 :             :     static struct option long_options[] = {
      59                 :             :         {"dbname", required_argument, NULL, 'd'},
      60                 :             :         {"host", required_argument, NULL, 'h'},
      61                 :             :         {"port", required_argument, NULL, 'p'},
      62                 :             :         {"quiet", no_argument, NULL, 'q'},
      63                 :             :         {"timeout", required_argument, NULL, 't'},
      64                 :             :         {"username", required_argument, NULL, 'U'},
      65                 :             :         {NULL, 0, NULL, 0}
      66                 :             :     };
      67                 :             : 
      68                 :           8 :     pg_logging_init(argv[0]);
      69                 :           8 :     progname = get_progname(argv[0]);
      70                 :           8 :     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
      71                 :           8 :     handle_help_version_opts(argc, argv, progname, help);
      72                 :             : 
      73         [ +  + ]:          16 :     while ((c = getopt_long(argc, argv, "d:h:p:qt:U:", long_options, NULL)) != -1)
      74                 :             :     {
      75   [ -  +  +  -  :          11 :         switch (c)
                +  -  + ]
      76                 :             :         {
      77                 :           0 :             case 'd':
      78                 :           0 :                 pgdbname = pg_strdup(optarg);
      79                 :           0 :                 break;
      80                 :           3 :             case 'h':
      81                 :           3 :                 pghost = pg_strdup(optarg);
      82                 :           3 :                 break;
      83                 :           3 :             case 'p':
      84                 :           3 :                 pgport = pg_strdup(optarg);
      85                 :           3 :                 break;
      86                 :           0 :             case 'q':
      87                 :           0 :                 quiet = true;
      88                 :           0 :                 break;
      89                 :           4 :             case 't':
      90                 :           4 :                 connect_timeout = pg_strdup(optarg);
      91                 :           4 :                 break;
      92                 :           0 :             case 'U':
      93                 :           0 :                 pguser = pg_strdup(optarg);
      94                 :           0 :                 break;
      95                 :           1 :             default:
      96                 :             :                 /* getopt_long already emitted a complaint */
      97                 :           1 :                 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
      98                 :             : 
      99                 :             :                 /*
     100                 :             :                  * We need to make sure we don't return 1 here because someone
     101                 :             :                  * checking the return code might infer unintended meaning
     102                 :             :                  */
     103                 :           1 :                 exit(PQPING_NO_ATTEMPT);
     104                 :             :         }
     105                 :             :     }
     106                 :             : 
     107         [ -  + ]:           5 :     if (optind < argc)
     108                 :             :     {
     109                 :           0 :         pg_log_error("too many command-line arguments (first is \"%s\")",
     110                 :             :                      argv[optind]);
     111                 :           0 :         pg_log_error_hint("Try \"%s --help\" for more information.", progname);
     112                 :             : 
     113                 :             :         /*
     114                 :             :          * We need to make sure we don't return 1 here because someone
     115                 :             :          * checking the return code might infer unintended meaning
     116                 :             :          */
     117                 :           0 :         exit(PQPING_NO_ATTEMPT);
     118                 :             :     }
     119                 :             : 
     120                 :           5 :     keywords[0] = "host";
     121                 :           5 :     values[0] = pghost;
     122                 :           5 :     keywords[1] = "port";
     123                 :           5 :     values[1] = pgport;
     124                 :           5 :     keywords[2] = "user";
     125                 :           5 :     values[2] = pguser;
     126                 :           5 :     keywords[3] = "dbname";
     127                 :           5 :     values[3] = pgdbname;
     128                 :           5 :     keywords[4] = "connect_timeout";
     129                 :           5 :     values[4] = connect_timeout;
     130                 :           5 :     keywords[5] = "fallback_application_name";
     131                 :           5 :     values[5] = progname;
     132                 :           5 :     keywords[6] = NULL;
     133                 :           5 :     values[6] = NULL;
     134                 :             : 
     135                 :             :     /*
     136                 :             :      * Get the host and port so we can display them in our output
     137                 :             :      */
     138         [ -  + ]:           5 :     if (pgdbname &&
     139         [ #  # ]:           0 :         (strncmp(pgdbname, "postgresql://", 13) == 0 ||
     140         [ #  # ]:           0 :          strncmp(pgdbname, "postgres://", 11) == 0 ||
     141         [ #  # ]:           0 :          strchr(pgdbname, '=') != NULL))
     142                 :             :     {
     143                 :           0 :         opts = PQconninfoParse(pgdbname, &errmsg);
     144         [ #  # ]:           0 :         if (opts == NULL)
     145                 :             :         {
     146                 :           0 :             pg_log_error("%s", errmsg);
     147                 :           0 :             exit(PQPING_NO_ATTEMPT);
     148                 :             :         }
     149                 :             :     }
     150                 :             : 
     151                 :           5 :     defs = PQconndefaults();
     152         [ -  + ]:           5 :     if (defs == NULL)
     153                 :             :     {
     154                 :           0 :         pg_log_error("could not fetch default options");
     155                 :           0 :         exit(PQPING_NO_ATTEMPT);
     156                 :             :     }
     157                 :             : 
     158         [ +  + ]:         265 :     for (opt = opts, def = defs; def->keyword; def++)
     159                 :             :     {
     160         [ +  + ]:         260 :         if (strcmp(def->keyword, "host") == 0)
     161                 :             :         {
     162   [ -  +  -  - ]:           5 :             if (opt && opt->val)
     163                 :           0 :                 pghost_str = opt->val;
     164         [ +  + ]:           5 :             else if (pghost)
     165                 :           3 :                 pghost_str = pghost;
     166         [ +  - ]:           2 :             else if (def->val)
     167                 :           2 :                 pghost_str = def->val;
     168                 :             :             else
     169                 :           0 :                 pghost_str = DEFAULT_PGSOCKET_DIR;
     170                 :             :         }
     171         [ +  + ]:         255 :         else if (strcmp(def->keyword, "hostaddr") == 0)
     172                 :             :         {
     173   [ -  +  -  - ]:           5 :             if (opt && opt->val)
     174                 :           0 :                 pghostaddr_str = opt->val;
     175         [ -  + ]:           5 :             else if (def->val)
     176                 :           0 :                 pghostaddr_str = def->val;
     177                 :             :         }
     178         [ +  + ]:         250 :         else if (strcmp(def->keyword, "port") == 0)
     179                 :             :         {
     180   [ -  +  -  - ]:           5 :             if (opt && opt->val)
     181                 :           0 :                 pgport_str = opt->val;
     182         [ +  + ]:           5 :             else if (pgport)
     183                 :           3 :                 pgport_str = pgport;
     184         [ +  - ]:           2 :             else if (def->val)
     185                 :           2 :                 pgport_str = def->val;
     186                 :             :         }
     187                 :             : 
     188         [ -  + ]:         260 :         if (opt)
     189                 :           0 :             opt++;
     190                 :             :     }
     191                 :             : 
     192                 :           5 :     rv = PQpingParams(keywords, values, 1);
     193                 :             : 
     194         [ +  - ]:           5 :     if (!quiet)
     195                 :             :     {
     196         [ -  + ]:           5 :         printf("%s:%s - ",
     197                 :             :                pghostaddr_str != NULL ? pghostaddr_str : pghost_str,
     198                 :             :                pgport_str);
     199                 :             : 
     200   [ +  -  +  -  :           5 :         switch (rv)
                      - ]
     201                 :             :         {
     202                 :           4 :             case PQPING_OK:
     203                 :           4 :                 printf(_("accepting connections\n"));
     204                 :           4 :                 break;
     205                 :           0 :             case PQPING_REJECT:
     206                 :           0 :                 printf(_("rejecting connections\n"));
     207                 :           0 :                 break;
     208                 :           1 :             case PQPING_NO_RESPONSE:
     209                 :           1 :                 printf(_("no response\n"));
     210                 :           1 :                 break;
     211                 :           0 :             case PQPING_NO_ATTEMPT:
     212                 :           0 :                 printf(_("no attempt\n"));
     213                 :           0 :                 break;
     214                 :           0 :             default:
     215                 :           0 :                 printf(_("unknown\n"));
     216                 :             :         }
     217                 :             :     }
     218                 :             : 
     219                 :           5 :     exit(rv);
     220                 :             : }
     221                 :             : 
     222                 :             : static void
     223                 :           1 : help(const char *progname)
     224                 :             : {
     225                 :           1 :     printf(_("%s issues a connection check to a PostgreSQL database.\n\n"), progname);
     226                 :           1 :     printf(_("Usage:\n"));
     227                 :           1 :     printf(_("  %s [OPTION]...\n"), progname);
     228                 :             : 
     229                 :           1 :     printf(_("\nOptions:\n"));
     230                 :           1 :     printf(_("  -d, --dbname=DBNAME      database name\n"));
     231                 :           1 :     printf(_("  -q, --quiet              run quietly\n"));
     232                 :           1 :     printf(_("  -V, --version            output version information, then exit\n"));
     233                 :           1 :     printf(_("  -?, --help               show this help, then exit\n"));
     234                 :             : 
     235                 :           1 :     printf(_("\nConnection options:\n"));
     236                 :           1 :     printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
     237                 :           1 :     printf(_("  -p, --port=PORT          database server port\n"));
     238                 :           1 :     printf(_("  -t, --timeout=SECS       seconds to wait when attempting connection, 0 disables (default: %s)\n"), DEFAULT_CONNECT_TIMEOUT);
     239                 :           1 :     printf(_("  -U, --username=USERNAME  user name to connect as\n"));
     240                 :           1 :     printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
     241                 :           1 :     printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
     242                 :           1 : }
        

Generated by: LCOV version 2.0-1