pgpool-II-3.3.2/0000775000076400007640000000000012245776616010351 500000000000000pgpool-II-3.3.2/TODO0000664000076400007640000000451512245576266010765 00000000000000$Header$ * General - Reset application name to "pgppol" when client disconnects(3.1. why not use set command?) -> Done. - Use reset_query_list to reset to "pgpool" for client disconnection - Reset to client specified application name when reusing existing connection. - Allow to call pcp commands/show commands as a stored procedures of PostgreSQL(3.1 SRAOSS) - Allow client encoding conversion. This was possible in pgpool-I - Avoid cross pgpool process deadlock situation. This is a long standing problem since pgpool-II was born (pgpool-I avoids this by setting timeout) - If DISCARD ALL is specified in the reset_query_list and transaction is not closed when client disconnects, automatically issue ABORT before issuing DISCARD ALL - Allow to specify queries issued when starting sessions - Audit functionality? - Make accept queue - Graceful attaching a node * Query handling - Allow multi statement - Enhance DROP DATABASE handling (not disconnect all idle connections) * Replication - Allow per table replication - Allow per session level and query level load balancing - More reliable way to replicate SEQUENCES - Allow to replicate OIDs, XIDs * Master/slave mode - Allow to use more than 1 standbys(3.1) * On line recovery * Query cache - Cache invalidation - More effcient cache (memcache?) * Log - Mutiple log levels(3.1, but low priority) - Multiple log destinations(3.1, but low priority) * Parallel query - Performance enhance for more complex queries - Allow to handle transaction - Allow to handle extended queries - process alias in FROM clause db=# select * from data1 as d1 inner join data2 as d2 on d1.id=d2.id; ERROR: sql error DETAIL: ERROR: missing FROM-clause entry for table "d1" LINE 1: SELECT pool_parallel("SELECT d1.id, d1.aaaa, d1.bbbb... ^ 2008-03-11 10:28:17 LOG: pid 6186: statement: SELECT pool_parallel("SELECT d1.id, d1.aaaa, d1.bbbb, a.cccc FROM data1") - process USING clause in JOIN * pgpoolAdmin - Allow to use double quotation in reset_query_list - German messages - Allow to run pgpoolAdmin on a host different from a host which pgpool-II is running on(3.2?) - Allow to stop PostgeSQL from pgpoolAdmin to make the on-line recovery more convenient(pgpool_stop()?) * Docs - Write libpcp API docs - French documentations(3.1) - German documentations(3.1) pgpool-II-3.3.2/README.euc_jp0000664000076400007640000000004412052601364012372 00000000000000doc/pgpool-ja.html を見てください。 pgpool-II-3.3.2/pool_type.h0000664000076400007640000001045412245576267012460 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2011 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_type.h.: type definition header file * */ #ifndef POOL_TYPE_H #define POOL_TYPE_H #include "config.h" #include #include #include "pcp/libpcp_ext.h" /* Define common boolean type. C++ and BEOS already has it so exclude them. */ #ifdef c_plusplus #ifndef __cplusplus #define __cplusplus #endif /* __cplusplus */ #endif /* c_plusplus */ #ifndef __BEOS__ #ifndef __cplusplus #ifndef bool typedef char bool; #endif #ifndef true #define true ((bool) 1) #endif #ifndef TRUE #define TRUE ((bool) 1) #endif #ifndef false #define false ((bool) 0) #endif #ifndef FALSE #define FALSE ((bool) 0) #endif #endif /* not C++ */ #endif /* __BEOS__ */ typedef signed char int8; /* == 8 bits */ typedef signed short int16; /* == 16 bits */ typedef signed int int32; /* == 32 bits */ /* * uintN * Unsigned integer, EXACTLY N BITS IN SIZE, * used for numerical computations and the * frontend/backend protocol. */ typedef unsigned char uint8; /* == 8 bits */ typedef unsigned short uint16; /* == 16 bits */ typedef unsigned int uint32; /* == 32 bits */ typedef long int int64; typedef enum { LOAD_UNSELECTED = 0, LOAD_SELECTED } LOAD_BALANCE_STATUS; /* * Backend status record file */ typedef struct { BACKEND_STATUS status[MAX_NUM_BACKENDS]; } BackendStatusRecord; /* * It seems that sockaddr_storage is now commonly used in place of sockaddr. * So, define it if it is not define yet, and create new SockAddr structure * that uses sockaddr_storage. */ #ifdef HAVE_STRUCT_SOCKADDR_STORAGE #ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY #ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY #define ss_family __ss_family #else #error struct sockaddr_storage does not provide an ss_family member #endif /* HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */ #endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY */ #ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN #define ss_len __ss_len #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 #endif /* HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN */ #else /* !HAVE_STRUCT_SOCKADDR_STORAGE */ /* Define a struct sockaddr_storage if we don't have one. */ struct sockaddr_storage { union { struct sockaddr sa; /* get the system-dependent fields */ long int ss_align; /* ensures struct is properly aligned. original uses int64 */ char ss_pad[128]; /* ensures struct has desired size */ } ss_stuff; }; #define ss_family ss_stuff.sa.sa_family /* It should have an ss_len field if sockaddr has sa_len. */ #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN #define ss_len ss_stuff.sa.sa_len #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 #endif #endif /* HAVE_STRUCT_SOCKADDR_STORAGE */ typedef struct { struct sockaddr_storage addr; /* ACCEPT_TYPE_ARG3 - Third argument type of accept(). * It is defined in ac_func_accept_argtypes.m4 */ ACCEPT_TYPE_ARG3 salen; } SockAddr; /* UserAuth type used for HBA which indicates the authentication method */ typedef enum UserAuth { uaReject, /* uaKrb4, */ /* uaKrb5, */ uaTrust, /* uaIdent, */ /* uaPassword, */ /* uaCrypt, */ uaMD5 #ifdef USE_PAM ,uaPAM #endif /* USE_PAM */ } UserAuth; #define AUTH_REQ_OK 0 /* User is authenticated */ #define AUTH_REQ_KRB4 1 /* Kerberos V4 */ #define AUTH_REQ_KRB5 2 /* Kerberos V5 */ #define AUTH_REQ_PASSWORD 3 /* Password */ #define AUTH_REQ_CRYPT 4 /* crypt password */ #define AUTH_REQ_MD5 5 /* md5 password */ #define AUTH_REQ_SCM_CREDS 6 /* transfer SCM credentials */ typedef unsigned int AuthRequest; #endif /* POOL_TYPE_H */ pgpool-II-3.3.2/md5.c0000664000076400007640000002506712245576256011132 00000000000000/* * md5.c * * Implements the MD5 Message-Digest Algorithm as specified in * RFC 1321. This implementation is a simple one, in that it * needs every input byte to be buffered before doing any * calculations. I do not expect this file to be used for * general purpose MD5'ing of large amounts of data, only for * generating hashed passwords from limited input. * * Sverre H. Huseby * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * This file is imported from PostgreSQL 8.1.3., and modified by * Taiki Yamaguchi * * IDENTIFICATION * $Header$ */ #include #include #include #include #include "pool.h" #include "md5.h" #ifdef NOT_USED typedef unsigned char uint8; /* == 8 bits */ typedef unsigned int uint32; /* == 32 bits */ #endif #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) #define FF(a, b, c, d, x, s, ac) { \ (a) += F((b), (c), (d)) + (x) + (uint32)(ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G((b), (c), (d)) + (x) + (uint32)(ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H((b), (c), (d)) + (x) + (uint32)(ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I((b), (c), (d)) + (x) + (uint32)(ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } const uint32 T[64] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; /* * PRIVATE FUNCTIONS */ /* * The returned array is allocated using malloc. the caller should free it * when it is no longer needed. */ static uint8 * createPaddedCopyWithLength(uint8 *b, uint32 *l) { /* * uint8 *b - message to be digested * uint32 *l - length of b */ uint8 *ret; uint32 q; uint32 len, newLen448; uint32 len_high, len_low; /* 64-bit value split into 32-bit sections */ len = ((b == NULL) ? 0 : *l); newLen448 = len + 64 - (len % 64) - 8; if (newLen448 <= len) newLen448 += 64; *l = newLen448 + 8; if ((ret = (uint8 *) malloc(sizeof(uint8) * *l)) == NULL) return NULL; if (b != NULL) memcpy(ret, b, sizeof(uint8) * len); /* pad */ ret[len] = 0x80; for (q = len + 1; q < newLen448; q++) ret[q] = 0x00; /* append length as a 64 bit bitcount */ len_low = len; /* split into two 32-bit values */ /* we only look at the bottom 32-bits */ len_high = len >> 29; len_low <<= 3; q = newLen448; ret[q++] = (len_low & 0xff); len_low >>= 8; ret[q++] = (len_low & 0xff); len_low >>= 8; ret[q++] = (len_low & 0xff); len_low >>= 8; ret[q++] = (len_low & 0xff); ret[q++] = (len_high & 0xff); len_high >>= 8; ret[q++] = (len_high & 0xff); len_high >>= 8; ret[q++] = (len_high & 0xff); len_high >>= 8; ret[q] = (len_high & 0xff); return ret; } static void doTheRounds(uint32 X[16], uint32 state[4]) { uint32 a, b, c, d; a = state[0]; b = state[1]; c = state[2]; d = state[3]; /* round 1 */ FF(a, b, c, d, X[ 0], S11, T[ 0]); FF(d, a, b, c, X[ 1], S12, T[ 1]); FF(c, d, a, b, X[ 2], S13, T[ 2]); FF(b, c, d, a, X[ 3], S14, T[ 3]); FF(a, b, c, d, X[ 4], S11, T[ 4]); FF(d, a, b, c, X[ 5], S12, T[ 5]); FF(c, d, a, b, X[ 6], S13, T[ 6]); FF(b, c, d, a, X[ 7], S14, T[ 7]); FF(a, b, c, d, X[ 8], S11, T[ 8]); FF(d, a, b, c, X[ 9], S12, T[ 9]); FF(c, d, a, b, X[10], S13, T[10]); FF(b, c, d, a, X[11], S14, T[11]); FF(a, b, c, d, X[12], S11, T[12]); FF(d, a, b, c, X[13], S12, T[13]); FF(c, d, a, b, X[14], S13, T[14]); FF(b, c, d, a, X[15], S14, T[15]); GG(a, b, c, d, X[ 1], S21, T[16]); GG(d, a, b, c, X[ 6], S22, T[17]); GG(c, d, a, b, X[11], S23, T[18]); GG(b, c, d, a, X[ 0], S24, T[19]); GG(a, b, c, d, X[ 5], S21, T[20]); GG(d, a, b, c, X[10], S22, T[21]); GG(c, d, a, b, X[15], S23, T[22]); GG(b, c, d, a, X[ 4], S24, T[23]); GG(a, b, c, d, X[ 9], S21, T[24]); GG(d, a, b, c, X[14], S22, T[25]); GG(c, d, a, b, X[ 3], S23, T[26]); GG(b, c, d, a, X[ 8], S24, T[27]); GG(a, b, c, d, X[13], S21, T[28]); GG(d, a, b, c, X[ 2], S22, T[29]); GG(c, d, a, b, X[ 7], S23, T[30]); GG(b, c, d, a, X[12], S24, T[31]); HH(a, b, c, d, X[ 5], S31, T[32]); HH(d, a, b, c, X[ 8], S32, T[33]); HH(c, d, a, b, X[11], S33, T[34]); HH(b, c, d, a, X[14], S34, T[35]); HH(a, b, c, d, X[ 1], S31, T[36]); HH(d, a, b, c, X[ 4], S32, T[37]); HH(c, d, a, b, X[ 7], S33, T[38]); HH(b, c, d, a, X[10], S34, T[39]); HH(a, b, c, d, X[13], S31, T[40]); HH(d, a, b, c, X[ 0], S32, T[41]); HH(c, d, a, b, X[ 3], S33, T[42]); HH(b, c, d, a, X[ 6], S34, T[43]); HH(a, b, c, d, X[ 9], S31, T[44]); HH(d, a, b, c, X[12], S32, T[45]); HH(c, d, a, b, X[15], S33, T[46]); HH(b, c, d, a, X[ 2], S34, T[47]); II(a, b, c, d, X[ 0], S41, T[48]); II(d, a, b, c, X[ 7], S42, T[49]); II(c, d, a, b, X[14], S43, T[50]); II(b, c, d, a, X[ 5], S44, T[51]); II(a, b, c, d, X[12], S41, T[52]); II(d, a, b, c, X[ 3], S42, T[53]); II(c, d, a, b, X[10], S43, T[54]); II(b, c, d, a, X[ 1], S44, T[55]); II(a, b, c, d, X[ 8], S41, T[56]); II(d, a, b, c, X[15], S42, T[57]); II(c, d, a, b, X[ 6], S43, T[58]); II(b, c, d, a, X[13], S44, T[59]); II(a, b, c, d, X[ 4], S41, T[60]); II(d, a, b, c, X[11], S42, T[61]); II(c, d, a, b, X[ 2], S43, T[62]); II(b, c, d, a, X[ 9], S44, T[63]); state[0] += a; state[1] += b; state[2] += c; state[3] += d; } static int calculateDigestFromBuffer(uint8 *b, uint32 len, uint8 sum[16]) { /* * uint8 *b - message to be digested * uint32 len - length of b * uint8 sum[16] - md5 digest calculated from b */ register uint32 i, j, k, newI; uint32 l; uint8 *input; register uint32 *wbp; uint32 workBuff[16], state[4]; l = len; state[0] = 0x67452301; state[1] = 0xEFCDAB89; state[2] = 0x98BADCFE; state[3] = 0x10325476; if ((input = createPaddedCopyWithLength(b, &l)) == NULL) return 0; for (i = 0;;) { if ((newI = i + 16 * 4) > l) break; k = i + 3; for (j = 0; j < 16; j++) { wbp = (workBuff + j); *wbp = input[k--]; *wbp <<= 8; *wbp |= input[k--]; *wbp <<= 8; *wbp |= input[k--]; *wbp <<= 8; *wbp |= input[k]; k += 7; } doTheRounds(workBuff, state); i = newI; } free(input); j = 0; for (i = 0; i < 4; i++) { k = state[i]; sum[j++] = (k & 0xff); k >>= 8; sum[j++] = (k & 0xff); k >>= 8; sum[j++] = (k & 0xff); k >>= 8; sum[j++] = (k & 0xff); } return 1; } static void bytesToHex(uint8 b[16], char *s) { static const char *hex = "0123456789abcdef"; int q, w; for (q = 0, w = 0; q < 16; q++) { s[w++] = hex[(b[q] >> 4) & 0x0F]; s[w++] = hex[b[q] & 0x0F]; } s[w] = '\0'; } /* * PUBLIC FUNCTIONS */ /* * pool_md5_hash * * Calculates the MD5 sum of the bytes in a buffer. * * SYNOPSIS int pool_md5_hash(const void *buff, size_t len, char *hexsum) * * INPUT buff the buffer containing the bytes that you want * the MD5 sum of. * len number of bytes in the buffer. * * OUTPUT hexsum the MD5 sum as a '\0'-terminated string of * hexadecimal digits. an MD5 sum is 16 bytes long. * each byte is represented by two heaxadecimal * characters. you thus need to provide an array * of 33 characters, including the trailing '\0'. * * RETURNS false on failure (out of memory for internal buffers) or * true on success. * * STANDARDS MD5 is described in RFC 1321. * * AUTHOR Sverre H. Huseby * MODIFIED by Taiki Yamaguchi * */ int pool_md5_hash(const void *buff, size_t len, char *hexsum) { uint8 sum[16]; if (!calculateDigestFromBuffer((uint8 *) buff, len, sum)) return 0; /* failed */ bytesToHex(sum, hexsum); return 1; /* success */ } /* * Computes MD5 checksum of "passwd" (a null-terminated string) followed * by "salt" (which need not be null-terminated). * * Output format is a 32-hex-digit MD5 checksum. * Hence, the output buffer "buf" must be at least 33 bytes long. * * Returns 1 if okay, 0 on error (out of memory). */ int pool_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf) { size_t passwd_len = strlen(passwd); char *crypt_buf = malloc(passwd_len + salt_len); int ret; if (!crypt_buf) return 0; /* failed */ /* * Place salt at the end because it may be known by users trying to crack * the MD5 output. */ strcpy(crypt_buf, passwd); memcpy(crypt_buf + passwd_len, salt, salt_len); ret = pool_md5_hash(crypt_buf, passwd_len + salt_len, buf); free(crypt_buf); return ret; } /* * Computes MD5 checksum of "passwd" (a null-terminated string) followed * by "salt" (which need not be null-terminated). * * Output format is "md5" followed by a 32-hex-digit MD5 checksum. * Hence, the output buffer "buf" must be at least 36 bytes long. * * Returns TRUE if okay, FALSE on error (out of memory). */ bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf) { size_t passwd_len = strlen(passwd); /* +1 here is just to avoid risk of unportable malloc(0) */ char *crypt_buf = malloc(passwd_len + salt_len + 1); bool ret; if (!crypt_buf) return false; /* * Place salt at the end because it may be known by users trying to crack * the MD5 output. */ memcpy(crypt_buf, passwd, passwd_len); memcpy(crypt_buf + passwd_len, salt, salt_len); strcpy(buf, "md5"); ret = pool_md5_hash(crypt_buf, passwd_len + salt_len, buf + 3); free(crypt_buf); return ret; } pgpool-II-3.3.2/pool_query_cache.c0000664000076400007640000006464312245576267013773 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2010 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_query_cache.c: query cache * */ #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #include "pool.h" #include "md5.h" #include "pool_stream.h" #include "pool_config.h" #include "pool_proto_modules.h" #include "parser/parsenodes.h" #define QUERY_CACHE_TABLE_NAME "query_cache" #define CACHE_REGISTER_PREPARED_STMT "register_prepared_stmt" #define DEFAULT_CACHE_SIZE 8192 #define SYSDB_CON (SYSDB_CONNECTION->con) #define SYSDB_MAJOR (SYSDB_CONNECTION->sp->major) #define CACHE_TABLE_INFO (SYSDB_INFO->query_cache_table_info) /* data structure to store RowDescription and DataRow cache */ typedef struct { char *md5_query; /* query in md5 hushed format*/ char *query; /* query string */ char *cache; /* cached data */ int cache_size; /* cached data size */ int cache_offset; /* points the end of cache */ char *db_name; /* database name */ char *create_time; /* cache create timestamp in ISO format */ } QueryCacheInfo; typedef enum { CACHE_FOUND, CACHE_NOT_FOUND, CACHE_ERROR } CACHE_STATUS; static QueryCacheInfo *query_cache_info; static CACHE_STATUS search_system_db_for_cache(POOL_CONNECTION *frontend, char *sql, int sql_len, struct timeval *t, char tstate); static int ForwardCacheToFrontend(POOL_CONNECTION *frontend, char *cache, char tstate); static int init_query_cache_info(POOL_CONNECTION *pc, char *database, char *query); static void free_query_cache_info(void); static int malloc_failed(void *p); static int write_cache(void *buf, int len); static char *pq_time_to_str(time_t t); static int system_db_connection_exists(void); static void define_prepared_statements(void); /* -------------------------------- * pool_clear_cache - clears cache data from the SystemDB * * return 0 on success, -1 otherwise * -------------------------------- */ int pool_clear_cache_by_time(Interval *interval, int size) { PGresult *pg_result = NULL; long interval_in_days = 0; long interval_in_seconds = 0; time_t query_delete_timepoint; char *query_delete_timepoint_in_str = NULL; int sql_len; char *sql = NULL; int i; if (! system_db_connection_exists()) return -1; for (i = 0; i < size; i++) { int q = interval[i].quantity; switch (interval[i].unit) { case millennium: case millenniums: q *= 10; case century: case centuries: q *= 10; case decade: case decades: q *= 10; case year: case years: q *= 12; case month: case months: q *= 31; /* should I change this according to the month? */ interval_in_days += q; break; case week: case weeks: q *= 7; case day: case days: q *= 24; case hour: case hours: q *= 60; case minute: case minutes: q *= 60; case second: case seconds: interval_in_seconds += q; break; } } interval_in_seconds = (interval_in_days * 86400) + interval_in_seconds; query_delete_timepoint = time(NULL) - interval_in_seconds; query_delete_timepoint_in_str = pq_time_to_str(query_delete_timepoint); if (malloc_failed(query_delete_timepoint_in_str)) return -1; sql_len = strlen(pool_config->system_db_schema) + strlen(QUERY_CACHE_TABLE_NAME) + strlen(query_delete_timepoint_in_str) + 64; sql = (char *)malloc(sql_len); if (malloc_failed(sql)) { free(query_delete_timepoint_in_str); return -1; } snprintf(sql, sql_len, "DELETE FROM %s.%s WHERE create_time <= '%s'", pool_config->system_db_schema, QUERY_CACHE_TABLE_NAME, query_delete_timepoint_in_str); pool_debug("pool_clear_cache: delete all query cache created before '%s'", query_delete_timepoint_in_str); pg_result = PQexec(system_db_info->pgconn, sql); if (!pg_result || PQresultStatus(pg_result) != PGRES_COMMAND_OK) { pool_error("pool_clear_cache: PQexec() failed. reason: %s", PQerrorMessage(system_db_info->pgconn)); PQclear(pg_result); free(query_delete_timepoint_in_str); free(sql); return -1; } PQclear(pg_result); free(query_delete_timepoint_in_str); free(sql); return 0; } /* -------------------------------- * pool_query_cache_table_exists - checks if query_cache table exists in the SystemDB * * This function is called once and only once from the pgpool parent process. * return 1 if query_cache table exists, 0 otherwise. * -------------------------------- */ int pool_query_cache_table_exists(void) { PGresult *pg_result = NULL; char *sql = NULL; int sql_len = strlen(pool_config->system_db_schema) + strlen(QUERY_CACHE_TABLE_NAME) + 64; if (! system_db_connection_exists()) return 0; sql = (char *)malloc(sql_len); if (malloc_failed(sql)) return 0; snprintf(sql, sql_len, "SELECT hash, query, value, dbname, create_time FROM %s.%s LIMIT 1", pool_config->system_db_schema, QUERY_CACHE_TABLE_NAME); pg_result = PQexec(system_db_info->pgconn, sql); if (!pg_result || PQresultStatus(pg_result) != PGRES_TUPLES_OK) { pool_error("pool_query_cache_table_exists: PQexec() failed. reason: %s", PQerrorMessage(system_db_info->pgconn)); PQclear(pg_result); free(sql); return 0; } PQclear(pg_result); pool_close_libpq_connection(); free(sql); return 1; } /* -------------------------------- * pool_query_cache_lookup - retrieve query cache from the SystemDB * * creates a SQL query string for searching a cache from the SystemDB. * * returns POOL_CONTINUE if cache is found. returns POOL_END if cache was * not found. returns POOL_ERROR if an error has been encountered while * searching. * * Note that POOL_END and POOL_ERROR are treated the same by the caller * (pool_process_query.c). * POOL_END and POOL_ERROR both indicates to the caller that the search * query must be forwarded to the backends in order to retrieve data and * the result be cached. * Only difference is that POOL_ERROR indicates that some fatal error has * occurred; query cache function, however, should be seamless to the user * whether cache was not found or error has occurred during cache retrieve. * -------------------------------- */ POOL_STATUS pool_query_cache_lookup(POOL_CONNECTION *frontend, char *query, char *database, char tstate) { char *sql = NULL; int sql_len; char md5_query[33]; struct timeval timeout; int status; if (! system_db_connection_exists()) return POOL_ERROR; /* same as POOL_END ... at least for now */ sql_len = strlen(pool_config->system_db_schema) + strlen(QUERY_CACHE_TABLE_NAME) + sizeof(md5_query) + strlen(database) + 64; sql = (char *)malloc(sql_len); if (malloc_failed(sql)) return POOL_ERROR; /* should I exit here rather than returning an error? */ /* cached data lookup */ pool_md5_hash(query, strlen(query), md5_query); snprintf(sql, sql_len, "SELECT value FROM %s.%s WHERE hash = '%s' AND dbname = '%s'", pool_config->system_db_schema, QUERY_CACHE_TABLE_NAME, md5_query, database); /* set timeout value for select */ timeout.tv_sec = pool_config->child_life_time; timeout.tv_usec = 0; pool_debug("pool_query_cache_lookup: searching cache for query: \"%s\"", query); status = search_system_db_for_cache(frontend, sql, strlen(sql)+1, &timeout, tstate); /* make sure that the remaining data is discarded */ SYSDB_CON->po = 0; SYSDB_CON->len = 0; free(sql); /* cache found, and no backend communication needed */ if (status == CACHE_FOUND) { return POOL_CONTINUE; } /* cache not found */ if (status == CACHE_ERROR) { pool_error("pool_query_cache_lookup: query cache lookup failed"); /* reset the SystemDB connection */ if (system_db_info->pgconn) pool_close_libpq_connection(); return POOL_ERROR; /* same as POOL_END ... at least for now */ } pool_debug("pool_query_cache_lookup: query cache not found"); return POOL_END; } /* -------------------------------- * search_system_db_for_cache - search for query cache in libpq protocol level * * sends a cache searching query string using libpq protocol to the SystemDB. * if the SystemDB returns cache, forward the data to the frontend, and return * CACHE_FOUND. if cache was not found, silently discards the remaining data * returned by the SystemDB, and return CACHE_NOT_FOUND. returns CACHE_ERROR * if an error was encountered. * -------------------------------- */ static CACHE_STATUS search_system_db_for_cache(POOL_CONNECTION *frontend, char *sql, int sql_len, struct timeval *t, char tstate) { fd_set readmask; int fds; int num_fds; struct timeval *timeout = NULL; char kind; int readlen; char *data = NULL; CACHE_STATUS return_value = CACHE_ERROR; int cache_found = 0; pool_debug("pool_query_cache_lookup: executing query: \"%s\"", sql); pool_write(SYSDB_CON, "Q", 1); if (SYSDB_MAJOR == PROTO_MAJOR_V3) { int sendlen = htonl(sql_len + 4); pool_write(SYSDB_CON, &sendlen, sizeof(sendlen)); } if (pool_write_and_flush(SYSDB_CON, sql, sql_len) < 0) { pool_error("pool_query_cache_lookup: error while sending data to the SystemDB"); return CACHE_ERROR; } if ((t->tv_sec + t->tv_usec) == 0) timeout = NULL; else timeout = t; /* don't really need select() or for(;;) here, but we may need it someday... or not */ for (;;) { FD_ZERO(&readmask); num_fds = 0; num_fds = SYSDB_CON->fd + 1; FD_SET(SYSDB_CON->fd, &readmask); fds = select(num_fds, &readmask, NULL, NULL, timeout); if (fds == -1) { if (errno == EINTR) continue; pool_error("pool_query_cache_lookup: select() failed. reason: %s", strerror(errno)); return CACHE_ERROR; } /* select() timeout */ if (fds == 0) return CACHE_ERROR; for (;;) { if (! FD_ISSET(SYSDB_CON->fd, &readmask)) { pool_error("pool_query_cache_lookup: select() failed"); return CACHE_ERROR; } /* read kind */ if (pool_read(SYSDB_CON, &kind, sizeof(kind)) < 0) { pool_error("pool_query_cache_lookup: error while reading message kind"); return CACHE_ERROR; } pool_debug("pool_query_cache_lookup: received %c from systemdb", kind); /* just do the routine work of reading data in. data won't be used */ if (kind == 'T') { if (SYSDB_MAJOR == PROTO_MAJOR_V3) { if (pool_read(SYSDB_CON, &readlen, sizeof(int)) < 0) { pool_error("pool_query_cache_lookup: error while reading message length"); return CACHE_ERROR; } readlen = ntohl(readlen) - sizeof(int); data = pool_read2(SYSDB_CON, readlen); } else { data = pool_read_string(SYSDB_CON, &readlen, 0); } } else if (kind == 'D') /* cache found! forward it to the frontend */ { char *cache; int status; cache_found = 1; if (SYSDB_MAJOR == PROTO_MAJOR_V3) { if (pool_read(SYSDB_CON, &readlen, sizeof(readlen)) < 0) { pool_error("pool_query_cache_lookup: error while reading message length"); return CACHE_ERROR; } readlen = ntohl(readlen) - sizeof(int); cache = pool_read2(SYSDB_CON, readlen); } else { cache = pool_read_string(SYSDB_CON, &readlen, 0); } if (cache == NULL) { pool_error("pool_query_cache_lookup: error while reading message body"); return CACHE_ERROR; } cache[readlen] = '\0'; cache += sizeof(short); /* number of columns in 'D' (we know it's always going to be 1, so skip) */ cache += sizeof(int); /* length of escaped bytea cache in string format. don't need the length */ status = ForwardCacheToFrontend(frontend, cache, tstate); if (status < 0) { /* fatal error has occurred while forwarding cache */ pool_error("pool_query_cache_lookup: query cache forwarding failed"); return_value = CACHE_ERROR; } } else if (kind == 'C') /* see if 'D' was received */ { if (cache_found) return_value = CACHE_FOUND; else return_value = CACHE_NOT_FOUND; /* must discard the remaining data */ if (SYSDB_MAJOR == PROTO_MAJOR_V3) { if (pool_read(SYSDB_CON, &readlen, sizeof(int)) < 0) { pool_error("pool_query_cache_lookup: error while reading message length"); return CACHE_ERROR; } readlen = ntohl(readlen) - sizeof(int); data = pool_read2(SYSDB_CON, readlen); } else { data = pool_read_string(SYSDB_CON, &readlen, 0); } } else if (kind == 'Z') { /* must discard the remaining data */ if (SYSDB_MAJOR == PROTO_MAJOR_V3) { if (pool_read(SYSDB_CON, &readlen, sizeof(int)) < 0) { pool_error("pool_query_cache_lookup: error while reading message length"); return CACHE_ERROR; } readlen = ntohl(readlen) - sizeof(int); data = pool_read2(SYSDB_CON, readlen); } else { data = pool_read_string(SYSDB_CON, &readlen, 0); } break; } else if (kind == 'E') { /* must discard the remaining data */ if (SYSDB_MAJOR == PROTO_MAJOR_V3) { if (pool_read(SYSDB_CON, &readlen, sizeof(int)) < 0) { pool_error("pool_query_cache_lookup: error while reading message length"); return CACHE_ERROR; } readlen = ntohl(readlen) - sizeof(int); data = pool_read2(SYSDB_CON, readlen); } else { data = pool_read_string(SYSDB_CON, &readlen, 0); } return_value = CACHE_ERROR; } else { /* shouldn't get here, but just in case */ return CACHE_ERROR; } } break; } return return_value; } /* -------------------------------- * ForwardCacheToFrontend - simply forwards cached data to the frontend * * since the cached data passed from the caller is in escaped binary string * format, unescape it and send it to the frontend appending 'Z' at the end. * returns 0 on success, -1 otherwise. * -------------------------------- */ static int ForwardCacheToFrontend(POOL_CONNECTION *frontend, char *cache, char tstate) { int sendlen; size_t sz; char *binary_cache = NULL; binary_cache = (char *)PQunescapeBytea((unsigned char *)cache, &sz); sendlen = (int) sz; if (malloc_failed(binary_cache)) return -1; pool_debug("ForwardCacheToFrontend: query cache found (%d bytes)", sendlen); /* forward cache to the frontend */ pool_write(frontend, binary_cache, sendlen); /* send ReadyForQuery to the frontend*/ pool_write(frontend, "Z", 1); sendlen = htonl(5); pool_write(frontend, &sendlen, sizeof(int)); if (pool_write_and_flush(frontend, &tstate, 1) < 0) { pool_error("pool_query_cache_lookup: error while writing data to the frontend"); PQfreemem(binary_cache); return -1; } PQfreemem(binary_cache); return 0; } /* -------------------------------- * pool_query_cache_register() - register query cache to the SystemDB * * returns 0 on success, -1 otherwise * -------------------------------- */ int pool_query_cache_register(char kind, POOL_CONNECTION *frontend, char *database, char *data, int data_len, char *query) { int ret; int send_len; if (! system_db_connection_exists()) return -1; if (! CACHE_TABLE_INFO.has_prepared_statement) define_prepared_statements(); switch (kind) { case 'T': /* RowDescription */ { /* for all SELECT result data from the backend, 'T' must come first */ if (query_cache_info != NULL) { pool_error("pool_query_cache_register: received RowDescription in the wrong order"); free_query_cache_info(); return -1; } pool_debug("pool_query_cache_register: saving cache for query: \"%s\"", query); /* initialize query_cache_info and save the query */ ret = init_query_cache_info(frontend, database, query); if (ret) return ret; /* store data into the cache */ write_cache(&kind, 1); send_len = htonl(data_len + sizeof(int)); write_cache(&send_len, sizeof(int)); write_cache(data, data_len); break; } case 'D': /* DataRow */ { /* for all SELECT result data from the backend, 'T' must come first */ if (query_cache_info == NULL) { pool_error("pool_query_cache_register: received DataRow in the wrong order"); return -1; } write_cache(&kind, 1); send_len = htonl(data_len + sizeof(int)); write_cache(&send_len, sizeof(int)); write_cache(data, data_len); break; } case 'C': /* CommandComplete */ { PGresult *pg_result = NULL; char *escaped_query = NULL; size_t escaped_query_len; time_t now = time(NULL); char *values[5]; int values_len[5]; int values_format[5]; int i; /* for all SELECT result data from the backend, 'T' must come first */ if (query_cache_info == NULL) { pool_error("pool_query_cache_register: received CommandComplete in the wrong order"); return -1; } /* pack CommandComplete data into the cache */ write_cache(&kind, 1); send_len = htonl(data_len + sizeof(int)); write_cache(&send_len, sizeof(int)); write_cache(data, data_len); query_cache_info->create_time = pq_time_to_str(now); if (malloc_failed(query_cache_info->create_time)) { free_query_cache_info(); return -1; } escaped_query = (char *)malloc(strlen(query_cache_info->query) * 2 + 1); if (malloc_failed(escaped_query)) { free_query_cache_info(); return -1; } /* escaped_query_len = PQescapeStringConn(system_db_info->pgconn, */ /* escaped_query, */ /* query_cache_info->query, */ /* strlen(query_cache_info->query))); */ escaped_query_len = PQescapeString(escaped_query, query_cache_info->query, strlen(query_cache_info->query)); /* all the result data have been received. store into the SystemDB */ values[0] = strdup(query_cache_info->md5_query); values[1] = strdup(escaped_query); values[2] = (char *)malloc(query_cache_info->cache_offset); memcpy(values[2], query_cache_info->cache, query_cache_info->cache_offset); values[3] = strdup(query_cache_info->db_name); values[4] = strdup(query_cache_info->create_time); for (i = 0; i < 5; i++) { if (malloc_failed(values[i])) { pool_error("pool_query_cache_register: malloc() failed"); free_query_cache_info(); { int j; for (j = 0; j < i; j++) free(values[j]); } return -1; } values_len[i] = strlen(values[i]); } values_format[0] = values_format[1] = values_format[3] = values_format[4] = 0; values_format[2] = 1; values_len[2] = query_cache_info->cache_offset; pg_result = PQexecPrepared(system_db_info->pgconn, CACHE_TABLE_INFO.register_prepared_statement, 5, (const char * const *)values, values_len, values_format, 0); if (!pg_result || PQresultStatus(pg_result) != PGRES_COMMAND_OK) { pool_error("pool_query_cache_register: PQexecPrepared() failed. reason: %s", PQerrorMessage(system_db_info->pgconn)); PQclear(pg_result); PQfreemem(escaped_query); free_query_cache_info(); for (i = 0; i < 5; i++) free(values[i]); return -1; } PQclear(pg_result); PQfreemem(escaped_query); for (i = 0; i < 5; i++) free(values[i]); free_query_cache_info(); break; } case 'E': { pool_debug("pool_query_cache_register: received 'E': free query cache buffer"); pool_close_libpq_connection(); free_query_cache_info(); break; } } return 0; } /* -------------------------------- * init_query_cache_info() - allocate memory for query_cache_info and stores query * * returns 0 on success, -1 otherwise `* -------------------------------- */ static int init_query_cache_info(POOL_CONNECTION *pc, char *database, char *query) { int query_len; /* length of the SELECT query to be cached */ query_cache_info = (QueryCacheInfo *)malloc(sizeof(QueryCacheInfo)); if (malloc_failed(query_cache_info)) return -1; /* query */ query_len = strlen(query); query_cache_info->query = (char *)malloc(query_len + 1); if (malloc_failed(query_cache_info->query)) return -1; memcpy(query_cache_info->query, query, query_len + 1); /* md5_query */ query_cache_info->md5_query = (char *)malloc(33); /* md5sum is always 33 bytes (including the '\0') */ if (malloc_failed(query_cache_info->md5_query)) return -1; pool_md5_hash(query_cache_info->query, query_len, query_cache_info->md5_query); /* malloc DEFAULT_CACHE_SIZE for query_cache_info->cache */ query_cache_info->cache = (char *)malloc(DEFAULT_CACHE_SIZE); if (malloc_failed(query_cache_info->cache)) return -1; query_cache_info->cache_size = DEFAULT_CACHE_SIZE; query_cache_info->cache_offset = 0; /* save database name */ query_cache_info->db_name = (char *)malloc(strlen(database)+1); if (malloc_failed(query_cache_info->db_name)) return -1; strcpy(query_cache_info->db_name, database); /* initialize create_timestamp */ query_cache_info->create_time = NULL; return 0; } /* -------------------------------- * free_query_cache_info() - free query_cache_info and its members * -------------------------------- */ static void free_query_cache_info(void) { if (query_cache_info == NULL) return; free(query_cache_info->md5_query); free(query_cache_info->query); free(query_cache_info->cache); free(query_cache_info->db_name); if (query_cache_info->create_time) free(query_cache_info->create_time); free(query_cache_info); query_cache_info = NULL; } /* -------------------------------- * malloc_failed() - checks if the caller's most recent malloc() has succeeded * * returns 0 if malloc() was a success, -1 otherwise `* -------------------------------- */ static int malloc_failed(void *p) { if (p != NULL) return 0; pool_error("pool_query_cache: malloc() failed"); free_query_cache_info(); return -1; } /* -------------------------------- * write_cache() - append result data to buffer * * returns 0 on success, -1 otherwise * -------------------------------- */ static int write_cache(void *buf, int len) { int required_len; if (len < 0) return -1; required_len = query_cache_info->cache_offset + len; if (required_len > query_cache_info->cache_size) { char *ptr; required_len = query_cache_info->cache_size * 2; ptr = (char *)realloc(query_cache_info->cache, required_len); if (malloc_failed(ptr)) return -1; query_cache_info->cache = ptr; query_cache_info->cache_size = required_len; pool_debug("pool_query_cache: extended cache buffer size to %d", query_cache_info->cache_size); } memcpy(query_cache_info->cache + query_cache_info->cache_offset, buf, len); query_cache_info->cache_offset += len; return 0; } /* -------------------------------- * pq_time_to_str() - convert time_t to ISO standard time output string * * returns a pointer to newly allocated string, NULL if malloc fails * -------------------------------- */ static char * pq_time_to_str(time_t t) { char *time_p; char iso_time[32]; struct tm *tm; tm = localtime(&t); strftime(iso_time, sizeof(iso_time), "%Y-%m-%d %H:%M:%S%z", tm); time_p = strdup(iso_time); return time_p; } /* -------------------------------- * system_db_connection_exists() - checks and if a connection to the SystemDB exists * * if not connected, it makes an attempt to connect to the SystemDB. If a connection * exists, returns 1, returns 0 otherwise. * -------------------------------- */ static int system_db_connection_exists(void) { if (!system_db_info->pgconn || (PQstatus(system_db_info->pgconn) != CONNECTION_OK)) { if (system_db_connect()) return 0; } return 1; } /* -------------------------------- * define_prepared_statements() - defines prepared statements for the current session * -------------------------------- */ static void define_prepared_statements(void) { PGresult *pg_result; char *sql = NULL; int sql_len; sql_len = strlen(pool_config->system_db_schema) + strlen(QUERY_CACHE_TABLE_NAME) + 1024; sql = (char *)malloc(sql_len); if (malloc_failed(sql)) { pool_error("pool_query_cache: malloc() failed"); return; } free(CACHE_TABLE_INFO.register_prepared_statement); CACHE_TABLE_INFO.register_prepared_statement = strdup(CACHE_REGISTER_PREPARED_STMT); if (malloc_failed(CACHE_TABLE_INFO.register_prepared_statement)) { pool_error("pool_query_cache: malloc() failed"); free(sql); return; } #ifdef HAVE_PQPREPARE snprintf(sql, sql_len, "INSERT INTO %s.%s VALUES ( $1, $2, $3, $4, $5 )", pool_config->system_db_schema, QUERY_CACHE_TABLE_NAME); pg_result = PQprepare(system_db_info->pgconn, CACHE_TABLE_INFO.register_prepared_statement, sql, 5, NULL); #else snprintf(sql, sql_len, "PREPARE %s (TEXT, TEXT, BYTEA, TEXT, TIMESTAMP WITH TIME ZONE) AS INSERT INTO %s.%s VALUES ( $1, $2, $3, $4, $5 )", CACHE_TABLE_INFO.register_prepared_statement, pool_config->system_db_schema, QUERY_CACHE_TABLE_NAME); pg_result = PQexec(system_db_info->pgconn, sql); #endif if (!pg_result || PQresultStatus(pg_result) != PGRES_COMMAND_OK) { pool_error("pool_query_cache: PQprepare() failed: %s", PQerrorMessage(system_db_info->pgconn)); free(CACHE_TABLE_INFO.register_prepared_statement); free(sql); return; } pool_debug("pool_query_cache: prepared statements created"); CACHE_TABLE_INFO.has_prepared_statement = 1; free(sql); PQclear(pg_result); } /* -------------------------------- * Execute query cache look up * -------------------------------- */ POOL_STATUS pool_execute_query_cache_lookup(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, Node *node) { SelectStmt *select = (SelectStmt *)node; POOL_STATUS status = POOL_END; /* cache not found */ if (! (select->intoClause || select->lockingClause)) { parsed_query = strdup(nodeToString(node)); if (parsed_query == NULL) { pool_error("pool_execute_query_cache_lookup: malloc failed"); return POOL_ERROR; } status = pool_query_cache_lookup(frontend, parsed_query, backend->info->database, TSTATE(backend, MASTER_NODE_ID)); if (status == POOL_CONTINUE) { free(parsed_query); parsed_query = NULL; } } return status; } pgpool-II-3.3.2/pool_shmem.c0000664000076400007640000001120312245576267012574 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2013, PgPool Global Development Group * Portions Copyright (c) 2003-2004, PostgreSQL Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include "pool.h" #include #include #include #include "pool_ipc.h" #ifdef SHM_SHARE_MMU /* use intimate shared memory on Solaris */ #define PG_SHMAT_FLAGS SHM_SHARE_MMU #else #define PG_SHMAT_FLAGS 0 #endif #define MAX_ON_EXITS 64 static struct ONEXIT { void (*function) (int code, Datum arg); Datum arg; } on_shmem_exit_list[MAX_ON_EXITS]; static int on_shmem_exit_index; static void IpcMemoryDetach(int status, Datum shmaddr); static void IpcMemoryDelete(int status, Datum shmId); /* * Create a shared memory segment of the given size and initialize. Also, * register an on_shmem_exit callback to release the storage. */ void * pool_shared_memory_create(size_t size) { int shmid; void *memAddress; /* Try to create new segment */ shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | IPCProtection); if (shmid < 0) { pool_error("could not create shared memory segment: %s", strerror(errno)); return NULL; } /* Register on-exit routine to delete the new segment */ on_shmem_exit(IpcMemoryDelete, shmid); /* OK, should be able to attach to the segment */ memAddress = shmat(shmid, NULL, PG_SHMAT_FLAGS); if (memAddress == (void *) -1) { pool_error("shmat(id=%d) failed: %s", shmid, strerror(errno)); return NULL; } /* Register on-exit routine to detach new segment before deleting */ on_shmem_exit(IpcMemoryDetach, (Datum) memAddress); return memAddress; } /* * Removes a shared memory segment from process' address spaceq (called as * an on_shmem_exit callback, hence funny argument list) */ static void IpcMemoryDetach(int status, Datum shmaddr) { if (shmdt((void *) shmaddr) < 0) pool_log("shmdt(%p) failed: %s", (void *) shmaddr, strerror(errno)); } /* * Deletes a shared memory segment (called as an on_shmem_exit callback, * hence funny argument list) */ static void IpcMemoryDelete(int status, Datum shmId) { struct shmid_ds shmStat; /* * Is a previously-existing shmem segment still existing and in use? */ if (shmctl(shmId, IPC_STAT, &shmStat) < 0 && (errno == EINVAL || errno == EACCES)) return; else if (shmStat.shm_nattch != 0) return; if (shmctl(shmId, IPC_RMID, NULL) < 0) pool_log("shmctl(%lu, %d, 0) failed: %s", shmId, IPC_RMID, strerror(errno)); } void pool_shmem_exit(int code) { shmem_exit(code); /* Close syslog connection here as this function is always called on exit */ closelog(); } /* * Run all of the on_shmem_exit routines --- but don't actually exit. This * is used by the postmaster to re-initialize shared memory and semaphores * after a backend dies horribly. */ void shmem_exit(int code) { pool_debug("shmem_exit(%d)", code); /* * Call all the registered callbacks. * * As with proc_exit(), we remove each callback from the list before * calling it, to avoid infinite loop in case of error. */ while (--on_shmem_exit_index >= 0) (*on_shmem_exit_list[on_shmem_exit_index].function) (code, on_shmem_exit_list[on_shmem_exit_index].arg); on_shmem_exit_index = 0; } /* * This function adds a callback function to the list of functions invoked * by shmem_exit(). */ void on_shmem_exit(void (*function) (int code, Datum arg), Datum arg) { if (on_shmem_exit_index >= MAX_ON_EXITS) pool_error("out of on_shmem_exit slots"); else { on_shmem_exit_list[on_shmem_exit_index].function = function; on_shmem_exit_list[on_shmem_exit_index].arg = arg; ++on_shmem_exit_index; } } /* * This function clears all on_proc_exit() and on_shmem_exit() registered * functions. This is used just after forking a backend, so that the * backend doesn't believe it should call the postmaster's on-exit routines * when it exits... */ void on_exit_reset(void) { on_shmem_exit_index = 0; } pgpool-II-3.3.2/configure0000775000076400007640000157232412245776600012207 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ;; esac ECHO=${lt_ECHO-echo} if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF $* _LT_EOF exit 0 fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL $0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL $0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "$0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" fi test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS enable_rpath_FALSE enable_rpath_TRUE MEMCACHED_DIR PGSQL_LIB_DIR PGSQL_INCLUDE_DIR MEMCACHED_RPATH_OPT MEMCACHED_LINK_OPT MEMCACHED_INCLUDE_OPT PGCONFIG LIBOBJS YFLAGS YACC LEXLIB LEX_OUTPUT_ROOT LEX CPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL lt_ECHO RANLIB AR OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld enable_libtool_lock enable_float4_byval enable_float8_byval with_pgsql with_pgsql_includedir with_pgsql_libdir with_openssl with_pam with_memcached enable_rpath enable_sequence_lock enable_table_lock ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP YACC YFLAGS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-float4-byval disable float4 passed by value --disable-float8-byval disable float8 passed by value --disable-rpath do not embed shared library search path in executables --enable-sequence-lock insert_lock compatible with pgpool-II 3.0 series (until 3.0.4) --enable-table-lock insert_lock compatible with pgpool-II 2.2 and 2.3 series Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-pgsql=DIR site header files for PostgreSQL in DIR --with-pgsql-includedir=DIR site header files for PostgreSQL in DIR --with-pgsql-libdir=DIR site library files for PostgreSQL in DIR --with-openssl build with OpenSSL support --with-pam build with PAM support --with-memcached=DIR site header files for libmemcached in DIR Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor YACC The `Yet Another Compiler Compiler' implementation to use. Defaults to the first program found out of: `bison -y', `byacc', `yacc'. YFLAGS The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of `-d' given by some make applications. Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 &5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.11' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=pgpool-II VERSION=3.3.2 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # AC_PROG_RANLIB case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.2.6b' macro_revision='1.3017' ltmain="$ac_aux_dir/ltmain.sh" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$ac_tool_prefix"; then for ac_prog in "dumpbin -symbols" "link -dump -symbols" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in "dumpbin -symbols" "link -dump -symbols" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:4808: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:4811: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:4814: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi else AR="$ac_cv_prog_AR" fi test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line 6020 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; pic_mode="$withval" else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then lt_prog_compiler_no_builtin_flag=' -fno-builtin' { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:7549: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:7553: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl*) # IBM XL C 8.0/Fortran 10.1 on PPC lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Sun\ F*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 $as_echo "$lt_prog_compiler_pic" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:7888: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:7892: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:7993: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:7997: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:8048: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:8052: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_flag_spec_ld= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag= tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec= hardcode_libdir_flag_spec_ld='-rpath $libdir' archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes=yes ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported whole_archive_flag_spec='' link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; freebsd1*) ld_shlibs=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_flag_spec_ld='+b $libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo(void) {} _ACEOF if ac_fn_c_try_link "$LINENO"; then : archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then archive_cmds_need_lc=no else archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 $as_echo "$archive_cmds_need_lc" >&6; } ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix[3-9]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line 10418 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line 10514 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LEX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test "x$LEX" != "x:"; then cat >conftest.l <<_ACEOF %% a { ECHO; } b { REJECT; } c { yymore (); } d { yyless (1); } e { yyless (input () != 0); } f { unput (yytext[0]); } . { BEGIN INITIAL; } %% #ifdef YYTEXT_POINTER extern char *yytext; #endif int main (void) { return ! yylex () + ! yywrap (); } _ACEOF { { ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$LEX conftest.l") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 $as_echo_n "checking lex output file root... " >&6; } if ${ac_cv_prog_lex_root+:} false; then : $as_echo_n "(cached) " >&6 else if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 $as_echo "$ac_cv_prog_lex_root" >&6; } LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root if test -z "${LEXLIB+set}"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 $as_echo_n "checking lex library... " >&6; } if ${ac_cv_lib_lex+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_LIBS=$LIBS ac_cv_lib_lex='none needed' for ac_lib in '' -lfl -ll; do LIBS="$ac_lib $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lex=$ac_lib fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext test "$ac_cv_lib_lex" != 'none needed' && break done LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 $as_echo "$ac_cv_lib_lex" >&6; } test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 $as_echo_n "checking whether yytext is a pointer... " >&6; } if ${ac_cv_prog_lex_yytext_pointer+:} false; then : $as_echo_n "(cached) " >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no ac_save_LIBS=$LIBS LIBS="$LEXLIB $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define YYTEXT_POINTER 1 `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_prog_lex_yytext_pointer=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 $as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } if test $ac_cv_prog_lex_yytext_pointer = yes; then $as_echo "#define YYTEXT_POINTER 1" >>confdefs.h fi rm -f conftest.l $LEX_OUTPUT_ROOT.c fi if test "$LEX" = :; then LEX=${am_missing_run}flex fi for ac_prog in 'bison -y' byacc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_YACC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_YACC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$YACC" && break done test -n "$YACC" || YACC="yacc" OLD_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -Wall" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wall option" >&5 $as_echo_n "checking for -Wall option... " >&6; } if ${ac_cv_wall+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { char a; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_wall=yes else ac_cv_wall=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi echo $ac_cv_wall if test $ac_cv_wall = no; then CFLAGS=$OLD_CFLAGS fi OLD_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -Wmissing-prototypes" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wmissing-prototypes option" >&5 $as_echo_n "checking for -Wmissing-prototypes option... " >&6; } if ${ac_cv_wmissing_prototypes+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { char a; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_wmissing_prototypes=yes else ac_cv_wmissing_prototypes=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi echo $ac_cv_wmissing_prototypes if test $ac_cv_wmissing_prototypes = no; then CFLAGS=$OLD_CFLAGS fi OLD_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -Wmissing-declarations" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wmissing-declarations option" >&5 $as_echo_n "checking for -Wmissing-declarations option... " >&6; } if ${ac_cv_wmissing_declarations+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { char a; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_wmissing_declarations=yes else ac_cv_wmissing_declarations=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi echo $ac_cv_wmissing_declarations if test $ac_cv_wmissing_declarations = no; then CFLAGS=$OLD_CFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5 $as_echo_n "checking for main in -lm... " >&6; } if ${ac_cv_lib_m_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_main=yes else ac_cv_lib_m_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5 $as_echo "$ac_cv_lib_m_main" >&6; } if test "x$ac_cv_lib_m_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lnsl" >&5 $as_echo_n "checking for main in -lnsl... " >&6; } if ${ac_cv_lib_nsl_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_main=yes else ac_cv_lib_nsl_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_main" >&5 $as_echo "$ac_cv_lib_nsl_main" >&6; } if test "x$ac_cv_lib_nsl_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsocket" >&5 $as_echo_n "checking for main in -lsocket... " >&6; } if ${ac_cv_lib_socket_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_main=yes else ac_cv_lib_socket_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_main" >&5 $as_echo "$ac_cv_lib_socket_main" >&6; } if test "x$ac_cv_lib_socket_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lipc" >&5 $as_echo_n "checking for main in -lipc... " >&6; } if ${ac_cv_lib_ipc_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lipc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ipc_main=yes else ac_cv_lib_ipc_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_main" >&5 $as_echo "$ac_cv_lib_ipc_main" >&6; } if test "x$ac_cv_lib_ipc_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBIPC 1 _ACEOF LIBS="-lipc $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lIPC" >&5 $as_echo_n "checking for main in -lIPC... " >&6; } if ${ac_cv_lib_IPC_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lIPC $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_IPC_main=yes else ac_cv_lib_IPC_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_IPC_main" >&5 $as_echo "$ac_cv_lib_IPC_main" >&6; } if test "x$ac_cv_lib_IPC_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBIPC 1 _ACEOF LIBS="-lIPC $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -llc" >&5 $as_echo_n "checking for main in -llc... " >&6; } if ${ac_cv_lib_lc_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lc_main=yes else ac_cv_lib_lc_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lc_main" >&5 $as_echo "$ac_cv_lib_lc_main" >&6; } if test "x$ac_cv_lib_lc_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBLC 1 _ACEOF LIBS="-llc $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lBSD" >&5 $as_echo_n "checking for main in -lBSD... " >&6; } if ${ac_cv_lib_BSD_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lBSD $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_BSD_main=yes else ac_cv_lib_BSD_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_BSD_main" >&5 $as_echo "$ac_cv_lib_BSD_main" >&6; } if test "x$ac_cv_lib_BSD_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBBSD 1 _ACEOF LIBS="-lBSD $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgen" >&5 $as_echo_n "checking for main in -lgen... " >&6; } if ${ac_cv_lib_gen_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgen $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gen_main=yes else ac_cv_lib_gen_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gen_main" >&5 $as_echo "$ac_cv_lib_gen_main" >&6; } if test "x$ac_cv_lib_gen_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGEN 1 _ACEOF LIBS="-lgen $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lPW" >&5 $as_echo_n "checking for main in -lPW... " >&6; } if ${ac_cv_lib_PW_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lPW $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_PW_main=yes else ac_cv_lib_PW_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_PW_main" >&5 $as_echo "$ac_cv_lib_PW_main" >&6; } if test "x$ac_cv_lib_PW_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPW 1 _ACEOF LIBS="-lPW $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lresolv" >&5 $as_echo_n "checking for main in -lresolv... " >&6; } if ${ac_cv_lib_resolv_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_resolv_main=yes else ac_cv_lib_resolv_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_main" >&5 $as_echo "$ac_cv_lib_resolv_main" >&6; } if test "x$ac_cv_lib_resolv_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRESOLV 1 _ACEOF LIBS="-lresolv $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lcrypt" >&5 $as_echo_n "checking for main in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_main=yes else ac_cv_lib_crypt_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_main" >&5 $as_echo "$ac_cv_lib_crypt_main" >&6; } if test "x$ac_cv_lib_crypt_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPT 1 _ACEOF LIBS="-lcrypt $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } if ${ac_cv_header_sys_wait_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_sys_wait_h=yes else ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 $as_echo "$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h fi for ac_header in fcntl.h unistd.h getopt.h netinet/tcp.h netinet/in.h netdb.h sys/param.h sys/types.h sys/socket.h sys/un.h sys/time.h sys/sem.h sys/shm.h sys/select.h crypt.h sys/pstat.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi # Macros to detect C compiler features # $PostgreSQL: pgsql/config/c-compiler.m4,v 1.19 2008/06/27 00:36:16 tgl Exp $ # PGAC_C_SIGNED # ------------- # Check if the C compiler understands signed types. # PGAC_C_SIGNED # PGAC_TYPE_64BIT_INT(TYPE) # ------------------------- # Check if TYPE is a working 64 bit integer type. Set HAVE_TYPE_64 to # yes or no respectively, and define HAVE_TYPE_64 if yes. # PGAC_TYPE_64BIT_INT # PGAC_C_FUNCNAME_SUPPORT # ----------------------- # Check if the C compiler understands __func__ (C99) or __FUNCTION__ (gcc). # Define HAVE_FUNCNAME__FUNC or HAVE_FUNCNAME__FUNCTION accordingly. # PGAC_C_FUNCNAME_SUPPORT # PGAC_PROG_CC_CFLAGS_OPT # ----------------------- # Given a string, check if the compiler supports the string as a # command-line option. If it does, add the string to CFLAGS. # PGAC_PROG_CC_CFLAGS_OPT # PGAC_PROG_CC_LDFLAGS_OPT # ------------------------ # Given a string, check if the compiler supports the string as a # command-line option. If it does, add the string to LDFLAGS. # For reasons you'd really rather not know about, this checks whether # you can link to a particular function, not just whether you can link. # In fact, we must actually check that the resulting program runs :-( # PGAC_PROG_CC_LDFLAGS_OPT # Macros that test various C library quirks # $PostgreSQL: pgsql/config/c-library.m4,v 1.33 2008/08/21 13:53:28 petere Exp $ # PGAC_VAR_INT_TIMEZONE # --------------------- # Check if the global variable `timezone' exists. If so, define # HAVE_INT_TIMEZONE. # PGAC_VAR_INT_TIMEZONE # PGAC_STRUCT_TIMEZONE # ------------------ # Figure out how to get the current timezone. If `struct tm' has a # `tm_zone' member, define `HAVE_TM_ZONE'. Also, if the # external array `tzname' is found, define `HAVE_TZNAME'. # This is the same as the standard macro AC_STRUCT_TIMEZONE, except that # tzname[] is checked for regardless of whether we find tm_zone. # PGAC_STRUCT_TIMEZONE # PGAC_FUNC_GETTIMEOFDAY_1ARG # --------------------------- # Check if gettimeofday() has only one arguments. (Normal is two.) # If so, define GETTIMEOFDAY_1ARG. # PGAC_FUNC_GETTIMEOFDAY_1ARG # PGAC_FUNC_GETPWUID_R_5ARG # --------------------------- # Check if getpwuid_r() takes a fifth argument (later POSIX standard, not draft version) # If so, define GETPWUID_R_5ARG # PGAC_FUNC_GETPWUID_R_5ARG # PGAC_FUNC_STRERROR_R_INT # --------------------------- # Check if strerror_r() returns an int (SUSv3) rather than a char * (GNU libc) # If so, define STRERROR_R_INT # PGAC_FUNC_STRERROR_R_INT # PGAC_UNION_SEMUN # ---------------- # Check if `union semun' exists. Define HAVE_UNION_SEMUN if so. # If it doesn't then one could define it as # union semun { int val; struct semid_ds *buf; unsigned short *array; } # PGAC_UNION_SEMUN # PGAC_STRUCT_SOCKADDR_UN # ----------------------- # If `struct sockaddr_un' exists, define HAVE_UNIX_SOCKETS. # (Requires test for !) # PGAC_STRUCT_SOCKADDR_UN # PGAC_STRUCT_SOCKADDR_STORAGE # ---------------------------- # If `struct sockaddr_storage' exists, define HAVE_STRUCT_SOCKADDR_STORAGE. # If it is missing then one could define it. # PGAC_STRUCT_SOCKADDR_STORAGE # PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS # -------------------------------------- # Check the members of `struct sockaddr_storage'. We need to know about # ss_family and ss_len. (Some platforms follow RFC 2553 and call them # __ss_family and __ss_len.) We also check struct sockaddr's sa_len; # if we have to define our own `struct sockaddr_storage', this tells us # whether we need to provide an ss_len field. # PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS # PGAC_STRUCT_ADDRINFO # ----------------------- # If `struct addrinfo' exists, define HAVE_STRUCT_ADDRINFO. # PGAC_STRUCT_ADDRINFO # PGAC_FUNC_POSIX_SIGNALS # ----------------------- # Check to see if the machine has the POSIX signal interface. Define # HAVE_POSIX_SIGNALS if so. Also set the output variable HAVE_POSIX_SIGNALS # to yes or no. # # Note that this test only compiles a test program, it doesn't check # whether the routines actually work. If that becomes a problem, make # a fancier check. # PGAC_FUNC_POSIX_SIGNALS # PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT # --------------------------------------- # Determine which format snprintf uses for long long int. We handle # %lld, %qd, %I64d. The result is in shell variable # LONG_LONG_INT_FORMAT. # # MinGW uses '%I64d', though gcc throws an warning with -Wall, # while '%lld' doesn't generate a warning, but doesn't work. # # PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT # PGAC_FUNC_PRINTF_ARG_CONTROL # --------------------------------------- # Determine if printf supports %1$ argument selection, e.g. %5$ selects # the fifth argument after the printf print string. # This is not in the C99 standard, but in the Single Unix Specification (SUS). # It is used in our language translation strings. # # PGAC_FUNC_PRINTF_ARG_CONTROL # backport from Autoconf 2.61a # http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=f0c325537a22105536ac8c4e88656e50f9946486 # AC_FUNC_FSEEKO # -------------- # AC_FUNC_FSEEKO # $PostgreSQL: pgsql/config/general.m4,v 1.10 2008/10/29 09:27:24 petere Exp $ # This file defines new macros to process configure command line # arguments, to replace the brain-dead AC_ARG_WITH and AC_ARG_ENABLE. # The flaw in these is particularly that they only differentiate # between "given" and "not given" and do not provide enough help to # process arguments that only accept "yes/no", that require an # argument (other than "yes/no"), etc. # # The point of this implementation is to reduce code size and # redundancy in configure.in and to improve robustness and consistency # in the option evaluation code. # Convert type and name to shell variable name (e.g., "enable_long_strings") # PGAC_ARG(TYPE, NAME, HELP-STRING-LHS-EXTRA, HELP-STRING-RHS, # [ACTION-IF-YES], [ACTION-IF-NO], [ACTION-IF-ARG], # [ACTION-IF-OMITTED]) # ------------------------------------------------------------ # This is the base layer. TYPE is either "with" or "enable", depending # on what you like. NAME is the rest of the option name. # HELP-STRING-LHS-EXTRA is a string to append to the option name on # the left-hand side of the help output, e.g., an argument name. If # set to "-", append nothing, but let the option appear in the # negative form (disable/without). HELP-STRING-RHS is the option # description, for the right-hand side of the help output. # ACTION-IF-YES is executed if the option is given without an argument # (or "yes", which is the same); similar for ACTION-IF-NO. # PGAC_ARG # PGAC_ARG_CHECK() # ---------------- # Checks if the user passed any --with/without/enable/disable # arguments that were not defined. Just prints out a warning message, # so this should be called near the end, so the user will see it. # PGAC_ARG_CHECK # PGAC_ARG_BOOL(TYPE, NAME, DEFAULT, HELP-STRING-RHS, # [ACTION-IF-YES], [ACTION-IF-NO]) # --------------------------------------------------- # Accept a boolean option, that is, one that only takes yes or no. # ("no" is equivalent to "disable" or "without"). DEFAULT is what # should be done if the option is omitted; it should be "yes" or "no". # (Consequently, one of ACTION-IF-YES and ACTION-IF-NO will always # execute.) # PGAC_ARG_BOOL # PGAC_ARG_REQ(TYPE, NAME, HELP-ARGNAME, HELP-STRING-RHS, # [ACTION-IF-GIVEN], [ACTION-IF-NOT-GIVEN]) # ------------------------------------------------------- # This option will require an argument; "yes" or "no" will not be # accepted. HELP-ARGNAME is a name for the argument for the help output. # PGAC_ARG_REQ # PGAC_ARG_OPTARG(TYPE, NAME, HELP-ARGNAME, HELP-STRING-RHS, # [DEFAULT-ACTION], [ARG-ACTION], # [ACTION-ENABLED], [ACTION-DISABLED]) # ---------------------------------------------------------- # This will create an option that behaves as follows: If omitted, or # called with "no", then set the enable_variable to "no" and do # nothing else. If called with "yes", then execute DEFAULT-ACTION. If # called with argument, set enable_variable to "yes" and execute # ARG-ACTION. Additionally, execute ACTION-ENABLED if we ended up with # "yes" either way, else ACTION-DISABLED. # # The intent is to allow enabling a feature, and optionally pass an # additional piece of information. # PGAC_ARG_OPTARG pgac_need_repl_snprintf=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long int is 64 bits" >&5 $as_echo_n "checking whether long int is 64 bits... " >&6; } if ${pgac_cv_type_long_int_64+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : # If cross-compiling, check the size reported by the compiler and # trust that the arithmetic works. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { static int test_array [1 - 2 * !(sizeof(long int) == 8)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : pgac_cv_type_long_int_64=yes else pgac_cv_type_long_int_64=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ typedef long int ac_int64; /* * These are globals to discourage the compiler from folding all the * arithmetic tests down to compile-time constants. */ ac_int64 a = 20000001; ac_int64 b = 40000005; int does_int64_work() { ac_int64 c,d; if (sizeof(ac_int64) != 8) return 0; /* definitely not the right size */ /* Do perfunctory checks to see if 64-bit arithmetic seems to work */ c = a * b; d = (c + b) / b; if (d != a+1) return 0; return 1; } main() { exit(! does_int64_work()); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : pgac_cv_type_long_int_64=yes else pgac_cv_type_long_int_64=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_type_long_int_64" >&5 $as_echo "$pgac_cv_type_long_int_64" >&6; } HAVE_LONG_INT_64=$pgac_cv_type_long_int_64 if test x"$pgac_cv_type_long_int_64" = xyes ; then $as_echo "#define HAVE_LONG_INT_64 1" >>confdefs.h fi if test x"$HAVE_LONG_INT_64" = x"no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long long int is 64 bits" >&5 $as_echo_n "checking whether long long int is 64 bits... " >&6; } if ${pgac_cv_type_long_long_int_64+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : # If cross-compiling, check the size reported by the compiler and # trust that the arithmetic works. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { static int test_array [1 - 2 * !(sizeof(long long int) == 8)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : pgac_cv_type_long_long_int_64=yes else pgac_cv_type_long_long_int_64=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ typedef long long int ac_int64; /* * These are globals to discourage the compiler from folding all the * arithmetic tests down to compile-time constants. */ ac_int64 a = 20000001; ac_int64 b = 40000005; int does_int64_work() { ac_int64 c,d; if (sizeof(ac_int64) != 8) return 0; /* definitely not the right size */ /* Do perfunctory checks to see if 64-bit arithmetic seems to work */ c = a * b; d = (c + b) / b; if (d != a+1) return 0; return 1; } main() { exit(! does_int64_work()); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : pgac_cv_type_long_long_int_64=yes else pgac_cv_type_long_long_int_64=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_type_long_long_int_64" >&5 $as_echo "$pgac_cv_type_long_long_int_64" >&6; } HAVE_LONG_LONG_INT_64=$pgac_cv_type_long_long_int_64 if test x"$pgac_cv_type_long_long_int_64" = xyes ; then $as_echo "#define HAVE_LONG_LONG_INT_64 1" >>confdefs.h fi fi if test x"$HAVE_LONG_LONG_INT_64" = xyes ; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define INT64CONST(x) x##LL long long int foo = INT64CONST(0x1234567890123456); int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_LL_CONSTANTS 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi # If we found "long int" is 64 bits, assume snprintf handles it. If # we found we need to use "long long int", better check. We cope with # snprintfs that use %lld, %qd, or %I64d as the format. If none of these # work, fall back to our own snprintf emulation (which we know uses %lld). if test "$HAVE_LONG_LONG_INT_64" = yes ; then if test $pgac_need_repl_snprintf = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking snprintf format for long long int" >&5 $as_echo_n "checking snprintf format for long long int... " >&6; } if ${pgac_cv_snprintf_long_long_int_format+:} false; then : $as_echo_n "(cached) " >&6 else for pgac_format in '%lld' '%qd' '%I64d'; do if test "$cross_compiling" = yes; then : pgac_cv_snprintf_long_long_int_format=cross; break else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include typedef long long int ac_int64; #define INT64_FORMAT "$pgac_format" ac_int64 a = 20000001; ac_int64 b = 40000005; int does_int64_snprintf_work() { ac_int64 c; char buf[100]; if (sizeof(ac_int64) != 8) return 0; /* doesn't look like the right size */ c = a * b; snprintf(buf, 100, INT64_FORMAT, c); if (strcmp(buf, "800000140000005") != 0) return 0; /* either multiply or snprintf is busted */ return 1; } main() { exit(! does_int64_snprintf_work()); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : pgac_cv_snprintf_long_long_int_format=$pgac_format; break fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi done fi LONG_LONG_INT_FORMAT='' case $pgac_cv_snprintf_long_long_int_format in cross) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cannot test (not on host machine)" >&5 $as_echo "cannot test (not on host machine)" >&6; };; ?*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_snprintf_long_long_int_format" >&5 $as_echo "$pgac_cv_snprintf_long_long_int_format" >&6; } LONG_LONG_INT_FORMAT=$pgac_cv_snprintf_long_long_int_format;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; };; esac if test "$LONG_LONG_INT_FORMAT" = ""; then # Force usage of our own snprintf, since system snprintf is broken pgac_need_repl_snprintf=yes LONG_LONG_INT_FORMAT='%lld' fi else # Here if we previously decided we needed to use our own snprintf LONG_LONG_INT_FORMAT='%lld' fi LONG_LONG_UINT_FORMAT=`echo "$LONG_LONG_INT_FORMAT" | sed 's/d$/u/'` INT64_FORMAT="\"$LONG_LONG_INT_FORMAT\"" UINT64_FORMAT="\"$LONG_LONG_UINT_FORMAT\"" else # Here if we are not using 'long long int' at all INT64_FORMAT='"%ld"' UINT64_FORMAT='"%lu"' fi cat >>confdefs.h <<_ACEOF #define INT64_FORMAT $INT64_FORMAT _ACEOF cat >>confdefs.h <<_ACEOF #define UINT64_FORMAT $UINT64_FORMAT _ACEOF # Now we have checked all the reasons to replace snprintf if test $pgac_need_repl_snprintf = yes; then $as_echo "#define USE_REPL_SNPRINTF 1" >>confdefs.h case " $LIBOBJS " in *" snprintf.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" ;; esac fi # Need a #define for the size of Datum (unsigned long) # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5 $as_echo_n "checking size of unsigned long... " >&6; } if ${ac_cv_sizeof_unsigned_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then : else if test "$ac_cv_type_unsigned_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5 $as_echo "$ac_cv_sizeof_unsigned_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long _ACEOF # And check size of void *, size_t (enables tweaks for > 32bit address space) # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 $as_echo_n "checking size of void *... " >&6; } if ${ac_cv_sizeof_void_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : else if test "$ac_cv_type_void_p" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (void *) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_void_p=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 $as_echo "$ac_cv_sizeof_void_p" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_VOID_P $ac_cv_sizeof_void_p _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 $as_echo_n "checking size of size_t... " >&6; } if ${ac_cv_sizeof_size_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then : else if test "$ac_cv_type_size_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (size_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_size_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 $as_echo "$ac_cv_sizeof_size_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SIZE_T $ac_cv_sizeof_size_t _ACEOF # Decide whether float4 is passed by value: user-selectable, enabled by default { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with float4 passed by value" >&5 $as_echo_n "checking whether to build with float4 passed by value... " >&6; } pgac_args="$pgac_args enable_float4_byval" # Check whether --enable-float4-byval was given. if test "${enable_float4_byval+set}" = set; then : enableval=$enable_float4_byval; case $enableval in yes) $as_echo "#define USE_FLOAT4_BYVAL 1" >>confdefs.h float4passbyval=true ;; no) float4passbyval=false ;; *) as_fn_error $? "no argument expected for --enable-float4-byval option" "$LINENO" 5 ;; esac else enable_float4_byval=yes $as_echo "#define USE_FLOAT4_BYVAL 1" >>confdefs.h float4passbyval=true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_float4_byval" >&5 $as_echo "$enable_float4_byval" >&6; } cat >>confdefs.h <<_ACEOF #define FLOAT4PASSBYVAL $float4passbyval _ACEOF # Decide whether float8 is passed by value. # Note: this setting also controls int8 and related types such as timestamp. # If sizeof(Datum) >= 8, this is user-selectable, enabled by default. # If not, trying to select it is an error. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with float8 passed by value" >&5 $as_echo_n "checking whether to build with float8 passed by value... " >&6; } if test $ac_cv_sizeof_unsigned_long -ge 8 ; then pgac_args="$pgac_args enable_float8_byval" # Check whether --enable-float8-byval was given. if test "${enable_float8_byval+set}" = set; then : enableval=$enable_float8_byval; case $enableval in yes) : ;; no) : ;; *) as_fn_error $? "no argument expected for --enable-float8-byval option" "$LINENO" 5 ;; esac else enable_float8_byval=yes fi else pgac_args="$pgac_args enable_float8_byval" # Check whether --enable-float8-byval was given. if test "${enable_float8_byval+set}" = set; then : enableval=$enable_float8_byval; case $enableval in yes) : ;; no) : ;; *) as_fn_error $? "no argument expected for --enable-float8-byval option" "$LINENO" 5 ;; esac else enable_float8_byval=no fi if test "$enable_float8_byval" = yes ; then as_fn_error $? "--enable-float8-byval is not supported on 32-bit platforms." "$LINENO" 5 fi fi if test "$enable_float8_byval" = yes ; then $as_echo "#define USE_FLOAT8_BYVAL 1" >>confdefs.h float8passbyval=true else float8passbyval=false fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_float8_byval" >&5 $as_echo "$enable_float8_byval" >&6; } cat >>confdefs.h <<_ACEOF #define FLOAT8PASSBYVAL $float8passbyval _ACEOF # $PostgreSQL: pgsql/config/ac_func_accept_argtypes.m4,v 1.6 2003/11/29 19:51:17 pgsql Exp $ # This comes from the official Autoconf macro archive at # # (I removed the $ before the Id CVS keyword below.) # PostgreSQL local changes: In the original version ACCEPT_TYPE_ARG3 # is a pointer type. That's kind of useless because then you can't # use the macro to define a corresponding variable. We also make the # reasonable(?) assumption that you can use arg3 for getsocktype etc. # as well (i.e., anywhere POSIX.2 has socklen_t). # # arg2 can also be `const' (e.g., RH 4.2). Change the order of tests # for arg3 so that `int' is first, in case there is no prototype at all. # # Solaris 7 and 8 have arg3 as 'void *' (disguised as 'Psocklen_t' # which is *not* 'socklen_t *'). If we detect that, then we assume # 'int' as the result, because that ought to work best. # # On Win32, accept() returns 'unsigned int PASCAL' ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" "#include #ifdef HAVE_SYS_SOCKET_H #include #endif " if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_STORAGE 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "ss_family" "ac_cv_member_struct_sockaddr_storage_ss_family" "#include #ifdef HAVE_SYS_SOCKET_H #include #endif " if test "x$ac_cv_member_struct_sockaddr_storage_ss_family" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "__ss_family" "ac_cv_member_struct_sockaddr_storage___ss_family" "#include #ifdef HAVE_SYS_SOCKET_H #include #endif " if test "x$ac_cv_member_struct_sockaddr_storage___ss_family" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "ss_len" "ac_cv_member_struct_sockaddr_storage_ss_len" "#include #ifdef HAVE_SYS_SOCKET_H #include #endif " if test "x$ac_cv_member_struct_sockaddr_storage_ss_len" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "__ss_len" "ac_cv_member_struct_sockaddr_storage___ss_len" "#include #ifdef HAVE_SYS_SOCKET_H #include #endif " if test "x$ac_cv_member_struct_sockaddr_storage___ss_len" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" "#include #ifdef HAVE_SYS_SOCKET_H #include #endif " if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_SA_LEN 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "union semun" "ac_cv_type_union_semun" "#include #include #include " if test "x$ac_cv_type_union_semun" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNION_SEMUN 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if ${ac_cv_type_signal+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF for ac_func in vprintf do : ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" if test "x$ac_cv_func_vprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VPRINTF 1 _ACEOF ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" if test "x$ac_cv_func__doprnt" = xyes; then : $as_echo "#define HAVE_DOPRNT 1" >>confdefs.h fi fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wait3 that fills in rusage" >&5 $as_echo_n "checking for wait3 that fills in rusage... " >&6; } if ${ac_cv_func_wait3_rusage+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_wait3_rusage=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #include #include #include /* HP-UX has wait3 but does not fill in rusage at all. */ int main () { struct rusage r; int i; /* Use a field that we can force nonzero -- voluntary context switches. For systems like NeXT and OSF/1 that don't set it, also use the system CPU time. And page faults (I/O) for Linux. */ r.ru_nvcsw = 0; r.ru_stime.tv_sec = 0; r.ru_stime.tv_usec = 0; r.ru_majflt = r.ru_minflt = 0; switch (fork ()) { case 0: /* Child. */ sleep(1); /* Give up the CPU. */ _exit(0); break; case -1: /* What can we do? */ _exit(0); break; default: /* Parent. */ wait3(&i, 0, &r); /* Avoid "text file busy" from rm on fast HP-UX machines. */ sleep(2); return (r.ru_nvcsw == 0 && r.ru_majflt == 0 && r.ru_minflt == 0 && r.ru_stime.tv_sec == 0 && r.ru_stime.tv_usec == 0); } } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_wait3_rusage=yes else ac_cv_func_wait3_rusage=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_wait3_rusage" >&5 $as_echo "$ac_cv_func_wait3_rusage" >&6; } if test $ac_cv_func_wait3_rusage = yes; then $as_echo "#define HAVE_WAIT3 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for accept()" >&5 $as_echo_n "checking types of arguments for accept()... " >&6; } if ${ac_cv_func_accept_return+:} false; then : $as_echo_n "(cached) " >&6 else if ${ac_cv_func_accept_arg1+:} false; then : $as_echo_n "(cached) " >&6 else if ${ac_cv_func_accept_arg2+:} false; then : $as_echo_n "(cached) " >&6 else if ${ac_cv_func_accept_arg3+:} false; then : $as_echo_n "(cached) " >&6 else for ac_cv_func_accept_return in 'int' 'unsigned int PASCAL'; do for ac_cv_func_accept_arg1 in 'int' 'unsigned int'; do for ac_cv_func_accept_arg2 in 'struct sockaddr *' 'const struct sockaddr *' 'void *'; do for ac_cv_func_accept_arg3 in 'int' 'size_t' 'socklen_t' 'unsigned int' 'void'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif extern $ac_cv_func_accept_return accept ($ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *); int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_not_found=no; break 4 else ac_not_found=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done done done done if test "$ac_not_found" = yes; then as_fn_error $? "could not determine argument types" "$LINENO" 5 fi if test "$ac_cv_func_accept_arg3" = "void"; then ac_cv_func_accept_arg3=int fi fi fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_accept_return, $ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *" >&5 $as_echo "$ac_cv_func_accept_return, $ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *" >&6; } cat >>confdefs.h <<_ACEOF #define ACCEPT_TYPE_RETURN $ac_cv_func_accept_return _ACEOF cat >>confdefs.h <<_ACEOF #define ACCEPT_TYPE_ARG1 $ac_cv_func_accept_arg1 _ACEOF cat >>confdefs.h <<_ACEOF #define ACCEPT_TYPE_ARG2 $ac_cv_func_accept_arg2 _ACEOF cat >>confdefs.h <<_ACEOF #define ACCEPT_TYPE_ARG3 $ac_cv_func_accept_arg3 _ACEOF for ac_func in setsid select socket sigprocmask strdup strerror strftime strtok asprintf vasprintf gai_strerror hstrerror pstat setproctitle vsyslog do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_prog in pg_config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PGCONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PGCONFIG"; then ac_cv_prog_PGCONFIG="$PGCONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_PGCONFIG="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PGCONFIG=$ac_cv_prog_PGCONFIG if test -n "$PGCONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PGCONFIG" >&5 $as_echo "$PGCONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PGCONFIG" && break done if test -z $PGCONFIG then PGSQL_INCLUDE_DIR=/usr/local/pgsql/include PGSQL_LIB_DIR=/usr/local/pgsql/lib else PGSQL_INCLUDE_DIR=`pg_config --includedir` PGSQL_LIB_DIR=`pg_config --libdir` fi # Check whether --with-pgsql was given. if test "${with_pgsql+set}" = set; then : withval=$with_pgsql; case "$withval" in "" | y | ye | yes | n | no) as_fn_error $? "*** You must supply an argument to the --with-pgsql option." "$LINENO" 5 ;; esac PGSQL_INCLUDE_DIR="$withval"/include PGSQL_LIB_DIR="$withval"/lib fi # Check whether --with-pgsql-includedir was given. if test "${with_pgsql_includedir+set}" = set; then : withval=$with_pgsql_includedir; case "$withval" in "" | y | ye | yes | n | no) as_fn_error $? "*** You must supply an argument to the --with-pgsql-includedir option." "$LINENO" 5 ;; esac PGSQL_INCLUDE_DIR="$withval" fi # Check whether --with-pgsql-libdir was given. if test "${with_pgsql_libdir+set}" = set; then : withval=$with_pgsql_libdir; case "$withval" in "" | y | ye | yes | n | no) as_fn_error $? "*** You must supply an argument to the --with-pgsql-libdir option." "$LINENO" 5 ;; esac PGSQL_LIB_DIR="$withval" fi # Check whether --with-openssl was given. if test "${with_openssl+set}" = set; then : withval=$with_openssl; else openssl=no fi if test "$with_openssl" = yes || test "$with_openssl" = auto; then for ac_header in openssl/ssl.h do : ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_ssl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OPENSSL_SSL_H 1 _ACEOF $as_echo "#define USE_SSL 1" >>confdefs.h else if test "$with_openssl" = yes; then as_fn_error $? "header file is required for SSL" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: header file is required for SSL" >&5 $as_echo "$as_me: WARNING: header file is required for SSL" >&2;} fi fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_new_ex_data in -lcrypto" >&5 $as_echo_n "checking for CRYPTO_new_ex_data in -lcrypto... " >&6; } if ${ac_cv_lib_crypto_CRYPTO_new_ex_data+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char CRYPTO_new_ex_data (); int main () { return CRYPTO_new_ex_data (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypto_CRYPTO_new_ex_data=yes else ac_cv_lib_crypto_CRYPTO_new_ex_data=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_CRYPTO_new_ex_data" >&5 $as_echo "$ac_cv_lib_crypto_CRYPTO_new_ex_data" >&6; } if test "x$ac_cv_lib_crypto_CRYPTO_new_ex_data" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPTO 1 _ACEOF LIBS="-lcrypto $LIBS" else as_fn_error $? "library 'crypto' is required for OpenSSL" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_library_init in -lssl" >&5 $as_echo_n "checking for SSL_library_init in -lssl... " >&6; } if ${ac_cv_lib_ssl_SSL_library_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSL_library_init (); int main () { return SSL_library_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ssl_SSL_library_init=yes else ac_cv_lib_ssl_SSL_library_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_library_init" >&5 $as_echo "$ac_cv_lib_ssl_SSL_library_init" >&6; } if test "x$ac_cv_lib_ssl_SSL_library_init" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSSL 1 _ACEOF LIBS="-lssl $LIBS" else as_fn_error $? "library 'ssl' is required for OpenSSL" "$LINENO" 5 fi fi # Check whether --with-pam was given. if test "${with_pam+set}" = set; then : withval=$with_pam; $as_echo "#define USE_PAM 1" >>confdefs.h fi if test "$with_pam" = yes ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_start in -lpam" >&5 $as_echo_n "checking for pam_start in -lpam... " >&6; } if ${ac_cv_lib_pam_pam_start+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pam_start (); int main () { return pam_start (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pam_pam_start=yes else ac_cv_lib_pam_pam_start=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_start" >&5 $as_echo "$ac_cv_lib_pam_pam_start" >&6; } if test "x$ac_cv_lib_pam_pam_start" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPAM 1 _ACEOF LIBS="-lpam $LIBS" else as_fn_error $? "library 'pam' is required for PAM" "$LINENO" 5 fi for ac_header in security/pam_appl.h do : ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default" if test "x$ac_cv_header_security_pam_appl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SECURITY_PAM_APPL_H 1 _ACEOF else for ac_header in pam/pam_appl.h do : ac_fn_c_check_header_mongrel "$LINENO" "pam/pam_appl.h" "ac_cv_header_pam_pam_appl_h" "$ac_includes_default" if test "x$ac_cv_header_pam_pam_appl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PAM_PAM_APPL_H 1 _ACEOF else as_fn_error $? "header file or is required for PAM." "$LINENO" 5 fi done fi done fi # Check whether --with-memcached was given. if test "${with_memcached+set}" = set; then : withval=$with_memcached; case "$withval" in "" | y | ye | yes | n | no) as_fn_error $? "*** You must supply an argument to the --with-memcached option." "$LINENO" 5 ;; *) MEMCACHED_INCLUDE_DIR="$withval"/include MEMCACHED_LIB_DIR="$withval"/lib OLD_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -I$MEMCACHED_INCLUDE_DIR" for ac_header in libmemcached/memcached.h do : ac_fn_c_check_header_mongrel "$LINENO" "libmemcached/memcached.h" "ac_cv_header_libmemcached_memcached_h" "$ac_includes_default" if test "x$ac_cv_header_libmemcached_memcached_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBMEMCACHED_MEMCACHED_H 1 _ACEOF $as_echo "#define USE_MEMCACHED 1" >>confdefs.h else as_fn_error $? "header file is required for memcached support" "$LINENO" 5 fi done CFLAGS=$OLD_CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking for memcached_create in -lmemcached" >&5 $as_echo_n "checking for memcached_create in -lmemcached... " >&6; } if ${ac_cv_lib_memcached_memcached_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmemcached $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char memcached_create (); int main () { return memcached_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_memcached_memcached_create=yes else ac_cv_lib_memcached_memcached_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_memcached_memcached_create" >&5 $as_echo "$ac_cv_lib_memcached_memcached_create" >&6; } if test "x$ac_cv_lib_memcached_memcached_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBMEMCACHED 1 _ACEOF LIBS="-lmemcached $LIBS" else as_fn_error $? "libmemcached is not installed" "$LINENO" 5 fi MEMCACHED_INCLUDE_OPT="-I $MEMCACHED_INCLUDE_DIR" MEMCACHED_LINK_OPT="-L$MEMCACHED_LIB_DIR" MEMCACHED_RPATH_OPT="-rpath $MEMCACHED_LIB_DIR" ;; esac fi OLD_LDFLAGS="$LDFLAGS" LDFLAGS="-L$PGSQL_LIB_DIR" OLD_LIBS="$LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQexecPrepared in -lpq" >&5 $as_echo_n "checking for PQexecPrepared in -lpq... " >&6; } if ${ac_cv_lib_pq_PQexecPrepared+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpq $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char PQexecPrepared (); int main () { return PQexecPrepared (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pq_PQexecPrepared=yes else ac_cv_lib_pq_PQexecPrepared=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_PQexecPrepared" >&5 $as_echo "$ac_cv_lib_pq_PQexecPrepared" >&6; } if test "x$ac_cv_lib_pq_PQexecPrepared" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPQ 1 _ACEOF LIBS="-lpq $LIBS" else as_fn_error $? "libpq is not installed or libpq is old" "$LINENO" 5 fi for ac_func in PQprepare do : ac_fn_c_check_func "$LINENO" "PQprepare" "ac_cv_func_PQprepare" if test "x$ac_cv_func_PQprepare" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PQPREPARE 1 _ACEOF fi done LDFLAGS="$OLD_LDFLAGS" LIBS="$OLD_LIBS" # --enable(disable)-rpath option # Check whether --enable-rpath was given. if test "${enable_rpath+set}" = set; then : enableval=$enable_rpath; case "${enableval}" in yes) rpath=yes ;; no) rpath=no ;; esac else rpath=yes fi if test x$rpath = xyes; then enable_rpath_TRUE= enable_rpath_FALSE='#' else enable_rpath_TRUE='#' enable_rpath_FALSE= fi # Decide whether to use row lock against the sequence table for insert_lock. # This lock method is compatible with pgpool-II 3.0 series(until 3.0.4). { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use row lock against the sequence table for insert_lock" >&5 $as_echo_n "checking whether to use row lock against the sequence table for insert_lock... " >&6; } pgac_args="$pgac_args enable_sequence_lock" # Check whether --enable-sequence-lock was given. if test "${enable_sequence_lock+set}" = set; then : enableval=$enable_sequence_lock; case $enableval in yes) : ;; no) : ;; *) as_fn_error $? "no argument expected for --enable-sequence-lock option" "$LINENO" 5 ;; esac else enable_sequence_lock=no fi if test "$enable_sequence_lock" = yes && test "$enable_table_lock" = yes ; then as_fn_error $? "--enable-table-lock cannot be enabled at the same time." "$LINENO" 5 fi if test "$enable_sequence_lock" = yes ; then $as_echo "#define USE_SEQUENCE_LOCK 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_sequence_lock" >&5 $as_echo "$enable_sequence_lock" >&6; } # Decide whether to use table lock against the target table for insert_lock. # This lock method is compatible with pgpool-II 2.2 and 2.3 series. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use table lock against the target table for insert_lock" >&5 $as_echo_n "checking whether to use table lock against the target table for insert_lock... " >&6; } pgac_args="$pgac_args enable_table_lock" # Check whether --enable-table-lock was given. if test "${enable_table_lock+set}" = set; then : enableval=$enable_table_lock; case $enableval in yes) : ;; no) : ;; *) as_fn_error $? "no argument expected for --enable-table-lock option" "$LINENO" 5 ;; esac else enable_table_lock=no fi if test "$enable_table_lock" = yes && test "$enable_sequence_lock" = yes ; then as_fn_error $? "--enable-sequence-lock cannot be enabled at the same time." "$LINENO" 5 fi if test "$enable_table_lock" = yes ; then $as_echo "#define USE_TABLE_LOCK 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_table_lock" >&5 $as_echo "$enable_table_lock" >&6; } ac_config_headers="$ac_config_headers config.h" ac_config_files="$ac_config_files Makefile parser/Makefile pcp/Makefile watchdog/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${enable_rpath_TRUE}" && test -z "${enable_rpath_FALSE}"; then as_fn_error $? "conditional \"enable_rpath\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # Quote evaled strings. for var in SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ AR \ AR_FLAGS \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ SHELL \ ECHO \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_wl \ lt_prog_compiler_pic \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_flag_spec_ld \ hardcode_libdir_separator \ fix_srcfile_path \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ;; esac ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "parser/Makefile") CONFIG_FILES="$CONFIG_FILES parser/Makefile" ;; "pcp/Makefile") CONFIG_FILES="$CONFIG_FILES pcp/Makefile" ;; "watchdog/Makefile") CONFIG_FILES="$CONFIG_FILES watchdog/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool 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 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == "file_magic". file_magic_cmd=$lt_file_magic_cmd # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name of the directory that contains temporary libtool files. objdir=$objdir # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that does not interpret backslashes. ECHO=$lt_ECHO # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # If ld is used when linking, flag to hardcode \$libdir into a binary # during linking. This must work even if \$libdir does not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path=$lt_fix_srcfile_path # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $* )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[^=]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$@"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$1+=\$2" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$1=\$$1\$2" } _LT_EOF ;; esac sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi pgpool-II-3.3.2/pcp.conf.sample0000664000076400007640000000153212245576256013201 00000000000000# PCP Client Authentication Configuration File # ============================================ # # This file contains user ID and his password for pgpool # communication manager authentication. # # Note that users defined here do not need to be PostgreSQL # users. These users are authorized ONLY for pgpool # communication manager. # # File Format # =========== # # List one UserID and password on a single line. They must # be concatenated together using ':' (colon) between them. # No spaces or tabs are allowed anywhere in the line. # # Example: # postgres:e8a48653851e28c69d0506508fb27fc5 # # Be aware that there will be no spaces or tabs at the # beginning of the line! although the above example looks # like so. # # Lines beginning with '#' (pound) are comments and will # be ignored. Again, no spaces or tabs allowed before '#'. # USERID:MD5PASSWD pgpool-II-3.3.2/pool_config.h0000664000076400007640000003206012245576266012740 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_config.h.: pool_config.l related header file * */ #ifndef POOL_CONFIG_H #define POOL_CONFIG_H /* * watchdog */ #include "watchdog/watchdog.h" /* * Master/slave sub mode */ #define MODE_STREAMREP "stream" /* Streaming Replication */ #define MODE_SLONY "slony" /* Slony-I */ /* * watchdog lifecheck method */ #define MODE_HEARTBEAT "heartbeat" #define MODE_QUERY "query" /* * Regex support in white and black list function */ #include #define BLACKLIST 0 #define WHITELIST 1 #define PATTERN_ARR_SIZE 16 /* Default length of regex array: 16 patterns */ typedef struct { char *pattern; int type; int flag; regex_t regexv; } RegPattern; /* * Flags for backendN_flag */ #define POOL_FAILOVER 0x0001 /* allow or disallow failover */ #define POOL_DISALLOW_TO_FAILOVER(x) ((unsigned short)(x) & POOL_FAILOVER) #define POOL_ALLOW_TO_FAILOVER(x) (!(POOL_DISALLOW_TO_FAILOVER(x))) /* * configuration parameters */ typedef struct { char *listen_addresses; /* hostnames/IP addresses to listen on */ int port; /* port # to bind */ int pcp_port; /* PCP port # to bind */ char *socket_dir; /* pgpool socket directory */ char *pcp_socket_dir; /* PCP socket directory */ int pcp_timeout; /* PCP timeout for an idle client */ int num_init_children; /* # of children initially pre-forked */ int child_life_time; /* if idle for this seconds, child exits */ int connection_life_time; /* if idle for this seconds, connection closes */ int child_max_connections; /* if max_connections received, child exits */ int client_idle_limit; /* If client_idle_limit is n (n > 0), the client is forced to be disconnected after n seconds idle */ int authentication_timeout; /* maximum time in seconds to complete client authentication */ int max_pool; /* max # of connection pool per child */ char *logdir; /* logging directory */ char *log_destination; /* log destination: stderr or syslog */ int syslog_facility; /* syslog facility: LOCAL0, LOCAL1, ... */ char *syslog_ident; /* syslog ident string: pgpool */ char *pid_file_name; /* pid file name */ char *backend_socket_dir; /* Unix domain socket directory for the PostgreSQL server */ int replication_mode; /* replication mode */ int log_connections; /* 0:false, 1:true - logs incoming connections */ int log_hostname; /* 0:false, 1:true - resolve hostname */ int enable_pool_hba; /* 0:false, 1:true - enables pool_hba.conf file authentication */ char *pool_passwd; /* pool_passwd file name. "" disables pool_passwd */ int load_balance_mode; /* load balance mode */ int replication_stop_on_mismatch; /* if there's a data mismatch between master and secondary * start degeneration to stop replication mode */ /* If there's a disagreement with the number of affected tuples in * UPDATE/DELETE, then degenerate the node which is most likely * "minority". # If false, just abort the transaction to keep the * consistency.*/ int failover_if_affected_tuples_mismatch; int replicate_select; /* if non 0, replicate SELECT statement when load balancing is disabled. */ char **reset_query_list; /* comma separated list of queries to be issued at the end of session */ char **white_function_list; /* list of functions with no side effects */ char **black_function_list; /* list of functions with side effects */ int print_timestamp; /* if non 0, print time stamp to each log line */ int master_slave_mode; /* if non 0, operate in master/slave mode */ char *master_slave_sub_mode; /* either "slony" or "stream" */ unsigned long long int delay_threshold; /* If the standby server delays more than delay_threshold, * any query goes to the primary only. The unit is in bytes. * 0 disables the check. Default is 0. * Note that health_check_period required to be greater than 0 * to enable the functionality. */ char *log_standby_delay; /* how to log standby lag */ int connection_cache; /* if non 0, cache connection pool */ int health_check_timeout; /* health check timeout */ int health_check_period; /* health check period */ char *health_check_user; /* PostgreSQL user name for health check */ char *health_check_password; /* password for health check username */ int health_check_max_retries; /* health check max retries */ int health_check_retry_delay; /* amount of time to wait between retries */ int sr_check_period; /* streaming replication check period */ char *sr_check_user; /* PostgreSQL user name streaming replication check */ char *sr_check_password; /* password for sr_check_user */ char *failover_command; /* execute command when failover happens */ char *follow_master_command; /* execute command when failover is ended */ char *failback_command; /* execute command when failback happens */ /* * If true, trigger fail over when writing to the backend * communication socket fails. This is the same behavior of * pgpool-II 2.2.x or earlier. If set to false, pgpool will report * an error and disconnect the session. */ int fail_over_on_backend_error; char *recovery_user; /* PostgreSQL user name for online recovery */ char *recovery_password; /* PostgreSQL user password for online recovery */ char *recovery_1st_stage_command; /* Online recovery command in 1st stage */ char *recovery_2nd_stage_command; /* Online recovery command in 2nd stage */ int recovery_timeout; /* maximum time in seconds to wait for remote start-up */ int search_primary_node_timeout; /* maximum time in seconds to search for new primary * node after failover */ int client_idle_limit_in_recovery; /* If > 0, the client is forced to be * disconnected after n seconds idle * This parameter is only valid while in recovery 2nd stage */ int insert_lock; /* if non 0, automatically lock table with INSERT to keep SERIAL data consistency */ int ignore_leading_white_space; /* ignore leading white spaces of each query */ int log_statement; /* 0:false, 1: true - logs all SQL statements */ int log_per_node_statement; /* 0:false, 1: true - logs per node detailed SQL statements */ int parallel_mode; /* if non 0, run in parallel query mode */ int enable_query_cache; /* if non 0, use query cache. 0 by default */ char *pgpool2_hostname; /* pgpool2 hostname */ char *system_db_hostname; /* system DB hostname */ int system_db_port; /* system DB port number */ char *system_db_dbname; /* system DB name */ char *system_db_schema; /* system DB schema name */ char *system_db_user; /* user name to access system DB */ char *system_db_password; /* password to access system DB */ char *lobj_lock_table; /* table name to lock for rewriting lo_creat */ int debug_level; /* debug message verbosity level. * 0: no message, 1 <= : more verbose */ BackendDesc *backend_desc; /* PostgreSQL Server description. Placed on shared memory */ LOAD_BALANCE_STATUS load_balance_status[MAX_NUM_BACKENDS]; /* to remember which DB node is selected for load balancing */ /* followings do not exist in the configuration file */ int num_reset_queries; /* number of queries in reset_query_list */ int num_white_function_list; /* number of functions in white_function_list */ int num_black_function_list; /* number of functions in black_function_list */ int num_white_memqcache_table_list; /* number of functions in white_memqcache_table_list */ int num_black_memqcache_table_list; /* number of functions in black_memqcache_table_list */ int logsyslog; /* flag used to start logging to syslog */ /* ssl configuration */ int ssl; /* if non 0, activate ssl support (frontend+backend) */ char *ssl_cert; /* path to ssl certificate (frontend only) */ char *ssl_key; /* path to ssl key (frontend only) */ char *ssl_ca_cert; /* path to root (CA) certificate */ char *ssl_ca_cert_dir; /* path to directory containing CA certificates */ time_t relcache_expire; /* relation cache life time in seconds */ int relcache_size; /* number of relation cache life entry */ int check_temp_table; /* enable temporary table check */ /* followings are for regex support and do not exist in the configuration file */ RegPattern *lists_patterns; /* Precompiled regex patterns for black/white lists */ int pattc; /* number of regexp pattern */ int current_pattern_size; /* size of the regex pattern array */ int memory_cache_enabled; /* if true, use the memory cache functionality, false by default */ char *memqcache_method; /* Cache store method. Either 'shmem'(shared memory) or 'memcached'. 'shmem' by default */ char *memqcache_memcached_host; /* Memcached host name. Mandatory if memqcache_method=memcached. */ int memqcache_memcached_port; /* Memcached port number. Mandatory if memqcache_method=memcached. */ int memqcache_total_size; /* Total memory size in bytes for storing memory cache. Mandatory if memqcache_method=shmem. */ int memqcache_max_num_cache; /* Total number of cache entries. Mandatory if memqcache_method=shmem. */ int memqcache_expire; /* Memory cache entry life time specified in seconds. 60 by default. */ int memqcache_auto_cache_invalidation; /* If true, invalidation of query cache is triggered by corresponding */ /* DDL/DML/DCL(and memqcache_expire). If false, it is only triggered */ /* by memqcache_expire. True by default. */ int memqcache_maxcache; /* Maximum SELECT result size in bytes. */ int memqcache_cache_block_size; /* Cache block size in bytes. 8192 by default */ char *memqcache_oiddir; /* Temporary work directory to record table oids */ char **white_memqcache_table_list; /* list of tables to memqcache */ char **black_memqcache_table_list; /* list of tables not to memqcache */ RegPattern *lists_memqcache_table_patterns; /* Precompiled regex patterns for black/white lists */ int memqcache_table_pattc; /* number of regexp pattern */ int current_memqcache_table_pattern_size; /* size of the regex pattern array */ /* * add for watchdog */ int use_watchdog; /* if non 0, use watchdog */ char *wd_lifecheck_method; /* method of lifecheck. 'heartbeat' or 'query' */ int clear_memqcache_on_escalation; /* if no 0, clear query cache on shmem when escalating */ char *wd_escalation_command; /* Executes this command at escalation on new active pgpool.*/ char *wd_hostname; /* watchdog hostname */ int wd_port; /* watchdog port */ WdDesc * other_wd; /* watchdog lists */ char * trusted_servers; /* icmp reachable server list (A,B,C) */ char * delegate_IP; /* delegate IP address */ int wd_interval; /* lifecheck interval (sec) */ char *wd_authkey; /* Authentication key for watchdog communication */ char * ping_path; /* path to ping command */ char * ifconfig_path; /* path to ifconfig command */ char * if_up_cmd; /* ifup command */ char * if_down_cmd; /* ifdown command */ char * arping_path; /* path to arping command */ char * arping_cmd; /* arping command */ int wd_life_point; /* life point (retry times at lifecheck) */ char *wd_lifecheck_query; /* lifecheck query */ char *wd_lifecheck_dbname; /* Database name connected for lifecheck */ char *wd_lifecheck_user; /* PostgreSQL user name for watchdog */ char *wd_lifecheck_password; /* password for watchdog user */ int wd_heartbeat_port; /* Port number for heartbeat lifecheck */ int wd_heartbeat_keepalive; /* Interval time of sending heartbeat signal (sec) */ int wd_heartbeat_deadtime; /* Deadtime interval for heartbeat signal (sec) */ WdHbIf hb_if[WD_MAX_IF_NUM]; /* interface devices */ int num_hb_if; /* number of interface devices */ } POOL_CONFIG; typedef enum { INIT_CONFIG = 1, /* 0x01 */ RELOAD_CONFIG = 2 /* 0x02 */ } POOL_CONFIG_CONTEXT; extern POOL_CONFIG *pool_config; /* configuration values */ extern int pool_init_config(void); extern int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context); extern int eval_logical(char *str); extern char *pool_flag_to_str(unsigned short flag); /* method use for syslog support */ extern int set_syslog_facility (char *); /* methods used for regexp support */ extern int add_regex_pattern(char *type, char *s); extern int growFunctionPatternArray(RegPattern item); extern int growMemqcacheTablePatternArray(RegPattern item); #endif /* POOL_CONFIG_H */ pgpool-II-3.3.2/pool_passwd.c0000664000076400007640000001113512245576267012770 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Module to handle pool_passwd */ #include #include #include "pool.h" #include "pool_passwd.h" #include "md5.h" static FILE *passwd_fd = NULL; /* File descriptor for pool_passwd */ static char saved_passwd_filename[POOLMAXPATHLEN+1]; /* * Initialize this module. * If pool_passwd does not exist yet, create it. * Open pool_passwd. */ void pool_init_pool_passwd(char *pool_passwd_filename) { if (passwd_fd) return; if (saved_passwd_filename[0] == '\0') { int len = strlen(pool_passwd_filename); memcpy(saved_passwd_filename, pool_passwd_filename, len); saved_passwd_filename[len] = '\0'; } passwd_fd = fopen(pool_passwd_filename, "r+"); if (!passwd_fd) { if (errno == ENOENT) { /* The file does not exist yet. Create it. */ passwd_fd = fopen(pool_passwd_filename, "w+"); if (passwd_fd) return; } pool_error("pool_init_pool_passwd: couldn't open %s. reason: %s", pool_passwd_filename, strerror(errno)); } } /* * Update passwd. If the user does not exist, create a new entry. * Returns 0 on success non 0 otherwise. */ int pool_create_passwdent(char *username, char *passwd) { int len; int c; char name[MAX_USER_NAME_LEN]; char *p; int readlen; if (!passwd_fd) { pool_error("pool_create_passwdent: passwd_fd is NULL"); return -1; } len = strlen(passwd); if (len != POOL_PASSWD_LEN) { pool_error("pool_create_passwdent: wrong password length:%d", len); return -1; } rewind(passwd_fd); name[0] = '\0'; while (!feof(passwd_fd)) { p = name; readlen = 0; while (readlen < sizeof(name)) { c = fgetc(passwd_fd); if (c == EOF) break; else if (c == ':') break; readlen++; *p++ = c; } *p = '\0'; if (!strcmp(username, name)) { /* User name found. Update password. */ while ((c = *passwd++)) { fputc(c, passwd_fd); } fputc('\n', passwd_fd); return 0; } else { /* Skip password */ while((c = fgetc(passwd_fd)) != EOF && c != '\n') ; } } fseek(passwd_fd, 0, SEEK_END); /* * Not found the user name. * Create a new entry. */ while ((c = *username++)) { fputc(c, passwd_fd); } fputc(':', passwd_fd); while ((c = *passwd++)) { fputc(c, passwd_fd); } fputc('\n', passwd_fd); return 0; } /* * Get password in pool_passwd by username. Returns NULL if specified * entry does not exist or error occurred. * Returned password is on the static memory. */ char *pool_get_passwd(char *username) { int c; char name[MAX_USER_NAME_LEN+1]; static char passwd[POOL_PASSWD_LEN+1]; char *p; int readlen; if (!username) { pool_error("pool_get_passwd: username is NULL"); return NULL; } if (!passwd_fd) { pool_error("pool_get_passwd: passwd_fd is NULL"); return NULL; } rewind(passwd_fd); name[0] = '\0'; while (!feof(passwd_fd)) { p = name; readlen = 0; while (readlen < (sizeof(name)-1)) { c = fgetc(passwd_fd); if (c == EOF) break; else if (c == ':') break; readlen++; *p++ = c; } *p = '\0'; if (!strcmp(username, name)) { /* User name found. Return password. */ p = passwd; readlen = 0; while((c = fgetc(passwd_fd)) != EOF && c != '\n' && readlen < (sizeof(passwd)-1)) { *p++ = c; readlen++; } *p = '\0'; return passwd; } else { /* Skip password */ while((c = fgetc(passwd_fd)) != EOF && c != '\n') ; } } return NULL; } /* * Delete the entry by username. If specified entry does not exist, * does nothing. */ void pool_delete_passwdent(char *username) { } /* * Finish this moil. Close pool_passwd. */ void pool_finish_pool_passwd(void) { if (passwd_fd) { fclose(passwd_fd); passwd_fd = NULL; } } void pool_reopen_passwd_file(void) { pool_finish_pool_passwd(); pool_init_pool_passwd(saved_passwd_filename); } pgpool-II-3.3.2/pool_signal.c0000664000076400007640000000767412245576256012757 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2008, PgPool Global Development Group * Portions Copyright (c) 2003-2004, PostgreSQL Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. */ /* * Signal stuff. Stolen from PostgreSQL source code. */ #include "config.h" #include "pool_signal.h" #include #ifdef HAVE_SIGPROCMASK sigset_t UnBlockSig, BlockSig, AuthBlockSig; #else int UnBlockSig, BlockSig, AuthBlockSig; #endif /* * Initialize BlockSig, UnBlockSig, and AuthBlockSig. * * BlockSig is the set of signals to block when we are trying to block * signals. This includes all signals we normally expect to get, but NOT * signals that should never be turned off. * * AuthBlockSig is the set of signals to block during authentication; * it's essentially BlockSig minus SIGTERM, SIGQUIT, SIGALRM. * * UnBlockSig is the set of signals to block when we don't want to block * signals (is this ever nonzero??) */ void poolinitmask(void) { #ifdef HAVE_SIGPROCMASK sigemptyset(&UnBlockSig); sigfillset(&BlockSig); sigfillset(&AuthBlockSig); /* * Unmark those signals that should never be blocked. Some of these * signal names don't exist on all platforms. Most do, but might as * well ifdef them all for consistency... */ #ifdef SIGTRAP sigdelset(&BlockSig, SIGTRAP); sigdelset(&AuthBlockSig, SIGTRAP); #endif #ifdef SIGABRT sigdelset(&BlockSig, SIGABRT); sigdelset(&AuthBlockSig, SIGABRT); #endif #ifdef SIGILL sigdelset(&BlockSig, SIGILL); sigdelset(&AuthBlockSig, SIGILL); #endif #ifdef SIGFPE sigdelset(&BlockSig, SIGFPE); sigdelset(&AuthBlockSig, SIGFPE); #endif #ifdef SIGSEGV sigdelset(&BlockSig, SIGSEGV); sigdelset(&AuthBlockSig, SIGSEGV); #endif #ifdef SIGBUS sigdelset(&BlockSig, SIGBUS); sigdelset(&AuthBlockSig, SIGBUS); #endif #ifdef SIGSYS sigdelset(&BlockSig, SIGSYS); sigdelset(&AuthBlockSig, SIGSYS); #endif #ifdef SIGCONT sigdelset(&BlockSig, SIGCONT); sigdelset(&AuthBlockSig, SIGCONT); #endif #ifdef SIGTERM sigdelset(&AuthBlockSig, SIGTERM); #endif #ifdef SIGQUIT sigdelset(&AuthBlockSig, SIGQUIT); #endif #ifdef SIGALRM sigdelset(&AuthBlockSig, SIGALRM); #endif #else UnBlockSig = 0; BlockSig = sigmask(SIGHUP) | sigmask(SIGQUIT) | sigmask(SIGTERM) | sigmask(SIGALRM) | sigmask(SIGINT) | sigmask(SIGUSR1) | sigmask(SIGUSR2) | sigmask(SIGCHLD) | sigmask(SIGWINCH) | sigmask(SIGFPE); AuthBlockSig = sigmask(SIGHUP) | sigmask(SIGINT) | sigmask(SIGUSR1) | sigmask(SIGUSR2) | sigmask(SIGCHLD) | sigmask(SIGWINCH) | sigmask(SIGFPE); #endif } /* Win32 signal handling is in backend/port/win32/signal.c */ #ifndef WIN32 /* * We need to check actually the system has the posix signals or not, but... */ #define HAVE_POSIX_SIGNALS /* * Set up a signal handler */ pool_sighandler_t pool_signal(int signo, pool_sighandler_t func) { #if !defined(HAVE_POSIX_SIGNALS) return signal(signo, func); #else struct sigaction act, oact; act.sa_handler = func; sigemptyset(&act.sa_mask); act.sa_flags = 0; if (signo != SIGALRM) act.sa_flags |= SA_RESTART; #ifdef SA_NOCLDSTOP if (signo == SIGCHLD) act.sa_flags |= SA_NOCLDSTOP; #endif if (sigaction(signo, &act, &oact) < 0) return SIG_ERR; return oact.sa_handler; #endif /* !HAVE_POSIX_SIGNALS */ } #endif /* WIN32 */ pgpool-II-3.3.2/NEWS0000664000076400007640000061142512245576266011000 00000000000000 Release Notes =============================================================================== 3.3 Series (2013/07/30 - ) =============================================================================== 3.3.2 (tokakiboshi) 2013/11/29 * Version 3.3.2 This is a bugfix release against pgpool-II 3.3.1. __________________________________________________________________ * Bug fixes - Fix incorrect time stamp rewriting in replication mode for certain time zones. (Tatsuo Ishii) Time stamp rewriting calls "SELECT now()" to get current time. Unfortunately the buffer for the current time is too small for certain time zones such as "02:30". Note that non-30-minutes-time-zone such as "0900" does not reveal the problem. This explains why we haven't the bug report until today. Bug reported in [pgpool-general: 2113] and fix provided by Sean Hogan. http://www.sraoss.jp/pipermail/pgpool-general/2013-September/002142.html - installer: Fix the way to specify pgpoolAdmin version in redhat/rpm_installer/getsources.sh. (Yugo Nagata) - Makefile: Replace pg_config by $(PG_CONFIG) in Makefiles so it can be overridden at build time when compiling for different PG major versions. (Tatsuo Ishii) Patch contributed by Christoph Berg ([pgpool-general: 2127]). http://www.sraoss.jp/pipermail/pgpool-general/2013-September/002156.html - watchdog: Fix a warning/error when compiling with -Werror=format-security. (Tatsuo Ishii) Patch contributed by Christoph Berg ([pgpool-general: 2127]). http://www.sraoss.jp/pipermail/pgpool-general/2013-September/002156.html - configure: Remove -lcompat because it confuses FreeBSD per bug#15. (Tatsuo Ishii) http://www.pgpool.net/mantisbt/view.php?id=15 - Fix segfault when pgpool.conf does not set log_standby_delay. (Tatsuo Ishii) This is caused by wrong initialization for log_standby_delay in pool_config.l. Per bug#74. http://www.pgpool.net/mantisbt/view.php?id=74 - doc: Modify descriptions about restrictions of parallel mode Muliple rows INSERT using VALUES are not supported in parallel mode. (Yugo Nagata) - Avoid calling find_primary_node_repeatedly() when standby node goes down. (Tatsuo Ishii) This will reduce the time to failover. Per bug #75, patch modified by Tatsuo Ishii. http://www.pgpool.net/mantisbt/view.php?id=75 - Fix data inconsistency problem with native replication mode + extended protocol case. (Tatsuo Ishii) It is reported that concurrent INSERT using JDBC driver causes data difference among database node. This only happens following conditions are all met: 1) Native replication mode 2) Extended protocol used 3) The portal created by parse message is reused by bind message 4) autocommit is on 5) SERIAL (sequence) is used Pgpool-II's parse message function knows it has to lock the target table when INSERT (plus #5) is issued by clients. Unfortunately bind message function did not know it. Once parse/bind/execute finishes, pgpool releases the lock obtained by parse because of #4. JDBC wants to reuse the portal and starts the cycle from bind message, which does not obtain lock. As as result, lock-free INSERT are floating around which causes data inconsistency of course. The solution is, lock the table in bind phase. For this bind needs to issue LOCK in extended protocol. This was a little bit hard because the module (do_command()) to issue internal SQL command (other than SELECT) does not support extended protocol. To solve the problem do_query() is modified so that it accepts other than SELECT because it already accepts extended protocol. The modification is minimum and is only tested for the case called from insert_lock(). I do not recommend to replace every occurrence of do_command () with do_query() at this point. BTW the reason why the bug is not reported is, most users uses JDBC with auto commit = off. In this case, the lock obtained by parse persists until user explicitly issues commit or rollback. Per bug report by Steve Kuekes in [pgpool-general: 2142]. http://www.sraoss.jp/pipermail/pgpool-general/2013-September/002171.html - Fix memory allocation size bug in the code path of query cache. (Tatsuo Ishii) In execute() memory allocation size is too small incertain case. No bug has been reported so far, but certainly this is a bug. - Fix occasional segfault in query cache + extended protocol. (Tatsuo Ishii) When the query is not "cache safe", bind_msg->param_offset was not set in Bind(). However, Execute() unconditionally uses bind_msg->param_offset to convert bind parameters to string so that they can be added to the cached query string and it causes segfault because bind_msg->param_offset is a garbage. Also logic bug to calculate bind_msg->param_offset is corrected. Per bug#76. http://www.pgpool.net/mantisbt/view.php?id=76 - Avoid to run out free query cache hash index entry. (Tatsuo Ishii) If hash index entries are run out, pgpool-II cannot reuse old cache entry because pgpool-II always expects there's at least one empty hash index entry. To mitigate the problem, if free hash index entries are run out, look for victim cache block to reuse the hash index entry. Per bug #70. http://www.pgpool.net/mantisbt/view.php?id=70 - installer: checkEnv() didn't do anything and always returned 0. (Nozomi Anzai) - Fix inappropriate shared memory allocation size for clock hand. (Tatsuo Ishii) The memory for clock hand was allocated as sizeof(pool_fsmm_clock_hand)) which is 8 bytes long because the variable is declared as: static int *pool_fsmm_clock_hand; This is plain wrong. The memory size actually needed is only 4 bytes, which is sizeof(*pool_fsmm_clock_hand)). In other word, the bug allocated unnecessary 4 bytes, which did nothing bd for the execution of program. But a bug is a bug. Per covery report "1111476 Wrong sizeof argument" - Fix "show pool_status" always shows memqcache_auto_cache_invalidation as 0. (Tatsuo Ishii) Per bug #80. http://www.pgpool.net/mantisbt/view.php?id=80 - Fix error message in read_password_packet(). (Tatsuo Ishii) - watchdog: Fix to pass big parameter by pointer instead of by value at some function. (Yugo Nagata) - Fix memory leak when SSL is requested. (Tatsuo Ishii) When SSL is requested, pgpool child retries to read start up packet. However it does not free the memory for previous start up packet. Per Coverity report "1111443 Resource". - Fix memory leak when do_query() fails in timestamp rewriting. (Tatsuo Ishii) For this purpose free_select_result() is changed to accept NULL argument. Per Coverity report "1111454, 1111455 Resource leak". - Fix load balance bug in replication mode. (Tatsuo Ishii) When load_balance_mode = off, SELECTs including writing function should be sent to all the DB nodes. Per [pgpool-general: 2221]. http://www.sraoss.jp/pipermail/pgpool-general/2013-October/002250.html The bug was introduced in: http://git.postgresql.org/gitweb/?p=pgpool2.git;a=commitdiff;h=1ac45a28258074ea4d9d902aca016f970d31f311 (3.3.1). - watchdog: Fix to put null character at end of ping result string used in watchdog. (Yugo Nagata) - Fix target node selection logic when "DEALLOCATE portal|statement". (Tatsuo Ishii) When "DEALLOCATE portal|statement" is used and last prepared statement or portal was not found, target node selection map is not set. Probably this is not actually harmful because prepared statement or portal was not found is an error case. The bug was there since day 0. Per Coverity report "1111491 Structurally dead code". - Fix range check bug of MAX_NUM_BACKENDS in corner case. (Tatsuo Ishii) MAX_NUM_BACKENDS is the allowed max number of DB nodes (128, at this point). In reality, probably no one ever tried more than 128 DB nodes and that's the reason why nobody noticed. Per Coverity report "1111429, 1111430 and 1111431 Out-of-bounds write". - Do not set/unset fronted connection info for dead backend. (Tatsuo Ishii) Per bug #82. http://www.pgpool.net/mantisbt/view.php?id=82 - Fix that the script forgets to allow public access to pgpool_catalog. (Tatsuo Ishii) The bug prevents inserting data into user tables if pgpool_catalog is created in native replication mode. The bug was there from day 1. I wonder why nobody noticed until today. Per [pgpool-general-jp: 1229]. http://www.sraoss.jp/pipermail/pgpool-general-jp/2013-November/001228.html - doc: Add description that it is recommended to specify multiple servers to trusted_servers. (Yugo Nagata) - Fix uninitialized variable in error case in pool_do_auth(). (Tatsuo Ishii) If there's no valid backend, pgpool will return garbage pid to frontend in auth phase. Actually because no backend is available, frontend will be disconnected later on. So this is not harmless. Per Coverity report "1127331 Uninitialized scalar variable". - Fix to add node id range check when issue an error message using node id. (Tatsuo Ishii) Per Coverity report #1111433 "Out-of-bounds read". - Fix buffer overrun bug and resource leak bug of parse_copy_data(). (Tatsuo Ishii) Per Coverity report 1111427 "Out-of-bounds write" and 1111453 "Resource leak". - Fix possible segfault in CopyDataRaws(). (Tatsuo Ishii) Coverity pointed out that if pool_get_id() returns an error, VALID_BACKEND will access out of array. Per Coverity report 1111413 "Memory - illegal accesses". - Fix query cache is enabled and protocol version = 2 case. (Tatsuo Ishii) When the protocol version = 2, we assume that session state is "idle". This is not feasible but no way. I recommend to not use query cache with protocol 2. Per Coverity report 1111488 "Uninitialized scalar variable". - Fix strftime() usage in pool_pools(). (Tatsuo Ishii) The buffer is not large enough as expected by the second parameter. This is not harmless because the format string will not produce longer result string than the buffer. Per Coverity report 1111426 "Out-of-bounds access". - RPM: Improved to specify the versions of pgool-II and PostgreSQL in the. spec file. (Nozomi Anzai) - Fix resource leak in make_persistent_db_connection. (Tatsio Ishii) For this pupose, new static function free_persisten_db_connection_memory is added. Per Coverity report #1111468. - Fix a bug that connection check to trusted servers fails when the RTT is very short. (Yugo Nagata) - Fix several small bug fixes detected by Coverity. (Tatsuo Ishii) =============================================================================== 3.3.1 (tokakiboshi) 2013/09/06 * Version 3.3.1 This is a bugfix release against pgpool-II 3.3.0. __________________________________________________________________ * Bug fixes - Fix to add the regression test suite for making tar boll (Tatsuo Ishii) This isn't included in the tar ball of 3.3.0 release. - Fix watchdog test script in regression test (Tatsuo Ishii) - Fix a memory overrun bug (Tatsuo Ishii) This problem is pointed out in [pgpool-general: 1956] by Sean Hogan. [pgpool-general: 1956] memory overrun bug? http://www.sraoss.jp/pipermail/pgpool-general/2013-July/001984.html - Fix a compile error (Yugo Nagata) - Fix child process termination with sig abort when memory query cache is enabled (Tatsuo Ishii) This is due to double free bug that occurs when multiple bind/execute messages come after a parse message. When a parse messages comes, query context is created along with temp cache. The pointer to the temp cache is added to the temp cache array when the query executed. Subsequent bind messages uses the same temp cache pointer. This is the source of double free bug when the cache array discarded. This is reported in Bug track #68 by harukat. #68: child process termination with sigabort when memory_cache_enabled = on http://www.pgpool.net/mantisbt/view.php?id=68 - Add some test cases to regression test (Tatsuo Ishii) - Fix typos of the document in installation of pgpool-recovery section. (Tatsuo Ishii) - Fix a typo of log message (Yugo Nagata) - Fix typos of the japanese document (Yugo Nagata) - Fix to send SELECT to master node only when load_balance_mode is off in replication mode (Tatsuo Ishii) When load_balance_mode is off in replication mode, SELECT queries should be sent to master node only, rather than sent to all nodes in an explicit transaction. This problem is reported in [pgpool-general: 2038] by Rypl Lukas. [pgpool-general: 2038] SELECT sent to both nodes in replication mode http://www.sraoss.jp/pipermail/pgpool-general/2013-August/002066.html - Fix pgpool_setup to work in standalone. (Tatsuo Ishii) =============================================================================== 3.3 (tokakiboshi) 2013/07/30 * Version 3.3 This is the first version of pgpool-II 3.3 series. That is, a "major version up" from 3.2 series. __________________________________________________________________ * Incompatible changes - All the follwing are about watchdog. See "New features" section below for details of these changes. - Default monitoring method was changed from query mode to heartbeat mode. - Failover/failback commands are executed in only one pgpool-II. - In default, all the query caches on shared memory are cleared when standby pgpool-II escalates to active. - Database name, user name, and password used for monitring other pgpool-II by query are specified by dedicated parameters. Previously, template1, recovery_user, and recovery_password are used. __________________________________________________________________ * New features ** Watchdog - Add a new monitring method using heartbeat signal of UDP packet in lifecheck. (Yugo Nagata) You can select a method from either of two methods, "heartbeat" mode or "query" mode. The heartbeat mode is the new method. In this mode, watchdog monitors other pgpool-II process by using heartbeat signal. Watchdog receives heartbeat signals sent by other pgpool-II periodically. If there are no signal for a certain period, watchdog regards it as failure of the pgpool-II. For redundancy you can use multiple networks for heartbeat exchange between pgpool-IIs. This mode is default and recommended one. The query mode is the conventional method. In this mode, watchdog monitors pgpool-II's service rather than process. Watchdog sends queries to other pgpool-II and checks the response. Note that this method requires connections from other pgpool-IIs, so it would fail motoring if num_init_children isn't large enough. This mode is deprecated and left for backward compatibility. Add these new parameters: - wd_lifecheck_method - wd_heartbeat_port - wd_heartbeat_keepalive - wd_heartbeat_deadtime - heartbeat_destinationX - heartbeat_destination_portX - heartbeat_deviceX - Add interlocking mechanism of exclusive failover/failback command execution. (Yugo Nagata) When using multiple pgpool-IIs with watchdog enabled, failover commands (failover_command, failback_command, and follow_master_command) get executed only at one pgpool-II. Previously, these command got executed at all pgpool-IIs. - Add authentication mechanism for watchdog packet communication. (Yugo Nagata) Watchdog packets (include heartbeat signal) from pgpool-II with wrong authentication key are rejected. All pgpool-IIs must have the same key, which is specified wd_authkey parameter in pgpool.conf. pgpool-II with wrong authkey can't even start watchdog, because the startup packet is rejected by other pgpool-IIs. - Add clear_memqcache_on_escalation parameter. (Yugo Nagata) If this is on, all the query caches on shared memory are cleared when standby pgpool-II escalates to active. This is aimed to prevent the new active pgpool-II from using inconsistent query caches with the previous active. - Add wd_escalation_command parameter. (Yugo Nagata) This specifies command which is executed at escalation on the new active pgpool-II server. The timing is just before virtual IP is brought up. - Add parameters wd_lifecheck_dbname, wd_lifecheck_user, and wd_lifecheck_password. (Yugo Nagata) These parameters specify the database name, the user name, and password used in query mode lifecheck of watchdog . Previously, these are hard coded to use template1, recovery_user, and recovery_password. - When delegate_IP parameter is emply, viertual IP is neither brought up nor switched. (Yugo Nagata) This allows multi-master like configuration without virtual IP. - Add pcp_watchdog_info command (Yugo Nagata) This is PCP command for retrieving the watchdog status. ** Others - Import PostgreSQL 9.2 raw parser. (Nozomi Anzai, Tatsuo Ishii) - Add a tool called pgpool_setup to set up pgpool-II and PostgreSQL temporary installation in current directory for *testing* purpose. (Tatsuo Ishii) usage: pgpool_setup [-m r|s][-n num_clusters][--no-stop] -m s: create an installation as streaming replication mode. (the default) -m r: create an installation as native replication mode. -n num_clusters: create num_clusters PostgreSQL database cluster nodes -p base_port: specify base port. The first PostgreSQL node's port is base_port. Second PostgreSQL node's port is base_port+1 ... nth PostgreSQL node's port is base_port+n-1, pgpool port is base_port+n, pcp port is base_port+n+1. --no-stop: do not stop pgpool and PostgreSQL after the work - Support installation method using CREATE EXTENSION for pgpool-recovery and pgpool-regclass. (Tatsuo Ishii) Older installtion method is still preserved. Note: extension names are "pgpool_recovery" and "pgpool_regclass", not "pgpool-recovery" and "pgpool-regclass" because latters are not convenient in using CREATE EXTENSION command (requires double quotes). - Add a function "pgpool_pgctl()" which enebles to execute pg_ctl stop/restart/reload (except for start) by SQL. (Nozomi Anzai) $ psql sales -c "select pgpool_pgctl('reload', 'fast')"; pgpool_pgctl -------------- t (1 row) This function always ignores the actual result and returns 't', so the user can't know if pg_ctl succeeded or failed. To use this we have to set the custom variable for security which limits the users to execute pg_ctl who has the permission of data directory. - Add shell scripts to install pgpool-II and pgpoolAdmin by RPM. (Nozomi Anzai, Yugo Nagata) To make the installer package execute getsources.sh, and the directory named "work" will be created. And you rpmbuild each spec files in work/, put RPMs into work/installer and make tar ball of work/installer. The installer does not only install RPMs but also edit postgresql.conf, pgpool.conf, pg_hba.conf, recovery.conf and scripts for failover and online recovery. This assumes two-nodes configuration and the install script have to be executed in both nodes. - Add new parameter "search_primary_node_timeout". (Muhammad Usama, Tatsuo Ishii) The parameter specifies the maximum amount of time in seconds to search for a primary node when a failover scenario occurs. Patch contributed by Muhammad Usama. Japanese doc and slight editing of English doc by Tatsuo Ishii. - Chinese tutorials for memqcache and watchdog. (Bambo Huang) - Add regression test suit. (Tatsuo Ishii) __________________________________________________________________ * Bug fixes - Consider timeout waiting for compeletion of failback request in on line recovery. (Tatsuo Ishii) This will prevent the situation that recovery operation continues forever and we cannot even shutdown pgpool-II main process. This could happen especially while executing follow master command. - Fix a bug that %H of follow_master_command is not assigned correctly the new primary node in stream replication mode. (Tatsuo Ishii) - Fix not to execute escalation when the pgpool-II which is already active receives down notification from other pgpool-II. (Yugo Nagata) - Fix wd_create_send_socket() not to execute select() before connect(). (Yugo Nagata) How select() works on an unconnected socket is undefined, and differs between platform. On Linux, this returns 2 and it is eventually harmless. However, on Soraris, this returns 0 and it is indistinguishable from time timeout, so watchdog wouldn't work correctly. - Fix error when pgpool_regclass is not installed. (Tatsuo Ishii) The query used in pool_has_pgpool_regclass() fails if pgpool_regclass does not exist. The bug was introduced in 3.2.4. See [pgpool-general: 1722] for more details. [pgpool-general: 1722] [PgPool-II 3.2.4] pgpool_regclass now mandatory? http://www.sraoss.jp/pipermail/pgpool-general/2013-May/001749.html - Fix do_query() not to hang when PostgreSQL returns an error. (Tatsuo Ishii) The typical symptom is "I see SELECT is keep on running according to pg_stat_activity". To fix this pgpool-II just exits the process and kill the existig connection. This is not gentle but at this point I believe this is the best solution. - Fix possible deadlock during failover with watchdog enabled. (Yugo Nagata) This is reported in Bug track #54 by arshu arora http://www.pgpool.net/mantisbt/view.php?id=54 - Fix unnecessary degeneration caused by error on commit. (Tatsuo Ishii) In master slave mode, if master gets an error at commit, while other slaves are normal at commit, we don't need to degenrate any backend because it is likely that the "kind mismatch error" was caused by a deferred trigger. - Fix bug with do_query which causes hung in extended protocol. (Tatsuo Ishii) This problem could occur when insert lock is enabled and pgpool_catalog.insert_lock exists, See [pgpool-general: 1684] for more details. [pgpool-general: 1684] insert_lock hangs http://www.sraoss.jp/pipermail/pgpool-general/2013-May/001711.html - Fix possible failure of query cache invalidation for DML in transaction. (Tatsuo Ishii) CREATE TABLE t1(i INTEGER); CREATE TABLE t2(i INTEGER); SELECT * FROM t1; BEGIN; DELETE FROM t2 WHERE i = 0; INSERT INTO t1(i) VALUES(1); COMMIT; SELECT * FROM t1; At commit pgpool tries to delete cache for t2 but failes because there's no oid table entry for t2. Problem is, it fails to check oid table for t1. So cahce for t1 remains and the last SELECT incorrectly returns cached data. Fix is, continuing to check oid table entries. This is reported in Bug track #58 by wms http://www.pgpool.net/mantisbt/view.php?id=58 - Fix to register pgpool_regclass in pg_catalog schema (Tatsuo Ishii) This is necessary to deal with clients which restricts schema search path to pg_catalog only. Postgres_fdw is such a client. - Fix a hang of "pgpool -m f stop" (Tatsuo Ishii) This is caused by unmanaged pgpool children remaining. This could happen when multiple PostgreSQLs are going down or even when pgpool is started before PostgreSQL startup. - Fix a potential crash in pg_md5 command (Muhammad Usama) - Fix a segmentation fault that occurs when on memory query cache enabled and the query is issued in extended query mode and the result is too large (Tatsuo Ishii) This is reported in Bug track #63 by harukat. Analysis and a test case are also provided. #63 Child process was terminated by segmentation fault with memcached http://www.pgpool.net/mantisbt/view.php?id=63 - Fix a segmentation fault of a child process that occurs when a startup packet has no PostgreSQL user information (Yugo Nagata) You can reproduce it by $ psql -p 9999 -U '' If enable_pool_hba is on, a child process terminates by segmentation fault. Otherwise if enable_pool_hba is off, the error message is ERROR: pool_discard_cp: cannot get connection pool for user (null) database (null) In both cases, psql terminates with no message on frontend. In the fixed version, if PostgreSQL user is not specified in startup packet, the message as following is output to both log and frontend. This is the same behavior as PostgreSQL. FATAL: no PostgreSQL user name specified in startup packet - Fix memory allocation logic in extended query processing with on-memory query cache enabled (Tatsuo Ishii) When very long query string (> 1024 bytes) supplied in extended query with bind parameters, it fails to allocate enough memory. - Fix to verify the backend node number in pcp_recovery_node (Yugo Nagata) When an invalid number is used, null value is passed as an arguments of recovery script, and this causes a malfunction. In especially, rsync may delete unrelated files in basebackup scripts. - Fix a segmentation fault on main process that could occures after backend error detection (Tatsuo Ishii) This is reported in Bug track #62 by tuomas. #62 Slave network outage causes a segmentation fault on main process http://www.pgpool.net/mantisbt/view.php?id=62 - Fix bug with health check when used with child_life_time (Tatsuo Ishii) Failover could happen even if the backend was running fine. This problem is reported in [pgpool-general: 1892] by larisa sabban. [pgpool-general: 1892] Pgpool is unable to connect backend PostgreSQL http://www.sraoss.jp/pipermail/pgpool-general/2013-July/001920.html - Fix bug in parsing prepared statements with transaction handling in replication mode (Tatsuo Ishii) Parse() automatically starts a transaction for non SELECT query to keep consistency among nodes in replication mode. But this wasn't closed. If wrong query comes in, the transaction goes into an abort state but pgpool does not close the transaction. Thus next query causes error because the transaction is still in abort status. This problem was reported in [pgpool-general: 1877] by Sean Hogan. [pgpool-general: 1877] current transaction is aborted, commands ignored http://www.sraoss.jp/pipermail/pgpool-general/2013-July/001905.html __________________________________________________________________ * Enhancements - Add mention about "-D" option to the man page. (Tatsuo Ishii) - Fix to restart watchdog processes automatically when these exit abnormally. (Yugo Nagata) - Add more error checks and reportings to functions executing ping command with watchdog enabled. (Tatsuo Ishii) - Replace some unsafe functions, sprintf and strncpy, with more safe ones, snprintf and strlcpy respectively. (Yugo Nagata) - Replace "sticky bit" to "setuid bit" in log message, comments and funcation names. (Yugo Nagata) These words were used mistakenly and caused confusion. - Fix description on SSL in pool_hba.conf.sample. (Tatsuo Ishii) - Allow to load balancing in an explicit transaction in replication mode. (Tatsuo Ishii) The condition to allow the load balancing is as follows: 1) replicate_select is off 2) no writing functions are used 3) transaction isolation level is not serializable 4) no DML/DDL are issued in the transaction - Chinese manual is updated to the latest especially about watchdog. (Bambo Huang) - Add mention about "-D" option to the man page. (Tatsuo Ishii) - Move ssl_ca_cert and ssl_ca_cert_dir descriptions to the SSL section in the document (Yugo Nagata) - Add ssl_ca_cert and ssl_ca_cert_dir descriptions to the japanese document (Yugo Nagata) =============================================================================== 3.2 Series (2012/08/03 - ) =============================================================================== 3.2.6 (namameboshi) 2013/09/06 * Version 3.2.6 This is a bugfix release against pgpool-II 3.2.5. __________________________________________________________________ * Bug fixes - Fix a segmentation fault on main process that could occures after backend error detection (Tatsuo Ishii) This is reported in Bug track #62 by tuomas. #62 Slave network outage causes a segmentation fault on main process http://www.pgpool.net/mantisbt/view.php?id=62 - Fix a bug with health check when used with child_life_time (Tatsuo Ishii) Failover could happen even if the backend was running fine. This problem is reported in [pgpool-general: 1892] by larisa sabban. [pgpool-general: 1892] Pgpool is unable to connect backend PostgreSQL http://www.sraoss.jp/pipermail/pgpool-general/2013-July/001920.html - Fix "Deploying pgpool-II" section in the document (Tatsuo Ishii) Update descriptions about watchdog use. - Fix a mistake in ssh command of doc/basebackup.sh (Tatsuo Ishii) - Fix a bug in parsing prepared statements with transaction handling in replication mode (Tatsuo Ishii) Parse() automatically starts a transaction for non SELECT query to keep consistency among nodes in replication mode. But this wasn't closed. If wrong query comes in, the transaction goes into an abort state but pgpool does not close the transaction. Thus next query causes error because the transaction is still in abort status. This problem was reported in [pgpool-general: 1877] by Sean Hogan. [pgpool-general: 1877] current transaction is aborted, commands ignored http://www.sraoss.jp/pipermail/pgpool-general/2013-July/001905.html - Fix child process termination with sig abort when memory query cache is enabled (Tatsuo Ishii) This is due to double free bug that occurs when multiple bind/execute messages come after a parse message. When a parse messages comes, query context is created along with temp cache. The pointer to the temp cache is added to the temp cache array when the query executed. Subsequent bind messages uses the same temp cache pointer. This is the source of double free bug when the cache array discarded. This is reported in Bug track #68 by harukat. #68: child process termination with sigabort when memory_cache_enabled = on http://www.pgpool.net/mantisbt/view.php?id=68 - Fix typos of the japanese document (Yugo Nagata) =============================================================================== 3.2.5 (namameboshi) 2013/07/10 * Version 3.2.5 This is a bugfix release against pgpool-II 3.2.4. __________________________________________________________________ * Bug fixes - Add mention about "-D" option to the man page. (Tatsuo Ishii) - Consider timeout waiting for compeletion of failback request in on line recovery (Tatsuo Ishii) This will prevent the situation that recovery operation continues forever and we cannot even shutdown pgpool-II main process. This could happen especially while executing follow master command. - Fix a bug that %H of follow_master_command is not assigned correctly the new primary node in stream replication mode (Tatsuo Ishii) - Fix wd_create_send_socket() to not execute select() before connect() (Yugo Nagata) How select() works on an unconnected socket is undefined, and differs between platform. On Linux, this returns 2 and it is eventually harmless. However, on Soraris, this returns 0 and it is indistinguishable from time timeout, so watchdog wouldn't work correctly. - Fix error when pgpool_regclass is not installed (Tatsuo Ishii) The query used in pool_has_pgpool_regclass() fails if pgpool_regclass does not exist. The bug was introduced in 3.2.4. See [pgpool-general: 1722] for more details. [pgpool-general: 1722] [PgPool-II 3.2.4] pgpool_regclass now mandatory? http://www.sraoss.jp/pipermail/pgpool-general/2013-May/001749.html - Fix do_query() to not hang when PostgreSQL returns an error (Tatsuo Ishii) The typical symptom is "I see SELECT is keep on running according to pg_stat_activity". To fix this pgpool-II just exits the process and kill the existig connection. This is not gentle but at this point I believe this is the best solution. - Fix possible deadlock during failover with watchdog enabled (Yugo Nagata) This is reported in Bug track #54 by arshu arora #54 pgpool-II semaphore lock problem http://www.pgpool.net/mantisbt/view.php?id=54 - Fix bug with do_query which causes hung in extended protocol (Tatsuo Ishii) This problem could occur when insert lock is enabled and pgpool_catalog.insert_lock exists, See [pgpool-general: 1684] for more details. [pgpool-general: 1684] insert_lock hangs http://www.sraoss.jp/pipermail/pgpool-general/2013-May/001711.html - Fix unnecessary degeneration caused by error on commit (Tatsuo Ishii) In master slave mode, if master gets an error at commit, while other slaves are normal at commit, we don't need to degenrate any backend because it is likely that the "kind mismatch error" was caused by a deferred trigger. - Fix possible failure of query cache invalidation for DML in transaction (Tatsuo Ishii) CREATE TABLE t1(i INTEGER); CREATE TABLE t2(i INTEGER); SELECT * FROM t1; BEGIN; DELETE FROM t2 WHERE i = 0; INSERT INTO t1(i) VALUES(1); COMMIT; SELECT * FROM t1; At commit pgpool tries to delete cache for t2 but failes because there's no oid table entry for t2. Problem is, it fails to check oid table for t1. So cahce for t1 remains and the last SELECT incorrectly returns cached data. Fix is, continuing to check oid table entries. This is reported in Bug track #58 by wms #58 query cache invalidation does not fire for multiple DML in transaction http://www.pgpool.net/mantisbt/view.php?id=58 - Fix to register pgpool_regclass in pg_catalog schema (Tatsuo Ishii) This is necessary to deal with clients which restricts schema search path to pg_catalog only. Postgres_fdw is such a client. - Fix a potential crash in pg_md5 command (Muhammad Usama) - Fix a segmentation fault that occurs when on memory query cache enabled and the query is issued in extended query mode and the result is too large (Tatsuo Ishii) This is reported in Bug track #63 by harukat. Analysis and a test case are also provided. #63 Child process was terminated by segmentation fault with memcached http://www.pgpool.net/mantisbt/view.php?id=63 - Fix a segmentation fault of a child process that occurs when a startup packet has no PostgreSQL user information (Yugo Nagata) You can reproduce it by $ psql -p 9999 -U '' If enable_pool_hba is on, a child process terminates by segmentation fault. Otherwise if enable_pool_hba is off, the error message is ERROR: pool_discard_cp: cannot get connection pool for user (null) database (null) In both cases, psql terminates with no message on frontend. In the fixed version, if PostgreSQL user is not specified in startup packet, the message as following is output to both log and frontend. This is the same behavior as PostgreSQL. FATAL: no PostgreSQL user name specified in startup packet - Fix memory allocation logic in extended query processing with on-memory query cache enabled (Tatsuo Ishii) When very long query string (> 1024 bytes) supplied in extended query with bind parameters, it fails to allocate enough memory. - Move ssl_ca_cert and ssl_ca_cert_dir descriptions to the SSL section in the document (Yugo Nagata) - Add ssl_ca_cert and ssl_ca_cert_dir descriptions to the japanese document (Yugo Nagata) - Fix to verify the backend node number in pcp_recovery_node (Yugo Nagata) When an invalid number is used, null value is passed as an arguments of recovery script, and this causes a malfunction. In especially, rsync may delete unrelated files in basebackup scripts. =============================================================================== 3.2.4 (namameboshi) 2013/04/26 * Version 3.2.4 This is a bugfix release against pgpool-II 3.2.3. __________________________________________________________________ * Bug fixes - Fix connect_inet_domain_socket_by_port() to set more appropriate value for timeout parameter of select(2). (Tatsuo Ishii) Some platforms such as Solaris do not allow to specify too large microseconds timeout value (>=1000000). So divide the timeout value to seconds and microseconds. - Fix connect_inet_domain_socket_by_port() to not return as normal when interrupted by alarm. (Tatsuo Ishii) This confuses health checking because connect_inet_domain_socket_by_port() returns unsable fd. This makes detecting errors in health checking longer. See the following for more details: [pgpool-general: 1458] health check timeout in pgpool-II-3.2.3 http://www.pgpool.net/pipermail/pgpool-general/2013-March/001482.html - Fix long standing bug with timestamp rewriting code for processing extended protocol. (Tatsuo Ishii) Parse() allocate memory using palloc() while rewriting the parse message. Problem is, the rewritten message was kept in the data which is managed by pool_create_sent_message() etc. The function assumes that all the data is in session context memory. However, palloc() allocates memory in query context of course, and gets freeed later on when the query context disappears. And the function tries to free the memory as well, which causes various problems, including segfault and double free. To fix this, memory to store rewritten message is allocated using session context. The bug was there since pgpool-II 3.0 was born. Problem analysis and patch contributed by Naoya Anzai. [pgpoolgenera-jp: 1146]. (in Japanese) http://www.pgpool.net/pipermail/pgpool-general-jp/2013-March/001145.html - Fix bug with md5 auth long user name handling. (Tatsuo Ishii) If user name is longer than 32 bytes, md5 authentication doesn't work. Problem reported in [pgpool-general: 1526] by Thomas Martin. [pgpool-general: 1526] [pgPool-II 3.2.3] MD5 authentication and username longer than 32 characters. http://www.pgpool.net/pipermail/pgpool-general/2013-March/001551.html - Fix to calculate replication delay only if standby server is behind from the primay server. (Yugo Nagata) When the primary server is behind from standby server, negative value of delay is calculated and the value is assigned to unsigned variable. It causes a log message informing negative replication delay. And what is worse, it also causes SELECT queries to be sent to the primary in load balance even though there are no replication delay in fact. The problem is reported and analyzed by Saitoh Hidenori in [pgpool-genera-jp: 1145]. [pgpool-general-jp: 1145] (in Japanese) http://www.pgpool.net/pipermail/pgpool-general-jp/2013-March/001144.html - pgpool-recovery adopts PostgreSQL 9.3. (Tatsuo Ishii) Patch contributed by Asif Rehman. Slight editing by Tatsuo Ishii. [pgpool-hackers: 180] compile error in ppool-recovery http://www.pgpool.net/pipermail/pgpool-hackers/2013-April/000179.html - Fix pool_has_pgpool_regclass() to check execute privilege of pgpool_regclass(). (Tatsuo Ishii) Even though pgpool_regclass() exists, if pgpool cannot execute the function, the connection to backend hangs. You can reproduce the problem by just dropping the execute privilege from pgpool_regclass and do some insert in native replication mode. The problem is reported in bugtrack #53. #53 pgpool_regclas hangs all connections Date: 2013-04-04 13:35 Reporter: tmandke http://www.pgpool.net/mantisbt/view.php?id=53 - Fix error message mistakes in detect_postmaster_down_error(). (Tatsuo Ishii) For example, "LOG: detect_stop_postmaster_error: detect_error error" is fixed to "LOG: detect_postmaster_down_error: detect_error error", and so on. - Remove root user check when watchdog is enabled. (Tatsuo Ishii) Per discussion [pgpool-general: 1627] Re: watchdog root requirement. [pgpool-general: 1627] Re: watchdog root requirement. http://www.pgpool.net/pipermail/pgpool-general/2013-April/001654.html - Fix bug with on memory query cache in handling UPDATE/DELETE with table alias. (Tatsuo Ishii) If UPDATE/DELETE is with table alias (UPDATE t1 AS foo...) pgpool thinks the table name is "t1 AS foo" and fails to invalidate query cache. This is caused by _outRangeVar() called from nodeToString() which generates a query string from RangeVar node in raw parse tree. The solution is removing "AS foo" part from the output of the string. Reported in bugtrack #56. #56 UPDATE with alias does not discard cache Date: 2013-04-18 17:33 Reporter: harukat http://www.pgpool.net/mantisbt/view.php?id=56 =============================================================================== 3.2.3 (namameboshi) 2013/02/18 * Version 3.2.3 This is a bug fix release against pgpool-II 3.2.2. Main purpose of this release is to fix fatal problem with pgpool-II 3.2.2's health checking. If all of following conditions are met, pgpool main process disappeared and all client connections to pgpool-II hang forever when failover happens. And the only way to recover from it is, manualy killing the pgpool child process and restart pgpool-II. - health checking is enabled - connecting method to PostgreSQL is TCP/IP, not UNIX domain socket(i.e. "backend_hostnameN" is not empty string) __________________________________________________________________ * Bug fixes - Fix connect_inet_domain_socket_by_port() bug introduced in 3.2.2. (Tatsuo Ishii) When non blocking connect() reports EINPROGRESS or EALREADY, it calls select(2) to wait for read or write fd ready. However it mistakenly checks error condition using getsockopt(). It should be called when select() returns > 0, rather than 0. Because of this, connect_inet_domain_socket_by_port() could return succeeded fd even it actually failed. And what is worse, this health_check() mistakenly believes that backend is alive and tries to write to backend socket, which of course fails. This triggers to call notice_backend_error(), which sends SIGUSR1 signal to pgpool main's parent process. This will result in various weird things: for example, if you start pgpool from a shell, the signal kills the shell. If you start pgpool in background, pgpool's parent is the process #1. As long as you started pgpool as non root, it's ok. Even if you start pgpool as root, init just reopens /dev/initctl by receiving SIGUSR1. These all annoying bugs have been there since pgpool was born. The connect_inet_domain_socket_by_port() bug just reveals it. To fix this, I modified notice_backend_error and child_exit() so that it does nothing when called from pgpool main process itself to prevent pgpool from shooting itself in the foot. - Fix to show pool_passwd in "SHOW pool_status". (Yugo Nagata) - Fix a typo at configure's help in configure.in. (Yugo Nagata) =============================================================================== 3.2.2 (namameboshi) 2013/02/08 * Version 3.2.2 This is a bugfix release against pgpool-II 3.2.1. __________________________________________________________________ * Bug fixes - Fix compile errors on FreeBSD. (Tatsuo Ishii) - Fix pgpool does not recognize VIEWs other than in default schema, which is usually "public". (Tatsuo Ishii) This makes pgpool to create caches for such a VIEW's query results, which of course should not be allowed. Problem reported and patch provided by jgentsch in bug id #30. #30 pgpool 3.2.1 - views in schema other than public are caching Reporter: jgentsch Date: 2012-10-19 23:13 http://www.pgpool.net/mantisbt/view.php?id=30 - Fix race condition when using md5 authentication. (Tatsuo Ishii) The file descriptor to pool_passwd is opened in pgpool main and pgpool child inherits it. When concurrent connections try to authenticate md5 method, they call pool_get_passwd and seek the fd and cause random md5 auth failure because underlying fd is shared. Fix is, let individual pgpool child open the file by calling pool_reopen_passwd_file. Problem reported and analyzed by Jason Slagle in pgpool-general:1141. [pgpool-general: 1141] Possible race condition in pool_get_passwd From: Jason Slagle Date: Sun, 28 Oct 2012 01:12:52 -0400 http://www.sraoss.jp/pipermail/pgpool-general/2012-October/001160.html - Clarify load balance condition information in manual. (Tatsuo Ishii) - Fix segfault due to bug with query cache array handling. (Tatsuo Ishii) The cache arrary is used to keep temporary cache results in a transaction. If there are more than 128 SELECTs in a transaction, the module expands cache_arrary by using realloc. However it does not record the new pointer returned by realloc. So the module keeps on using the old pointer which is absoleted. This problem is reported in bug track #31 by jgentsch. #31 pgpool V3_2_STABLE - segfault in pool_memqcache.c:2529 Reporter:jgentsch Date: 2012-10-23 06:25 http://www.pgpool.net/mantisbt/view.php?id=31 - Fix hung up while repeating pcp_attach_node and pcp_detatch_node (Tatsuo Ishii) When node status is changed by pcp_attach_node and pcp_detatch_node, failover() sends SIGUSR1 to pcp_child process expecting it exits to refresh node status. In this situation lots of pgpool children exit and produce SIGCHLD as well. The SIGCHLD handler reaper() tries catch all SIGCHLD but sometimes it fails depending on the system load and timing. If SIGCHLD produced by pcp child is not caught, the process becomes zombie and never restarted. This problem is reported in bug track #32 (by oleg_myrk) etc. #32 PGPool hangs on pcp_attach/detach Reporter: oleg_myrk Date: 2012-10-24 00:01 http://www.pgpool.net/mantisbt/view.php?id=32 - Fix pool_send_severity_message() not to use uninitialized memory. (Tatsuo Ishii) It cause a segmentaion fault. Reported in Bug #33's attached valgrind output by dudee. #33 pgpool-II 3.2.1 segfault Reporter: dudee Date: 2012-10-30 19:16 http://www.pgpool.net/mantisbt/view.php?id=33 - Fix bug with query cache returning incorrect data in some cases when a persistent table and temp table have same name. (Tatsuo Ishii) Here is a sequence to trigger the bug: 1) CREATE TABLE t1(i int); -- create a persistent table 2) INSERT INTO t1 VALUES(1); 3) SELECT * FROM t1; -- query cache entry created 4) CREATE TEMP TABLE t1(i int); -- create a temp table 5) SELECT * FROM t1; -- query cache entry mistakenly created! Problem is #3 creates relcache entry for t1, and #5 incorrecly uses it and believes that temp table t1 is not a temp table. - Add a description about "-f" to help message. (Tatsuo Ishii) - Fix reaper() not to exit wait3() loop when catches pcp or worker child exit event. (Tatsuo Ishii) Otherwise reaper() mistakenly ignore some process exit event and make a risk of creating zombie process and forgetting to create new process. Problem reported and fix suggested by Goto in [pgpool-general-jp: 1123]. http://www.sraoss.jp/pipermail/pgpool-general-jp/2012-November/001122.html (in Japanese) - Fix a typo of configure help message. (Yugo Nagata) - Add wd_hostname to pool_process_reporting.c. (Yugo Nagata) Otherwise, wd_hostname is not contained in results of SHOW pool_status and cp_pool_status. - Fix connect_inet_domain_socket_by_port() to not error out when connect(2) returns EISCONN (Socket is already connected) error. (Tatsuo Ishii) This could happen with non blocking socket and should be treated as normal. Per bug track #29 (by spork) and pgpool-general 1218 (by Mikola Rose). #29 pgpool 3.2.1 cannot connect to db hosts Reporter: spork Date: 2012-10-18 15:03 http://www.pgpool.net/mantisbt/view.php?id=29 [pgpool-general: 1218] pgpool 3.2.1 - Health check failing to connect From: Mikola Rose Date: Tue, 4 Dec 2012 20:21:55 +0000 http://www.sraoss.jp/pipermail/pgpool-general/2012-December/001237.html - Fix health_check() to check the health check timer before retrying with template1 database. (Tatuo Ishii) Without this, the retry with node 0 always fails because health check timer may be already expired. - Fix pool_search_relcache() to use MASTER or MASTER_NODE_ID macro, rather than REAL_MASTER_NODE_ID. (Tatsuo Ishii) In case node 0 fail back in streaming replication mode, pgpool does not restart child process. So REAL_MASTER_NODE_ID looks for node 0 con info, which is not present until new connection to backend made. Thus referring to node con info results in segfault. MASTER or MASTER_NODE_ID are safe in this situation because they look at cached former master node id. - Fix long standing bug "portal not found" error when replication delay is too much in streaming replication mode. (Tatsuo Ishii) The bug had been there since the delay threshold was introduced. We changed destination DB node if delay threshold exceeds in bind, describe and execute. However, if parse sends to different node, bind, describe or execute will fail because no parsed statement or portal exists. Solution is, not to send to different parse node even if delay threshold is too much. - Fix pg_md5 to output "\n" after user inputs password. (Yugo Nagata) - Fix to print error message when the port number for watchdog is already used. (Yugo Nagata) This issue was reported by Will Ferguson in [pgpool-general: 1167]. [pgpool-general: 1167] Re: Watchdog error - wd_init: delegate_IP already exists From: Will Ferguson Date: Tue, 6 Nov 2012 13:03:36 +0000 http://www.sraoss.jp/pipermail/pgpool-general/2012-November/001186.html - Fix child_exit() to not call send_frontend_exits() if there's no connection pool. (Tatsuo Ishii) Otherwise, it segfaults because send_frontend_exits() referes to objects pointed to by pool_connection_pool. Per bug track #44 by tuomas. #44 pgpool went haywire after slave shutdown triggering master failover Reporter: tuomas Date: 2012-12-11 00:33 http://www.pgpool.net/mantisbt/view.php?id=44 - Fix bug that only tables in white_memqcache_table_list was cached when black_memqcache_table_list has any tables. (Yugo Nagata) - Fix read_startup_packet() to reset alarm and free StartupPacket when pool_read() returns 0 which means incorrect packet length. (Nozomi Anzai) Previously, authentication timeout occurs when connected by a program monitoring the pgpool port.It is reported in bug track #35. #35 Authentication is timeout Reporter: tuomas Date: 2012-11-20 11:54 http://www.pgpool.net/mantisbt/view.php?id=35 - Fix long standing bug with pool_open(). (Tatsuo Ishii) It initializes wrong buffer pointer. Actually this is harmless because the pointer is initialized by prior memset() call, though. - Log that failover is avoided because "fail_over_on_backend_error" is turned off. (Tatsuo Ishii) - Fix LISTEN/NOTIFY handling bugs. (Tatsuo Ishii) 1) In streaming replication mode: Session 1: LISTEN aaa; Session 2: NOTIFY aaa; Session 1: LISTEN aaa; --- hangs (If LISTEN and NOTIFY are issued in a same session, it works fine.) We assume that packets come from all nodes. However in streaming replication mode, notification message only comes from primary node and we should avoid reading from standby nodes. 2) In streaming replication mode: If primary node is not node 0, it hangs like #1 even if fix applies. This is because MASTER_NODE_ID macro (actually pool_virtual_master_db_node_id()) always returns REAL_MASTER_NODE_ID, which is node 0 (if it is alive). The function should return PRIMARY_NODE_ID in master/slave mode. 3) In replication mode, LISTEN/NOTIFY simply does not work. In the mode, NOTIFY is sent to all backends. However the order of arrival of 'Notification response' is not necessarily the master first and then slaves. So if it arrives slave first, we should try to read from master, rather than just discard it. Fixed in pool_process_query(). 4) In replication mode, if LISTEN and NOTIFY are issued in a same session, the session is disconnected because do_command() may receive other than 'N', 'E', 'S' and 'C'. The solution is, put 'A' packet on a stack and pop out when it is convenient. For this purpose, new functions pool_push(), pool_pop() and pool_stacklen() are added. This probmel is reported in but grack #45 by rpashin. #45 LISTEN/NOTIFY doesn't work if cluster contains more then 1 node in streaming replication mode Reporter: rpashin Date: 2012-12-12 00:09 http://www.pgpool.net/mantisbt/view.php?id=45 Considering the size of the patch, I do not back patch to 3.1 or before(so far, we have not heard any complaints on 3.1 or before). - Fix connect_inet_domain_socket_by_port() to call select(2) rather than error out when connect(2) returns EINPROGESS or EALREADY error. (Tatsuo Ishii) When using non-blocking socket, despite the errors like "Connection timed out", actually connection has been established. To solve the problem we should use select(2) to wait for connection establishing when connect(2) reports EINPROGRESS or EALREADY, instead of doing a retry tight loop. This problem is reported in bug track #46 by mcousin. #46 Watchdog failing to connect sometimes Reporter: mcousin Date: 2012-12-15 01:01 http://www.pgpool.net/mantisbt/view.php?id=46 - Add caution to increase num_init_children if watchdog enabled in manual. (Tatsuo Ishii) See [pgpool-general: 1330] for more details. [pgpool-general: 1330] WatchDog and pgool sudden stop working From: Tomas Halgas Date: Fri, 18 Jan 2013 14:47:23 +0100 http://www.sraoss.jp/pipermail/pgpool-general/2013-January/001350.html - Fix segmentation fault while pgpool-II stating up or fail over when watchdog is enabled. (Yugo Nagata) This is caused by wrong usage of pthread, namely pthread_detach and pthread_join are mixed together. Solution is to use pthread_join only if we need to get status of child thread. BTW, the problem could occu on moderately modern OS such as Fedora 17, but the reason why the problem is not observed on other OSs is, just we were lucky. Problem reported in [pgpool-general: 1179] by Lonni J Friedman. [pgpool-general: 1179] 3.2.1 segfaults at startup on Fedora17. From: Lonni J Friedman Date: Mon, 12 Nov 2012 15:58:29 -0800 http://www.sraoss.jp/pipermail/pgpool-general/2012-November/001198.html Patch provided by chads in bug track #48. pthread_detach is being used wrong; causes pgpool to segfault. Reporter: chads Date: 2013-01-16 05:44 http://www.pgpool.net/mantisbt/view.php?id=48 - Avoid split-brain situation reported in [pgpool-general: 1046] (Yugo Nagata) After all backend nodes are detached from pgpools and then some backend node are attached to these, multiple active pgpools could exist simultaneously, that is to say, split-brain situation occurs. In this fix, when once all backend DB nodes are detached from pgpool, the pgpool stays DOWN status until this is restarted. The pgpool in DOWN status cannot escalate to active (delegate IP holder), so split-brain situation is avoided. [pgpool-general: 1046] watchdog enabled delegate_IP on multiple nodes simultaneously From: Lonni J Friedman Date: Wed, 26 Sep 2012 09:05:09 -0700 http://www.sraoss.jp/pipermail/pgpool-general/2012-September/001064.html - Avoid a possible hang during the active pgpool exits. (Yugo Nagata) When exiting, the active pgpool brings down the virtual IP and then sends a packet to other pgpools. However, the packet sometimes is sent before the virtual IP is brought down completely. In this case the packet sender is set to this IP. When the IP is brought down before other pgpools respond, the active pgpool can not recieve the response, and hang up. In this fix, the active pgpool confirms that the virtual IP is brought down before sending the packet. - Modify descriptions of restrictions on watchdog. (Yugo Nagata) - Modify pgpool.conf.sample* and documents to correct information of whether a certain parameter change requires restart. (Yugo Nagata) - Add pool_passwd option to pgpool.conf.sample*, pool_process_reporting.c, and documents. (Yugo Nagata) Otherwise, wd_hostname is not contained in results of SHOW pool_status and pcp_pool_status. =============================================================================== 3.2.1 (namameboshi) 2012/10/12 * Version 3.2.1 This is a bugfix release against pgpool-II 3.2.0. __________________________________________________________________ * Bug fixes - Fix send_cached_messages(). (Tatsuo Ishii) Before it had 8192 bytes fix length buffer for each row data and if data exceeded 8192 bytes, it just crashed. To fix this, eliminate copying raw data which is passed as an argument to buffer and pass the pointer to send_message. - Fix that extended queries failed due to query cache. (Nozomi Anzai) - Fix read_startup_packet(). (Tatsuo Ishii) If packet length is lower than 0, it should have returned immediately. Otherwise it would cause memory allocation error later on. per pgpool-general:886. Also add canceling alarm. [pgpool-general: 886] read_startup_packet: out of memory From: Lonni J Friedman Date: Wed, 8 Aug 2012 10:18:15 -0700 http://www.sraoss.jp/pipermail/pgpool-general/2012-August/000896.html - Fix too watchdog process's aggressively kill other processes when pgpool shuts down. (Tatsuo Ishii) watchdog process calls kill(0,SIG) to kill all processes related to watchdog. Unfortunately this will kill not only watchdog related processes but parent pgpool and even httpd in case when pgpool was invoked from pgpoolAdmin because they are in the same process group. So for now, fix is removing call to the kill() and setpgid() because setpgid() does nothing useful. In the future, we should call setsid() to establish new process group in any case. - Fix query cache to regist such queries that start with "-- comment" or have comments more than one. (Nozomi Anzai) - Fix query cache to ignore multi statement. (Nozomi Anzai) In previous, queries like "SELECT 1;UPDATE..." were cached, too, but it was wrong. - Add a watchdog restriction to documents. (Yugo Nagata) - Add NOTICE message handling to s_do_auth(). (Tatsuo Ishii) Without this, health check responses false alarm and causes failover. per bug track: #25 s_do_auth doesn't handle NoticeResponse (N) message Date: 2012-08-28 03:57 Reporter: singh.gurjeet Date: http://www.pgpool.net/mantisbt/view.php?id=25 - Remove unnecessary/confusing debug log from s_do_auth().(Tatsuo Ishii) - Fix buffer overrun in Execute when memory cache enabled. (Tatsuo Ishii) If one of bind parameter < 0, it was possible to produce more than 2 byte string for "%02X" due to sign extention. Also use snprintf, rather than sprintf to prevent from possible buffer overrun in the future. - Fix long standing memory leak bug with free_select_result() since pgpool-II 2.3 was born in December 2009. (Tatsuo Ishii) Actually this bug only appears when operated in replication mode (triggered by timestamp rewriting process by coincidence). Per bug track #24: #24 Severe memory leak in an OLTP environment Date: 2012-08-28 03:43 Reporter: singh.gurjeet Date: http://www.pgpool.net/mantisbt/view.php?id=24 - Fix typo in cache_reporting(). (Tatsuo Ishii) - Fix inifinit loop in SSL mode. (Tatsuo Ishii) When there's pending data in SSL layer of frontend, pool_process_query() checks pending data in backend. If there's non, it loops again and checks frontend/backend receive buffer by using is_cache_empty(). Unfortunately it first checks pending data in SSL layer of frontend, thus goes to backend data and checks again (infinite loop). The solution is, if there's pending data in SSL layer of frontend and query is not in progress, call ProcessFrontendResponse() to process new request from frontend. - Fix is_system_catalog() to use pgpool_regclass if available. (Tatsuo Ishii) - Fix memory leak in pool_get_insert_table_name(). (Tatsuo Ishii) If session context's memory contex is used for nodeToString(), memory is not freed until session ends. See bug track #24 for more details. #24 Severe memory leak in an OLTP environment Date: 2012-08-28 03:43 Reporter: singh.gurjeet http://www.pgpool.net/mantisbt/view.php?id=24 - Use fcntl(2) rather than flock(2) to lock oid map files. (Tatsuo Ishii) flock(2) is not portable and cannot be used on Solaris. Patch contributed by Ibrar Ahmed. - Fix oversight of get_next_master_node() when operated in raw mode. (Tatsuo Ishii) If master node goes down, it always returned master node id 0. See [pgpool-general: 1039] for more details. [pgpool-general: 1039] Raw failover not working as expected on pgpool-II v3.2.0 From: Quentin White Date: Tue, 25 Sep 2012 07:45:34 +0000 http://www.sraoss.jp/pipermail/pgpool-general/2012-September/001057.html - Fix segfault of do_query(). (Tatsuo Ishii) When memqcache enabled and extended protocol is used, do_query() accesses system catalog and use pool_read2(). Unfortunately parse message packet is given to Parse() and the packet contents is on pool_read2's buffer. Thus do_query could break the packet contents, and it leads to segfault. Solution is, allocate memory and copies the packet contents and pass to Parse(). Note that query context holds query string, which is in the packet as well. So we need to copy it and save the pointer in the query context. We think the problem is not only with Parse() but with other protocol modules. So this fix is not Parse() only, rather for other modules. For this purpose ProcessFrontendResponse() is changed. See bugtrack in detai. #21 pgpool-II 3.2.0 cannot execute sql through jdbc Date: 2012-08-17 16:31 Reporter: elisechiang http://www.pgpool.net/mantisbt/view.php?id=21 - Fix to set unix domain socket path for pgpool PCP communication before setting up signal handlers. (Yugo Nagata) Previously, unlink of the socket in exitting process was failed because the path of the socket was not set. Patch contributed by Gilles Darold [pgpool-hackers: 131] Found bug with watchdog resulting in pgpool segmentation fault From: Gilles Darold Date: Thu, 13 Sep 2012 18:54:42 +0200 http://www.sraoss.jp/pipermail/pgpool-hackers/2012-September/000130.html - Fix to output the message when, in watchdog, ifup/down or arping command does not exist. (Yugo Nagata) - Fix long standing problem with do_query(). (Tatsuo Ishii) When 1) extended protocol used and 2)unnamed portal is used and 3) no explicit transaction is used, user's unnamed portal is removed by Sync message. This is because Sync message closes transaction and unnamed portal is removed. This leads to "portal "" does not exist" error. Fix is, use "Flush" message instead of Sync. Main difference between using Sync and Flush is, Flush does not return Ready for Query message. So do_query() does not return until all expected responses are returned. It seems the order of messages returned from backend is random, and do_query () manages it by using state bits. =============================================================================== 3.2.0 (namameboshi) 2012/08/03 * Version 3.2.0 This is the first version of pgpool-II 3.2 series. That is, a "major version up" from 3.1 series. __________________________________________________________________ * Incompatible changes - The new query cache "On memory query cache" took the place of the old one. - Now the parameter "enable_query_cache" is deleted. __________________________________________________________________ * New features ** Memory based query cache Original author is Masanori Yamazaki, improved by Development Group. (Tatsuo Ishii, Nozomi Anzai, Yugo Nagata) Overview: On memory query cache is faster because cache storage is on memory. Moreover you don't need to restart pgpool-II when the cache is outdated because the underlying table gets updated. On memory cache saves pair of SELECT statements (with its Bind parameters if the SELECT is an extended query). If the same SELECTs comes in, it returns the value from cache. Since no SQL parsing nor access to PostgreSQL are involed, it's extremely fast. On the other hand, it might be slower than the normal path because it adds some overhead to store cache. Moreover when a table is updated, pgpool automatically deletes all the caches related to the table. So the prformace will be degraded by a system with a lot of updates. If the cache_hit_ratio is lower than 70%, you might want to disable onl memory cache. Choosing cache storage: You can choose a cache storage: shared memory or memcached (you can't use the both). Query cache with shared memory is fast and easy because you don't have to install and config memcached, but restricted the max size of cache by the one of shared memory. Query cache with memcached needs a overhead to access network, but you can set the size as you like. Restrictions: - On memory query cache deletes the all cache of an updated table automatically with monitoring if the executed query is UPDATE, INSERT, ALTER TABLE and so on. But pgpool-II isn't able to recognize implicit updates due to trigers, foreign keys and DROP TABLE CASCADE. You can avoid this problem with memqcache_expire by which pgpool deletes old cache in a fixed time automatically, or with black_memqcache_table_list by which pgpool's memory cache flow ignores the tables. - If you want to use multiple instances of pgpool-II with online memory cache which uses shared memory, it could happen that one pgpool deletes cache, and the other one doesn't do it thus finds old cached result when a table gets updated. Memcached is the better cache storage in this case. New parameters: - Add parameters for on memoey query cache as follows: memory_cache_enabled, memqcache_method, memqcache_expire, memqcache_maxcache, memqcache_oiddir. (Tatsuo Ishii) - Add parameters about shared memory for on memory query cache as follows: memqcache_total_size, memqcache_max_num_cache, memqcache_cache_block_size. (Tatsuo Ishii) - Add parameters about memcached for on memory query cache as follows: memqcache_memcached_host, memqcache_memcached_port. (Tatsuo Ishii) - Add parameters about relation cache for on memory query cache as follows: relcache_expire, relcache_size. (Tatsuo Ishii) - Add a parameter "check_temp_table" to check if the SELECTed table is temp table. (Tatsuo Ishii) - Add the parameters of white_memqcache_table_list, black_memqcache_table_list that check if the SELECTed tables, temp tables and views are to be cached or not. (Nozomi Anzai) - Add a parameter "memqcache_auto_cache_invalidation" of the flag if query cache is triggered by corresponding DDL/DML/DCL (and memqcache_expire). (Yugo Nagata) New commands: - Add "SHOW pool cache" which shows hit ratio of query cache and the status of cache storage. - Add "--with-memcached" option to configure. (Nozomi Anzai) - Add "-C, --clear-oidmaps" option to "pgpool" command. (Nozomi Anzai) If pgpool with memcached starts / restarts with -C option, discard oid maps, if not, it can reuse old oid maps and query caches. ** Watchdog The author is Atsushi Mitani, tested by Yugo Nagata. Overview: "Watchdog" is a sub process of pgpool-II aiming for adding high availability feature to it. Features added by watchdog include: - Life checking of pgpool service Watchdog monitors responses of pgpool service rather than process. It sends queries to PostgreSQL via pgpool which is being monitored by watchdog and watchdog checks the response. Also watchdog monitors connections to up stream servers (application servers etc.) from the pgpool. The connection between the up stream servers and the pgpool is monitored as service of pgpool. - Mutual monitoring of watchdog processes Watchdog processes exchange information on the monitored servers to keep the information up to date, and to allow watchdog processes to mutually monitor each other. - Changing active/standby state in case of certain faults detected When a fault is detected in the pgpool service, watchdog notifies the other watchdogs of it. Watchdogs decide the new active pgpool if previous active pgpool is broken by voting and change active/standby state. - Automatic virtual IP address assigning synchronous to server switching When a standby pgpool server promotes to active, the new active server brings up virtual IP interface. Meanwhile, the previous active server brings down the virtual IP interface. This enables the active pgpool to work using the same IP address even when servers is switched over. - Automatic registration of a server as standby in recovery When broken server recovers or new server is attached, the watchdog process notifies the other watchdog process along with information of the new server, and the watchdog process receives information on the active server and other servers. Then, the attached server is registered as standby. New parameters: - Add a parameter to enable watchdog: use_watchdog. (Atsushi Mitani) - Add the parameters about life checking of pgpool service as follows: wd_interval,other_pgpool_port wd_life_point, wd_lifecheck_query, other_pgpool_hostname, other_pgpool_port. (Atsushi Mitani) - Add the parameters about up to stream connection (e.g. to application servers) as follows: trusted_servers, ping_path. (Atsushi Mitani) - Add the parameters about mutual monitoring of watchdog processes as follows: wd_hostname, wd_port, other_wd_port. (Atsushi Mitani) - Add the parameters about virtual IP as follows: ifconfig_path, if_up_cmd, if_down_cmd, arping_path, arping_cmd. (Atsushi Mitani) __________________________________________________________________ * Enhancements - Retry if health check faied rather than immediately do failover. For this purpose new directives "health_check_max_retries" and "health_check_retry_delay" were added. (Tatsuo Ishii) Patch contributed by Matt Solnit. Subject: [Pgpool-hackers] Health check retries (patch) From: Matt Solnit Date: Fri, 18 Nov 2011 16:28:44 -0500 - Log client IP and port number when pgpool failed to parse given query. (Tasuo) This is usefull to identify which client gives wrong query without enabling log_connections, which produces too many log entries on busy web systems. - Refactor pool_process_query(). (Tatsuo Ishii) Deal with the case when: 1) query not in progress 2) other than master node has pending data. It is reported that pgpool goes into infinite loop in this case. [pgpool-general: 43] Re: [Pgpool-general] seemingly hung pgpool process consuming 100% CPU http://www.pgpool.net/pipermail/pgpool-general/2011-December/000042.html - Add "role" which represents "primary" or "standby" iin streaming replication mode for example to "SHOW pool_nodes" command.(Tatsuo Ishii) - Add params to the result of "SHOW pool_status": backend_data_directory, ssl_ca_cert, ssl_ca_cert_dir, and sort by orders in pgpool.conf. (Anzai) - Commentout params about system db from pgpool.conf.sample-*. (Nozomi Anzai) - Add new parameter to failover/failback/followmaster command. (Tatsuo Ishii) %r: new master port number %R: new master database cluster path - Allow to reload to recognize md5 password change. (Tatsuo Ishii) Before, the only way to recognize md5 password change was restarting pgpool-II. Patch contributed by Gurjeet Singh. - Remove unused parameter "query" from is_set_transaction_serializable(). (Tastuo Ishii) - Fix on memory query cache section's comments in pgpool.com in the way which other sections employ. (Tastuo Ishii) - Add missing health_check_max_retries and health_check_retry_delay directives to pgpool.conf.sample-master-slave, pgpool.conf.sample-replication pgpool.conf.sample-stream. (Tastuo Ishii) - Fix pool_ssl_write. It seems someone forgot to do retrying when SSL returns SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. Per [pgpool-general: 797] [pgpool-general: 797] Re: Problem with pgpool when using SSL, for client/pgpool communication http://www.sraoss.jp/pipermail/pgpool-general/2012-July/000807.html - Improve the design of manuals. (Nozomi Anzai) __________________________________________________________________ * Bug Fix - Fix memory leak in Raw mode.(Tatsuo Ishii) - Fix failover/failback in Raw mode. (Tatsuo Ishii) - Simply does not failover if target node is not master. - Fail to select master node if the node is in CON_UP. - Allow health check retry while connect(). (Tatsuo Ishii) It is reported that connect() blocks sigalarm under some conditions, for example: When system is configured for security reasons not to return destination host unreachable messages ([pgpool-general: 131]) Part of changes are contributed by Stevo Slavic. [pgpool-general: 131] Healthcheck timeout not always respected http://www.pgpool.net/pipermail/pgpool-general/2012-January/000131.html - Fix pool_send_and_wait() to send or not to send COMMIT / ABORT depending on the transaction state on each node. (Tatsuo Ishii) It is possible that only primary is in an explicit transaction but standby is not in it if multi statement query has been sent. Per bug report [pgpool-general-jp: 1049]. - Fix load balance in Solaris. (Tatsuo Ishii) Problem is, random() in using random() in Solaris results in strange load balancing calculation. Use srand()/rand() instead although they produce lesser quality random Problem reported at [pgpool-general: 396]. [pgpool-general: 396] strange load balancing issue in Solaris http://www.pgpool.net/pipermail/pgpool-general/2012-April/000397.html - Fix segfault of pcp_systemdb_info not in parallel mode. (Nozomi Anzai) - Fix "unnamed prepared statment does not exist" error. (Tatsuo Ishii) This is caused by pgpool's internal query, which breaks client's unnamed statements. To fix this, if extended query is used, named statement/portal for internal are used for internal query. - Fix hangup when query conflict occurs in Hot-Standby mode. (Yugo Nagata) Query example to reproduce: (S1) BEGIN; (S1) SELECT * FROM t; (S2) DELETE FROM t; (S2) VACUUM t; - Fix pool_process_query() bug reported in [pgpool-general: 672]. (Tatsuo Ishii) This is caused by the function waits for primary node which does not have pending data, while standbys have pending data. [pgpool-general: 672] Transaction never finishes http://www.pgpool.net/pipermail/pgpool-general/2012-June/000676.html - Fix wait_for_query_response() not to send param status to frontend if frontend is NULL. (Tatsuo Ishii) This could happen while processing reset_query_list and occur crash. - Fix bug with treatment of BEGIN TRANSACTION in master/slave mode. (Tatsuo Ishii) Original complain is [pgpool-general: 714]. From 3.1, pgpool-II sends BEGIN.. to all DB nodes. Of course we cannot send BEGIN TRANSACTION READ WRITE to standby nodes. Problem is, we did not check BEGIN WORK ISOLATION LEVEL SERIALIZABLE; and sent to standby nodes. Of course this is wrong, since it's not allowed to run transactions in serializable mode on standby nodes. So added check for BEGIN WORK ISOLATION LEVEL SERIALIZABLE case. [pgpool-general: 714] Load Balancing / Streaming Replication / Isolation Level serializable http://www.pgpool.net/pipermail/pgpool-general/2012-July/000719.html - Fix send_to_where() to send the query to only primary if the it is like SET TRANSACTION ISOLATION LEVELSERIALIZABLE etc. (Tatsuo Ishii) Case in streaming replication mode. Previously, it was sent to not only primary but also to standby and of course this causes an error. Similar SQLs are: SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE or SET transaction_isolation TO 'serializable' SET default_transaction_isolation TO 'serializable' Original complain is [pgpool-general: 715]. [pgpool-general: 715] Re: Load Balancing / Streaming Replication / Isolation Level serializable http://www.pgpool.net/pipermail/pgpool-general/2012-July/000720.html - Prevent errors even if memcached is not available with on memory query cache enabled and cache storage is memcached. (Tatsuo Ishii) This is mainly achieved by modifying pool_fetch_cache to pretend "cache not found" if memcached_get returns error other than MEMCACHED_NOTFOUND. Also we set pool_config->memory_cache_enabled to 0 to prevent future errors by accessing memcached. - Run rerun libtoolize with --copy and --force option. (Tatsuo Ishii) This should prevent build problems in different environment. Following commands were executed: libtoolize --copy --force aclocal autoheader automake -a autoconf - Fix pool_ssl_read. (Tatsuo Ishii) When SSL_read returns unknown error, treat as if EOF detected and returns 0 to caller (pool_read). This is same as libpq's behavior. Also this will avoid unwanted failover in pool_read. pool_read triggers failover if underlying I/O functions, read(2) or pool_ssl_read returns -1. - Fix pool_process_query. (Tatsuo Ishii) When other than primary sends packet, pgpool tries to terminate session gracefully and hung because now ssl_read returns EOF, rather than error and triggers failover. For example [pgpool-general: 766] reported this: 2012-07-17 00:11:03 NZST [15692]: [257-1] ERROR: canceling statement due to conflict with recovery 2012-07-17 00:11:03 NZST [15692]: [258-1] DETAIL: User query might have needed to see row versions that must be removed. 2012-07-17 00:11:03 NZST [15692]: [259-1] STATEMENT: 2012-07-17 00:11:03 NZST [15696]: [366-1] FATAL: terminating connection due to conflict with recovery 2012-07-17 00:11:03 NZST [15696]: [367-1] DETAIL: User query might have needed to see row versions that must be removed. In this case pool_process_query should return POOL_ERROR, rather than POOL_END. [pgpool-general: 766] Re: pgpool dropping backends too much http://www.pgpool.net/pipermail/pgpool-general/2012-July/000774.html - If frontend terminates while reading large number of query results from backend, pgpool continues to read from backend and write to frontend until all query results consumued. (Tatsuo Ishii) This will take very long time if query results is huge. To finish pgpool session as soon as possible, modify pool_flush_it to returns error if fail to write to frontend when operated in other than replication mode. In replication mode, we need to keep the previous behavior to save consistency among backends). Also fix SimpleForwardToFrontend to return pool_write_and_flush error status. Before it was ignored. =============================================================================== 3.1 Series (2011/09/08 - ) =============================================================================== 3.1.9 (hatsuiboshi) 2013/09/06 * Version 3.1.9 This is a bugfix release against pgpool-II 3.1.8. __________________________________________________________________ * Bug fixes - Fix a mistake in ssh command of doc/basebackup.sh (Tatsuo Ishii) - Fix a bug in parsing prepared statements with transaction handling in replication mode (Tatsuo Ishii) Parse() automatically starts a transaction for non SELECT query to keep consistency among nodes in replication mode. But this wasn't closed. If wrong query comes in, the transaction goes into an abort state but pgpool does not close the transaction. Thus next query causes error because the transaction is still in abort status. This problem was reported in [pgpool-general: 1877] by Sean Hogan. [pgpool-general: 1877] current transaction is aborted, commands ignored http://www.sraoss.jp/pipermail/pgpool-general/2013-July/001905.html - Fix typos of the japanese document (Yugo Nagata) =============================================================================== 3.1.8 (hatsuiboshi) 2013/07/10 * Version 3.1.8 This is a bugfix release against pgpool-II 3.1.7. __________________________________________________________________ * Bug fixes - Add mention about "-D" option to the man page. (Tatsuo Ishii) - Consider timeout waiting for compeletion of failback request in on line recovery (Tatsuo Ishii) This will prevent the situation that recovery operation continues forever and we cannot even shutdown pgpool-II main process. This could happen especially while executing follow master command. - Fix a bug that %H of follow_master_command is not assigned correctly the new primary node in stream replication mode (Tatsuo Ishii) - Fix do_query() to not hang when PostgreSQL returns an error (Tatsuo Ishii) The typical symptom is "I see SELECT is keep on running according to pg_stat_activity". To fix this pgpool-II just exits the process and kill the existig connection. This is not gentle but at this point I believe this is the best solution. - Fix bug with do_query which causes hung in extended protocol (Tatsuo Ishii) This problem could occur when insert lock is enabled and pgpool_catalog.insert_lock exists, See [pgpool-general: 1684] for more details. [pgpool-general: 1684] insert_lock hangs http://www.sraoss.jp/pipermail/pgpool-general/2013-May/001711.html - Fix unnecessary degeneration caused by error on commit (Tatsuo Ishii) In master slave mode, if master gets an error at commit, while other slaves are normal at commit, we don't need to degenrate any backend because it is likely that the "kind mismatch error" was caused by a deferred trigger. - Fix to register pgpool_regclass in pg_catalog schema (Tatsuo Ishii) This is necessary to deal with clients which restricts schema search path to pg_catalog only. Postgres_fdw is such a client. - Fix a potential crash in pg_md5 command (Muhammad Usama) - Fix a segmentation fault of a child process that occurs when a startup packet has no PostgreSQL user information (Yugo Nagata) You can reproduce it by $ psql -p 9999 -U '' If enable_pool_hba is on, a child process terminates by segmentation fault. Otherwise if enable_pool_hba is off, the error message is ERROR: pool_discard_cp: cannot get connection pool for user (null) database (null) In both cases, psql terminates with no message on frontend. In the fixed version, if PostgreSQL user is not specified in startup packet, the message as following is output to both log and frontend. This is the same behavior as PostgreSQL. FATAL: no PostgreSQL user name specified in startup packet - Move ssl_ca_cert and ssl_ca_cert_dir descriptions to the SSL section in the document (Yugo Nagata) - Add ssl_ca_cert and ssl_ca_cert_dir descriptions to the japanese document (Yugo Nagata) - Fix to verify the backend node number in pcp_recovery_node (Yugo Nagata) When an invalid number is used, null value is passed as an arguments of recovery script, and this causes a malfunction. In especially, rsync may delete unrelated files in basebackup scripts. =============================================================================== 3.1.7 (hatsuiboshi) 2013/04/26 * Version 3.1.7 This is a bugfix release against pgpool-II 3.1.6. __________________________________________________________________ * Bug fixes - Fix to show pool_passwd in "SHOW pool_status". (Yugo Nagata) - Fix long standing bug with timestamp rewriting code for processing extended protocol. (Tatsuo Ishii) Parse() allocate memory using palloc() while rewriting the parse message. Problem is, the rewritten message was kept in the data which is managed by pool_create_sent_message() etc. The function assumes that all the data is in session context memory. However, palloc() allocates memory in query context of course, and gets freeed later on when the query context disappears. And the function tries to free the memory as well, which causes various problems, including segfault and double free. To fix this, memory to store rewritten message is allocated using session context. The bug was there since pgpool-II 3.0 was born. Problem analysis and patch contributed by Naoya Anzai. [pgpoolgenera-jp: 1146]. (in Japanese) http://www.pgpool.net/pipermail/pgpool-general-jp/2013-March/001145.html - Fix bug with md5 auth long user name handling. (Tatsuo Ishii) If user name is longer than 32 bytes, md5 authentication doesn't work. Problem reported in [pgpool-general: 1526] by Thomas Martin. [pgpool-general: 1526] [pgPool-II 3.2.3] MD5 authentication and username longer than 32 characters. http://www.pgpool.net/pipermail/pgpool-general/2013-March/001551.html - Fix to calculate replication delay only if standby server is behind from the primay server. (Yugo Nagata) When the primary server is behind from standby server, negative value of delay is calculated and the value is assigned to unsigned variable. It causes a log message informing negative replication delay. And what is worse, it also causes SELECT queries to be sent to the primary in load balance even though there are no replication delay in fact. The problem is reported and analyzed by Saitoh Hidenori in [pgpool-genera-jp: 1145]. [pgpool-general-jp: 1145] (in Japanese) http://www.pgpool.net/pipermail/pgpool-general-jp/2013-March/001144.html - pgpool-recovery adopts PostgreSQL 9.3. (Tatsuo Ishii) Patch contributed by Asif Rehman. Slight editing by Tatsuo Ishii. [pgpool-hackers: 180] compile error in ppool-recovery http://www.pgpool.net/pipermail/pgpool-hackers/2013-April/000179.html - Fix pool_has_pgpool_regclass() to check execute privilege of pgpool_regclass(). (Tatsuo Ishii) Even though pgpool_regclass() exists, if pgpool cannot execute the function, the connection to backend hangs. You can reproduce the problem by just dropping the execute privilege from pgpool_regclass and do some insert in native replication mode. The problem is reported in bugtrack #53. #53 pgpool_regclas hangs all connections Date: 2013-04-04 13:35 Reporter: tmandke http://www.pgpool.net/mantisbt/view.php?id=53 - Fix error message mistakes in detect_postmaster_down_error(). (Tatsuo Ishii) For example, "LOG: detect_stop_postmaster_error: detect_error error" is fixed to "LOG: detect_postmaster_down_error: detect_error error", and so on. =============================================================================== 3.1.6 (hatsuiboshi) 2013/02/08 * Version 3.1.6 This is a bugfix release against pgpool-II 3.1.5 __________________________________________________________________ * Bug fixes - Fix race condition when using md5 authentication. (Tatsuo Ishii) The file descriptor to pool_passwd is opened in pgpool main and pgpool child inherits it. When concurrent connections try to authenticate md5 method, they call pool_get_passwd and seek the fd and cause random md5 auth failure because underlying fd is shared. Fix is, let individual pgpool child open the file by calling pool_reopen_passwd_file. Problem reported and analyzed by Jason Slagle in pgpool-general:1141. [pgpool-general: 1141] Possible race condition in pool_get_passwd From: Jason Slagle Date: Sun, 28 Oct 2012 01:12:52 -0400 http://www.sraoss.jp/pipermail/pgpool-general/2012-October/001160.html - Fix hung up while repeating pcp_attach_node and pcp_detatch_node (Tatsuo Ishii) When node status is changed by pcp_attach_node and pcp_detatch_node, failover() sends SIGUSR1 to pcp_child process expecting it exits to refresh node status. In this situation lots of pgpool children exit and produce SIGCHLD as well. The SIGCHLD handler reaper() tries catch all SIGCHLD but sometimes it fails depending on the system load and timing. If SIGCHLD produced by pcp child is not caught, the process becomes zombie and never restarted. This problem is reported in bug track #32 (by oleg_myrk) etc. #32 PGPool hangs on pcp_attach/detach Reporter: oleg_myrk $B!!(BDate: 2012-10-24 00:01 http://www.pgpool.net/mantisbt/view.php?id=32 - Fix pool_send_severity_message() not to use uninitialized memory. (Tatsuo Ishii) It cause a segmentaion fault. Reported in Bug #33's attached valgrind output by dudee. #33 pgpool-II 3.2.1 segfault Reporter: dudee Date: 2012-10-30 19:16 http://www.pgpool.net/mantisbt/view.php?id=33 - Add a description about "-f" to help message. (Tatsuo Ishii) - Fix reaper() not to exit wait3() loop when catches pcp or worker child exit event. (Tatsuo Ishii) Otherwise reaper() mistakenly ignore some process exit event and make a risk of creating zombie process and forgetting to create new process. Problem reported and fix suggested by Goto in [pgpool-general-jp: 1123]. http://www.sraoss.jp/pipermail/pgpool-general-jp/2012-November/001122.html (in Japanese) - Fix pool_search_relcache() to use MASTER or MASTER_NODE_ID macro, rather than REAL_MASTER_NODE_ID. (Tatsuo Ishii) In case node 0 fail back in streaming replication mode, pgpool does not restart child process. So REAL_MASTER_NODE_ID looks for node 0 con info, which is not present until new connection to backend made. Thus referring to node con info results in segfault. MASTER or MASTER_NODE_ID are safe in this situation because they look at cached former master node id. - Fix long standing bug "portal not found" error when replication delay is too much in streaming replication mode. (Tatsuo Ishii) The bug had been there since the delay threshold was introduced. We changed destination DB node if delay threshold exceeds in bind, describe and execute. However, if parse sends to different node, bind, describe or execute will fail because no parsed statement or portal exists. Solution is, not to send to different parse node even if delay threshold is too much. - Fix pg_md5 to output "\n" after user inputs password. (Yugo Nagata) - Fix child_exit() to not call send_frontend_exits() if there's no connection pool. (Tatsuo Ishii) Otherwise, it segfaults because send_frontend_exits() referes to objects pointed to by pool_connection_pool. Per bug track #44 by tuomas. #44 pgpool went haywire after slave shutdown triggering master failover Reporter: tuomas Date: 2012-12-11 00:33 http://www.pgpool.net/mantisbt/view.php?id=4 - Fix read_startup_packet() to reset alarm and free StartupPacket when pool_read() returns 0 which means incorrect packet length. (Nozomi Anzai) Previously, authentication timeout occurs when connected by a program monitoring the pgpool port.It is reported in bug track #35 by tuomas. #35 Authentication is timeout Reporter: tuomas Date: 2012-11-20 11:54 http://www.pgpool.net/mantisbt/view.php?id=3 - Fix long standing bug with pool_open(). (Tatsuo Ishii) It initializes wrong buffer pointer. Actually this is harmless because the pointer is initialized by prior memset() call, though. - Modify documents to correct information of whether a certain parameter change requires restart. (Yugo Nagata) - Add pool_passwd option to pgpool.conf.sample*, and documents. (Yugo Nagata) =============================================================================== 3.1.5 (hatsuiboshi) 2012/10/12 * Version 3.1.5 This is a bugfix release against pgpool-II 3.1.4 __________________________________________________________________ * Bug fixes - Fix read_startup_packet. (Tatsuo Ishii) If packet length is lower than 0, it should have returned immediately. Otherwise it would cause memory allocation error later on. per pgpool-general:886. Also add canceling alarm. - Add NOTICE message handling to s_do_auth. (Tatsuo Ishii) Without this, health check responses false alarm and causes failover. per bug track: http://www.pgpool.net/mantisbt/view.php?id=25 Also allow to receive ready for query packet *not* right after backend keydata. I'm not sure if this could happen in the real world but the protocol seems to allow this. - Remove unnecessary/confusing debug log from s_do_auth.(Tatsuo Ishii) - Fix inifinit loop in SSL mode. When there's pending data in SSL layer of frontend, pool_process_query() checks pending data in backend. (Tatsuo Ishii) If there's non, it loops again and checks frontend/backend receive buffer by using is_cache_empty(). Unfortunately it first checks pending data in SSL layer of frontend, thus goes to backend data and checks again (infinite loop). The solution is, if there's pending data in SSL layer of frontend and query is not in progress, call ProcessFrontendResponse() to process new request from frontend. - Fix is_system_catalog to use pgpool_regclass if available. (Tatsuo Ishii) - Fix memory leak in pool_get_insert_table_name(). (Tatsuo Ishii) If session context's memory contex is used for nodeToString(), memory is not freed until session ends. - Fix possible memory leak in nodeToString(). (Tatsuo Ishii) Since the memory context could be session context, memory used for String object may be considerable if user session continues for hours or days. See bug track #24 for more details. - Fix long standing problem with do_query(). (Tatsuo Ishii) When 1) extended protocol used and 2)unnamed portal is used and 3) no explicit transaction is used, user's unnamed portal is removed by Sync message. This is because Sync message closes transaction and unnamed portal is removed. This leads to "portal "" does not exist" error. Fix is, use "Flush" message instead of Sync. Main difference between using Sync and Flush is, Flush does not return Ready for Query message. So do_query() does not return until all expected responses are returned. It seems the order of messages returned from backend is random, and do_query () manages it by using state bits. =============================================================================== 3.1.4 (hatsuiboshi) 2012/08/06 * Version 3.1.4 This is a bugfix release against pgpool-II 3.1.3. __________________________________________________________________ * Bug fixes * General - Adopt PostgreSQL 9.2. (Tatsuo Ishii) * Bug fixes - Fix pool_send_and_wait() to send or not to send COMMIT / ABORT depending on the transaction state on each node. (Tatsuo Ishii) It is possible that only primary is in an explicit transaction but standby is not in it if multi statement query has been sent. Per bug report [pgpool-general-jp: 1049]. - Fix load balance in Solaris. (Tatsuo Ishii) Problem is, random() in using random() in Solaris results in strange load balancing calculation. Use srand()/rand() instead although they produce lesser quality random Problem reported at [pgpool-general: 396]. [pgpool-general: 396] strange load balancing issue in Solaris http://www.pgpool.net/pipermail/pgpool-general/2012-April/000397.html - Add params to the result of "SHOW pool_status": backend_data_directory, ssl_ca_cert, ssl_ca_cert_dir. (Nozomi Anzai) - Fix segfault of pcp_systemdb_info not in parallel mode. (Nozomi Anzai) - Fix "unnamed prepared statment does not exist" error. (Tatsuo Ishii) This is caused by pgpool's internal query, which breaks client's unnamed statements. To fix this, if extended query is used, named statement/portal for internal are used for internal query. - Fix is_system_catalog(). Its relcach was accidently defined as "session local". (Tatsuo Ishii) - Fix hangup when query conflict occurs in Hot-Standby mode. (Yugo Nagata) Query example to reproduce: (S1) BEGIN; (S1) SELECT * FROM t; (S2) DELETE FROM t; (S2) VACUUM t; - Improve reading and writing pid_file. (Tatsuo Ishii) - Fix pool_process_query() bug reported in [pgpool-general: 672]. (Tatsuo Ishii) This is caused by the function waits for primary node which does not have pending data, while standbys have pending data. [pgpool-general: 672] Transaction never finishes http://www.pgpool.net/pipermail/pgpool-general/2012-June/000676.html - Fix wait_for_query_response() not to send param status to frontend if frontend is NULL. (Tatsuo Ishii) This could happen while processing reset_query_list and occur crash. - Fix bug with treatment of BEGIN TRANSACTION in master/slave mode. (Tatsuo Ishii) Original complain is [pgpool-general: 714]. From 3.1, pgpool-II sends BEGIN.. to all DB nodes. Of course we cannot send BEGIN TRANSACTION READ WRITE to standby nodes. Problem is, we did not check BEGIN WORK ISOLATION LEVEL SERIALIZABLE; and sent to standby nodes. Of course this is wrong, since it's not allowed to run transactions in serializable mode on standby nodes. So added check for BEGIN WORK ISOLATION LEVEL SERIALIZABLE case. [pgpool-general: 714] Load Balancing / Streaming Replication / Isolation Level serializable http://www.pgpool.net/pipermail/pgpool-general/2012-July/000719.html - Fix send_to_where() to send the query to only primary if the it is like SET TRANSACTION ISOLATION LEVELSERIALIZABLE etc. (Tatsuo Ishii) Case in streaming replication mode. Previously, it was sent to not only primary but also to standby and of course this causes an error. Similar SQLs are: SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE or SET transaction_isolation TO 'serializable' SET default_transaction_isolation TO 'serializable' Original complain is [pgpool-general: 715]. [pgpool-general: 715] Re: Load Balancing / Streaming Replication / Isolation Level serializable http://www.pgpool.net/pipermail/pgpool-general/2012-July/000720.html =============================================================================== 3.1.3 (hatsuiboshi) 2012/04/23 * Version 3.1.3 This is a bugfix release against pgpool-II 3.1.2. __________________________________________________________________ * Bug fixes - Add m4 files. This should prevent compiling problem on older OS's. (Tatsuo Ishii) - Fix to handle failover properly in detect_postmaster_down_error(). (Tatsuo Ishii) It is possible that it fails to read backend socket after detecting backend errors and before actually detaching the backend. - Fix bug that the process exits before unlocking semaphore by a signal interrupt. (Tatsuo Ishii) - Fix a memory leak in case of reset_query. (Tatsuo Ishii) - Fix pool_ssl_read() to deal with large data reading. (Tatsuo Ishii) Original complain is here: http://www.pgpool.net/pipermail/pgpool-general/2012-March/000299.html - Fix deadlock by enabling log_destination = syslog. (Tatsuo Ishii) Reported in bug tracker http://www.pgpool.net/mantisbt/view.php?id=9. Patch provided by Gilles Darold. - Allow to use multi statement in master/slave mode. (Tatsuo Ishii) From 3.1 transactional statements such as "BEGIN" are sent to not only primary but also standbys. This brings an unfortunate side effect: if the multi statement is "BEGIN;DELETE FROM table;END", this will be sent to standy as well and cause an error because standby does notallow write SQL. So fix is, if a query is a multi statement one, then send it to primary only. - Allow to have private cache of master node id. (Tatsuo Ishii) When master goes down running pgpool children look into NULL pointer because the process does not connect to the new master yet. The private cache returns the old master node id and will avoid the situation. Per bug reported in http://www.pgpool.net/mantisbt/view.php?id=51 - Fix pool_start_query() so that it uses my_master_node_id instead of REAL_MASTER_NODE_ID for initial virtual_master_node_id. (Tatsuo Ishii) Real master node could be changed while pgpool is running in streaming replication mode. Previously it is assigned REAL_MASTER_NODE_ID, which could have no connections after fail over and cause segafult. - Fix pool_setall_node_to_be_sent() to use private_backend_status instead of BACKEND_INFO macro. (Tatsuo Ishii) It is possible that while processing, the node returned by BACKEND_INFO is not usable any more. - Fix failover(). (Tatsuo Ishii) Before it only restarts worker child only when pgpool child do not need restart. This is wrong. We need to restart worker child in any case. Otherwise it continues to send replication time lag check request to down the node. - Fix debug log message so that it does not contain null characters. (Toshihiro Kitagawa) - Fix SimpleQuery() so that it restores parser memory context when: 1) Builtin show commands are used 2) Parallel query mode 3) Query cache is used (Tatsuo Ishii) - Fix hangup when PREPARE statement causes error. (Toshihiro Kitagawa) This issue was reported by Tomonari Katsumata: Subject: [pgpool-general: 121] question of pgpool's behavior - Add doc/pgpool-fr.html to Makefile.am. (Tatsuo Ishii) This had been forgotten when the doc was added. - Fix hangup during md5 authentication that occurs in daemon mode and log_destination is 'syslog'. (Yugo Nagata) Reported in bug tracker http://www.pgpool.net/mantisbt/view.php?id=2. =============================================================================== 3.1.2 (hatsuiboshi) 2012/01/31 * Version 3.1.2 This is a bugfix release against pgpool-II 3.1.1. __________________________________________________________________ * Bug fixes - Fix to recognize READ UNCOMMITTED and REPEATABLE READ of transaction isolation levels. (Tatsuo Ishii) - Fix infinite loop reported in this thread (Tatsuo Ishii): http://www.pgpool.net/pipermail/pgpool-general/2011-December/000099.html It was not considered the case that, when received buffer in primary was empty but the one in a standby was not, the standby spontaneously sent packet to pgpool. This could happen when, for example, reloading postgresql.conf. The fix is that such buffer in standby is discarded. =============================================================================== 3.1.1 (hatsuiboshi) 2011/12/06 * Version 3.1.1 This is a bugfix release against pgpool-II 3.1. __________________________________________________________________ * Bug fixes - Fix add_regex_pattern(). It does not allocate enough memory for each black/white_function_list items. The function adds "^" and "$" to each function items which do not contain those characters. Unfortunately the function forgot to add extra 2 bytes for those characters. This may lead to memory corruption errors when pgpool starting up. - Fix error message of check_replication_time_lag(Tatsuo Ishii). It emitted wrong error message when it failed to connect to PostgreSQL while checking streaming replication delay. Because it does not use health_check_user anymore. - Fix memory leak(Toshihiro Kitagawa). This is essentially same as the fix made for 3.0.5 (commit 19a4ea9215da0b61728741fc0da2271958b09238). - Major cleanup for strncpy(Tatsuo Ishii). There are several places where strncpy() is used. Problem is some of them do not consider the case when copy lengh == buffer size. In this case copied buffer is not null terminated and may cause tons of problems later. To fix this, most of them are replaced by strlcpy(). - Update cached backend status whenever possible(Tatsuo Ishii). This solves the problem of follow_master_command not being able to lookup backend status correctly which was reported by Jeff Frost: Subject: [Pgpool-general] diagnosing BackendError from pcp_recovery_node To: pgpool-general@pgfoundry.org Date: Wed, 05 Oct 2011 15:15:07 -0700 - Fix buffer overrun problem when pcp password is longer than 32 (Tatsuo Ishii). - Remove PGDLLIMPORTI which is only neccessary for Windows and cause a problem for non gcc. Patch contributed by Ibrar Ahmed. =============================================================================== 3.1 (hatsuiboshi) 2011/09/08 * Version 3.1 This is the first version of pgpool-II 3.1 series. That is, a "major version up" from 3.0 series. __________________________________________________________________ * Incompatible changes - Change the lock method of insert_lock. The previous insert_lock uses row locking against the sequence relation, but the current one uses row locking against pgpool_catalog.insert_lock table. The reason is that PostgreSQL core developers decided to disallow row locking against the sequence relation to avoid an internal error which it leads. So creating insert_lock table in all databases which are accessed via pgpool-II beforehand is required. If does not exist insert_lock table, pgpool-II locks the insert target table. This behavior is same as pgpool-II 2.2 and 2.3 series. If you want to use insert_lock which is compatible with older releases, you can specify lock method by configure options: --enable-sequence-lock, --enable-table-lock(Toshihiro Kitagawa) - Deprecate backend_socket_dir. Instead, if backend_hostname starts with '/' it is regarded the as path to Unix domain. If backend_hostname is left empty, then default Unix domain path(/tmp) is used. This follows the convention of libpq interface. Patch contributed by Jehan-Guillaume (ioguix) de Rorthais. - Now "pgpool_walrecrunning()" was not used. pgpool-II used to consider the node that is promoted a primary node using the function. Now, pgpool-II waits for completing of the promotion to primary node because it did not work as we intended. But we still have a problem that pgpool-II waits while recovery_timeout, when there is no primary node(Toshihiro Kitagawa) - Add node_id to each PostgreSQL DB node info in the output of show pool_nodes(Jean-Paul Argudo) - Change the handling of sequence functions(nextval, setval) so that they completely obey setting of black/white_function_list. They were always handled as write functions before(Toshihiro Kitagawa) __________________________________________________________________ * New features - Add syslog support. Patch contributed by Gilles Darold. Review and editing by Guillaume Lelarge. - Adapt application_name introduced in PostgreSQL 9.0. When reusing connection, send application_name in the startup packet to backend and send parameter status to frontend(Tatsuo Ishii) - Add relcache_expire directive to control the expiration of the internal system catalog cache. ALTER TABLE might make these cache values obsoleted and the new directive will make the risk lower(Tatsuo Ishii). - Add follow_master_command directive. This directive specifies a command to run in master/slave streaming replication only after a master failover. Patch contributed by Gilles Darold. - Add pcp_promote_node command. This command promotes a new master node to pgpool-II. This can use in master/slave streaming replication only. Patch contributed by Gilles Darold. - Add pcp_pool_status command which produces similar output of show pool_status. Also C API for this command is added. Patch contributed by Jehan-Guillaume (ioguix) de Rorthais. - Add new per backend directive "backend_flag". This controls per backend behavior. Currently "ALLOW_TO_FAILOVER" or "DISALLOW_TO_FAILOVER" are allowed(Tatsuo Ishii) - Add health_check_password directive(Nicolas Thauvin) - Add sr_check_period, sr_check_user and sr_check_password directives. These are used for streaming replication delay checking and determining primary node(Tatsuo Ishii) - Add --username(or -u) option to pg_md5 command. This allows to manage users which do not have UNIX accounts. Japanese document change by Tatsuo Ishii(Nicolas Thauvin) - Add pgpool_adm functions to pgpool_adm/. These are user-defined functions written in C language which work like pcp commands (Jehan-Guillaume (ioguix) de Rorthais) - Add Simplified Chinese version of documents(Huang Jian, Sun Peng) - Add SQL files to uninstall functions to sql/(Nicolas Thauvin) - In master/slave mode, SELECTs to unlogged table execute only on master/primary(Toshihiro Kitagawa) __________________________________________________________________ * Bug fixes - Fix bug which cannot use the cursors of JDBC driver on standby node. The transaction commands come to be sent to all nodes by this fix in master/slave mode(Toshihiro Kitagawa) - Fix bug with the handling of empty queries. The empty queries come to be handled the same as SELECT queries. This fix allows load-balance after the empty query(Toshihiro Kitagawa) - Fix insert_lock so that it works correctly even if the column definition such as "DEFAULT nextval(('"x_seq"'::text)::regclass)" (Toshihiro Kitagawa) - Fix pcp_attach_node command so that it emits error message while doing failover(Toshihiro Kitagawa) - Fix log message which is emitted when pgpool-II cannot parse the query in the extended query protocol so that it shows the query (Toshihiro Kitagawa) - Fix description about backend_weight inpgpool-II manual. It can be changed by reloading pgpool.conf(Tatsuo Ishii) - Fix and enhance wording in English tutorial document. Fix suggested by Huang Jian(Tatsuo Ishii) - Fix bug which does not update the node status when reattaching the node in raw mode(Guillaume Lelarge) - Fix incorrect calculation of the replication delay in streaming replication mode(Tatsuo Ishii) - Replace wrong function name "notice_backend_error" with correct one "degenerate_backend_set" in the failover log message(Tatsuo Ishii) - Remove unnecessary logging at the end of pgpool.conf parsing (Tatsuo Ishii) - Fix possible crash of pgpool/worker child after attaching new backend. Fix suggested by Gurjeet Singh(Tatsuo Ishii) - Fix bug that SELECTs which have subquery with FOR SHARE/UPDATE clause are sent to slave/standby(Tatsuo Ishii) - Fix bug which rewriting timestamp of default value fails in PREPARE statements. This used to work but was broken in 3.0(Toshihiro Kitagawa) - Fix fail to compile pcp commands on the environment without getopt_long()(Tatsuo Ishii) - Fix crash of pgpool child when frontend connects if in raw mode, enable_hba is off and more than 2 backends(Toshihiro Kitagawa) - Fix some memory leaks(Toshihiro Kitagawa) __________________________________________________________________ * Enhancements - Enhance online recovery in streaming replication mode. Now restarting pgpool-II children is avoided when recovery finished. So existing sessions can be continued while doing online recovery (Tatsuo Ishii) - pcp_attach_node does not diconnect existing sessions in streaming replication mode. In other mode, pcp_attache_node still disconnects existing sessions(Tatsuo Ishii). - Import PostgreSQL 9.0 parser. This allows to use CREATE INDEX with implicit index name, which is new in 9.0. Patch contributed by Akio Ishida. - Allow to use regular expressions in black and white function list. Patch contributed by Gilles Darold. Patch reviewed by Guillaume Lelarge. - Reorganize pgpool.conf sample files so that they are easier to read (Guillaume Lelarge) - Add tags into all parameters in the pgpool-II user manual(Haruka Takatsuka) - Enhance online recovery documents in streaming replication(Tatsuo Ishii) - Change the function to check the replication delay in streaming replication mode. Currently, pgpool uses pg_last_xlog_replay_location() instead of pg_last_xlog_receive_location(). Fix suggested by Anton Yuzhaninov (Tatsuo Ishii) - Allow time stamp rewriting to work with arbitrary expression in default value of a column. Before we detected anything including now() then simply replaced it to now(). This will lead to wrong rewriting of default value. for example, timezone('utc'::text, now()). Note that, however, this only adopts to simple queries. Extended protocols(for example Java, PHP PDO) or SQL "PREPARE" still remain same(Tatsuo Ishii) - Enhance the error message which is emitted when failed to check replication delay(Nicolas Thauvin) - Change error message "do_md5: read_password_packet failed" into debug level(Toshihiro Kitagawa) - Allow to compile pgpool-regclass() against PostgreSQL 9.1(Tatsuo Ishii) - Update and sync pgpool-II manuals of English version and Japanese version(Tatsuo Ishii) =============================================================================== 3.0 Series (2010/09/10 - ) =============================================================================== 3.0.13 (umiyameboshi) 2013/09/06 * Version 3.0.13 This is a bugfix release against pgpool-II 3.0.12. __________________________________________________________________ * Bug fixes - Fix a mistake in ssh command of doc/basebackup.sh (Tatsuo Ishii) - Fix a bug in parsing prepared statements with transaction handling in replication mode (Tatsuo Ishii) Parse() automatically starts a transaction for non SELECT query to keep consistency among nodes in replication mode. But this wasn't closed. If wrong query comes in, the transaction goes into an abort state but pgpool does not close the transaction. Thus next query causes error because the transaction is still in abort status. This problem was reported in [pgpool-general: 1877] by Sean Hogan. [pgpool-general: 1877] current transaction is aborted, commands ignored http://www.sraoss.jp/pipermail/pgpool-general/2013-July/001905.html - Fix typos of the japanese document (Yugo Nagata) =============================================================================== 3.0.12 (umiyameboshi) 2013/07/10 * Version 3.0.12 This is a bugfix release against pgpool-II 3.0.11 __________________________________________________________________ * Bug fixes - Add mention about "-D" option to the man page. (Tatsuo Ishii) - Consider timeout waiting for compeletion of failback request in on line recovery (Tatsuo Ishii) This will prevent the situation that recovery operation continues forever and we cannot even shutdown pgpool-II main process. This could happen especially while executing follow master command. - Fix do_query() to not hang when PostgreSQL returns an error (Tatsuo Ishii) The typical symptom is "I see SELECT is keep on running according to pg_stat_activity". To fix this pgpool-II just exits the process and kill the existig connection. This is not gentle but at this point I believe this is the best solution. - Fix bug with do_query which causes hung in extended protocol (Tatsuo Ishii) This problem could occur when insert lock is enabled and pgpool_catalog.insert_lock exists, See [pgpool-general: 1684] for more details. [pgpool-general: 1684] insert_lock hangs http://www.sraoss.jp/pipermail/pgpool-general/2013-May/001711.html - Fix unnecessary degeneration caused by error on commit (Tatsuo Ishii) In master slave mode, if master gets an error at commit, while other slaves are normal at commit, we don't need to degenrate any backend because it is likely that the "kind mismatch error" was caused by a deferred trigger. - Fix to register pgpool_regclass in pg_catalog schema (Tatsuo Ishii) This is necessary to deal with clients which restricts schema search path to pg_catalog only. Postgres_fdw is such a client. - Fix a potential crash in pg_md5 command (Muhammad Usama) - Fix a segmentation fault of a child process that occurs when a startup packet has no PostgreSQL user information (Yugo Nagata) You can reproduce it by $ psql -p 9999 -U '' If enable_pool_hba is on, a child process terminates by segmentation fault. Otherwise if enable_pool_hba is off, the error message is ERROR: pool_discard_cp: cannot get connection pool for user (null) database (null) In both cases, psql terminates with no message on frontend. In the fixed version, if PostgreSQL user is not specified in startup packet, the message as following is output to both log and frontend. This is the same behavior as PostgreSQL. FATAL: no PostgreSQL user name specified in startup packet - Move ssl_ca_cert and ssl_ca_cert_dir descriptions to the SSL section in the document (Yugo Nagata) - Add ssl_ca_cert and ssl_ca_cert_dir descriptions to the japanese document (Yugo Nagata) - Fix to verify the backend node number in pcp_recovery_node (Yugo Nagata) When an invalid number is used, null value is passed as an arguments of recovery script, and this causes a malfunction. In especially, rsync may delete unrelated files in basebackup scripts. =============================================================================== 3.0.11 (umiyameboshi) 2013/04/26 * Version 3.1.7 This is a bugfix release against pgpool-II 3.1.6. __________________________________________________________________ * Bug fixes - Fix to show pool_passwd in "SHOW pool_status". (Yugo Nagata) - Fix long standing bug with timestamp rewriting code for processing extended protocol. (Tatsuo Ishii) Parse() allocate memory using palloc() while rewriting the parse message. Problem is, the rewritten message was kept in the data which is managed by pool_create_sent_message() etc. The function assumes that all the data is in session context memory. However, palloc() allocates memory in query context of course, and gets freeed later on when the query context disappears. And the function tries to free the memory as well, which causes various problems, including segfault and double free. To fix this, memory to store rewritten message is allocated using session context. The bug was there since pgpool-II 3.0 was born. Problem analysis and patch contributed by Naoya Anzai. [pgpoolgenera-jp: 1146]. (in Japanese) http://www.pgpool.net/pipermail/pgpool-general-jp/2013-March/001145.html - Fix bug with md5 auth long user name handling. (Tatsuo Ishii) If user name is longer than 32 bytes, md5 authentication doesn't work. Problem reported in [pgpool-general: 1526] by Thomas Martin. [pgpool-general: 1526] [pgPool-II 3.2.3] MD5 authentication and username longer than 32 characters. http://www.pgpool.net/pipermail/pgpool-general/2013-March/001551.html - Fix to calculate replication delay only if standby server is behind from the primay server. (Yugo Nagata) When the primary server is behind from standby server, negative value of delay is calculated and the value is assigned to unsigned variable. It causes a log message informing negative replication delay. And what is worse, it also causes SELECT queries to be sent to the primary in load balance even though there are no replication delay in fact. The problem is reported and analyzed by Saitoh Hidenori in [pgpool-genera-jp: 1145]. [pgpool-general-jp: 1145] (in Japanese) http://www.pgpool.net/pipermail/pgpool-general-jp/2013-March/001144.html - pgpool-recovery adopts PostgreSQL 9.3. (Tatsuo Ishii) Patch contributed by Asif Rehman. Slight editing by Tatsuo Ishii. [pgpool-hackers: 180] compile error in ppool-recovery http://www.pgpool.net/pipermail/pgpool-hackers/2013-April/000179.html - Fix pool_has_pgpool_regclass() to check execute privilege of pgpool_regclass(). (Tatsuo Ishii) Even though pgpool_regclass() exists, if pgpool cannot execute the function, the connection to backend hangs. You can reproduce the problem by just dropping the execute privilege from pgpool_regclass and do some insert in native replication mode. The problem is reported in bugtrack #53. #53 pgpool_regclas hangs all connections Date: 2013-04-04 13:35 Reporter: tmandke http://www.pgpool.net/mantisbt/view.php?id=53 - Fix error message mistakes in detect_postmaster_down_error(). (Tatsuo Ishii) For example, "LOG: detect_stop_postmaster_error: detect_error error" is fixed to "LOG: detect_postmaster_down_error: detect_error error", and so on. =============================================================================== 3.0.10 (umiyameboshi) 2013/02/08 * Version 3.0.10 This is a bugfix release against pgpool-II 3.0.9 __________________________________________________________________ * Bug fixes - Fix race condition when using md5 authentication. (Tatsuo Ishii) The file descriptor to pool_passwd is opened in pgpool main and pgpool child inherits it. When concurrent connections try to authenticate md5 method, they call pool_get_passwd and seek the fd and cause random md5 auth failure because underlying fd is shared. Fix is, let individual pgpool child open the file by calling pool_reopen_passwd_file. Problem reported and analyzed by Jason Slagle in pgpool-general:1141. [pgpool-general: 1141] Possible race condition in pool_get_passwd From: Jason Slagle Date: Sun, 28 Oct 2012 01:12:52 -0400 http://www.sraoss.jp/pipermail/pgpool-general/2012-October/001160.html - Fix pool_send_severity_message() not to use uninitialized memory. (Tatsuo Ishii) It cause a segmentaion fault. Reported in Bug #33's attached valgrind output by dudee. #33 pgpool-II 3.2.1 segfault Reporter: dudee Date: 2012-10-30 19:16 http://www.pgpool.net/mantisbt/view.php?id=33 - Fix reaper() not to exit wait3() loop when catches pcp or worker child exit event. (Tatsuo Ishii) Otherwise reaper() mistakenly ignore some process exit event and make a risk of creating zombie process and forgetting to create new process. Problem reported and fix suggested by Goto in [pgpool-general-jp: 1123]. http://www.sraoss.jp/pipermail/pgpool-general-jp/2012-November/001122.html (in Japanese) - Fix pool_search_relcache() to use MASTER or MASTER_NODE_ID macro, rather than REAL_MASTER_NODE_ID. (Tatsuo Ishii) In case node 0 fail back in streaming replication mode, pgpool does not restart child process. So REAL_MASTER_NODE_ID looks for node 0 con info, which is not present until new connection to backend made. Thus referring to node con info results in segfault. MASTER or MASTER_NODE_ID are safe in this situation because they look at cached former master node id. - Fix long standing bug "portal not found" error when replication delay is too much in streaming replication mode. (Tatsuo Ishii) The bug had been there since the delay threshold was introduced. We changed destination DB node if delay threshold exceeds in bind, describe and execute. However, if parse sends to different node, bind, describe or execute will fail because no parsed statement or portal exists. Solution is, not to send to different parse node even if delay threshold is too much. - Fix pg_md5 to output "\n" after user inputs password. (Yugo Nagata) - Fix child_exit() to not call send_frontend_exits() if there's no connection pool. (Tatsuo Ishii) Otherwise, it segfaults because send_frontend_exits() referes to objects pointed to by pool_connection_pool. Per bug track #44 by tuomas. #44 pgpool went haywire after slave shutdown triggering master failover Reporter: tuomas Date: 2012-12-11 00:33 http://www.pgpool.net/mantisbt/view.php?id=44 - Fix read_startup_packet() to reset alarm and free StartupPacket when pool_read() returns 0 which means incorrect packet length. (Nozomi Anzai) Previously, authentication timeout occurs when connected by a program monitoring the pgpool port.It is reported in bug track #35 by tuomas. #35 Authentication is timeout Reporter: tuomas Date: 2012-11-20 11:54 http://www.pgpool.net/mantisbt/view.php?id=35 - Fix long standing bug with pool_open(). (Tatsuo Ishii) It initializes wrong buffer pointer. Actually this is harmless because the pointer is initialized by prior memset() call, though. - Add a description about "-f" to help message. (Tatsuo Ishii) - Modify documents to correct information of whether a certain parameter change requires restart. (Yugo Nagata) - Add pool_passwd option to pgpool.conf.sample*, and documents. (Yugo Nagata) =============================================================================== 3.0.9 (umiyameboshi) 2012/10/12 * Version 3.0.9 This is a bugfix release against pgpool-II 3.0.8 __________________________________________________________________ * Bug fixes - Fix read_startup_packet. (Tatsuo Ishii) If packet length is lower than 0, it should have returned immediately. Otherwise it would cause memory allocation error later on. per pgpool-general:886. Also add canceling alarm. - Add NOTICE message handling to s_do_auth. (Tatsuo Ishii) Without this, health check responses false alarm and causes failover. per bug track: http://www.pgpool.net/mantisbt/view.php?id=25 Also allow to receive ready for query packet *not* right after backend keydata. I'm not sure if this could happen in the real world but the protocol seems to allow this. - Remove unnecessary/confusing debug log from s_do_auth.(Tatsuo Ishii) - Fix inifinit loop in SSL mode. When there's pending data in SSL layer of frontend, pool_process_query() checks pending data in backend. (Tatsuo Ishii) If there's non, it loops again and checks frontend/backend receive buffer by using is_cache_empty(). Unfortunately it first checks pending data in SSL layer of frontend, thus goes to backend data and checks again (infinite loop). The solution is, if there's pending data in SSL layer of frontend and query is not in progress, call ProcessFrontendResponse() to process new request from frontend. - Fix is_system_catalog to use pgpool_regclass if available. (Tatsuo Ishii) - Fix memory leak in pool_get_insert_table_name(). (Tatsuo Ishii) If session context's memory contex is used for nodeToString(), memory is not freed until session ends. - Fix possible memory leak in nodeToString(). (Tatsuo Ishii) Since the memory context could be session context, memory used for String object may be considerable if user session continues for hours or days. See bug track #24 for more details. - Fix long standing problem with do_query(). (Tatsuo Ishii) When 1) extended protocol used and 2)unnamed portal is used and 3) no explicit transaction is used, user's unnamed portal is removed by Sync message. This is because Sync message closes transaction and unnamed portal is removed. This leads to "portal "" does not exist" error. Fix is, use "Flush" message instead of Sync. Main difference between using Sync and Flush is, Flush does not return Ready for Query message. So do_query() does not return until all expected responses are returned. It seems the order of messages returned from backend is random, and do_query () manages it by using state bits. =============================================================================== 3.0.8 (umiyameboshi) 2012/08/0 * Version 3.0.8 This is a bugfix release against pgpool-II 3.0.7 __________________________________________________________________ * Bug fixes * General - Adopt PostgreSQL 9.2. (Tatsuo Ishii) * Bug fixes - Fix load balance in Solaris. (Tatsuo Ishii) Problem is, random() in using random() in Solaris results in strange load balancing calculation. Use srand()/rand() instead although they produce lesser quality random Problem reported at [pgpool-general: 396]. [pgpool-general: 396] strange load balancing issue in Solaris http://www.pgpool.net/pipermail/pgpool-general/2012-April/000397.html - Fix segfault of pcp_systemdb_info not in parallel mode. (Nozomi Anzai) - Fix "unnamed prepared statment does not exist" error. (Tatsuo Ishii) This is caused by pgpool's internal query, which breaks client's unnamed statements. To fix this, if extended query is used, named statement/portal for internal are used for internal query. - Fix is_system_catalog(). Its relcach was accidently defined as "session local". (Tatsuo Ishii) - Improve reading and writing pid_file. (Tatsuo Ishii) - Fix pool_process_query() bug reported in [pgpool-general: 672]. (Tatsuo Ishii) This is caused by the function waits for primary node which does not have pending data, while standbys have pending data. [pgpool-general: 672] Transaction never finishes http://www.pgpool.net/pipermail/pgpool-general/2012-June/000676.html - Fix wait_for_query_response() not to send param status to frontend if frontend is NULL. (Tatsuo Ishii) This could happen while processing reset_query_list and occur crash. =============================================================================== 3.0.7 (umiyameboshi) 2012/04/23 * Version 3.0.7 This is a bugfix release against pgpool-II 3.0.6. __________________________________________________________________ * Bug fixes - Add m4 files. This should prevent compiling problem on older OS's. (Tatsuo Ishii) - Fix bug that the process exits before unlocking semaphore by a signal interrupt. (Tatsuo Ishii) - Fix a memory leak in case of reset_query. (Tatsuo Ishii) - Fix SimpleQuery() so that it restores parser memory context when: 1) Builtin show commands are used 2) Parallel query mode 3) Query cache is used (Tatsuo Ishii) - Fix pool_ssl_read() to deal with large data reading. (Tatsuo Ishii) Original complain is here: http://www.pgpool.net/pipermail/pgpool-general/2012-March/000299.html - Fix hangup when PREPARE statement causes error. (Toshihiro Kitagawa) This issue was reported by Tomonari Katsumata: Subject: [pgpool-general: 121] question of pgpool's behavior =============================================================================== 3.0.6 (umiyameboshi) 2012/01/31 * Version 3.0.6 This version fixes various bugs since 3.0.5. - Fix infinite loop reported in this thread (Tatsuo Ishii): http://www.pgpool.net/pipermail/pgpool-general/2011-December/000099.html It was not considered the case that, when received buffer in primary was empty but the one in a standby was not, the standby spontaneously sent packet to pgpool. This could happen when, for example, reloading postgresql.conf. The fix is that such buffer in standby is discarded. =============================================================================== 3.0.5 (umiyameboshi) 2011/10/31 * Version 3.0.5 This version fixes various bugs since 3.0.4. __________________________________________________________________ * Bug fixes - Fix bug with the handling of empty queries. The empty queries come to be handled the same as SELECT queries. This fix allows load-balance after the empty query(Toshihiro Kitagawa) - Fix insert_lock so that it works correctly even if the column definition such as "DEFAULT nextval(('"x_seq"'::text)::regclass)" (Toshihiro Kitagawa) - Fix log message which is emitted when pgpool-II cannot parse the query in the extended query protocol so that it shows the query (Toshihiro Kitagawa) - Fix description about backend_weight inpgpool-II manual. It can be changed by reloading pgpool.conf(Tatsuo Ishii) - Fix bug which does not update the node status when reattaching the node in raw mode(Guillaume Lelarge) - Fix bug that SELECTs which have subquery with FOR SHARE/UPDATE clause are sent to slave/standby(Tatsuo Ishii) - Fix bug which rewriting timestamp of default value fails in PREPARE statements. This used to work but was broken in 3.0(Toshihiro Kitagawa) - Fix crash of pgpool child when frontend connects if in raw mode, enable_hba is off and more than 2 backends(Toshihiro Kitagawa) - Fix some memory leaks(Toshihiro Kitagawa) __________________________________________________________________ * Enhancements - Allow time stamp rewriting to work with arbitrary expression in default value of a column. Before we detected anything including now() then simply replaced it to now(). This will lead to wrong rewriting of default value. for example, timezone('utc'::text, now()). Note that, however, this only adopts to simple queries. Extended protocols(for example Java, PHP PDO) or SQL "PREPARE" still remain same(Tatsuo Ishii) - Change error message "do_md5: read_password_packet failed" into debug level(Toshihiro Kitagawa) =============================================================================== 3.0.4 (umiyameboshi) 2011/06/01 * Version 3.0.4 This version fixes various bugs since 3.0.3. __________________________________________________________________ * Incompatible changes - In streaming replication, if delay_threshold is 0 or health checking is disabled, the delay checking is not performed. This is the behaviour according to a description of the pgpool-II manual. But, so far the delay checking was performed even if health checking was disabled(Guillaume Lelarge) __________________________________________________________________ * Bug fixes - Fix pgpool-regclass() to be compiled in PostgreSQL 8.0 or later. 7.4 still produces errors(Tatsuo Ishii) - Fix possible hangup when using /*NO LOAD BALANCE*/ comment in streaming replication(Toshihiro Kitagawa) - Fix hangup when received Flush(H) message or CloseComplete(C) message(Toshihiro Kitagawa) - Fix possible hangup that happen for the receiving timing of ReadyForQuery(Z) message after pgpool-II connects to backends (Toshihiro Kitagawa) - Add description about parameters for recovery_1st_stage_command and recovery_2nd_stage_command(Tatsuo Ishii) - Increase size of the internal system catalog cache from 32 to 128. This has the effect of reducing "unnamed prepared statement does not exist" error(Tatsuo, Kitagawa) - Fix bug with pcp_connect() which causes double free. Patch contributed by Jehan-Guillaume (ioguix) de Rorthais(Tatsuo Ishii) - Fix bug with start_recoery() which is apparently wrong usage of PQfinish()(Tatsuo Ishii) - Fix incorrect error message which is sent to the frontend when client idle time reached client_idle_limit(Tatsuo Ishii) - Fix "backend status" variable name correctly in pool_status. Replace the space with a '_'(Guillaume Lelarge) - Fix hangup when using md5 authentication method and running as daemon. Patch contributed by Nicolas Thauvin(Tatsuo Ishii) - Fix log_per_node_statement so that it prints statements in the extended query protocol. This used to work but was broken in 3.0 (Toshihiro Kitagawa) __________________________________________________________________ * Enhancements - Add currval() and lastval() to black_function_list of sample configuration files. If they are load balanced, currval() or lastval() may be called before the result of nextval() or setval() is propagated to slaves(Tatsuo Ishii) =============================================================================== 3.0.3 (umiyameboshi) 2011/02/23 * Version 3.0.3 This version fixes various bugs since 3.0.1. Please note that 3.0.2 was canceled due to a packaging problem. __________________________________________________________________ * Incompatible changes - Now installing C function "pgpool_walrecrunning()" is recommended if you plan to use streaming replication mode. This is necessary for better use of online recovery in the mode. Also new variable "%P" can be used in the online recovery script. If you do not install the function, these functionalities Cannot be used(Tatsuo Ishii). - In raw mode if there's only one DB node and if a problem arises with the DB node, it will be brought to down status. However if the DB node goes into good condition again, you can use the DB node without restarting pgpool. This change has been included in 3.0, but did not work(Tatsuo, Kitagawa) __________________________________________________________________ * Bug fixes - Fix non portable code in password authentication. Bug report from a FreeBSD user(Tatsuo Ishii) - Fix bug that insert_lock locks all rows in user table (Tatsuo, Kitagawa) - Fix bug with password authentication. If user name is 32 bytes long, pgpool child segfaults.(Tatsuo Ishii) - Fix bug with md5 authentication. If raw mode or number of backend is 1, pgpool child segfaults. Patch contributed by Rob Shepherd(Tatsuo Ishii) - Fix long standing bug with timestamp rewriting against array and complex types. Patch contributed by Akio Ishida(Tatsuo Ishii) - Fix bug that debug_level directive doesn't work. Patch contributed by Gilles Darold(Tatsuo Ishii) - Fix possible crash of pgpool child while doing failover (Toshihiro Kitagawa) - Fix white/black_function_list so that it works correctly when user calls function with schema name(Tatsuo Ishii) - Fix bug that DROP DATABASE fails by connection cache (Toshihiro Kitagawa) - Fix bug that failover fails in raw mode(Toshihiro Kitagawa) - Fix possible termination of pgpool child when both simple query protocol and extended query protocol are used in one session (Toshihiro Kitagawa) - Fix possible hang up when an error occurs while using extended query protocol(Toshihiro Kitagawa) - Fix pgpool-regclass() so that it doesn't use PG_TRY/CATCH. It appeared that using PG_TRY/CATCH is not safe, sometimes backend dies with PANIC: ERRORDATA_STACK_SIZE exceeded.(Tatsuo Ishii) - Fix bug that select query isn't sent to master node when it meets the following conditions(Toshihiro Kitagawa) - in MASTER/SLAVE mode - use extended query protocol - started transaction explicitly - after write queries - Fix bug with load_balance that JDBC driver sends BEGIN to master node many times(Toshihiro Kitagawa) - Fix pool_status so that failback_command and fail_over_on_backend_error show correct values(Toshihiro Kitagawa) - Remove parameters from pool_status: recovery_password, system_db_password(Toshihiro Kitagawa) - Fix online recovery problem in the streaming replication mode(Tatsuo Ishii). Consider following scenario. Suppose node 0 is the initial primary server and 1 is the initial standby server. 1) Node 0 going down and node 1 promotes to new primary. 2) Recover node 0 as new standby. 3) pgpool-II assumes that node 0 is the new primary. This problem happens because pgpool-II regarded unconditionally the youngest node to be the primary. pgpool-II 3.0.3 now checks each node by using pgpool_walrecrunning() to see if it is a actually primary or not and is able to avoid the problem and regards node as standby correctly. Also you can use new variable "%P" to be used in the recovery script. If you do not install the function, the above problem is not resolved. - Fix backend complaining "unexpected EOF on client connection" while doing failover in streaming replication mode(Tatsuo Ishii) - Fix pgpool crashes when all backends go down(Tatsuo Ishii) - Fix replication delay checking so that it does not keep persistent connection to backends. Because the persistent connection may become bogus if a node down and then wake up between replication delay checking period(Tatsuo Ishii) - Rewrite and review english document(Marc Cousin, Gleu) __________________________________________________________________ * Enhancements - Emit log if particular backend is down status while reading the status file(Tatsuo Ishii) - Emit error message if an error occurred by the query that pgpool executed(Tatsuo Ishii) - Add sql directories main Makefile(Tatsuo Ishii) =============================================================================== 3.0.1 (umiyameboshi) 2010/10/19 * Version 3.0.1 This version fixes various bug in 3.0. __________________________________________________________________ * Bug fixes - Fix bug with md5 auth. If there's more than 1 servers to be authenticated, it segfaults(Tatsuo Ishii) - Fix bug that a child process crashes when clients execute a query contains syntax error in extended query protocol(Toshihiro Kitagawa) - Fix bug with handling of portal information, it terminates a child process(Toshihiro Kitagawa) - Fix hungup when a query sent to one node caused an error in extended query protocol(Toshihiro Kitagawa) - Fix typo in English doc. Patch contributed by Asaf Ohaion(Tatsuo Ishii) =============================================================================== 3.0 (umiyameboshi) 2010/09/10 * Version 3.0 This is the first version of pgpool-II 3.0 series. That is, a "major version up" from 2.2 or 2.3 series. The biggest news is, this version adapts to PostgreSQL 9.0's new feature: Streaming Replication/Hot Standby. Streaming replication can be used as a sub mode of master slave mode. Master slave mode itself heavily enhanced: - SELECTs in explicit transactions can be load balanced - In extended protocol, PARSE/BIND/DESCRIBE messages are sent to the node which execute EXECUTE message, not all node. This will reduce lock contentions. - Auto start of transaction happens only when it needed. - Temporary tables can be used safely. - SELECT which calls functions possibly write to database executes on master(primary) Also many new features are added and major refactoring has been made to the internal structure of pgpoo-II. For example, in replication mode, SELECTs calling functions possibly write to database will not allow to load balance. __________________________________________________________________ * New features - Online recovery can be used with master/slave/streaming replication mode(Tatsuo Ishii) - New directive "delay_threshold" is added to monitor replication delay in master/slave/streaming replication mode. If replication delay is too much, SELECTs are not load balanced(Tatsuo Ishii) - show pool_status shows replication delay in master/slave/streaming replication mode(Tatsuo Ishii) - New directive "log_standby_delay" is added to control logging of replication delay in master/slave/streaming replication mode(Tatsuo Ishii) - When insert_lock is enabled and the table includes SERIAL data type, issue row lock on the sequence table. Before we issues table lock. Problem is, the table lock conflicts with auto vacuum and sometimes caused excessive lock waiting(Tatsuo Ishii) - Add support for more "SHOW" commands: pool_nodes, pool_processes, pool_pools, and pool_version(Guillaume Lelarge) - Backend process id and whether frontend connects to this connection pool or not are added to pcp_proc_info's output(Tatsuo Ishii) - "Gracefuly detach" option is added to pcp_detatch_node. With this option, pcp_detatch_node waits until all frontends disconnected(Tatsuo Ishii) - New directive "white_function_list" and "black_function_list" are added to register functions those do not or do write to database(Tatsuo Ishii) - In master/slave mode, SELECTs to system catalogs executes only on master/primary(Tatsuo Ishii) - In master/slave mode, SELECTs to temporary table executes only on master/primary(Tatsuo Ishii) - In master/slave mode, write queries outside of explicit transactions no longer trigger to start internal transaction(Tatsuo Ishii) - In master/slave mode, SELECTs inside explicit transactions are load balanced(Tatsuo Ishii, Toshihiro Kitagawa) - In master/slave mode, commands are no longer sent to all DB nodes. This will prevent unnecessary locking (Tatsuo Ishii, Toshihiro Kitagawa) - New command option adds to ignore the status file when starting up(Tatsuo Ishii) - Supports PostgreSQL 9.0's new VACUUM syntax(Tatsuo Ishii) - New directive "failover_if_affected_tuples_mismatch" controls the behavior when number of result rows of INSERT/UPDATE/DELETE are differ(Tatsuo Ishii) - When number of result rows of INSERT/UPDATE/DELETE are differ, each number are logged(Tatsuo Ishii) - md5 authentication is supported in replication mode and master/slave mode(Tatsuo Ishii) - Allow to force to move to online recovery second stage even there are connecting frontends(Tatsuo Ishii) - If there's only one DB node and it triggers failover, pgpool-II will automatically connects if the DB node coming up(Tatsuo Ishii) - Pcp commands supports long options(Guillaume Lelarge) - New directive "debug_level" added to control the debug message logging(Tatsuo Ishii) - Allow to use various boolean representations as PostgreSQL in pgpool.conf(Toshihiro Kitagawa) - New C language function pgpool_switch_xlog for online recovery added(Toshihiro Kitagawa) - New C language function pgpool_regclass added to avoid a trouble about handling of duplicate table names in different schema (Tatsuo Ishii) __________________________________________________________________ * Bug fixes - Do not rewrite statement which accesses columns having now() etc. as the default value but the data type are not timestamp etc. Otherwise we have an error in DMLs(Tatsuo Ishii) - Fix timestamp rewriting not to omit schema qualification(Tatsuo Ishii) - Fix bug with timeout handling in pcp commands(Tatsuo Ishii) - Fix SSL hang when large amount of data transfered(Tatsuo Ishii) - Fix failover when there's only one DB node(Tatsuo Ishii) - Fix bug with postmaster start check in online recovery. Before it continued infinitely to try to connect to postmaster if the first attempt failed(Tatsuo Ishii) =============================================================================== 2.3 Series (2009/12/07 - 2010/02/22) =============================================================================== 2.3.4 (tomiteboshi) 2012/08/06 * Version 2.3.4 This version fixes various bugs since 2.3.3. __________________________________________________________________ * Bug fixes - Fix do_error_execute_command() so that it discards responses from backend until ErrorResponse received. (Toshihiro Kitagawa) Note that we need to preserve non-error responses (i.e. ReadyForQuery) and put back them using pool_unread(). Otherwise, ReadyForQuery response of DEALLOCATE. This could happen if PHP PDO used. - Fix SimpleForwardToFrontend() so that it reset select_in_transaction flag and execute_select flag when bind error occurred while executing SELECT. (Toshihiro Kitagawa) - Fix SSL connection sometimes hung if lots of data read from backend. This is caused by the buffering in OpenSSL layer. To fix the problem, (Tatsuo Ishii) we check the buffer has any pending data by using SSL_pending() before calling select(2). See thread [Pgpool-general] Fwd: PGPOOL II 2.3.3 hang in ssl mode for more details. - Fix bug with pcp_check_fd()'s timeout handling. (Tatsuo Ishii) Per erboles. Subject: [Pgpool-general] question about pcp_check_fd Date: Sun, 23 May 2010 18:21:41 -0500 To: pgpool - Do not force replication of DEALLOCATE if operated in master/slave mode. Reported by Jan Kantert. (Toshihiro Kitagawa) See: Subject: [Pgpool-hackers] Problems with PgPool 2.3.3 Prepare / Deallocation handling in Master/Slave mode Date: Fri, 28 May 2010 20:59:47 +0200 For more details. - Make timestamp rewriting schema aware. (Tatsuo Ishii) - Do not rewrite statement which accesses columns having now() etc. as the default value but the data type are not timestamp etc. (Tatsuo Ishii) Otherwise we have an error in DMLS. See: Subject: [Pgpool-general] function epoch seems to be causing error To: pgpool-general@pgfoundry.org Date: Mon, 16 Aug 2010 21:48:31 +0000 (UTC) For more details. - Fix insert_lock to be schema aware. (Tatsuo Ishii) - Fix long standing bug with timestamp rewriting against array and complex types. (Tatsuo Ishii) Failed examples are: INSERT INTO r1(col[1], col2.foo) VALUES (1, 2); -- insert_column_item UPDATE r1 SET col1[1] = 1, col2.foo = 1; -- set_target PREPARE "p" (int4[]) AS SELECT $1[1]; -- c_expr SELECT (ARRAY[1,2,3])[1]; SELECT (ARRAY[ARRAY[1]])[1][1]; SELECT ('{1,2,3}'::int[])[1]; SELECT ('{1,2,3}'::int[3])[1]; SELECT r1.col[1], (r1.col1).bar, (r1.col1).* FROM r1; -- columnref SELECT (r1.col1).baz[1], (r1.col1).baz[1][2] FROM r1; Patch provided by Akio Ishida. - Fix buffer overrun problem when pcp password is longer than 32. (Tatsuo Ishii) - Fix wait_for_query_response() not to send param status to frontend if frontend is NULL. This could happen while processing reset_query_list. (Tatsuo Ishii) =============================================================================== 2.3.3 (tomiteboshi) 2010/04/23 * Version 2.3.3 This version fixes various bugs since 2.3.2.2. __________________________________________________________________ * Incompatible changes - Please note that this version of pgpool consumes more shared memory than before. If you encounter problems when starting up pgpool, please look into pgpool log. If you find messages something like "could not create shared memory segment: Cannot allocate memory", please increase the shared memory on your system. - Now parallel mode requires replication mode turned on. parallel mode without replication mode turned on has been broken since pgpool-II was born anyway(Toshihiro Kitagawa) - Change default value for insert_lock to false since there's no point in turning this on in master/slave mode. Fix suggested by Fujii Masao(Tatsuo Ishii) __________________________________________________________________ * Newly added documents - README.online-recovery, which is an internal document of online recovery, added(Tatsuo Ishii) __________________________________________________________________ * Bug fixes - Fix long standing bug since pgpool-II 1.0 which causes segfault of pgpool child process. This was caused by miscalculation of shmem size in pgpool parent. Bug analysis by Kitagawa patch created by Tatsuo - Add restriction for parallel mode(Toshihiro Kitagawa) - The Natural Join is not supported - The USING CLAUSE is converted to ON CLAUSE by query rewrite process - Fix possible crash during rewriting JOIN syntax that have USING in parallel query mode(Toshihiro Kitagawa) This fix is supporting such as following JOIN syntax. example: - SELECT * FROM a JOIN b USING (aid) JOIN c USING (cid); - SELECT * FROM a JOIN b USING (aid) JOIN c USING (cid) JOIN d USING (did) - Fix parallel query so that it can parse INSERT statements that have current_time before a partitioning key column (Toshihiro Kitagawa) - Fix SimpleForwardToBackend() so that pgpool doesn't keep waiting for reply from a backend, when clients using the extended query protocol cause a command error such as bind error. This bug occur in master/slave, raw, and connection pool mode. This fix is, sending SYNC message to recover error after command error(Toshihiro Kitagawa) - Fix SIGINT/SIGQUIT is ignored if pgpool child is in select(). In this case pgpool retries select() thus the signal is ignored(Tatsuo Ishii) - Fix connect_inet_domain_socket_by_port/ connect_unix_domain_socket_by_port so that they check if SIGTERM/SIGINT/SIGQUIT signal has been delivered. Per bug report from Daniel Codina(Tatsuo Ishii) - Fix possible crash during creating "kind mismatch" error message. This used to work but was broken in 2.3.2(Tatsuo Ishii) - Fix bug with healh checking. If a network problem such as unplugged wire happens while calling connect(), health checking does not work since connect_unix_domain_socket()/connect_inet_domain_socket() do retry if connect() is interrupted by ALARM signal. Added new retry argument which controls the retrying behavior to those functions. Per bug report and problem analysis by Daniel Codina(Tatsuo Ishii) - Fix enbug in 2.3.2.2 with time stamp rewriting in SimpleForwardToBackend. Per bug report from Bugtrack #1010771. Report from Peter Pramberge(Tatsuo Ishii) - Fix rewriting "*" in paralell query. Patch conributed by sho-san(Toshihiro Kitagawa) - Fix connect_inet_domain_socket_by_port() so that it print out error message by using hstrerror(), rather than strerror()(Tatsuo Ishii) =============================================================================== 2.3.2.2 (tomiteboshi) 2010/02/22 * Version 2.3.2.2 This version fixes various bug in 2.3.x. - When rewriting timestamp in extended query, it allocated less than what it actually needed. This causes random problematic behavior, typically "message: invalid string in message" error in backend(Tatsuo Ishii). - In extended query, if one of parameters contains NULL, ppool crashes(Tatsuo Ishii). - If in previous status file all nodes were marked down status, it is regarded that this file is bogus. This will prevent "all node down" syndrome(Tatsuo Ishii). =============================================================================== 2.3.2.1 (tomiteboshi) 2010/02/11 * Version 2.3.2.1 This version fixes bug in 2.3.x. It is identfied that pgpool-II 2.3.x has a problem with erroneous query processing(Akio Ishida). =============================================================================== 2.3.2 (tomiteboshi) 2010/02/07 * Version 2.3.2 This version includes various fixes for bugs in 2.3.1 or before. All 2.3.x users are encouraged to upgrade to 2.3.2 as soon as possible. Also this version enables long awaited SSL support and large object replication support. __________________________________________________________________ * Enhancements - SSL support(Sean Finney) - Large object replication support. You need PostgreSQL 8.1 or later, however(Tatsuo Ishii) - Emit statement log when error or notice message comes from query parsing process. This is usefull because PostgreSQL does not log particular statement if the error was detected *before* raw parser get executed. This typlically happens when encoding error was found(Tatsuo Ishii) - Display original query to log if kind mismatch error was caused by DEALLOCATE(Tatsuo Ishii) - While health checking and recovery use postgres database if possible. If postgres database does not exist, use template1 as it stands now. While connecting template1, certain commands, for example DROP DATABASE cannot used. Using postgres database allows to use these commands while recovery(Tatsuo Ishii) __________________________________________________________________ * Bug fixes - Fix errors in timestamp rewriting which occasionaly cause broken packet sentto slave nodes(Tatsuo Ishii) - Fix errors when timestamp rewriting is used with V2 protocol(Toshihiro Kitagawa) - Propagate Bind, Describe and Close messages to only master node if running in master/slave and in transaction (Tatsuo Ishii) - Fix do_child() so that check_stop_request() exits immediately when smart shutdown signal has been sent. This has been used to work in 2.2(Toshihiro Kitagawa) - Fix ProcessFrontendResponse not to accept invalid frotend packet(Xavier Noguer) - Use %dz for sizeof in fprintf for more portability(Tatsuo Ishii) - Fix compiler warnings(Tatsuo Ishii) - Do not force replication of DEALLOCATE if operated in master/slave mode. Now that pgpool do not execute PARSE in all nodes, this was pointless and caused problem (kind mismatch when executing DEALLOCATE)(Tatsuo Ishii) =============================================================================== 2.3.1 (tomiteboshi) 2009/12/18 * Version 2.3.1 This version includes various fixes for bugs in 2.3 or before. All 2.3 users are encouraged to upgrade to 2.3.1 as soon as possible. __________________________________________________________________ * Bug fixes - If all of following conditions met, incorrect data is written to DB(Tatsuo Ishii) - pgpool is running in replication mode - pgpool is running on 64bit OS - INSERT or UPDATE are used which explicitly include now(), - CURRENT_TIMESTAMP, CURRENT_DATE, CURRENT_TIME. Or the target - Table's default value use above functions - The SQL statement inclludes out of 32bit integer value(-2147483648 to 2147483647 in decimal) Example SQL: INSERT INTO t1(id, regdate) VALUES(98887776655, NOW()); - Fix crush in case of more than 18 DB nodes are used(Tatsuo Ishii) - Enhance kind mismatch error message. If kind is ERROR or NOTICE, the error or notice message from PostgreSQL will be printed (Tatsuo Ishii) =============================================================================== 2.3 (tomiteboshi) 2009/12/07 * Version 2.3 This version enhances replication, especially CURRENT_TIMESTAMP, CURRENT_DATE, now() etc. now can be properly replicated. Also perforance of replication when num_init_children == 1 is enhanced. Pgpool-II now records the status of down nodes, and remember when it restarts to ensure that keep the node status as before. Also some logs are enhanced and more fine fail over controls are added. Please note that pgpool-II 2.3 includes all of enhancements and fixes of pgpool-II 2.2.1 to 2.2.6. __________________________________________________________________ * Incompatibilities from 2.2.x - pgpool_status file is created under logdir. So you need to give write permission to the directory so that pgpool-II can read/write pgpool_status file. __________________________________________________________________ * Enhancements - Enable proper replication of results of temporal functions (CURRENT_TIMESTAMP, CURRENT_DATE, now() etc.). Now applications can execute INSERT/UPDATE tables which include defaut values using those temporal functions. There are small limitations. See restriction sections of docs for more details (Akio Ishida) - Use PostgreSQL 8.4's SQL parser(Akio Ishida) - Enhance the performance 20% to 100% of replication when num_init_children == 1(Tatsuo Ishii) - Add new directive log_per_node_statement which is similar to log_statement except that prints info for each DB node to make it easier which query is sent to which DB node(Tatsuo Ishii) - Add new directive fail_over_on_backend_error to control the behaviro of fail over(Tatsuo Ishii) - Record DB node status and remember when pgpool-II restarts(Tatsuo Ishii) - EXPLAIN and EXPLAIN ANALYZE for SELECT query are now load balanced. This will prevent unwanted kind mismatch errors when EXPLAIN produces slightly different plan(Tatsuo Ishii) - Enhance CSS of pgpool-ja.html(Tatsuo Ishii) - Add sample configuration file for replication mode and master/slave mode(Tatsuo Ishii) - Add test for temporal data(Akio Ishida) =============================================================================== 2.2 Series (2009/02/08 - 2010/04/15) =============================================================================== 2.2.8 (urukiboshi) 2012/08/06 * Version 2.2.8 It includes various fixes for bugs various bug fixes in 2.2.7. __________________________________________________________________ * Bug fixes - Fix do_error_execute_command() so that it discards responses from backend until ErrorResponse received. (Toshihiro Kitagawa) Note that we need to preserve non-error responses (i.e. ReadyForQuery) and put back them using pool_unread(). Otherwise, ReadyForQuery response of DEALLOCATE. This could happen if PHP PDO used. - Fix SimpleForwardToFrontend() so that it reset select_in_transaction flag and execute_select flag when bind error occurred while executing SELECT. (Toshihiro Kitagawa) - Fix bug with pcp_check_fd()'s timeout handling. (Tatsuo Ishii) Per erboles. Subject: [Pgpool-general] question about pcp_check_fd Date: Sun, 23 May 2010 18:21:41 -0500 To: pgpool - Fix buffer overrun problem when pcp password is longer than 32. (Tatsuo Ishii) - Fix wait_for_query_response() not to send param status to frontend if frontend is NULL. This could happen while processing reset_query_list. (Tatsuo Ishii) =============================================================================== 2.2.7 (urukiboshi) 2010/04/15 * Version 2.2.7 This version enhances displaying error messages when kind mismatch error occurs. Also it includes various fixes for bugs in 2.2.6 or before as usual. __________________________________________________________________ * Bug fixes - Fix occasional hangup in extend protocol + master/slave mode, row mode or connection pool mode. Back patch from 2.3 tree(Toshihiro Kitagawa) - Fix long standing bug since pgpool-II 1.0 which causes segfault of pgpool child process. This was caused by miscalculation of shmem size in pgpool parent. Bug analysis by Kitagawa patch created by Tatsuo - Send Parse, Bind, Describe and Close message to only master node if operated in explicit transaction and master/slave mode(Tatsuo Ishii). - Emit a log when postmaster goes down(Tatsuo Ishii) - Fix memory leak in make_persistent_db_connection(Xavier Noguer) - Do not force replication of DEALLOCATE if operated in master/slave mode. Now that pgpool do not execute PARSE in all nodes, this was pointless and caused problem (kind mismatch when executing DEALLOCATE) (Tatsuo Ishii) - Fix crash with show pool_status when there many (more than 18) DB nodes(Tatsuo Ishii) - Enhance "kind mismatch" message. If kind is ERROR or NOTICE, print the ERROR/NOTICE message to help users to find what's going on(Tatsuo Ishii) =============================================================================== 2.2.6 (urukiboshi) 2009/12/01 * Version 2.2.6 This version enhances handling of backend weight. Also it allows to use temp tables in master/slave mode. It includes various fixes for bugs in 2.2.5 or before as usual. __________________________________________________________________ * Bug fixes - Do not allow to load balance DECLARE, CLOSE, FETCH and MOVE. If data gets updated and CLOSE issued after transaction commit(i.e. holdbale cursor), this will cause data inconsistency since CLOSE is executed one of the severs, rather than all(Tatsuo Ishii) - In master/slave mode, execute Parse message on only master node. In previous versions Parse executed on all nodes, which grabbed unneccessary lock(Tatsuo Ishii) - Remove init script from all runlevels before uninstall(Devrim) - Fix pgpoo.spec(Devrim) - Do not execute REINDEX DATABASE or SYSTEM, CREATE/DROP TABLE SPACE inside a transaction block(Tatsuo Ishii) __________________________________________________________________ * Enhancements - Allow to change weight by reloading pgool.conf. This will take effect for next client sessions(Tatsuo Ishii) - Reply with usefull error messages, rather than "server closed the connection unexpectedly" when authentication fails(Glyn Astill) - Add info to logs when writing to sockets falis to know if it was for backend or frontend(Tatsuo Ishii) - Do not complain when writing to socket of frontend fails(Tatsuo Ishii) - Allow to use temp tables in master/slave mode. INSERT/UPDATE/DELETE will automatically be sent to master only. Still SELECT you need to add /*NO LOAD BALANCE*/ comment(Tatsuo Ishii) - Add temp table test to test/jdbc(Tatsuo Ishii) =============================================================================== 2.2.5 (urukiboshi) 2009/10/4 * Version 2.2.5 This version fixes various bugs in 2.2.4 or before. __________________________________________________________________ * Bug fixes - Fix connection_count_down(). It decrements the connection counter too much in some corner cases and causes online recover never completes(Tatsuo Ishii) - Detect frontend exiting while waiting for commands complete in other cases such as internal locks are issued and Parse (Tatsuo Ishii) - Fix inifinit loop in reset_backend(Xavier Noguer, Tatsuo) - Fix Parse() to print actual query when it detects kind mismatch error(Tatsuo Ishii) - Document enhancements(Tatsuo Ishii) =============================================================================== 2.2.4 (urukiboshi) 2009/8/24 * Version 2.2.4 This version fixes various bugs in 2.2.3 or before. __________________________________________________________________ * Bug fixes - Fix possible bug introduced in pgpool-II 2.2.2. Load balance control variables may remain not be restored and subsequent DML/DDL call might sent to only master node(Tatsuo Ishii) - Send NOTICE message to frontend periodically if V2 protocol is used. This is ifdef out since it affectes visible change to applications. 2.2.3 unconditionaly sends param packet to client even it uses version 2 protocol, which is apparentlt wrong. Also tweak checking period from 1 second to 30 seconds since 1 second seems too aggressive(Tatsuo Ishii) - Block signals before forking children rather after. Otherwise parent will be killed by failover signal if it receives a signal before establishing signal handler(Tatsuo Ishii) - Remove unnecessary spaces and tabs at the end of line(Jun Kuriyama) =============================================================================== 2.2.3 (urukiboshi) 2009/8/11 * Version 2.2.3 This version fixes various bugs in 2.2.2 or before. __________________________________________________________________ * Bug fixes - Fix child process death if one of backends is not available(Tatsuo Ishii). - Fix various parallel query bugs(Yoshiharu Mori) - Fix message corruption for kid mismatch error(Akio Ishida) - Now stetmemt_time works(Tatsuo Ishii) - Enhance health checking to detect postmaster stopping by SIGSTOP(Tatsuo Ishii) - Detect frontend abnormal exiting while waiting for reply from backend. This only works with V3 protocol(Tatsuo Ishii) - Do not start internal transaction if command is CLUSTER without arguments(Tatsuo Ishii) - Fix bug with COPY FROM in that backend process remains after COPY failed(Tatsuo Ishii) __________________________________________________________________ * Enhancements - Show last query for extended protocol(Akio Ishida) - Allow to compile sql/pgpool-recovery/pgpool-recovery.c with PostgreSQL 8.4(Tatsuo Ishii) =============================================================================== 2.2.2 (urukiboshi) 2009/5/5 * Version 2.2.2 This version fixes various bugs in 2.2.1 or before. Please note that an importan fix is made to avoid data incositency risk, which could happen when client does not exit gracely(without sending "X" packet) while pgpool is trying to send data to it. This could happen with all version of pgpool-II. __________________________________________________________________ * Bug fixes - Ignore write error on frontend connection. This is needed to continue processing with backend, otherwise we risk data incositency(Tatsuo Ishii) - Fix bug introduced in 2.2.1 (In master slave mode, sometimes DEALLOCATE fails). If prepared statement reused, pgpool hangs(Toshihiro Kitagawa) - Fix pgpool crash when SQL command PREPARE and protocol level EXECUTE are mixed. The bug was introduced in 2.2(Tatsuo Ishii) - Avoid "unexpected EOF on client connection" error in PostgreSQL when reset query fails(Tatsuo Ishii) =============================================================================== 2.2.1 (urukiboshi) 2009/4/25 * Version 2.2.1 This version fixes various bugs in 2.2. __________________________________________________________________ * Bug fixes - In master slave mode, sometimes DEALLOCATE fails. This is caused by that the first PREPARE was not executed on the slave(Toshihiro Kitagawa) - Update pgpool.spec along with related files(Devrim) - Fix inser_lock so that it is ignored when protocol version is 2(Tatsuo Ishii) - Remove excessive log messages regarding parameter change notice(Tatsuo Ishii) - Add missing files to doc(Tatsuo Ishii) =============================================================================== 2.2 (urukiboshi) 2009/2/28 * Version 2.2 This version enhances SERIAL data type handling and on line recovery. Also an important bug, serializable transactions could cause data inconsistency among DB nodes, is fixed. Query cancelation, which never worked since pgpool-II was born, is finally fixed. __________________________________________________________________ * New features/enhancements - With insert_lock, now a table is locked only if it has SERIAL data type and now the default value for insert_lock is true(Tatsuo Ishii) - Start internal transaction other than INSERT, UPDATE, DELETE and SELECT to keep node consistency(Tatsuo Ishii) - Add client_idle_limit_in_recovery directive. This will prevent 2nd stage of on line recovery from not going forward by idle clients sitting forever(Tatsuo Ishii) - Add pid_file_name directive which specifies a path to the file containing pgpool process id. "logdir" is no more used(Tatsuo Ishii) - Allow to load balance DECLARE, FETCH and CLOSE(Tatsuo Ishii) - Add -d option to pcp commands(Jun Kuriyama) - Enahnce kind mismatch error message to include originarl query string(Tatsuo Ishii) __________________________________________________________________ * Bug fixes - Close all file descriptors when running in daemon mode. Otherwise we inherit sockets from apache when it's started by pgpoolAdmin. This results in that port 80 is occupied for example. Patch provided by Akio Ishida. Also add chdir("/"). This is always good for daemon programs(Tatsuo Ishii) - Allow MD5 authentication in raw mode as stated in docs(Tatsuo Ishii) - Check transaction serialization failure error in serializable mode and abort all nodes if so. Otherwise we allow data inconsistency among DB nodes(Tatsuo Ishii). See following scenario: (M:master, S:slave) M:S1:BEGIN; M:S2:BEGIN; S:S1:BEGIN; S:S2:BEGIN; M:S1:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; M:S2:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; S:S1:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; S:S2:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; M:S1:UPDATE t1 SET i = i + 1; S:S1:UPDATE t1 SET i = i + 1; M:S2:UPDATE t1 SET i = i + 1; <-- blocked S:S1:COMMIT; M:S1:COMMIT; M:S2:ERROR: could not serialize access due to concurrent update S:S2:UPDATE t1 SET i = i + 1; <-- success in UPDATE and data becomes inconsistent! - avoid kind mismatch error caused by "SET TRANSACTION ISOLATION LEVEL must be called before any query"(Tatsuo Ishii). This could happen in following scenario: M:S1:BEGIN; S:S1:BEGIN; M:S1:SELECT 1; <-- only sent to MASTER M:S1:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; S:S1:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; M: <-- error S: <-- ok since no previous SELECT is sent. kind mismatch error occurs! - Process status display has extra space on FreeeBSD(Jun Kuriyama) - Fix incorrect kind mismatch detection case. e.g: BEGIN; BEGIN; (Tatsuo Ishii) - If PostgreSQL sends lots of DEBUG message, sometimes pgpool complains: 2008-11-08 22:41:53 ERROR: pid 23744: do_command: backend does not return ReadyForQuery. This due to a wrong assumption for the client/server protocol(Tatsuo Ishii) - Fix the case when sending an erronous query to abort transaction. It assumed that after sending an error query, always ReadyForQuery came right after that. If some debugging or logging verboseness is set, PostgreSQL might sends NOTICE before ReadyForQuery(Tatsuo Ishii) - Query cancelation now works. It never worked since pgpool-II was born(Tatsuo Ishii) - Fix online recovery to wait for failback done before allowing to accept connections from clients. It was supposed to work like this but actually was not since the day 0 when online recovery was born. Without the fix there could be potential data inconsistency among DB nodes(Tatsuo Ishii) - Fix pgpool-II crash after on line recovery. This happens after the failback process adds a recovered node which has no connection to the node(Tatsuo Ishii) - Fix pgpool-II errors when postgresql.conf is reloaded. This was caused by parameter status packet sent asynchronously from backend, which indicates the internal setting of backend has been changed(Tatsuo Ishii) __________________________________________________________________ * Incompatible changes - Always fail over and restart all children. Before we do restart only if master has not been changed. This is wrong. If we have trouble with network cable or something, TCP/IP stack keeps on retrying for long time and the only way to prevent it is restarting process(Tatsuo Ishii) - "logdir" is no more used. Instead use "pid_file_name"(Tatsuo Ishii) - Default value for insert_lock is now true(Tatsuo Ishii) =============================================================================== 2.1 Series (2008/07/25 - 2008/07/25) =============================================================================== 2.1 (inamiboshi) 2008/7/25 * Version 2.1 __________________________________________________________________ * New feature - Add '%m' format to failover_command and failback_command to obtain new master node ID. (Yoshiyuki Asaba) - Add '%m' format to failover_command and failback_command to obtain old master node ID. (Yoshiyuki Asaba) - Add new directive "recovery_timeout" to specify recovery timeout in second. (Taiki Yamaguchi) - Add optino '-v' to print pgpool version. (Yoshiyuki Asaba) __________________________________________________________________ * Incompatibility - Restrict pgpool_recovery() and pgpool_remote_start() functions to superusers. (Yoshiyuki Asaba) - Do not create a connection pool to standby node in raw mode. (Yoshiyuki Asaba) - Remove "replication_timeout" parameter. (Yoshiyuki Asaba) - This enabled if replication_strict was false. However, replication_strict was already removed. - Ignore timeout argument of pcp commands. (Taiki Yamaguchi) - Do not replicate "COPY TO STDOUT" when replicate_select is false. (Yoshiyuki Asaba) __________________________________________________________________ * Bug fix ** General - Fix crash when CloseComplete message was received. (Yoshiyuki Asaba) - Improve network I/O routine. (Yoshiyuki Asaba) - Fix compile errors on Solaris 10. (Yoshiyuki Asaba) - Improve log messages of health check and recovery. (Tatsuo Ishii) - Change error level of the "failed to read kind from frontend" message from ERROR to LOG. (Yoshiyuki Asaba) - Fix failover failure in raw mode. (Taiki Yamaguchi) - Fix zombie process bug. (Yoshiyuki Asaba) - Fix health_check_timeout to work correctly. (Kenichi Sawada) - Support ps status on FreeBSD. (ISHIDA Akio) - Improve bind(2) failure report. (Jun Kuriyama) - Improve error message when client authentication failed. (Tatsuo Ishii) ** Replication - Fix replicate_select to work correctly. (Tatsuo Ishii) - Fix a wrong rollback bug with extended query. (Yoshiyuki Asaba) - Fix a bug with asynchronous query. (Yoshiyuki Asaba) - Fix hint clause handling like /*REPLICATION*/ with extended query. (Yoshiyuki Asaba) - Fix crash of "DEALLOCATE ALL". (Yoshiyuki Asaba) - Fix hang up when a backend node does immediate shutdown. (Yoshiyuki Asaba) - Fix hang up online recovery in high load. (Yoshiyuki Asaba) - Fix hang up with extended query protocol when SELECT is failed inside a transaction block. (Yoshiyuki Asaba) ** Master Slave - Fix load balancing to work correctly. (Yoshiyuki Asaba) - Fix crash if SET, PREPARE or DEALLOCATE is executed inside a transaction block. (Yoshiyuki Asaba) ** Parallel query - Fix INSERT failure. (Yoshiharu Mori) - Fix syntax error when a query contains "AS" in FROM clause. (sho) - Fix Hung up when two or more statment was executed in parallel mode (Yoshiharu Mori) - Fix Query rewriting of Join Expression and DISTINCT ON (Yoshiharu Mori) =============================================================================== 2.0 Series (2007/11/16 - 2007/11/21) =============================================================================== 2.0.1 (hikitsuboshi) 2007/11/21 * Version 2.0.1 * Fix process down with UPDATE or DELETE query.(Yoshiyuki Asaba) * Send a syntax query only to a master node if master_slave is true.(Yoshiyuki Asaba) =============================================================================== 2.0 (hikitsuboshi) 2007/11/16 * Version 2.0 __________________________________________________________________ * Incompatibility since pgpool-II 1.x - the default value for ignore_leading_white_space is now true(Yoshiyuki Asaba) - replicate_strict is removed. The value is always true(Yoshiyuki Asaba) __________________________________________________________________ * General - Allow to reload pgpool.conf(Yoshiyuki Asaba) - The paraser is now compatible with PostgreSQL 8.3(Yoshiyuki Asaba) - Add new directive "failover_command" to specify command when a node is detached(Yoshiyuki Asaba) - Add new directive "client_idle_limit" to specify the time out since the last command is arrived from a client(Tatsuo Ishii) __________________________________________________________________ * Replication - Always start a new transaction even if the query is not in an explicit transaction to enhance the reliabilty of replication(Yoshiyuki Asaba) - Enhance the performance of replication for write queries. Now the worst case is 1/2 compared with single DB node regardless the number of DB nodes. Previous release tends to degrade according to the numer of DB nodes(Yoshiyuki Asaba) - Add "online recovery" which allows to add a DB node and sync with other DB nodes without stopping the pgpool server(Yoshiyuki Asaba) - Abort a transaction if INSERT, UPDATE and DELETE reports different number of result rows(Yoshiyuki Asaba) x=# update t set a = a + 1; ERROR: pgpool detected difference of the number of update tuples HINT: check data consistency between master and other db node - If the results from DB nodes do not match, select the possible correct result by "decide by majority". Previous release always trust the result of the master DB node(Yoshiyuki Asaba) - Allow load balance in V2 frontend/backend protocol(Yoshiyuki Asaba) __________________________________________________________________ * Parallel query - Allow "partial replication" to enhance the performance of the parallel query(Yoshiharu Mori) =============================================================================== 1.3 Series (2007/10/23 - 2007/10/23) =============================================================================== 1.3 (sohiboshi) 2007/10/23 * Version 1.3 * Add new "authentication_timeout" directive, being the default value is 60. (Yoshiyuki Asaba) - Maximum time in seconds to complete client authentication. * Reject a connection when startup packet length is greater than 10,000 byte. (Yoshiyuki Asaba) * Fix invalid memory access when pgpool processed DEALLOCATE statement. (Yoshiyuki Asaba) * Fix hang up in load balance mode. (Yoshiyuki Asaba) - This was introduced in V1.2. * Fix segmentation fault in 64-bit environment when query cache is enable. (Yoshiyuki Asaba) =============================================================================== 1.2 Series (2007/08/01 - 2007/09/28) =============================================================================== 1.2.1 (tomoboshi) 2007/09/28 * Version 1.2.1 * Fix deadlock while processing Parse message. (Yoshiyuki Asaba) * Fix memory leak in reset_prepared_list(). (Yoshiyuki Asaba) * Fix compile error on FreeBSD 4.11. (Yoshiyuki Asaba) * SET, PREPARE and DEALLOCATE statements are replicated in master/slave mode. (Yoshiyuki Asaba) =============================================================================== 1.2 (tomoboshi) 2007/08/01 * Version 1.2 * Add new "replicate_select" directive, being the default value is false. (Yoshiyuki Asaba) - If it is true, SELECT query is replicated. This behavior is same as V3.2 or earlier. * Improve signal handling. (Yoshiyuki Asaba) - Occasionaly, zombie processes were remained. Or processes were unstable. * Fix hang up when SELECT was error inside a transaction block. The bug was introduced in V3.3. (Yoshiyuki Asaba) * Fix PREPARE/EXECUTE handling in master slave mode. (Yoshiyuki Asaba) * Fix "kind mismatch error" when deadlock error * Fix hang up and SEGV in extended query protocol when a warning SQL like "SELECT '\'';" executed. (Yoshiyuki Asaba) * Fix hang up when postmaster did fast or immediate shutdown. (Yoshiyuki Asaba) * Fix memory leak when connection cache was full. (Yoshiyuki Asaba) * Load balancing node is selected when a session starts. (Yoshiyuki Asaba) * Fix buffer overrun if connection_life_time was set. (Yoshiyuki Asaba) =============================================================================== 1.1 Series (2007/5/25 - 2007/6/15) =============================================================================== 1.1.1 (amiboshi) 2007/6/15 * Version 1.1.1 * Fix "kind mismatch" bug when load_balance_mode is true introduced in 1.1 (Yoshiyuki Asaba) * Fix deadlock with extended query protocol(Yoshiyuki Asaba) * Fix numerous bugs with protocol V2(Yoshiyuki Asaba) =============================================================================== 1.1 (amiboshi) 2007/5/25 * Version 1.1 * Support HBA authentication(Taiki Yamaguchi) * Support log_connections(Taiki Yamaguchi) * Support log_hostname(Taiki Yamaguchi) * Show pgpool status in ps command(Taiki Yamaguchi) * Fix compile error on MacOS X(Yoshiyuki Asaba) * Allow load balancing with extended protocol(Yoshiyuki Asaba) * Improve replication. SELECT nextval() and SELECT setval() are now replicated. (Yoshiyuki Asaba) * Change SELECT query is only sent to the master node. (Yoshiyuki Asaba) - Use /*REPLICATION*/ comment to repliate a SELECT query. * Fix unexpected failover error due to receiving an interrupt signal while connecting to the backend. (Yoshiyuki Asaba) * Add "pgpool.pam" file, for PAM configuration file, to be installed under "$PREFIX/share/pgpool-II/". (Taiki Yamaguchi) * Fix core dump when executing large SQL. (Yoshiyuki Asaba) =============================================================================== 1.0 Series (2006/09/08 - 2007/02/12) =============================================================================== 1.0.2 (suboshi) 2007/02/12 * Version 1.0.2 * Fix bug when executing large SQL to prevent pgpool goes into infinite loop(Yoshiyuki Asaba) * Fix bug with extended protocol handling(Yoshiyuki Asaba) * Enhance log for failover and failback(Tatsuo Ishii) * Add backend status info to show pool_status(Tatsuo Ishii) * Fix UPDATE/DELETE returns wrong number of rows(Tatsuo Ishii) * Fix configure fails to link libpq when used with older version of gcc(Yoshiyuki Asaba) * Fix DEALLOCATE treatment when used with PHP:PDO DBD-Pg(Yoshiyuki Asaba) * Do not load balance SELECT FOR UPDATE, SELECT INTO and SELECT with comments. This behavior is compatible with pgpool-I(Yoshiyuki Asaba) * Obtain path to libpq using pg_config. --with-pgsql will be removed in next version(Yoshiyuki Asaba) * When reusing connection pool, reconnect to backend if the socket is broken(Yoshiyuki Asaba) * Fix error with configure when used with PostgreSQL 7.4(Yoshiyuki Asaba) =============================================================================== 1.0.1 (suboshi) 2006/09/22 * Version 1.0.1 * This version fixes bugs including master/slave not being working, deadlock problem in COPY FROM STDIN. Also documents are improved. =============================================================================== 1.0.0 (suboshi) 2006/09/08 * Initial release Local Variables: mode: outline End: pgpool-II-3.3.2/version.h0000664000076400007640000000004412245576267012125 00000000000000#define PGPOOLVERSION "tokakiboshi" pgpool-II-3.3.2/pool_lobj.h0000664000076400007640000000215612245576256012423 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2010 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_lobj.h.: pool_lobj.c related header file * */ #ifndef POOL_LOBJ_H #define POOL_LOBJ_H #include "pool.h" extern char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int* len); #endif /* POOL_LOBJ_H */ pgpool-II-3.3.2/pool_process_reporting.h0000664000076400007640000000376212245576267015252 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_process_reporting.h.: header file for pool_process_reporting.c * */ #ifndef POOL_PROCESS_REPORTING_H #define POOL_PROCESS_REPORTING_H extern void send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, short num_fields, char **field_names); extern void send_complete_and_ready(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const int num_rows); extern POOL_REPORT_CONFIG* get_config(int *nrows); extern POOL_REPORT_POOLS* get_pools(int *nrows); extern POOL_REPORT_PROCESSES* get_processes(int *nrows); extern POOL_REPORT_NODES* get_nodes(int *nrows); extern POOL_REPORT_VERSION* get_version(void); extern void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern void pools_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern void processes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern void nodes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern void version_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern void cache_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); #endif pgpool-II-3.3.2/pool_path.h0000664000076400007640000000547712245576256012442 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2008, PgPool Global Development Group * Portions Copyright (c) 2004, PostgreSQL Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_path.h.: interface to pool_path.c * */ #ifndef POOL_PATH_H #define POOL_PATH_H /* * MAXPGPATH: standard size of a pathname buffer in PostgreSQL (hence, * maximum usable pathname length is one less). * * We'd use a standard system header symbol for this, if there weren't * so many to choose from: MAXPATHLEN, MAX_PATH, PATH_MAX are all * defined by different "standards", and often have different values * on the same platform! So we just punt and use a reasonably * generous setting here. */ #define MAXPGPATH 1024 #define IS_DIR_SEP(ch) ((ch) == '/') #define is_absolute_path(filename) \ ( \ ((filename)[0] == '/') \ ) /* * StrNCpy * Like standard library function strncpy(), except that result string * is guaranteed to be null-terminated --- that is, at most N-1 bytes * of the source string will be kept. * Also, the macro returns no result (too hard to do that without * evaluating the arguments multiple times, which seems worse). * * BTW: when you need to copy a non-null-terminated string (like a text * datum) and add a null, do not do it with StrNCpy(..., len+1). That * might seem to work, but it fetches one byte more than there is in the * text object. One fine day you'll have a SIGSEGV because there isn't * another byte before the end of memory. Don't laugh, we've had real * live bug reports from real live users over exactly this mistake. * Do it honestly with "memcpy(dst,src,len); dst[len] = '\0';", instead. */ #define StrNCpy(dst,src,len) \ do \ { \ char * _dst = (dst); \ size_t _len = (len); \ \ if (_len > 0) \ { \ strncpy(_dst, (src), _len); \ _dst[_len-1] = '\0'; \ } \ } while (0) extern void get_parent_directory(char *path); extern void join_path_components(char *ret_path, const char *head, const char *tail); extern void canonicalize_path(char *path); #endif /* POOL_PATH_H */ pgpool-II-3.3.2/pool_auth.c0000664000076400007640000007701612245576266012441 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_auth.c: authentication stuff * */ #include "pool.h" #include "pool_stream.h" #include "pool_config.h" #include "pool_passwd.h" #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_PARAM_H #include #endif #include #include #include #define AUTHFAIL_ERRORCODE "28000" static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid, int key, int protoMajor); static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); static void pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp); static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); static int send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt); static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize); static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password); static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor); /* * After sending the start up packet to the backend, do the * authentication against backend. if success return 0 otherwise non * 0. */ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { signed char kind; int pid; int key; int protoMajor; int length; int authkind; int i; StartupPacket *sp; protoMajor = MAJOR(cp); kind = pool_read_kind(cp); if (kind < 0) { return -1; } /* error response? */ if (kind == 'E') { /* we assume error response at this stage is likely version * protocol mismatch (v3 frontend vs. v2 backend). So we throw * a V2 protocol error response in the hope that v3 frontend * will negotiate again using v2 protocol. */ pool_log("pool_do_auth: maybe protocol version mismatch (current version %d)", protoMajor); ErrorResponse(frontend, cp); return -1; } else if (kind != 'R') { pool_error("pool_do_auth: expect \"R\" got %c", kind); return -1; } /* * message length (v3 only) */ if (protoMajor == PROTO_MAJOR_V3 && pool_read_message_length(cp) < 0) { pool_error("Failed to read the authentication packet length. \ This is likely caused by the inconsistency of auth method among DB nodes. \ In this case you can check the previous error messages (hint: length field) \ from pool_read_message_length and recheck the pg_hba.conf settings."); return -1; } /* * read authentication request kind. * * 0: authentication ok * 1: kerberos v4 * 2: kerberos v5 * 3: clear text password * 4: crypt password * 5: md5 password * 6: scm credential * * in replication mode, we only support kind = 0, 3. this is because "salt" * cannot be replicated. * in non replication mode, we support kind = 0, 3, 4, 5 */ authkind = pool_read_int(cp); if (authkind < 0) { pool_error("pool_do_auth: read auth kind failed"); return -1; } authkind = ntohl(authkind); pool_debug("pool_do_auth: auth kind:%d", authkind); /* trust? */ if (authkind == 0) { int msglen; pool_write(frontend, "R", 1); if (protoMajor == PROTO_MAJOR_V3) { msglen = htonl(8); pool_write(frontend, &msglen, sizeof(msglen)); } msglen = htonl(0); if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0) { return -1; } MASTER(cp)->auth_kind = 0; } /* clear text password authentication? */ else if (authkind == 3) { for (i=0;iauth_method != uaMD5 && !RAW_MODE && NUM_BACKENDS > 1) { pool_send_error_message(frontend, protoMajor, AUTHFAIL_ERRORCODE, "MD5 authentication is unsupported in replication, master-slave and parallel modes.", "", "check pg_hba.conf", __FILE__, __LINE__); return -1; } for (i=0;isp; pid = -1; for (i=0;iinfo[i]:%p pid:%u", &cp->info[i], ntohl(pid)); CONNECTION_SLOT(cp, i)->pid = cp->info[i].pid = pid; /* read key */ if (pool_read(CONNECTION(cp, i), &key, sizeof(key)) < 0) { pool_error("pool_do_auth: failed to read key in slot %d", i); return -1; } CONNECTION_SLOT(cp, i)->key = cp->info[i].key = key; cp->info[i].major = sp->major; cp->info[i].minor = sp->minor; strlcpy(cp->info[i].database, sp->database, sizeof(cp->info[i].database)); strlcpy(cp->info[i].user, sp->user, sizeof(cp->info[i].user)); cp->info[i].counter = 1; } } if (pid == -1) { pool_error("pool_do_auth: all backends are down"); return -1; } return pool_send_backend_key_data(frontend, pid, key, protoMajor); } /* * do re-authentication for reused connection. if success return 0 otherwise non 0. */ int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { int status; int protoMajor; protoMajor = MAJOR(cp); switch(MASTER(cp)->auth_kind) { case 0: /* trust */ status = 0; break; case 3: /* clear text password */ status = do_clear_text_password(MASTER(cp), frontend, 1, protoMajor); break; case 4: /* crypt password */ status = do_crypt(MASTER(cp), frontend, 1, protoMajor); break; case 5: /* md5 password */ status = do_md5(MASTER(cp), frontend, 1, protoMajor); break; default: pool_error("pool_do_reauth: unknown authentication request code %d", MASTER(cp)->auth_kind); return -1; } if (status == 0) { int msglen; pool_write(frontend, "R", 1); if (protoMajor == PROTO_MAJOR_V3) { msglen = htonl(8); pool_write(frontend, &msglen, sizeof(msglen)); } msglen = htonl(0); if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0) { return -1; } } else { pool_debug("pool_do_reauth: authentication failed"); pool_send_auth_fail(frontend, cp); return -1; } return (pool_send_backend_key_data(frontend, MASTER_CONNECTION(cp)->pid, MASTER_CONNECTION(cp)->key, protoMajor) != POOL_CONTINUE); } /* * send authentication failure message text to frontend */ static void pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { int messagelen; char *errmessage; int protoMajor; bool send_error_to_frontend = true; protoMajor = MAJOR(cp); messagelen = strlen(MASTER_CONNECTION(cp)->sp->user) + 100; if ((errmessage = (char *)malloc(messagelen+1)) == NULL) { pool_error("pool_send_auth_fail_failed: malloc failed: %s", strerror(errno)); child_exit(1); } snprintf(errmessage, messagelen, "password authentication failed for user \"%s\"", MASTER_CONNECTION(cp)->sp->user); if (send_error_to_frontend) pool_send_fatal_message(frontend, protoMajor, "XX000", errmessage, "", "", __FILE__, __LINE__); free(errmessage); } /* * Send backend key data to frontend. if success return 0 otherwise non 0. */ static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid, int key, int protoMajor) { char kind; int len; /* Send backend key data */ kind = 'K'; pool_write(frontend, &kind, 1); if (protoMajor == PROTO_MAJOR_V3) { len = htonl(12); pool_write(frontend, &len, sizeof(len)); } pool_debug("pool_send_auth_ok: send pid %d to frontend", ntohl(pid)); pool_write(frontend, &pid, sizeof(pid)); if (pool_write_and_flush(frontend, &key, sizeof(key)) < 0) { return -1; } return 0; } /* * perform clear text password authentication */ static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) { static int size; static char password[MAX_PASSWORD_SIZE]; char response; int kind; int len; /* master? */ if (IS_MASTER_NODE_ID(backend->db_node_id)) { pool_write(frontend, "R", 1); /* authentication */ if (protoMajor == PROTO_MAJOR_V3) { len = htonl(8); pool_write(frontend, &len, sizeof(len)); } kind = htonl(3); /* clear text password authentication */ pool_write_and_flush(frontend, &kind, sizeof(kind)); /* indicating clear text password authentication */ /* read password packet */ if (protoMajor == PROTO_MAJOR_V2) { if (pool_read(frontend, &size, sizeof(size))) { pool_debug("do_clear_text_password: failed to read password packet size"); return -1; } } else { char k; if (pool_read(frontend, &k, sizeof(k))) { pool_debug("do_clear_text_password: failed to read password packet \"p\""); return -1; } if (k != 'p') { pool_error("do_clear_text_password: password packet does not start with \"p\""); return -1; } if (pool_read(frontend, &size, sizeof(size))) { pool_error("do_clear_text_password: failed to read password packet size"); return -1; } } if ((ntohl(size) - 4) > sizeof(password)) { pool_error("do_clear_text_password: password is too long (size: %d)", ntohl(size) - 4); return -1; } if (pool_read(frontend, password, ntohl(size) - 4)) { pool_error("do_clear_text_password: failed to read password (size: %d)", ntohl(size) - 4); return -1; } } /* connection reusing? */ if (reauth) { if ((ntohl(size) - 4) != backend->pwd_size) { pool_debug("do_clear_text_password; password size does not match in re-authentication"); return -1; } if (memcmp(password, backend->password, backend->pwd_size) != 0) { pool_debug("do_clear_text_password; password does not match in re-authentication"); return -1; } return 0; } /* send password packet to backend */ if (protoMajor == PROTO_MAJOR_V3) pool_write(backend, "p", 1); pool_write(backend, &size, sizeof(size)); pool_write_and_flush(backend, password, ntohl(size) -4); if (pool_read(backend, &response, sizeof(response))) { pool_error("do_clear_text_password: failed to read authentication response"); return -1; } if (response != 'R') { pool_debug("do_clear_text_password: backend does not return R while processing clear text password authentication"); return -1; } if (protoMajor == PROTO_MAJOR_V3) { if (pool_read(backend, &len, sizeof(len))) { pool_error("do_clear_text_password: failed to read authentication packet size"); return -1; } if (ntohl(len) != 8) { pool_error("do_clear_text_password: incorrect authentication packet size (%d)", ntohl(len)); return -1; } } /* expect to read "Authentication OK" response. kind should be 0... */ if (pool_read(backend, &kind, sizeof(kind))) { pool_debug("do_clear_text_password: failed to read Authentication OK response"); return -1; } /* if authenticated, save info */ if (!reauth && kind == 0) { if (IS_MASTER_NODE_ID(backend->db_node_id)) { int msglen; pool_write(frontend, "R", 1); if (protoMajor == PROTO_MAJOR_V3) { msglen = htonl(8); pool_write(frontend, &msglen, sizeof(msglen)); } msglen = htonl(0); if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0) { return -1; } } backend->auth_kind = 3; backend->pwd_size = ntohl(size) - 4; memcpy(backend->password, password, backend->pwd_size); } return kind; } /* * perform crypt authentication */ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) { char salt[2]; static int size; static char password[MAX_PASSWORD_SIZE]; char response; int kind; int len; if (!reauth) { /* read salt */ if (pool_read(backend, salt, sizeof(salt))) { pool_error("do_crypt: failed to read salt"); return -1; } } else { memcpy(salt, backend->salt, sizeof(salt)); } /* master? */ if (IS_MASTER_NODE_ID(backend->db_node_id)) { pool_write(frontend, "R", 1); /* authentication */ if (protoMajor == PROTO_MAJOR_V3) { len = htonl(10); pool_write(frontend, &len, sizeof(len)); } kind = htonl(4); /* crypt authentication */ pool_write(frontend, &kind, sizeof(kind)); /* indicating crypt authentication */ pool_write_and_flush(frontend, salt, sizeof(salt)); /* salt */ /* read password packet */ if (protoMajor == PROTO_MAJOR_V2) { if (pool_read(frontend, &size, sizeof(size))) { pool_error("do_crypt: failed to read password packet size"); return -1; } } else { char k; if (pool_read(frontend, &k, sizeof(k))) { pool_debug("do_crypt_password: failed to read password packet \"p\""); return -1; } if (k != 'p') { pool_error("do_crypt_password: password packet does not start with \"p\""); return -1; } if (pool_read(frontend, &size, sizeof(size))) { pool_error("do_crypt_password: failed to read password packet size"); return -1; } } if ((ntohl(size) - 4) > sizeof(password)) { pool_error("do_crypt: password is too long(size: %d)", ntohl(size) - 4); return -1; } if (pool_read(frontend, password, ntohl(size) - 4)) { pool_error("do_crypt: failed to read password (size: %d)", ntohl(size) - 4); return -1; } } /* connection reusing? */ if (reauth) { pool_debug("size: %d saved_size: %d", (ntohl(size) - 4), backend->pwd_size); if ((ntohl(size) - 4) != backend->pwd_size) { pool_debug("do_crypt: password size does not match in re-authentication"); return -1; } if (memcmp(password, backend->password, backend->pwd_size) != 0) { pool_debug("do_crypt: password does not match in re-authentication"); return -1; } return 0; } /* send password packet to backend */ if (protoMajor == PROTO_MAJOR_V3) pool_write(backend, "p", 1); pool_write(backend, &size, sizeof(size)); pool_write_and_flush(backend, password, ntohl(size) -4); if (pool_read(backend, &response, sizeof(response))) { pool_error("do_crypt: failed to read authentication response"); return -1; } if (response != 'R') { pool_debug("do_crypt: backend does not return R while processing crypt authentication(%02x) DB node id: %d", response, backend->db_node_id); return -1; } if (protoMajor == PROTO_MAJOR_V3) { if (pool_read(backend, &len, sizeof(len))) { pool_error("do_crypt: failed to read authentication packet size"); return -1; } if (ntohl(len) != 8) { pool_error("do_crypt: incorrect authentication packet size (%d)", ntohl(len)); return -1; } } /* expect to read "Authentication OK" response. kind should be 0... */ if (pool_read(backend, &kind, sizeof(kind))) { pool_debug("do_crypt: failed to read Authentication OK response"); return -1; } /* if authenticated, save info */ if (!reauth && kind == 0) { int msglen; pool_write(frontend, "R", 1); if (protoMajor == PROTO_MAJOR_V3) { msglen = htonl(8); pool_write(frontend, &msglen, sizeof(msglen)); } msglen = htonl(0); if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0) { return -1; } backend->auth_kind = 4; backend->pwd_size = ntohl(size) - 4; memcpy(backend->password, password, backend->pwd_size); memcpy(backend->salt, salt, sizeof(salt)); } return kind; } /* * perform MD5 authentication */ static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) { char salt[4]; static int size; static char password[MAX_PASSWORD_SIZE]; int kind; char encbuf[POOL_PASSWD_LEN+1]; char *pool_passwd = NULL; if (NUM_BACKENDS > 1) { /* Read password entry from pool_passwd */ pool_passwd = pool_get_passwd(frontend->username); if (!pool_passwd) { pool_debug("do_md5: %s does not exist in pool_passwd", frontend->username); return -1; } /* master? */ if (IS_MASTER_NODE_ID(backend->db_node_id)) { /* Send md5 auth request to frontend with my own salt */ pool_random_salt(salt); if (send_md5auth_request(frontend, protoMajor, salt)) { pool_error("do_md5: send_md5auth_request failed"); return -1; } /* Read password packet */ if (read_password_packet(frontend, protoMajor, password, &size)) { pool_debug("do_md5: read_password_packet failed"); return -1; } /* Check the password using my salt + pool_passwd */ pg_md5_encrypt(pool_passwd+strlen("md5"), salt, sizeof(salt), encbuf); if (strcmp(password, encbuf)) { /* Password does not match */ pool_debug("password does not match: frontend:%s pgpool:%s", password, encbuf); return -1; } } kind = 0; if (!reauth) { /* * If ok, authenticate against backends using pool_passwd */ /* Read salt */ if (pool_read(backend, salt, sizeof(salt))) { pool_error("do_md5: failed to read salt"); return -1; } pool_debug("DB node id: %d salt: %hhx%hhx%hhx%hhx", backend->db_node_id, salt[0], salt[1], salt[2], salt[3]); /* Encrypt password in pool_passwd using the salt */ pg_md5_encrypt(pool_passwd+strlen("md5"), salt, sizeof(salt), encbuf); /* Send password packet to backend and receive auth response */ kind = send_password_packet(backend, protoMajor, encbuf); if (kind < 0) { return -1; } } if (!reauth && kind == 0) { if (IS_MASTER_NODE_ID(backend->db_node_id)) { /* Send auth ok to frontend */ if (send_auth_ok(frontend, protoMajor) < 0) { pool_error("do_md5: send_auth_ok failed"); return -1; } } /* Save the auth info */ backend->auth_kind = 5; } return kind; } /* * Followings are NUM_BACKEND == 1 case. */ if (!reauth) { /* read salt */ if (pool_read(backend, salt, sizeof(salt))) { pool_error("do_md5: failed to read salt"); return -1; } pool_debug("DB node id: %d salt: %hhx%hhx%hhx%hhx", backend->db_node_id, salt[0], salt[1], salt[2], salt[3]); } else { memcpy(salt, backend->salt, sizeof(salt)); } /* master? */ if (IS_MASTER_NODE_ID(backend->db_node_id)) { /* Send md5 auth request to frontend */ if (send_md5auth_request(frontend, protoMajor, salt)) { pool_error("do_md5: send_md5auth_request failed"); return -1; } /* Read password packet */ if (read_password_packet(frontend, protoMajor, password, &size)) { pool_debug("do_md5: read_password_packet failed"); return -1; } } /* connection reusing? */ if (reauth) { if (size != backend->pwd_size) { pool_debug("do_md5; password size does not match in re-authentication"); return -1; } if (memcmp(password, backend->password, backend->pwd_size) != 0) { pool_debug("do_md5; password does not match in re-authentication"); return -1; } return 0; } /* Send password packet to backend and receive auth response */ kind = send_password_packet(backend, protoMajor, password); if (kind < 0) { return -1; } /* If authenticated, reply back to frontend and save info */ if (!reauth && kind == 0) { if (send_auth_ok(frontend, protoMajor) < 0) { pool_error("do_md5: send_auth_ok failed"); return -1; } backend->auth_kind = 5; backend->pwd_size = size; memcpy(backend->password, password, backend->pwd_size); memcpy(backend->salt, salt, sizeof(salt)); } return kind; } /* * Send md5 authentication request packet to frontend */ static int send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt) { int len; int kind; pool_write(frontend, "R", 1); /* authentication */ if (protoMajor == PROTO_MAJOR_V3) { len = htonl(12); pool_write(frontend, &len, sizeof(len)); } kind = htonl(5); pool_write(frontend, &kind, sizeof(kind)); /* indicating MD5 */ pool_write_and_flush(frontend, salt, 4); /* salt */ return 0; } /* * Read password packet from frontend */ static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize) { int size; /* Read password packet */ if (protoMajor == PROTO_MAJOR_V2) { if (pool_read(frontend, &size, sizeof(size))) { pool_error("read_password_packet: failed to read password packet size"); return -1; } } else { char k; if (pool_read(frontend, &k, sizeof(k))) { pool_debug("read_password_packet: failed to read password packet \"p\""); return -1; } if (k != 'p') { pool_error("read_password_packet: password packet does not start with \"p\""); return -1; } if (pool_read(frontend, &size, sizeof(size))) { pool_error("read_password_packet: failed to read password packet size"); return -1; } } *pwdSize = ntohl(size) - 4; if (*pwdSize > MAX_PASSWORD_SIZE) { pool_error("read_password_packet: too long password string (size: %d)", *pwdSize); /* * We do not read to throw away packet here. Since it is possible that * it's a denial of service attack. */ return -1; } else if (*pwdSize <= 0) { pool_error("read_password_packet: invalid password string size (size: %d)", *pwdSize); return -1; } if (pool_read(frontend, password, *pwdSize)) { pool_error("read_password_packet: failed to read password (size: %d)", *pwdSize); return -1; } password[*pwdSize] = '\0'; return 0; } /* * Send password packet to backend and receive authentication response * packet. Return value is the last field of authentication * response. If it's 0, authentication was successful. * "password" must be null-terminated. */ static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password) { int size; int len; int kind; char response; /* Send password packet to backend */ if (protoMajor == PROTO_MAJOR_V3) pool_write(backend, "p", 1); size = htonl(sizeof(size) + strlen(password)+1); pool_write(backend, &size, sizeof(size)); pool_write_and_flush(backend, password, strlen(password)+1); if (pool_read(backend, &response, sizeof(response))) { pool_error("send_password_packet: failed to read authentication response"); return -1; } if (response != 'R') { pool_debug("send_password_packet: backend does not return R"); return -1; } if (protoMajor == PROTO_MAJOR_V3) { if (pool_read(backend, &len, sizeof(len))) { pool_error("send_password_packet: failed to read authentication packet size"); return -1; } if (ntohl(len) != 8) { pool_error("send_password_packet: incorrect authentication packet size (%d)", ntohl(len)); return -1; } } /* Expect to read "Authentication OK" response. kind should be 0... */ if (pool_read(backend, &kind, sizeof(kind))) { pool_debug("send_password_packet: failed to read Authentication OK response"); return -1; } return kind; } /* * Send auth ok to frontend */ static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor) { int msglen; pool_write(frontend, "R", 1); if (protoMajor == PROTO_MAJOR_V3) { msglen = htonl(8); pool_write(frontend, &msglen, sizeof(msglen)); } msglen = htonl(0); if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0) { return -1; } return 0; } /* * read message length (V3 only) */ int pool_read_message_length(POOL_CONNECTION_POOL *cp) { int status; int length, length0; int i; /* read message from master node */ status = pool_read(CONNECTION(cp, MASTER_NODE_ID), &length0, sizeof(length0)); if (status < 0) { pool_error("pool_read_message_length: error while reading message length in slot %d", MASTER_NODE_ID); return -1; } length0 = ntohl(length0); pool_debug("pool_read_message_length: slot: %d length: %d", MASTER_NODE_ID, length0); for (i=0;i 0 # (change requires restart) # -- heartbeat mode -- wd_heartbeat_port = 9694 # Port number for receiving heartbeat signal # (change requires restart) wd_heartbeat_keepalive = 2 # Interval time of sending heartbeat signal (sec) # (change requires restart) wd_heartbeat_deadtime = 30 # Deadtime interval for heartbeat signal (sec) # (change requires restart) heartbeat_destination0 = 'host0_ip1' # Host name or IP address of destination 0 # for sending heartbeat signal. # (change requires restart) heartbeat_destination_port0 = 9694 # Port number of destination 0 for sending # heartbeat signal. Usually this is the # same as wd_heartbeat_port. # (change requires restart) heartbeat_device0 = '' # Name of NIC device (such like 'eth0') # used for sending/receiving heartbeat # signal to/from destination 0. # This works only when this is not empty # and pgpool has root privilege. # (change requires restart) #heartbeat_destination1 = 'host0_ip2' #heartbeat_destination_port1 = 9694 #heartbeat_device1 = '' # -- query mode -- wd_life_point = 3 # lifecheck retry times # (change requires restart) wd_lifecheck_query = 'SELECT 1' # lifecheck query to pgpool from watchdog # (change requires restart) wd_lifecheck_dbname = 'template1' # Database name connected for lifecheck # (change requires restart) wd_lifecheck_user = 'nobody' # watchdog user monitoring pgpools in lifecheck # (change requires restart) wd_lifecheck_password = '' # Password for watchdog user in lifecheck # (change requires restart) # - Other pgpool Connection Settings - #other_pgpool_hostname0 = 'host0' # Host name or IP address to connect to for other pgpool 0 # (change requires restart) #other_pgpool_port0 = 5432 # Port number for othet pgpool 0 # (change requires restart) #other_wd_port0 = 9000 # Port number for othet watchdog 0 # (change requires restart) #other_pgpool_hostname1 = 'host1' #other_pgpool_port1 = 5432 #other_wd_port1 = 9000 #------------------------------------------------------------------------------ # OTHERS #------------------------------------------------------------------------------ relcache_expire = 0 # Life time of relation cache in seconds. # 0 means no cache expiration(the default). # The relation cache is used for cache the # query result against PostgreSQL system # catalog to obtain various information # including table structures or if it's a # temporary table or not. The cache is # maintained in a pgpool child local memory # and being kept as long as it survives. # If someone modify the table by using # ALTER TABLE or some such, the relcache is # not consistent anymore. # For this purpose, cache_expiration # controls the life time of the cache. relcache_size = 256 # Number of relation cache # entry. If you see frequently: # "pool_search_relcache: cache replacement happend" # in the pgpool log, you might want to increate this number. check_temp_table = on # If on, enable temporary table check in SELECT statements. # This initiates queries against system catalog of primary/master # thus increases load of master. # If you are absolutely sure that your system never uses temporary tables # and you want to save access to primary/master, you could turn this off. # Default is on. #------------------------------------------------------------------------------ # ON MEMORY QUERY MEMORY CACHE #------------------------------------------------------------------------------ memory_cache_enabled = off # If on, use the memory cache functionality, off by default memqcache_method = 'shmem' # Cache storage method. either 'shmem'(shared memory) or # 'memcached'. 'shmem' by default # (change requires restart) memqcache_memcached_host = 'localhost' # Memcached host name or IP address. Mandatory if # memqcache_method = 'memcached'. # Defaults to localhost. # (change requires restart) memqcache_memcached_port = 11211 # Memcached port number. Mondatory if memqcache_method = 'memcached'. # Defaults to 11211. # (change requires restart) memqcache_total_size = 67108864 # Total memory size in bytes for storing memory cache. # Mandatory if memqcache_method = 'shmem'. # Defaults to 64MB. # (change requires restart) memqcache_max_num_cache = 1000000 # Total number of cache entries. Mandatory # if memqcache_method = 'shmem'. # Each cache entry consumes 48 bytes on shared memory. # Defaults to 1,000,000(45.8MB). # (change requires restart) memqcache_expire = 0 # Memory cache entry life time specified in seconds. # 0 means infinite life time. 0 by default. # (change requires restart) memqcache_auto_cache_invalidation = on # If on, invalidation of query cache is triggered by corresponding # DDL/DML/DCL(and memqcache_expire). If off, it is only triggered # by memqcache_expire. on by default. # (change requires restart) memqcache_maxcache = 409600 # Maximum SELECT result size in bytes. # Must be smaller than memqcache_cache_block_size. Defaults to 400KB. # (change requires restart) memqcache_cache_block_size = 1048576 # Cache block size in bytes. Mandatory if memqcache_method = 'shmem'. # Defaults to 1MB. # (change requires restart) memqcache_oiddir = '/var/log/pgpool/oiddir' # Temporary work directory to record table oids # (change requires restart) white_memqcache_table_list = '' # Comma separated list of table names to memcache # that don't write to database # Regexp are accepted black_memqcache_table_list = '' # Comma separated list of table names not to memcache # that don't write to database # Regexp are accepted pgpool-II-3.3.2/Makefile.am0000664000076400007640000001645312245576266012335 00000000000000bin_PROGRAMS = pgpool pg_md5 pgpool_SOURCES = pool.h pool_type.h version.h pgpool.conf.sample \ pgpool.conf.sample-replication pgpool.conf.sample-master-slave \ pgpool.conf.sample-stream \ README.euc_jp README.online-recovery pgpool.spec \ main.c child.c pool_auth.c pool_config.l pool_config.h pool_error.c \ pool_process_query.c pool_stream.c pool_stream.h pool_connection_pool.c pool_params.c \ pool_signal.h pool_signal.c pcp_child.c md5.c md5.h pcp.conf.sample \ pool_ipc.h pool_shmem.c pool_sema.c pool_system.c \ pool_rewrite_query.c pool_rewrite_query.h pool_rewrite_outfuncs.c \ pool_query_cache.c pool_hba.conf.sample sample/pgpool.pam\ pool_hba.c pool_path.h pool_path.c pool_ip.h pool_ip.c pool_type.h \ ps_status.c strlcpy.c recovery.c pool_relcache.c pool_relcache.h pool_process_reporting.c \ pool_ssl.c pool_timestamp.c pool_timestamp.h \ pool_proto2.c pool_proto_modules.c pool_proto_modules.h \ pool_lobj.c pool_lobj.h \ pool_process_context.c pool_process_context.h \ pool_memqcache.c pool_memqcache.h \ pool_session_context.c pool_session_context.h \ pool_query_context.c pool_query_context.h \ pool_worker_child.c \ pool_passwd.c pool_passwd.h \ pool_globals.c \ pool_select_walker.c pool_select_walker.h \ getopt_long.c getopt_long.h pg_md5_SOURCES = pg_md5.c md5.c md5.h \ pool.h \ pool_config_md5.c pool_config.h \ pool_error.c \ pool_signal.h pool_signal.c \ pool_passwd.c pool_passwd.h \ pool_globals.c strlcpy.c DEFS = @DEFS@ \ -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" sysconf_DATA = pgpool.conf.sample pcp.conf.sample pool_hba.conf.sample \ pgpool.conf.sample-replication pgpool.conf.sample-master-slave \ pgpool.conf.sample-stream pkgdata_DATA = sql/insert_lock.sql sql/system_db.sql sample/pgpool.pam AM_CPPFLAGS = -D_GNU_SOURCE -I @PGSQL_INCLUDE_DIR@ # suggested by libtoolize ACLOCAL_AMFLAGS = -I m4 pgpool_LDADD = -L@PGSQL_LIB_DIR@ -lpq parser/libsql-parser.a pcp/libpcp.la parser/nodes.o watchdog/lib-watchdog.a -lpthread if enable_rpath pgpool_LDFLAGS = -rpath @PGSQL_LIB_DIR@ -rpath $(libdir) else pgpool_LDFLAGS = endif AM_YFLAGS = -d man_MANS = pgpool.8 pgpool.8: pgpool.8.in sed 's,@sysconfdir\@,$(sysconfdir),g' $? >$@ CLEANFILES = pgpool.8 EXTRA_DIST = pgpool.8.in sample/pgpool.pam \ doc/pgpool-ja.html doc/pgpool-en.html doc/pgpool-zh_cn.html \ doc/wd-ja.jpg doc/wd-en.jpg \ doc/tutorial-ja.html doc/tutorial-en.html doc/tutorial-zh_cn.html \ doc/pgpool.css doc/pgpool-ja.css \ doc/where_to_send_queries.pdf doc/where_to_send_queries.odg \ doc/basebackup.sh doc/pgpool_remote_start doc/recovery.conf.sample \ sample/pgpool_remote_start sample/pgpool_recovery sample/pgpool_recovery_pitr \ sample/dist_def_pgbench.sql sample/replicate_def_pgbench.sql \ sql/Makefile \ sql/insert_lock.sql sql/system_db.sql \ sql/pgpool-recovery/pgpool-recovery.c \ sql/pgpool-recovery/pgpool-recovery.sql.in \ sql/pgpool-recovery/uninstall_pgpool-recovery.sql \ sql/pgpool-recovery/pgpool_recovery--1.0.sql \ sql/pgpool-recovery/pgpool_recovery.control \ sql/pgpool-recovery/Makefile \ sql/pgpool-regclass/pgpool-regclass.c \ sql/pgpool-regclass/pgpool-regclass.sql.in \ sql/pgpool-regclass/uninstall_pgpool-regclass.sql \ sql/pgpool-regclass/pgpool_regclass--1.0.sql \ sql/pgpool-regclass/pgpool_regclass.control \ sql/pgpool-regclass/Makefile \ pgpool_adm/Makefile pgpool_adm/TODO pgpool_adm/pgpool_adm--1.0.sql \ pgpool_adm/pgpool_adm.c pgpool_adm/pgpool_adm.control \ pgpool_adm/pgpool_adm.h pgpool_adm/pgpool_adm.sql.in \ test/parser/expected/copy.out test/parser/expected/create.out \ test/parser/expected/cursor.out test/parser/expected/delete.out \ test/parser/expected/drop.out test/parser/expected/insert.out \ test/parser/expected/misc.out test/parser/expected/prepare.out \ test/parser/expected/privileges.out test/parser/expected/scanner.out \ test/parser/expected/select.out \ test/parser/expected/transaction.out test/parser/expected/update.out \ test/parser/expected/v84.out test/parser/expected/v90.out \ test/parser/expected/var.out \ test/parser/input/alter.sql \ test/parser/input/copy.sql test/parser/input/create.sql \ test/parser/input/cursor.sql test/parser/input/delete.sql \ test/parser/input/drop.sql test/parser/input/insert.sql \ test/parser/input/misc.sql test/parser/input/prepare.sql \ test/parser/input/privileges.sql test/parser/input/scanner.sql \ test/parser/input/select.sql \ test/parser/input/transaction.sql test/parser/input/update.sql \ test/parser/input/v84.sql test/parser/input/v90.sql \ test/parser/input/var.sql \ test/parser/.cvsignore test/parser/Makefile \ test/parser/README test/parser/main.c \ test/parser/pool.h test/parser/run-test \ test/parser/parse_schedule \ test/C/Makefile test/C/test_extended.c \ test/jdbc/*.java test/jdbc/README.euc_jp test/jdbc/pgpool.properties test/jdbc/prepare.sql test/jdbc/run.sh \ test/jdbc/expected/autocommit test/jdbc/expected/batch \ test/jdbc/expected/column test/jdbc/expected/lock test/jdbc/expected/select \ test/jdbc/expected/update test/jdbc/expected/insert test/jdbc/expected/CreateTempTable \ test/pdo-test/README.euc_jp test/pdo-test/collections.inc test/pdo-test/def.inc \ test/pdo-test/log.txt test/pdo-test/pdotest.php test/pdo-test/regsql.inc \ test/pdo-test/SQLlist/test1.sql test/pdo-test/SQLlist/test2.sql \ test/pdo-test/mod/database.inc test/pdo-test/mod/def.inc test/pdo-test/mod/errorhandler.inc \ test/timestamp/Makefile test/timestamp/input/insert.sql \ test/timestamp/input/update.sql test/timestamp/input/misc.sql \ test/timestamp/expected/insert.out test/timestamp/expected/update.out \ test/timestamp/expected/misc.out test/timestamp/main.c \ test/timestamp/parse_schedule test/timestamp/run-test \ test/pgpool_setup \ test/regression/README \ test/regression/clean.sh \ test/regression/regress.sh \ test/regression/tests/057.bug61/test.sh \ test/regression/tests/050.bug58/test.sh \ test/regression/tests/002.native_replication/test.sh \ test/regression/tests/001.load_balance/test.sh \ test/regression/tests/052.do_query/test.sh \ test/regression/tests/055.backend_all_down/test.sh \ test/regression/tests/053.insert_lock_hangs/test.sh \ test/regression/tests/056.bug63/jdbctest2.java \ test/regression/tests/056.bug63/test.sh \ test/regression/tests/054.postgres_fdw/test.sh \ test/regression/tests/051.bug60/bug.sql \ test/regression/tests/051.bug60/test.sh \ test/regression/tests/051.bug60/database-clean.sql \ test/regression/tests/051.bug60/database-setup.sql \ test/regression/tests/004.watchdog/master.conf \ test/regression/tests/004.watchdog/test.sh \ test/regression/tests/004.watchdog/standby.conf \ test/regression/tests/003.failover/expected.s \ test/regression/tests/003.failover/test.sh \ test/regression/tests/003.failover/expected.r \ test/regression/libs.sh \ redhat/pgpool.init redhat/pgpool.sysconfig redhat/pgpool.conf.sample.patch \ redhat/rpm_installer/getsources.sh redhat/rpm_installer/config_for_script \ redhat/rpm_installer/install.sh redhat/rpm_installer/uninstall.sh \ redhat/rpm_installer/basebackup-replication.sh redhat/rpm_installer/basebackup-stream.sh \ redhat/rpm_installer/pgpool_recovery_pitr redhat/rpm_installer/pgpool_remote_start \ redhat/rpm_installer/recovery.conf redhat/rpm_installer/failover.sh SUBDIRS = parser pcp watchdog pgpool-II-3.3.2/getopt_long.h0000664000076400007640000000161412245576256012763 00000000000000/* * Portions Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Portions Copyright (c) 2003-2010, PostgreSQL Global Development Group * * $PostgreSQL: pgsql/src/include/getopt_long.h,v 1.12 2010-01-02 16:58:00 momjian Exp $ */ #ifndef GETOPT_LONG_H #define GETOPT_LONG_H #ifdef HAVE_GETOPT_H #include #endif /* These are picked up from the system's getopt() facility. */ extern int opterr; extern int optind; extern int optopt; extern char *optarg; extern int optreset; #ifndef HAVE_STRUCT_OPTION struct option { const char *name; int has_arg; int *flag; int val; }; #define no_argument 0 #define required_argument 1 #endif #ifndef HAVE_GETOPT_LONG extern int getopt_long(int argc, char *const argv[], const char *optstring, const struct option * longopts, int *longindex); #endif #endif /* GETOPT_LONG_H */ pgpool-II-3.3.2/pool_sema.c0000664000076400007640000000706412245576256012420 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2009, PgPool Global Development Group * Portions Copyright (c) 2003-2004, PostgreSQL Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include "pool.h" #include #include #include #include "pool_ipc.h" #ifndef HAVE_UNION_SEMUN union semun { int val; struct semid_ds *buf; unsigned short *array; }; #endif static int semId; /* * Removes a semaphore set. */ static void IpcSemaphoreKill(int status, Datum semId) { union semun semun; struct semid_ds seminfo; /* * Is a previously-existing sema segment still existing and in use? */ semun.buf = &seminfo; if (semctl(semId, 0, IPC_STAT, semun) < 0 && (errno == EINVAL || errno == EACCES #ifdef EIDRM || errno == EIDRM #endif )) return; semun.val = 0; /* unused, but keep compiler quiet */ if (semctl(semId, 0, IPC_RMID) < 0) pool_log("semctl(%lu, 0, IPC_RMID, ...) failed: %s", semId, strerror(errno)); } /* * Create a semaphore set and initialize. */ int pool_semaphore_create(int numSems) { int i; /* Try to create new semaphore set */ semId = semget(IPC_PRIVATE, numSems, IPC_CREAT | IPC_EXCL | IPCProtection); if (semId < 0) { pool_error("could not create %d semaphores: %s", numSems, strerror(errno)); return -1; } on_shmem_exit(IpcSemaphoreKill, semId); /* Initialize it to count 1 */ for (i = 0; i < numSems; i++) { union semun semun; semun.val = 1; if (semctl(semId, i, SETVAL, semun) < 0) { pool_error("semctl(%d, %d, SETVAL, %d) failed: %s", semId, i, 1, strerror(errno)); return -1; } } return 0; } /* * Lock a semaphore (decrement count), blocking if count would be < 0 */ void pool_semaphore_lock(int semNum) { int errStatus; struct sembuf sops; sops.sem_op = -1; /* decrement */ sops.sem_flg = 0; sops.sem_num = semNum; /* * Note: if errStatus is -1 and errno == EINTR then it means we returned * from the operation prematurely because we were sent a signal. So we * try and lock the semaphore again. */ do { errStatus = semop(semId, &sops, 1); } while (errStatus < 0 && errno == EINTR); if (errStatus < 0) pool_error("semop(id=%d) failed: %s", semId, strerror(errno)); } /* * Unlock a semaphore (increment count) */ void pool_semaphore_unlock(int semNum) { int errStatus; struct sembuf sops; sops.sem_op = 1; /* increment */ sops.sem_flg = 0; sops.sem_num = semNum; /* * Note: if errStatus is -1 and errno == EINTR then it means we returned * from the operation prematurely because we were sent a signal. So we * try and unlock the semaphore again. Not clear this can really happen, * but might as well cope. */ do { errStatus = semop(semId, &sops, 1); } while (errStatus < 0 && errno == EINTR); if (errStatus < 0) pool_error("semop(id=%d) failed: %s", semId, strerror(errno)); } pgpool-II-3.3.2/pool_relcache.h0000664000076400007640000000514612245576267013247 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2010 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_relcache.h.: pool_relcache.c related header file * */ #ifndef POOL_RELCACHE_H #define POOL_RELCACHE_H /* ------------------------ * Relation cache structure *------------------------- */ #define MAX_ITEM_LENGTH 1024 /* Relation lookup cache structure */ typedef void *(*func_ptr) (); typedef struct { char dbname[MAX_ITEM_LENGTH]; /* database name */ char relname[MAX_ITEM_LENGTH]; /* table name */ void *data; /* user data */ int refcnt; /* reference count */ int session_id; /* LocalSessionId */ time_t expire; /* cache expiration absolute time in seconds */ } PoolRelCache; typedef struct { int num; /* number of cache items */ char sql[MAX_ITEM_LENGTH]; /* Query to relation */ /* * User defined function to be called at data register. * Argument is POOL_SELECT_RESULT *. * This function must return a pointer to be * saved in cache->data. */ func_ptr register_func; /* * User defined function to be called at data unregister. * Argument cache->data. */ func_ptr unregister_func; bool cache_is_session_local; /* True if cache life time is session local */ bool no_cache_if_zero; /* if register func returns 0, do not cache the data */ PoolRelCache *cache; /* cache data */ } POOL_RELCACHE; extern POOL_RELCACHE *pool_create_relcache(int cachesize, char *sql, func_ptr register_func, func_ptr unregister_func, bool issessionlocal); extern void pool_discard_relcache(POOL_RELCACHE *relcache); extern void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backend, char *table); extern void *int_register_func(POOL_SELECT_RESULT *res); extern void *int_unregister_func(void *data); extern void *string_register_func(POOL_SELECT_RESULT *res); extern void *string_unregister_func(void *data); #endif /* POOL_RELCACHE_H */ pgpool-II-3.3.2/pool_connection_pool.c0000664000076400007640000004444412245576266014667 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * poo_connection_pool.c: connection pool stuff */ #include "config.h" #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_NETINET_TCP_H #include #endif #include #include #include #include #include #include #include #include "pool.h" #include "pool_stream.h" #include "pool_config.h" #include "pool_process_context.h" static int pool_index; /* Active pool index */ POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */ volatile sig_atomic_t backend_timer_expired = 0; /* flag for connection closed timer is expired */ volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check timer expired */ static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int slot); static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p); static int check_socket_status(int fd); /* * initialize connection pools. this should be called once at the startup. */ int pool_init_cp(void) { int i; pool_connection_pool = (POOL_CONNECTION_POOL *)malloc(sizeof(POOL_CONNECTION_POOL)*pool_config->max_pool); if (pool_connection_pool == NULL) { pool_error("pool_init_cp: malloc() failed"); return -1; } memset(pool_connection_pool, 0, sizeof(POOL_CONNECTION_POOL)*pool_config->max_pool); for (i = 0; i < pool_config->max_pool; i++) { pool_connection_pool[i].info = pool_coninfo(pool_get_process_context()->proc_id, i, 0); memset(pool_connection_pool[i].info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS); } return 0; } /* * find connection by user and database */ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket) { #ifdef HAVE_SIGPROCMASK sigset_t oldmask; #else int oldmask; #endif int i, freed = 0; ConnectionInfo *info; POOL_CONNECTION_POOL *p = pool_connection_pool; if (p == NULL) { pool_error("pool_get_cp: pool_connection_pool is not initialized"); return NULL; } POOL_SETMASK2(&BlockSig, &oldmask); for (i=0;imax_pool;i++) { if (MASTER_CONNECTION(p) && MASTER_CONNECTION(p)->sp && MASTER_CONNECTION(p)->sp->major == protoMajor && MASTER_CONNECTION(p)->sp->user != NULL && strcmp(MASTER_CONNECTION(p)->sp->user, user) == 0 && strcmp(MASTER_CONNECTION(p)->sp->database, database) == 0) { int sock_broken = 0; int j; /* mark this connection is under use */ MASTER_CONNECTION(p)->closetime = 0; for (j=0;jinfo[j].counter++; } POOL_SETMASK(&oldmask); if (check_socket) { for (j=0;jfd); if (sock_broken < 0) break; } else { sock_broken = -1; break; } } if (sock_broken < 0) { pool_log("connection closed. retry to create new connection pool."); for (j=0;jsp); freed = 1; } pool_close(CONNECTION(p, j)); free(CONNECTION_SLOT(p, j)); } info = p->info; memset(p, 0, sizeof(POOL_CONNECTION_POOL_SLOT)); p->info = info; memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS); POOL_SETMASK(&oldmask); return NULL; } } POOL_SETMASK(&oldmask); pool_index = i; return p; } p++; } POOL_SETMASK(&oldmask); return NULL; } /* * disconnect and release a connection to the database */ void pool_discard_cp(char *user, char *database, int protoMajor) { POOL_CONNECTION_POOL *p = pool_get_cp(user, database, protoMajor, 0); ConnectionInfo *info; int i, freed = 0; if (p == NULL) { pool_error("pool_discard_cp: cannot get connection pool for user %s database %s", user, database); return; } for (i=0;isp); freed = 1; } pool_close(CONNECTION(p, i)); free(CONNECTION_SLOT(p, i)); } info = p->info; memset(p, 0, sizeof(POOL_CONNECTION_POOL)); p->info = info; memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS); } /* * create a connection pool by user and database */ POOL_CONNECTION_POOL *pool_create_cp(void) { int i, freed = 0; time_t closetime; POOL_CONNECTION_POOL *oldestp; POOL_CONNECTION_POOL *ret; ConnectionInfo *info; POOL_CONNECTION_POOL *p = pool_connection_pool; if (p == NULL) { pool_error("pool_create_cp: pool_connection_pool is not initialized"); return NULL; } for (i=0;imax_pool;i++) { if (MASTER_CONNECTION(p) == NULL) { ret = new_connection(p); if (ret) pool_index = i; return ret; } p++; } pool_debug("no empty connection slot was found"); /* * no empty connection slot was found. look for the oldest connection and discard it. */ oldestp = p = pool_connection_pool; closetime = MASTER_CONNECTION(p)->closetime; pool_index = 0; for (i=0;imax_pool;i++) { pool_debug("user: %s database: %s closetime: %ld", MASTER_CONNECTION(p)->sp->user, MASTER_CONNECTION(p)->sp->database, MASTER_CONNECTION(p)->closetime); if (MASTER_CONNECTION(p)->closetime < closetime) { closetime = MASTER_CONNECTION(p)->closetime; oldestp = p; pool_index = i; } p++; } p = oldestp; pool_send_frontend_exits(p); pool_debug("discarding old %zd th connection. user: %s database: %s", oldestp - pool_connection_pool, MASTER_CONNECTION(p)->sp->user, MASTER_CONNECTION(p)->sp->database); for (i=0;isp); freed = 1; } pool_close(CONNECTION(p, i)); free(CONNECTION_SLOT(p, i)); } info = p->info; memset(p, 0, sizeof(POOL_CONNECTION_POOL)); p->info = info; memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS); ret = new_connection(p); return ret; } /* * set backend connection close timer */ void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend) { POOL_CONNECTION_POOL *p = pool_connection_pool; int i; pool_debug("pool_connection_pool_timer: set close time %ld", time(NULL)); MASTER_CONNECTION(backend)->closetime = time(NULL); /* set connection close time */ if (pool_config->connection_life_time == 0) return; /* look for any other timeout */ for (i=0;imax_pool;i++, p++) { if (!MASTER_CONNECTION(p)) continue; if (!MASTER_CONNECTION(p)->sp) continue; if (MASTER_CONNECTION(p)->sp->user == NULL) continue; if (p != backend && MASTER_CONNECTION(p)->closetime) return; } /* no other timer found. set my timer */ pool_debug("pool_connection_pool_timer: set alarm after %d seconds", pool_config->connection_life_time); pool_signal(SIGALRM, pool_backend_timer_handler); alarm(pool_config->connection_life_time); } /* * backend connection close timer handler */ RETSIGTYPE pool_backend_timer_handler(int sig) { backend_timer_expired = 1; } void pool_backend_timer(void) { #define TMINTMAX 0x7fffffff POOL_CONNECTION_POOL *p = pool_connection_pool; int i, j; time_t now; time_t nearest = TMINTMAX; ConnectionInfo *info; POOL_SETMASK(&BlockSig); now = time(NULL); pool_debug("pool_backend_timer_handler called at %ld", now); for (i=0;imax_pool;i++, p++) { if (!MASTER_CONNECTION(p)) continue; if (!MASTER_CONNECTION(p)->sp) continue; if (MASTER_CONNECTION(p)->sp->user == NULL) continue; /* timer expire? */ if (MASTER_CONNECTION(p)->closetime) { int freed = 0; pool_debug("pool_backend_timer_handler: expire time: %ld", MASTER_CONNECTION(p)->closetime+pool_config->connection_life_time); if (now >= (MASTER_CONNECTION(p)->closetime+pool_config->connection_life_time)) { /* discard expired connection */ pool_debug("pool_backend_timer_handler: expires user %s database %s", MASTER_CONNECTION(p)->sp->user, MASTER_CONNECTION(p)->sp->database); pool_send_frontend_exits(p); for (j=0;jsp); freed = 1; } pool_close(CONNECTION(p, j)); free(CONNECTION_SLOT(p, j)); } info = p->info; memset(p, 0, sizeof(POOL_CONNECTION_POOL)); p->info = info; memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS); } else { /* look for nearest timer */ if (MASTER_CONNECTION(p)->closetime < nearest) nearest = MASTER_CONNECTION(p)->closetime; } } } /* any remaining timer */ if (nearest != TMINTMAX) { nearest = pool_config->connection_life_time - (now - nearest); if (nearest <= 0) nearest = 1; pool_signal(SIGALRM, pool_backend_timer_handler); alarm(nearest); } POOL_SETMASK(&UnBlockSig); } /* * connect to postmaster through INET domain socket */ int connect_inet_domain_socket(int slot, bool retry) { char *host; int port; host = pool_config->backend_desc->backend_info[slot].backend_hostname; port = pool_config->backend_desc->backend_info[slot].backend_port; return connect_inet_domain_socket_by_port(host, port, retry); } /* * connect to postmaster through UNIX domain socket */ int connect_unix_domain_socket(int slot, bool retry) { int port; char *socket_dir; port = pool_config->backend_desc->backend_info[slot].backend_port; socket_dir = pool_config->backend_desc->backend_info[slot].backend_hostname; return connect_unix_domain_socket_by_port(port, socket_dir, retry); } /* * Connect to PostgreSQL server by using UNIX domain socket. * If retry is true, retry to call connect() upon receiving EINTR error. */ int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry) { struct sockaddr_un addr; int fd; int len; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { pool_error("connect_unix_domain_socket_by_port: socket() failed: %s", strerror(errno)); return -1; } memset((char *) &addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/.s.PGSQL.%d", socket_dir, port); len = sizeof(struct sockaddr_un); for (;;) { if (exit_request) /* exit request already sent */ { pool_log("connect_unix_domain_socket_by_port: exit request has been sent"); close(fd); return -1; } if (connect(fd, (struct sockaddr *)&addr, len) < 0) { if ((errno == EINTR && retry) || errno == EAGAIN) continue; pool_error("connect_unix_domain_socket_by_port: connect() failed to %s: %s", addr.sun_path, strerror(errno)); close(fd); return -1; } break; } return fd; } /* * Connect to PostgreSQL server by using INET domain socket. * If retry is true, retry to call connect() upon receiving EINTR error. */ int connect_inet_domain_socket_by_port(char *host, int port, bool retry) { int fd; int len; int on = 1; struct sockaddr_in addr; struct hostent *hp; struct timeval timeout; fd_set rset, wset; int error; socklen_t socklen; int sts; #define CONNECT_TIMEOUT_MSEC 1000 /* specify select(2) timeout in milliseconds */ #define CONNECT_TIMEOUT_SEC CONNECT_TIMEOUT_MSEC/1000 /* seconds part */ /* microseconds part */ #define CONNECT_TIMEOUT_MICROSEC (CONNECT_TIMEOUT_SEC == 0?CONNECT_TIMEOUT_MSEC*1000:\ CONNECT_TIMEOUT_MSEC*1000 - CONNECT_TIMEOUT_SEC*1000*1000) fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { pool_error("connect_inet_domain_socket_by_port: socket() failed: %s", strerror(errno)); return -1; } /* set nodelay */ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) { pool_error("connect_inet_domain_socket_by_port: setsockopt() failed: %s", strerror(errno)); close(fd); return -1; } memset((char *) &addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); len = sizeof(struct sockaddr_in); hp = gethostbyname(host); if ((hp == NULL) || (hp->h_addrtype != AF_INET)) { pool_error("connect_inet_domain_socket: gethostbyname() failed: %s host: %s", hstrerror(h_errno), host); close(fd); return -1; } memmove((char *) &(addr.sin_addr), (char *) hp->h_addr, hp->h_length); pool_set_nonblock(fd); for (;;) { if (exit_request) /* exit request already sent */ { pool_log("connect_inet_domain_socket_by_port: exit request has been sent"); close(fd); return -1; } if (health_check_timer_expired && getpid() == mypid) /* has health check timer expired */ { pool_log("connect_inet_domain_socket_by_port: health check timer expired"); close(fd); return -1; } if (connect(fd, (struct sockaddr *)&addr, len) < 0) { if (errno == EISCONN) { /* Socket is already connected */ break; } if ((errno == EINTR && retry) || errno == EAGAIN) continue; /* * If error was "connect(2) is in progress", then wait for * completion. Otherwise error out. */ if (errno != EINPROGRESS && errno != EALREADY) { pool_error("connect_inet_domain_socket: connect() failed: %s",strerror(errno)); close(fd); return -1; } timeout.tv_sec = CONNECT_TIMEOUT_SEC; timeout.tv_usec = CONNECT_TIMEOUT_MICROSEC; FD_ZERO(&rset); FD_SET(fd, &rset); FD_ZERO(&wset); FD_SET(fd, &wset); sts = select(fd+1, &rset, &wset, NULL, &timeout); if (sts == 0) { /* select timeout */ if (retry) { pool_log("connect_inet_domain_socket: select() timed out. retrying..."); continue; } else { pool_error("connect_inet_domain_socket: select() timed out"); close(fd); return -1; } } else if (sts > 0) { /* * If read data or write data was set, either connect * succeeded or error. We need to figure it out. This * is the hardest part in using non blocking * connect(2). See W. Richar Stevens's "UNIX Network * Programming: Volume 1, Second Edition" section * 15.4. */ if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { error = 0; socklen = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &socklen) < 0) { /* Solaris returns error in this case */ pool_error("connect_inet_domain_socket: getsockopt() failed: %s", strerror(errno)); close(fd); return -1; } /* Non Solaris case */ if (error != 0) { pool_error("connect_inet_domain_socket: getsockopt() detected error: %s", strerror(error)); close(fd); return -1; } } else { pool_error("connect_inet_domain_socket: both read data and write data was not set"); close(fd); return -1; } } else /* select returns error */ { if((errno == EINTR && retry) || errno == EAGAIN) { pool_log("connect_inet_domain_socket: select() interrupted. retrying..."); continue; } pool_log("connect_inet_domain_socket: select() interrupted"); close(fd); return -1; } } break; } pool_unset_nonblock(fd); return fd; } /* * create connection pool */ static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int slot) { BackendInfo *b = &pool_config->backend_desc->backend_info[slot]; int fd; if (*b->backend_hostname == '/') { fd = connect_unix_domain_socket(slot, TRUE); } else { fd = connect_inet_domain_socket(slot, TRUE); } if (fd < 0) { pool_error("connection to %s(%d) failed", b->backend_hostname, b->backend_port); return NULL; } cp->sp = NULL; cp->con = pool_open(fd); cp->closetime = 0; return cp; } /* * create actual connections to backends */ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) { POOL_CONNECTION_POOL_SLOT *s; int active_backend_count = 0; int i; for (i=0;ifail_over_on_backend_error) { notice_backend_error(i); } else { pool_log("new_connection: do not failover because fail_over_on_backend_error is off"); } child_exit(1); } p->info[i].create_time = time(NULL); p->slots[i] = s; if (pool_init_params(&s->con->params)) { return NULL; } BACKEND_INFO(i).backend_status = CON_UP; active_backend_count++; } if (active_backend_count > 0) { return p; } return NULL; } /* check_socket_status() * RETURN: 0 => OK * -1 => broken socket. */ static int check_socket_status(int fd) { fd_set rfds; int result; struct timeval t; for (;;) { FD_ZERO(&rfds); FD_SET(fd, &rfds); t.tv_sec = t.tv_usec = 0; result = select(fd+1, &rfds, NULL, NULL, &t); if (result < 0 && errno == EINTR) { continue; } else { return (result == 0 ? 0 : -1); } } return -1; } /* * Return current used index (i.e. frontend connected) */ int pool_pool_index(void) { return pool_index; } pgpool-II-3.3.2/AUTHORS0000664000076400007640000000017312052601364011321 00000000000000Authors of pgpool pgpool was originally written by Tatsuo Ishii, then was contributed to pgpool Global Development Group. pgpool-II-3.3.2/pool.h0000664000076400007640000005251712245576266011424 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool.h.: master definition header file * */ #ifndef POOL_H #define POOL_H #include "config.h" #include "pool_type.h" #include "pool_signal.h" #include "parser/nodes.h" #include "libpq-fe.h" #include #include #include #include #include #ifdef USE_SSL #include #include #include #endif #include /* undef this if you have problems with non blocking accept() */ #define NONE_BLOCK #define POOLMAXPATHLEN 8192 /* configuration file name */ #define POOL_CONF_FILE_NAME "pgpool.conf" /* PCP user/password file name */ #define PCP_PASSWD_FILE_NAME "pcp.conf" /* HBA configuration file name */ #define HBA_CONF_FILE_NAME "pool_hba.conf" /* pid file directory */ #define DEFAULT_LOGDIR "/tmp" /* Unix domain socket directory */ #define DEFAULT_SOCKET_DIR "/tmp" /* pid file name */ #define DEFAULT_PID_FILE_NAME "/var/run/pgpool/pgpool.pid" /* status file name */ #define STATUS_FILE_NAME "pgpool_status" /* default string used to identify pgpool on syslog output */ #define DEFAULT_SYSLOG_IDENT "pgpool" typedef enum { POOL_CONTINUE = 0, POOL_IDLE, POOL_END, POOL_ERROR, POOL_FATAL, POOL_DEADLOCK } POOL_STATUS; /* protocol major version numbers */ #define PROTO_MAJOR_V2 2 #define PROTO_MAJOR_V3 3 /* Cancel packet proto major */ #define PROTO_CANCEL 80877102 /* * In protocol 3.0 and later, the startup packet length is not fixed, but * we set an arbitrary limit on it anyway. This is just to prevent simple * denial-of-service attacks via sending enough data to run the server * out of memory. */ #define MAX_STARTUP_PACKET_LENGTH 10000 typedef struct StartupPacket_v2 { int protoVersion; /* Protocol version */ char database[SM_DATABASE]; /* Database name */ char user[SM_USER]; /* User name */ char options[SM_OPTIONS]; /* Optional additional args */ char unused[SM_UNUSED]; /* Unused */ char tty[SM_TTY]; /* Tty for debug output */ } StartupPacket_v2; /* startup packet info */ typedef struct { char *startup_packet; /* raw startup packet without packet length (malloced area) */ int len; /* raw startup packet length */ int major; /* protocol major version */ int minor; /* protocol minor version */ char *database; /* database name in startup_packet (malloced area) */ char *user; /* user name in startup_packet (malloced area) */ char *application_name; /* not malloced are. pointing to in startup_packet */ } StartupPacket; typedef struct CancelPacket { int protoVersion; /* Protocol version */ int pid; /* backend process id */ int key; /* cancel key */ } CancelPacket; #define MAX_PASSWORD_SIZE 1024 typedef struct { int num; /* number of entries */ char **names; /* parameter names */ char **values; /* values */ } ParamStatus; /* * stream connection structure */ typedef struct { int fd; /* fd for connection */ char *wbuf; /* write buffer for the connection */ int wbufsz; /* write buffer size */ int wbufpo; /* buffer offset */ #ifdef USE_SSL SSL_CTX *ssl_ctx; /* SSL connection context */ SSL *ssl; /* SSL connection */ #endif int ssl_active; /* SSL is failed if < 0, off if 0, on if > 0 */ char *hp; /* pending data buffer head address */ int po; /* pending data offset */ int bufsz; /* pending data buffer size */ int len; /* pending data length */ char *sbuf; /* buffer for pool_read_string */ int sbufsz; /* its size in bytes */ char *buf2; /* buffer for pool_read2 */ int bufsz2; /* its size in bytes */ char *buf3; /* buffer for pool_push/pop */ int bufsz3; /* its size in bytes */ int isbackend; /* this connection is for backend if non 0 */ int db_node_id; /* DB node id for this connection */ char tstate; /* Transaction state (V3 only) 'I' if idle * (not in a transaction block); 'T' if in a * transaction block; or 'E' if in a failed * transaction block */ /* True if an internal transaction has already started */ bool is_internal_transaction_started; /* * following are used to remember when re-use the authenticated connection */ int auth_kind; /* 3: clear text password, 4: crypt password, 5: md5 password */ int pwd_size; /* password (sent back from frontend) size in host order */ char password[MAX_PASSWORD_SIZE]; /* password (sent back from frontend) */ char salt[4]; /* password salt */ /* * following are used to remember current session parameter status. * re-used connection will need them (V3 only) */ ParamStatus params; int no_forward; /* if non 0, do not write to frontend */ char kind; /* kind cache */ /* * frontend info needed for hba */ int protoVersion; SockAddr raddr; UserAuth auth_method; char *auth_arg; char *database; char *username; } POOL_CONNECTION; /* * connection pool structure */ typedef struct { StartupPacket *sp; /* startup packet info */ int pid; /* backend pid */ int key; /* cancel key */ POOL_CONNECTION *con; time_t closetime; /* absolute time in second when the connection closed * if 0, that means the connection is under use. */ } POOL_CONNECTION_POOL_SLOT; typedef struct { ConnectionInfo *info; /* connection info on shmem */ POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS]; } POOL_CONNECTION_POOL; typedef struct { SystemDBInfo *info; PGconn *pgconn; /* persistent connection to the system DB */ POOL_CONNECTION_POOL_SLOT *connection; BACKEND_STATUS *system_db_status; } POOL_SYSTEMDB_CONNECTION_POOL; /* * for pool_clear_cache() in pool_query_cache.c * * used to specify the time which cached data created before it to be deleted. */ typedef enum { second, seconds, minute, minutes, hour, hours, day, days, week, weeks, month, months, year, years, decade, decades, century, centuries, millennium, millenniums } UNIT; typedef struct { int quantity; UNIT unit; } Interval; /* NUM_BACKENDS now always returns actual number of backends */ #define NUM_BACKENDS (pool_config->backend_desc->num_backends) #define BACKEND_INFO(backend_id) (pool_config->backend_desc->backend_info[(backend_id)]) #define LOAD_BALANCE_STATUS(backend_id) (pool_config->load_balance_status[(backend_id)]) /* * This macro returns true if: * current query is in progress and the DB node is healthy OR * no query is in progress and the DB node is healthy */ extern bool pool_is_node_to_be_sent_in_current_query(int node_id); extern int pool_virtual_master_db_node_id(void); extern BACKEND_STATUS* my_backend_status[]; extern int my_master_node_id; #define VALID_BACKEND(backend_id) \ ((RAW_MODE && (backend_id) == REAL_MASTER_NODE_ID) || \ (pool_is_node_to_be_sent_in_current_query((backend_id)) && \ ((*(my_backend_status[(backend_id)]) == CON_UP) || \ (*(my_backend_status[(backend_id)]) == CON_CONNECT_WAIT)))) /* * For raw mode failover control */ #define VALID_BACKEND_RAW(backend_id) \ ((*(my_backend_status[(backend_id)]) == CON_UP) || \ (*(my_backend_status[(backend_id)]) == CON_CONNECT_WAIT)) #define CONNECTION_SLOT(p, slot) ((p)->slots[(slot)]) #define CONNECTION(p, slot) (CONNECTION_SLOT(p, slot)->con) /* * The first DB node id appears in pgpool.conf or the first "live" DB * node otherwise. */ #define REAL_MASTER_NODE_ID (Req_info->master_node_id) /* * The primary node id in streaming replication mode. If not in the * mode or there's no primary node, this macro returns * REAL_MASTER_NODE_ID. */ #define PRIMARY_NODE_ID (Req_info->primary_node_id >=0?\ Req_info->primary_node_id:REAL_MASTER_NODE_ID) /* * Real primary node id. If not in the mode or there's no primary * node, this macro returns -1. */ #define REAL_PRIMARY_NODE_ID (Req_info->primary_node_id) /* * "Virtual" master node id. It's same as REAL_MASTER_NODE_ID if not * in load balance mode. If in load balance, it's the first load * balance node. */ #define MASTER_NODE_ID (pool_virtual_master_db_node_id()) #define IS_MASTER_NODE_ID(node_id) (MASTER_NODE_ID == (node_id)) #define MASTER_CONNECTION(p) ((p)->slots[MASTER_NODE_ID]) #define MASTER(p) MASTER_CONNECTION(p)->con #define REPLICATION (pool_config->replication_mode) #define MASTER_SLAVE (pool_config->master_slave_mode) #define DUAL_MODE (REPLICATION || MASTER_SLAVE) #define PARALLEL_MODE (pool_config->parallel_mode) #define RAW_MODE (!REPLICATION && !PARALLEL_MODE && !MASTER_SLAVE) #define MAJOR(p) MASTER_CONNECTION(p)->sp->major #define TSTATE(p, i) (CONNECTION(p, i)->tstate) #define INTERNAL_TRANSACTION_STARTED(p, i) (CONNECTION(p, i)->is_internal_transaction_started) #define SYSDB_INFO (system_db_info->info) #define SYSDB_CONNECTION (system_db_info->connection) #define SYSDB_STATUS (*system_db_info->system_db_status) #define Max(x, y) ((x) > (y) ? (x) : (y)) #define Min(x, y) ((x) < (y) ? (x) : (y)) #define LOCK_COMMENT "/*INSERT LOCK*/" #define LOCK_COMMENT_SZ (sizeof(LOCK_COMMENT)-1) #define NO_LOCK_COMMENT "/*NO INSERT LOCK*/" #define NO_LOCK_COMMENT_SZ (sizeof(NO_LOCK_COMMENT)-1) #define NO_LOAD_BALANCE "/*NO LOAD BALANCE*/" #define NO_LOAD_BALANCE_COMMENT_SZ (sizeof(NO_LOAD_BALANCE)-1) #define MAX_NUM_SEMAPHORES 4 #define CONN_COUNTER_SEM 0 #define REQUEST_INFO_SEM 1 #define SHM_CACHE_SEM 2 #define QUERY_CACHE_STATS_SEM 3 /* * number specified when semaphore is locked/unlocked */ typedef enum SemNum { SEMNUM_CONFIG, SEMNUM_NODES, SEMNUM_PROCESSES } SemNum; /* * up/down request info area in shared memory */ typedef enum { NODE_UP_REQUEST = 0, NODE_DOWN_REQUEST, NODE_RECOVERY_REQUEST, CLOSE_IDLE_REQUEST, PROMOTE_NODE_REQUEST } POOL_REQUEST_KIND; typedef struct { POOL_REQUEST_KIND kind; /* request kind */ int node_id[MAX_NUM_BACKENDS]; /* request node id */ int master_node_id; /* the youngest node id which is not in down status */ int primary_node_id; /* the primary node id in streaming replication mode */ int conn_counter; bool switching; /* it true, failover or failback is in progress */ } POOL_REQUEST_INFO; /* description of row. corresponding to RowDescription message */ typedef struct { char *attrname; /* attribute name */ int oid; /* 0 or non 0 if it's a table object */ int attrnumber; /* attribute number starting with 1. 0 if it's not a table */ int typeoid; /* data type oid */ int size; /* data length minus means variable data type */ int mod; /* data type modifier */ } AttrInfo; typedef struct { int num_attrs; /* number of attributes */ AttrInfo *attrinfo; } RowDesc; typedef struct { RowDesc *rowdesc; /* attribute info */ int numrows; /* number of rows */ int *nullflags; /* if NULL, -1 or length of the string excluding termination null */ char **data; /* actual row character data terminated with null */ } POOL_SELECT_RESULT; /* * recovery mode */ typedef enum { RECOVERY_INIT = 0, RECOVERY_ONLINE, RECOVERY_DETACH, RECOVERY_PROMOTE } POOL_RECOVERY_MODE; /* * global variables */ extern pid_t mypid; /* parent pid */ extern bool run_as_pcp_child; extern POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */ extern volatile sig_atomic_t backend_timer_expired; /* flag for connection closed timer is expired */ extern volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check timer expired */ extern long int weight_master; /* normalized weight of master (0-RAND_MAX range) */ extern int my_proc_id; /* process table id (!= UNIX's PID) */ extern POOL_SYSTEMDB_CONNECTION_POOL *system_db_info; /* systemdb */ extern ProcessInfo *process_info; /* shmem process information table */ extern ConnectionInfo *con_info; /* shmem connection info table */ extern POOL_REQUEST_INFO *Req_info; extern volatile sig_atomic_t *InRecovery; extern char remote_ps_data[]; /* used for set_ps_display */ extern volatile sig_atomic_t got_sighup; extern volatile sig_atomic_t exit_request; #define QUERY_STRING_BUFFER_LEN 1024 extern char query_string_buffer[]; /* last query string sent to simpleQuery() */ extern BACKEND_STATUS private_backend_status[MAX_NUM_BACKENDS]; extern char remote_host[]; /* client host */ extern char remote_port[]; /* client port */ /* * public functions */ extern char *get_config_file_name(void); extern char *get_hba_file_name(void); #ifdef __GNUC__ extern void pool_error(const char *fmt,...) __attribute__((format (printf, 1, 2))); extern void pool_debug(const char *fmt,...) __attribute__((format (printf, 1, 2))); extern void pool_log(const char *fmt,...) __attribute__((format (printf, 1, 2))); #else extern void pool_error(const char *fmt,...); extern void pool_debug(const char *fmt,...); extern void pool_log(const char *fmt,...); #endif extern void do_child(int unix_fd, int inet_fd); extern void pcp_do_child(int unix_fd, int inet_fd, char *pcp_conf_file); extern int select_load_balancing_node(void); extern int pool_init_cp(void); extern POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int reset_request); extern int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp); /* SSL functionality */ extern void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp); extern void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp); extern void pool_ssl_close(POOL_CONNECTION *cp); extern int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size); extern int pool_ssl_write(POOL_CONNECTION *cp, const void *buf, int size); extern bool pool_ssl_pending(POOL_CONNECTION *cp); extern POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern POOL_STATUS NoticeResponse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern void notice_backend_error(int node_id); extern void degenerate_backend_set(int *node_id_set, int count); extern void promote_backend(int node_id); extern void send_failback_request(int node_id); extern void pool_set_timeout(int timeoutval); extern int pool_check_fd(POOL_CONNECTION *cp); extern void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend); extern int pool_read_message_length(POOL_CONNECTION_POOL *cp); extern int *pool_read_message_length2(POOL_CONNECTION_POOL *cp); extern signed char pool_read_kind(POOL_CONNECTION_POOL *cp); extern int pool_read_int(POOL_CONNECTION_POOL *cp); extern POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len, char *contents); extern POOL_STATUS ParameterStatus(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern int pool_init_params(ParamStatus *params); extern void pool_discard_params(ParamStatus *params); extern char *pool_find_name(ParamStatus *params, char *name, int *pos); extern int pool_get_param(ParamStatus *params, int index, char **name, char **value); extern int pool_add_param(ParamStatus *params, char *name, char *value); extern void pool_param_debug_print(ParamStatus *params); extern void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor, char *code, char *message, char *detail, char *hint, char *file, int line); extern void pool_send_fatal_message(POOL_CONNECTION *frontend, int protoMajor, char *code, char *message, char *detail, char *hint, char *file, int line); extern void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, char *code, char *message, char *detail, char *hint, char *file, char *severity, int line); extern void pool_send_readyforquery(POOL_CONNECTION *frontend); extern int send_startup_packet(POOL_CONNECTION_POOL_SLOT *cp); extern void pool_free_startup_packet(StartupPacket *sp); extern void child_exit(int code); extern void init_prepared_list(void); extern void *pool_shared_memory_create(size_t size); extern void pool_shmem_exit(int code); extern int pool_semaphore_create(int numSems); extern void pool_semaphore_lock(int semNum); extern void pool_semaphore_unlock(int semNum); extern BackendInfo *pool_get_node_info(int node_number); extern int pool_get_node_count(void); extern int *pool_get_process_list(int *array_size); extern ProcessInfo *pool_get_process_info(pid_t pid); extern SystemDBInfo *pool_get_system_db_info(void); extern POOL_STATUS OneNode_do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, char *query, char *database); /* child.c */ extern POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( char *hostname, int port, char *dbname, char *user, char *password, bool retry); extern void discard_persistent_db_connection(POOL_CONNECTION_POOL_SLOT *cp); /* define pool_system.c */ extern POOL_CONNECTION_POOL_SLOT *pool_system_db_connection(void); extern DistDefInfo *pool_get_dist_def_info (char * dbname, char * schema_name, char * table_name); extern RepliDefInfo *pool_get_repli_def_info (char * dbname, char * schema_name, char * table_name); extern int pool_get_id (DistDefInfo *info, const char * value); extern int system_db_connect (void); extern int pool_memset_system_db_info (SystemDBInfo *info); extern void pool_close_libpq_connection(void); /* pool_query_cache.c */ extern POOL_STATUS pool_query_cache_lookup(POOL_CONNECTION *frontend, char *query, char *database, char tstate); extern int pool_query_cache_register(char kind, POOL_CONNECTION *frontend, char *database, char *data, int data_len, char *query); extern int pool_query_cache_table_exists(void); extern int pool_clear_cache_by_time(Interval *interval, int size); extern POOL_STATUS pool_execute_query_cache_lookup(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, Node *node); /* pool_hba.c */ extern int load_hba(char *hbapath); extern void ClientAuthentication(POOL_CONNECTION *frontend); /* pool_ip.c */ extern void pool_getnameinfo_all(SockAddr *saddr, char *remote_host, char *remote_port); /* strlcpy.c */ extern size_t strlcpy(char *dst, const char *src, size_t siz); /* ps_status.c */ extern bool update_process_title; extern char **save_ps_display_args(int argc, char **argv); extern void init_ps_display(const char *username, const char *dbname, const char *host_info, const char *initial_str); extern void set_ps_display(const char *activity, bool force); extern const char *get_ps_display(int *displen); extern void pool_ps_idle_display(POOL_CONNECTION_POOL *backend); /* recovery.c */ extern int start_recovery(int recovery_node); extern void finish_recovery(void); extern int wait_connection_closed(void); /* child.c */ extern void cancel_request(CancelPacket *sp); extern void check_stop_request(void); extern void pool_initialize_private_backend_status(void); /* pool_process_query.c */ extern void reset_variables(void); extern void reset_connection(void); extern void per_node_statement_log(POOL_CONNECTION_POOL *backend, int node_id, char *query); extern void per_node_error_log(POOL_CONNECTION_POOL *backend, int node_id, char *query, char *prefix, bool unread); extern int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int major, bool unread, char **message); extern POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, char *query, int protoMajor, int pid, int key, int no_ready_for_query); extern POOL_STATUS do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int major); extern void free_select_result(POOL_SELECT_RESULT *result); extern int compare(const void *p1, const void *p2); extern POOL_STATUS do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id, int major); extern POOL_STATUS pool_discard_packet_contents(POOL_CONNECTION_POOL *cp); extern void pool_dump_valid_backend(int backend_id); /* pool_auth.c */ extern void pool_random_salt(char *md5Salt); /* main.c */ extern void pool_sleep(unsigned int second); /* pool_worker_child.c */ extern void do_worker_child(void); /* md5.c */ extern bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf); /* pool_connection_pool.c */ extern int pool_init_cp(void); extern POOL_CONNECTION_POOL *pool_create_cp(void); extern POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket); extern void pool_discard_cp(char *user, char *database, int protoMajor); extern void pool_backend_timer(void); extern void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend); extern RETSIGTYPE pool_backend_timer_handler(int sig); extern int connect_inet_domain_socket(int slot, bool retry); extern int connect_unix_domain_socket(int slot, bool retry); extern int connect_inet_domain_socket_by_port(char *host, int port, bool retry); extern int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry); extern int pool_pool_index(void); #endif /* POOL_H */ pgpool-II-3.3.2/pool_worker_child.c0000664000076400007640000002044212245576267014144 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * child.c: worker child process main * */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_NETINET_TCP_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #include #include #ifdef HAVE_CRYPT_H #include #endif #include "pool.h" #include "pool_process_context.h" #include "pool_session_context.h" #include "pool_config.h" #include "pool_ip.h" #include "md5.h" #include "pool_stream.h" extern int myargc; extern char **myargv; char remote_ps_data[NI_MAXHOST]; /* used for set_ps_display */ static POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS]; static volatile sig_atomic_t reload_config_request = 0; static volatile sig_atomic_t restart_request = 0; static void establish_persistent_connection(void); static void discard_persistent_connection(void); static void check_replication_time_lag(void); static long text_to_lsn(char *text); static RETSIGTYPE my_signal_handler(int sig); static RETSIGTYPE reload_config_handler(int sig); static void reload_config(void); #define CHECK_REQUEST \ do { \ if (reload_config_request) \ { \ reload_config(); \ reload_config_request = 0; \ } else if (restart_request) \ { \ pool_log("worker process received restart request"); \ exit(1); \ } \ } while (0) /* * worker child main loop */ void do_worker_child(void) { pool_debug("I am %d", getpid()); /* Identify myself via ps */ init_ps_display("", "", "", ""); set_ps_display("worker process", false); /* set up signal handlers */ signal(SIGALRM, SIG_DFL); signal(SIGTERM, my_signal_handler); signal(SIGINT, my_signal_handler); signal(SIGHUP, reload_config_handler); signal(SIGQUIT, my_signal_handler); signal(SIGCHLD, SIG_IGN); signal(SIGUSR1, my_signal_handler); signal(SIGUSR2, SIG_IGN); signal(SIGPIPE, SIG_IGN); /* Initialize my backend status */ pool_initialize_private_backend_status(); /* Initialize per process context */ pool_init_process_context(); for (;;) { CHECK_REQUEST; if (pool_config->sr_check_period <= 0) { sleep(30); } /* * If streaming replication mode, do time lag checking */ if (pool_config->sr_check_period > 0 && MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP)) { /* Check and establish persistent connections to the backend */ establish_persistent_connection(); /* Do replication time lag checking */ check_replication_time_lag(); /* Discard persistent connections */ discard_persistent_connection(); } sleep(pool_config->sr_check_period); } exit(0); } /* * Establish persistent connection to backend */ static void establish_persistent_connection(void) { int i; BackendInfo *bkinfo; POOL_CONNECTION_POOL_SLOT *s; for (i=0;ibackend_hostname, bkinfo->backend_port, "postgres", pool_config->sr_check_user, pool_config->sr_check_password, true); if (s) slots[i] = s; else slots[i] = NULL; } } } /* * Discard persistent connection to backend */ static void discard_persistent_connection(void) { int i; for (i=0;icon, query, &res, PROTO_MAJOR_V3); if (sts != POOL_CONTINUE) { if (res) free_select_result(res); pool_error("check_replication_time_lag: %s failed", query); return; } if (!res) { pool_error("check_replication_time_lag: %s result is null", query); return; } if (res->numrows <= 0) { pool_error("check_replication_time_lag: %s returns no rows", query); free_select_result(res); return; } if (res->data[0] == NULL) { pool_error("check_replication_time_lag: %s returns no data", query); free_select_result(res); return; } if (res->nullflags[0] == -1) { pool_log("check_replication_time_lag: %s returns NULL", query); free_select_result(res); lsn[i] = 0; } else { lsn[i] = text_to_lsn(res->data[0]); free_select_result(res); } } for (i=0;i lsn[i]) ? lsn[PRIMARY_NODE_ID] - lsn[i] : 0; if (PRIMARY_NODE_ID == i) { bkinfo->standby_delay = 0; } else { bkinfo->standby_delay = lag; /* Log delay if necessary */ if ((!strcmp(pool_config->log_standby_delay, "always") && lag > 0) || (pool_config->delay_threshold && !strcmp(pool_config->log_standby_delay, "if_over_threshold") && lag > pool_config->delay_threshold)) { pool_log("Replication of node:%d is behind %llu bytes from the primary server (node:%d)", i, lsn[PRIMARY_NODE_ID] - lsn[i], PRIMARY_NODE_ID); } } } } /* * Convert logid/recoff style text to 64bit log location (LSN) */ static long text_to_lsn(char *text) { /* * WAL segment size in bytes. XXX We should fetch this from * PostgreSQL, rather than having fixed value. */ #define WALSEGMENTSIZE 16 * 1024 * 1024 unsigned int xlogid; unsigned int xrecoff; unsigned long long int lsn; if (sscanf(text, "%X/%X", &xlogid, &xrecoff) != 2) { pool_error("text_to_lsn: wrong log location format: %s", text); return 0; } lsn = xlogid * ((unsigned long long int)0xffffffff - WALSEGMENTSIZE) + xrecoff; #ifdef DEBUG pool_log("lsn: %X %X %llX", xlogid, xrecoff, lsn); #endif return lsn; } static RETSIGTYPE my_signal_handler(int sig) { POOL_SETMASK(&BlockSig); switch (sig) { case SIGTERM: case SIGINT: case SIGQUIT: exit(0); break; /* Failback or new node added */ case SIGUSR1: restart_request = 1; break; default: exit(1); break; } POOL_SETMASK(&UnBlockSig); } static RETSIGTYPE reload_config_handler(int sig) { POOL_SETMASK(&BlockSig); reload_config_request = 1; POOL_SETMASK(&UnBlockSig); } static void reload_config(void) { pool_log("reload config files."); pool_get_config(get_config_file_name(), RELOAD_CONFIG); if (pool_config->enable_pool_hba) load_hba(get_hba_file_name()); reload_config_request = 0; } pgpool-II-3.3.2/configure.in0000664000076400007640000003276012245576266012611 00000000000000dnl Process this file with autoconf to produce a configure script. AC_INIT dnl Checks for programs. AC_PROG_CC AM_INIT_AUTOMAKE(pgpool-II, 3.3.2) # AC_PROG_RANLIB AC_PROG_LIBTOOL AM_PROG_LEX AC_PROG_YACC dnl suggested by libtoolize --force AC_CONFIG_MACRO_DIR([m4]) dnl Check compiler option dnl check -Wall option OLD_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -Wall" AC_MSG_CHECKING(for -Wall option) AC_CACHE_VAL(ac_cv_wall, AC_TRY_COMPILE([], [char a;], ac_cv_wall=yes, ac_cv_wall=no)) echo $ac_cv_wall if test $ac_cv_wall = no; then CFLAGS=$OLD_CFLAGS fi dnl check -Wmissing-prototypes OLD_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -Wmissing-prototypes" AC_MSG_CHECKING(for -Wmissing-prototypes option) AC_CACHE_VAL(ac_cv_wmissing_prototypes, AC_TRY_COMPILE([], [char a;], ac_cv_wmissing_prototypes=yes, ac_cv_wmissing_prototypes=no)) echo $ac_cv_wmissing_prototypes if test $ac_cv_wmissing_prototypes = no; then CFLAGS=$OLD_CFLAGS fi dnl check -Wmissing-prototypes OLD_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -Wmissing-declarations" AC_MSG_CHECKING(for -Wmissing-declarations option) AC_CACHE_VAL(ac_cv_wmissing_declarations, AC_TRY_COMPILE([], [char a;], ac_cv_wmissing_declarations=yes, ac_cv_wmissing_declarations=no)) echo $ac_cv_wmissing_declarations if test $ac_cv_wmissing_declarations = no; then CFLAGS=$OLD_CFLAGS fi dnl Checks for libraries. AC_CHECK_LIB(m, main) AC_CHECK_LIB(nsl, main) AC_CHECK_LIB(socket, main) AC_CHECK_LIB(ipc, main) AC_CHECK_LIB(IPC, main) AC_CHECK_LIB(lc, main) AC_CHECK_LIB(BSD, main) AC_CHECK_LIB(gen, main) AC_CHECK_LIB(PW, main) AC_CHECK_LIB(resolv, main) AC_CHECK_LIB(crypt, main) dnl Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(fcntl.h unistd.h getopt.h netinet/tcp.h netinet/in.h netdb.h sys/param.h sys/types.h sys/socket.h sys/un.h sys/time.h sys/sem.h sys/shm.h sys/select.h crypt.h sys/pstat.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_PID_T AC_HEADER_TIME dnl ===== Copied from PostgreSQL's configure start ===== dnl dnl Check to see if we have a working 64-bit integer type. dnl This breaks down into two steps: dnl (1) figure out if the compiler has a 64-bit int type with working dnl arithmetic, and if so dnl (2) see whether snprintf() can format the type correctly. (Currently, dnl snprintf is the only library routine we really need for int8 support.) dnl It's entirely possible to have a compiler that handles a 64-bit type dnl when the C library doesn't; this is fairly likely when using gcc on dnl an older platform, for example. dnl If there is no native snprintf() or it does not handle the 64-bit type, dnl we force our own version of snprintf() to be used instead. dnl Note this test must be run after our initial check for snprintf/vsnprintf. m4_include([c-compiler.m4]) m4_include([c-library.m4]) m4_include([general.m4]) dnl This mazic variable is set to "yes" in PostgreSQL's configure.in dnl if PORTNAME is "win32". dnl pgpool-II does not suppport Windows at the moment, so we set to "no". pgac_need_repl_snprintf=no PGAC_TYPE_64BIT_INT([long int]) if test x"$HAVE_LONG_INT_64" = x"no" ; then PGAC_TYPE_64BIT_INT([long long int]) fi dnl If we need to use "long long int", figure out whether nnnLL notation works. if test x"$HAVE_LONG_LONG_INT_64" = xyes ; then AC_TRY_COMPILE([ #define INT64CONST(x) x##LL long long int foo = INT64CONST(0x1234567890123456); ], [], [AC_DEFINE(HAVE_LL_CONSTANTS, 1, [Define to 1 if constants of type 'long long int' should have the suffix LL.])], []) fi # If we found "long int" is 64 bits, assume snprintf handles it. If # we found we need to use "long long int", better check. We cope with # snprintfs that use %lld, %qd, or %I64d as the format. If none of these # work, fall back to our own snprintf emulation (which we know uses %lld). if test "$HAVE_LONG_LONG_INT_64" = yes ; then if test $pgac_need_repl_snprintf = no; then PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT if test "$LONG_LONG_INT_FORMAT" = ""; then # Force usage of our own snprintf, since system snprintf is broken pgac_need_repl_snprintf=yes LONG_LONG_INT_FORMAT='%lld' fi else # Here if we previously decided we needed to use our own snprintf LONG_LONG_INT_FORMAT='%lld' fi LONG_LONG_UINT_FORMAT=`echo "$LONG_LONG_INT_FORMAT" | sed 's/d$/u/'` INT64_FORMAT="\"$LONG_LONG_INT_FORMAT\"" UINT64_FORMAT="\"$LONG_LONG_UINT_FORMAT\"" else # Here if we are not using 'long long int' at all INT64_FORMAT='"%ld"' UINT64_FORMAT='"%lu"' fi AC_DEFINE_UNQUOTED(INT64_FORMAT, $INT64_FORMAT, [Define to the appropriate snprintf format for 64-bit ints, if any.]) AC_DEFINE_UNQUOTED(UINT64_FORMAT, $UINT64_FORMAT, [Define to the appropriate snprintf format for unsigned 64-bit ints, if any.]) # Now we have checked all the reasons to replace snprintf if test $pgac_need_repl_snprintf = yes; then AC_DEFINE(USE_REPL_SNPRINTF, 1, [Use replacement snprintf() functions.]) AC_LIBOBJ(snprintf) fi # Need a #define for the size of Datum (unsigned long) AC_CHECK_SIZEOF([unsigned long]) # And check size of void *, size_t (enables tweaks for > 32bit address space) AC_CHECK_SIZEOF([void *]) AC_CHECK_SIZEOF([size_t]) # Decide whether float4 is passed by value: user-selectable, enabled by default AC_MSG_CHECKING([whether to build with float4 passed by value]) PGAC_ARG_BOOL(enable, float4-byval, yes, [disable float4 passed by value], [AC_DEFINE([USE_FLOAT4_BYVAL], 1, [Define to 1 if you want float4 values to be passed by value. (--enable-float4-byval)]) float4passbyval=true], [float4passbyval=false]) AC_MSG_RESULT([$enable_float4_byval]) AC_DEFINE_UNQUOTED([FLOAT4PASSBYVAL], [$float4passbyval], [float4 values are passed by value if 'true', by reference if 'false']) # Decide whether float8 is passed by value. # Note: this setting also controls int8 and related types such as timestamp. # If sizeof(Datum) >= 8, this is user-selectable, enabled by default. # If not, trying to select it is an error. AC_MSG_CHECKING([whether to build with float8 passed by value]) if test $ac_cv_sizeof_unsigned_long -ge 8 ; then PGAC_ARG_BOOL(enable, float8-byval, yes, [disable float8 passed by value]) else PGAC_ARG_BOOL(enable, float8-byval, no, [disable float8 passed by value]) if test "$enable_float8_byval" = yes ; then AC_MSG_ERROR([--enable-float8-byval is not supported on 32-bit platforms.]) fi fi if test "$enable_float8_byval" = yes ; then AC_DEFINE([USE_FLOAT8_BYVAL], 1, [Define to 1 if you want float8, int8, etc values to be passed by value. (--enable-float8-byval)]) float8passbyval=true else float8passbyval=false fi AC_MSG_RESULT([$enable_float8_byval]) AC_DEFINE_UNQUOTED([FLOAT8PASSBYVAL], [$float8passbyval], [float8, int8, and related values are passed by value if 'true', by reference if 'false']) dnl Rest of part cannot be executed by autocnf-2.59. dnl AC_CHECK_ALIGNOF is supported autoconf-2.60 or higher. dnl ===== Copied from PostgreSQL's configure start ===== dnl Checks for sockaddr_storage structure, members and necessary types m4_include([ac_func_accept_argtypes.m4]) AC_CHECK_TYPES([struct sockaddr_storage], [], [], [#include #ifdef HAVE_SYS_SOCKET_H #include #endif ]) AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family, struct sockaddr_storage.__ss_family, struct sockaddr_storage.ss_len, struct sockaddr_storage.__ss_len, struct sockaddr.sa_len], [], [], [#include #ifdef HAVE_SYS_SOCKET_H #include #endif ]) AC_CHECK_TYPES([union semun],[],[],[#include #include #include ]) dnl Checks for library functions. AC_TYPE_SIGNAL AC_FUNC_VPRINTF AC_FUNC_WAIT3 AC_FUNC_ACCEPT_ARGTYPES AC_CHECK_FUNCS(setsid select socket sigprocmask strdup strerror strftime strtok asprintf vasprintf gai_strerror hstrerror pstat setproctitle vsyslog) dnl Checks for pg_config command. AC_CHECK_PROGS(PGCONFIG, pg_config) if test -z $PGCONFIG then PGSQL_INCLUDE_DIR=/usr/local/pgsql/include PGSQL_LIB_DIR=/usr/local/pgsql/lib else PGSQL_INCLUDE_DIR=`pg_config --includedir` PGSQL_LIB_DIR=`pg_config --libdir` fi AC_ARG_WITH(pgsql, [ --with-pgsql=DIR site header files for PostgreSQL in DIR], [ case "$withval" in "" | y | ye | yes | n | no) AC_MSG_ERROR([*** You must supply an argument to the --with-pgsql option.]) ;; esac PGSQL_INCLUDE_DIR="$withval"/include PGSQL_LIB_DIR="$withval"/lib ]) AC_ARG_WITH(pgsql-includedir, [ --with-pgsql-includedir=DIR site header files for PostgreSQL in DIR], [ case "$withval" in "" | y | ye | yes | n | no) AC_MSG_ERROR([*** You must supply an argument to the --with-pgsql-includedir option.]) ;; esac PGSQL_INCLUDE_DIR="$withval" ]) AC_ARG_WITH(pgsql-libdir, [ --with-pgsql-libdir=DIR site library files for PostgreSQL in DIR], [ case "$withval" in "" | y | ye | yes | n | no) AC_MSG_ERROR([*** You must supply an argument to the --with-pgsql-libdir option.]) ;; esac PGSQL_LIB_DIR="$withval" ]) AC_ARG_WITH(openssl, [ --with-openssl build with OpenSSL support], [], [openssl=no]) if test "$with_openssl" = yes || test "$with_openssl" = auto; then AC_CHECK_HEADERS(openssl/ssl.h, [AC_DEFINE([USE_SSL], 1, [Define to 1 to build with SSL support. (--with-openssl)])], [ if test "$with_openssl" = yes; then AC_MSG_ERROR([header file is required for SSL]) else AC_MSG_WARN([header file is required for SSL]) fi ]) AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])]) AC_CHECK_LIB(ssl, SSL_library_init, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])]) fi AC_ARG_WITH(pam, [ --with-pam build with PAM support], [AC_DEFINE([USE_PAM], 1, [Define to 1 to build with PAM support. (--with-pam)])]) if test "$with_pam" = yes ; then AC_CHECK_LIB(pam, pam_start, [], [AC_MSG_ERROR([library 'pam' is required for PAM])]) AC_CHECK_HEADERS(security/pam_appl.h, [], [AC_CHECK_HEADERS(pam/pam_appl.h, [], [AC_MSG_ERROR([header file or is required for PAM.])])]) fi AC_ARG_WITH(memcached, [ --with-memcached=DIR site header files for libmemcached in DIR], [ case "$withval" in "" | y | ye | yes | n | no) AC_MSG_ERROR([*** You must supply an argument to the --with-memcached option.]) ;; *) MEMCACHED_INCLUDE_DIR="$withval"/include MEMCACHED_LIB_DIR="$withval"/lib OLD_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -I$MEMCACHED_INCLUDE_DIR" AC_CHECK_HEADERS( [libmemcached/memcached.h], [AC_DEFINE([USE_MEMCACHED], 1, [Define to 1 to build with memcached support])], [AC_MSG_ERROR([header file is required for memcached support])]) CFLAGS=$OLD_CFLAGS AC_CHECK_LIB(memcached, memcached_create, [], [AC_MSG_ERROR(libmemcached is not installed)]) MEMCACHED_INCLUDE_OPT="-I $MEMCACHED_INCLUDE_DIR" MEMCACHED_LINK_OPT="-L$MEMCACHED_LIB_DIR" MEMCACHED_RPATH_OPT="-rpath $MEMCACHED_LIB_DIR" ;; esac ]) AC_SUBST(MEMCACHED_INCLUDE_OPT) AC_SUBST(MEMCACHED_LINK_OPT) AC_SUBST(MEMCACHED_RPATH_OPT) OLD_LDFLAGS="$LDFLAGS" LDFLAGS="-L$PGSQL_LIB_DIR" OLD_LIBS="$LIBS" AC_CHECK_LIB(pq, PQexecPrepared, [], [AC_MSG_ERROR(libpq is not installed or libpq is old)]) AC_CHECK_FUNCS(PQprepare) LDFLAGS="$OLD_LDFLAGS" LIBS="$OLD_LIBS" AC_SUBST(PGSQL_INCLUDE_DIR) AC_SUBST(PGSQL_LIB_DIR) AC_SUBST(MEMCACHED_DIR) # --enable(disable)-rpath option AC_ARG_ENABLE(rpath, [ --disable-rpath do not embed shared library search path in executables], [case "${enableval}" in yes) rpath=yes ;; no) rpath=no ;; esac], [rpath=yes] ) AM_CONDITIONAL([enable_rpath], test x$rpath = xyes) # Decide whether to use row lock against the sequence table for insert_lock. # This lock method is compatible with pgpool-II 3.0 series(until 3.0.4). AC_MSG_CHECKING([whether to use row lock against the sequence table for insert_lock]) PGAC_ARG_BOOL(enable, sequence-lock, no, [insert_lock compatible with pgpool-II 3.0 series (until 3.0.4)]) if test "$enable_sequence_lock" = yes && test "$enable_table_lock" = yes ; then AC_MSG_ERROR([--enable-table-lock cannot be enabled at the same time.]) fi if test "$enable_sequence_lock" = yes ; then AC_DEFINE([USE_SEQUENCE_LOCK], 1, [Define to 1 if you want to use row lock against the sequence table for insert_lock. (--enable-sequence-lock)]) fi AC_MSG_RESULT([$enable_sequence_lock]) # Decide whether to use table lock against the target table for insert_lock. # This lock method is compatible with pgpool-II 2.2 and 2.3 series. AC_MSG_CHECKING([whether to use table lock against the target table for insert_lock]) PGAC_ARG_BOOL(enable, table-lock, no, [insert_lock compatible with pgpool-II 2.2 and 2.3 series]) if test "$enable_table_lock" = yes && test "$enable_sequence_lock" = yes ; then AC_MSG_ERROR([--enable-sequence-lock cannot be enabled at the same time.]) fi if test "$enable_table_lock" = yes ; then AC_DEFINE([USE_TABLE_LOCK], 1, [Define to 1 if you want to use table lock against the target table for insert_lock. (--enable-table-lock)]) fi AC_MSG_RESULT([$enable_table_lock]) AM_CONFIG_HEADER(config.h) AC_OUTPUT([Makefile parser/Makefile pcp/Makefile watchdog/Makefile]) pgpool-II-3.3.2/ps_status.c0000664000076400007640000002412512245576267012466 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * This file was imported from PostgreSQL source code. * See below for the copyright and description. * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2012 PgPool Global Development Group * */ /*-------------------------------------------------------------------- * ps_status.c * * Routines to support changing the ps display of PostgreSQL backends * to contain some useful information. Mechanism differs wildly across * platforms. * * $PostgreSQL: pgsql/src/backend/utils/misc/ps_status.c,v 1.33 2006/10/04 00:30:04 momjian Exp $ * * Copyright (c) 2000-2006, PostgreSQL Global Development Group * various details abducted from various places *-------------------------------------------------------------------- */ #include #ifdef HAVE_SYS_PSTAT_H #include /* for HP-UX */ #endif #ifdef HAVE_PS_STRINGS #include /* for old BSD */ #include #endif #if defined(__darwin__) #include #endif #include "pool.h" #include #include extern char **environ; bool update_process_title = true; /* * Alternative ways of updating ps display: * * PS_USE_SETPROCTITLE * use the function setproctitle(const char *, ...) * (newer BSD systems) * PS_USE_PSTAT * use the pstat(PSTAT_SETCMD, ) * (HPUX) * PS_USE_PS_STRINGS * assign PS_STRINGS->ps_argvstr = "string" * (some BSD systems) * PS_USE_CHANGE_ARGV * assign argv[0] = "string" * (some other BSD systems) * PS_USE_CLOBBER_ARGV * write over the argv and environment area * (most SysV-like systems) * PS_USE_WIN32 * push the string out as the name of a Windows event * PS_USE_NONE * don't update ps display * (This is the default, as it is safest.) */ #if defined(HAVE_SETPROCTITLE) #define PS_USE_SETPROCTITLE #elif defined(HAVE_PSTAT) && defined(PSTAT_SETCMD) #define PS_USE_PSTAT #elif defined(HAVE_PS_STRINGS) #define PS_USE_PS_STRINGS #elif (defined(BSD) || defined(__bsdi__) || defined(__hurd__)) && !defined(__darwin__) #define PS_USE_CHANGE_ARGV #elif defined(__linux__) || defined(_AIX) || defined(__sgi) || (defined(sun) && !defined(BSD)) || defined(ultrix) || defined(__ksr__) || defined(__osf__) || defined(__svr4__) || defined(__svr5__) || defined(__darwin__) #define PS_USE_CLOBBER_ARGV #elif defined(WIN32) #define PS_USE_WIN32 #else #define PS_USE_NONE #endif /* Different systems want the buffer padded differently */ #if defined(_AIX) || defined(__linux__) || defined(__svr4__) #define PS_PADDING '\0' #else #define PS_PADDING ' ' #endif #ifndef PS_USE_CLOBBER_ARGV /* all but one options need a buffer to write their ps line in */ #define PS_BUFFER_SIZE 256 static char ps_buffer[PS_BUFFER_SIZE]; static const size_t ps_buffer_size = PS_BUFFER_SIZE; #else /* PS_USE_CLOBBER_ARGV */ static char *ps_buffer; /* will point to argv area */ static size_t ps_buffer_size; /* space determined at run time */ #endif /* PS_USE_CLOBBER_ARGV */ static size_t ps_buffer_fixed_size; /* size of the constant prefix */ /* save the original argv[] location here */ static int save_argc; static char **save_argv; /* * Call this early in startup to save the original argc/argv values. * If needed, we make a copy of the original argv[] array to preserve it * from being clobbered by subsequent ps_display actions. * * (The original argv[] will not be overwritten by this routine, but may be * overwritten during init_ps_display. Also, the physical location of the * environment strings may be moved, so this should be called before any code * that might try to hang onto a getenv() result.) */ char ** save_ps_display_args(int argc, char **argv) { save_argc = argc; save_argv = argv; #if defined(PS_USE_CLOBBER_ARGV) /* * If we're going to overwrite the argv area, count the available space. * Also move the environment to make additional room. */ { char *end_of_area = NULL; char **new_environ; int i; /* * check for contiguous argv strings */ for (i = 0; i < argc; i++) { if (i == 0 || end_of_area + 1 == argv[i]) end_of_area = argv[i] + strlen(argv[i]); } if (end_of_area == NULL) /* probably can't happen? */ { ps_buffer = NULL; ps_buffer_size = 0; return argv; } /* * check for contiguous environ strings following argv */ for (i = 0; environ[i] != NULL; i++) { if (end_of_area + 1 == environ[i]) end_of_area = environ[i] + strlen(environ[i]); } ps_buffer = argv[0]; ps_buffer_size = end_of_area - argv[0]; /* * move the environment out of the way */ new_environ = (char **) malloc((i + 1) * sizeof(char *)); for (i = 0; environ[i] != NULL; i++) new_environ[i] = strdup(environ[i]); new_environ[i] = NULL; environ = new_environ; } #endif /* PS_USE_CLOBBER_ARGV */ #if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV) /* * If we're going to change the original argv[] then make a copy for * argument parsing purposes. * * (NB: do NOT think to remove the copying of argv[], even though * postmaster.c finishes looking at argv[] long before we ever consider * changing the ps display. On some platforms, getopt() keeps pointers * into the argv array, and will get horribly confused when it is * re-called to analyze a subprocess' argument string if the argv storage * has been clobbered meanwhile. Other platforms have other dependencies * on argv[]. */ { char **new_argv; int i; new_argv = (char **) malloc((argc + 1) * sizeof(char *)); for (i = 0; i < argc; i++) new_argv[i] = strdup(argv[i]); new_argv[argc] = NULL; #if defined(__darwin__) /* * Darwin (and perhaps other NeXT-derived platforms?) has a static * copy of the argv pointer, which we may fix like so: */ *_NSGetArgv() = new_argv; #endif argv = new_argv; } #endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */ return argv; } /* * Call this once during subprocess startup to set the identification * values. At this point, the original argv[] array may be overwritten. */ void init_ps_display(const char *username, const char *dbname, const char *host_info, const char *initial_str) { #ifndef PS_USE_NONE /* no ps display if you didn't call save_ps_display_args() */ if (!save_argv) return; #ifdef PS_USE_CLOBBER_ARGV /* If ps_buffer is a pointer, it might still be null */ if (!ps_buffer) return; #endif /* * Overwrite argv[] to point at appropriate space, if needed */ #ifdef PS_USE_CHANGE_ARGV save_argv[0] = ps_buffer; save_argv[1] = NULL; #endif /* PS_USE_CHANGE_ARGV */ #ifdef PS_USE_CLOBBER_ARGV { int i; /* make extra argv slots point at end_of_area (a NUL) */ for (i = 1; i < save_argc; i++) save_argv[i] = ps_buffer + ps_buffer_size; } #endif /* PS_USE_CLOBBER_ARGV */ /* * Make fixed prefix of ps display. */ #ifdef PS_USE_SETPROCTITLE /* * apparently setproctitle() already adds a `progname: ' prefix to the * ps line */ snprintf(ps_buffer, ps_buffer_size, ""); #else snprintf(ps_buffer, ps_buffer_size, "pgpool: "); #endif ps_buffer_fixed_size = strlen(ps_buffer); set_ps_display(initial_str, true); #endif /* not PS_USE_NONE */ } /* * Call this to update the ps status display to a fixed prefix plus an * indication of what you're currently doing passed in the argument. */ void set_ps_display(const char *activity, bool force) { if (!force && !update_process_title) return; #ifndef PS_USE_NONE #ifdef PS_USE_CLOBBER_ARGV /* If ps_buffer is a pointer, it might still be null */ if (!ps_buffer) return; #endif /* Update ps_buffer to contain both fixed part and activity */ strlcpy(ps_buffer + ps_buffer_fixed_size, activity, ps_buffer_size - ps_buffer_fixed_size); /* Transmit new setting to kernel, if necessary */ #ifdef PS_USE_SETPROCTITLE setproctitle("%s", ps_buffer); #endif #ifdef PS_USE_PSTAT { union pstun pst; pst.pst_command = ps_buffer; pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); } #endif /* PS_USE_PSTAT */ #ifdef PS_USE_PS_STRINGS PS_STRINGS->ps_nargvstr = 1; PS_STRINGS->ps_argvstr = ps_buffer; #endif /* PS_USE_PS_STRINGS */ #ifdef PS_USE_CLOBBER_ARGV { int buflen; /* pad unused memory */ buflen = strlen(ps_buffer); memset(ps_buffer + buflen, PS_PADDING, ps_buffer_size - buflen); } #endif /* PS_USE_CLOBBER_ARGV */ #ifdef PS_USE_WIN32 { /* * Win32 does not support showing any changed arguments. To make it at * all possible to track which backend is doing what, we create a * named object that can be viewed with for example Process Explorer. */ static HANDLE ident_handle = INVALID_HANDLE_VALUE; char name[PS_BUFFER_SIZE + 32]; if (ident_handle != INVALID_HANDLE_VALUE) CloseHandle(ident_handle); sprintf(name, "pgident: %s", ps_buffer); ident_handle = CreateEvent(NULL, TRUE, FALSE, name); } #endif /* PS_USE_WIN32 */ #endif /* not PS_USE_NONE */ } /* * Returns what's currently in the ps display, in case someone needs * it. Note that only the activity part is returned. On some platforms * the string will not be null-terminated, so return the effective * length into *displen. */ const char * get_ps_display(int *displen) { #ifdef PS_USE_CLOBBER_ARGV size_t offset; /* If ps_buffer is a pointer, it might still be null */ if (!ps_buffer) { *displen = 0; return ""; } /* Remove any trailing spaces to offset the effect of PS_PADDING */ offset = ps_buffer_size; while (offset > ps_buffer_fixed_size && ps_buffer[offset - 1] == PS_PADDING) offset--; *displen = offset - ps_buffer_fixed_size; #else *displen = strlen(ps_buffer + ps_buffer_fixed_size); #endif return ps_buffer + ps_buffer_fixed_size; } /* * Show ps idle status */ void pool_ps_idle_display(POOL_CONNECTION_POOL *backend) { StartupPacket *sp; char psbuf[1024]; sp = MASTER_CONNECTION(backend)->sp; if (MASTER(backend)->tstate == 'T') snprintf(psbuf, sizeof(psbuf), "%s %s %s idle in transaction", sp->user, sp->database, remote_ps_data); else snprintf(psbuf, sizeof(psbuf), "%s %s %s idle", sp->user, sp->database, remote_ps_data); set_ps_display(psbuf, false); } pgpool-II-3.3.2/pool_ipc.h0000664000076400007640000000236112245576256012246 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2008, PgPool Global Development Group * Portions Copyright (c) 2003-2004, PostgreSQL Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #ifndef IPC_H #define IPC_H typedef unsigned long Datum; /* XXX sizeof(long) >= sizeof(void *) */ #define IPCProtection (0600) /* access/modify by user only */ extern void shmem_exit(int code); extern void on_shmem_exit(void (*function) (int code, Datum arg), Datum arg); extern void on_exit_reset(void); #endif /* IPC_H */ pgpool-II-3.3.2/general.m40000664000076400007640000001351012063517515012135 00000000000000# $PostgreSQL: pgsql/config/general.m4,v 1.10 2008/10/29 09:27:24 petere Exp $ # This file defines new macros to process configure command line # arguments, to replace the brain-dead AC_ARG_WITH and AC_ARG_ENABLE. # The flaw in these is particularly that they only differentiate # between "given" and "not given" and do not provide enough help to # process arguments that only accept "yes/no", that require an # argument (other than "yes/no"), etc. # # The point of this implementation is to reduce code size and # redundancy in configure.in and to improve robustness and consistency # in the option evaluation code. # Convert type and name to shell variable name (e.g., "enable_long_strings") m4_define([pgac_arg_to_variable], [$1[]_[]patsubst($2, -, _)]) # PGAC_ARG(TYPE, NAME, HELP-STRING-LHS-EXTRA, HELP-STRING-RHS, # [ACTION-IF-YES], [ACTION-IF-NO], [ACTION-IF-ARG], # [ACTION-IF-OMITTED]) # ------------------------------------------------------------ # This is the base layer. TYPE is either "with" or "enable", depending # on what you like. NAME is the rest of the option name. # HELP-STRING-LHS-EXTRA is a string to append to the option name on # the left-hand side of the help output, e.g., an argument name. If # set to "-", append nothing, but let the option appear in the # negative form (disable/without). HELP-STRING-RHS is the option # description, for the right-hand side of the help output. # ACTION-IF-YES is executed if the option is given without an argument # (or "yes", which is the same); similar for ACTION-IF-NO. AC_DEFUN([PGAC_ARG], [ pgac_args="$pgac_args pgac_arg_to_variable([$1],[$2])" m4_case([$1], enable, [ AC_ARG_ENABLE([$2], [AS_HELP_STRING([--]m4_if($3, -, disable, enable)[-$2]m4_if($3, -, , $3), [$4])], [ case [$]enableval in yes) m4_default([$5], :) ;; no) m4_default([$6], :) ;; *) $7 ;; esac ], [$8])[]dnl AC_ARG_ENABLE ], with, [ AC_ARG_WITH([$2], [AS_HELP_STRING([--]m4_if($3, -, without, with)[-$2]m4_if($3, -, , $3), [$4])], [ case [$]withval in yes) m4_default([$5], :) ;; no) m4_default([$6], :) ;; *) $7 ;; esac ], [$8])[]dnl AC_ARG_WITH ], [m4_fatal([first argument of $0 must be 'enable' or 'with', not '$1'])] ) ])# PGAC_ARG # PGAC_ARG_CHECK() # ---------------- # Checks if the user passed any --with/without/enable/disable # arguments that were not defined. Just prints out a warning message, # so this should be called near the end, so the user will see it. AC_DEFUN([PGAC_ARG_CHECK], [for pgac_var in `set | sed 's/=.*//' | $EGREP 'with_|enable_'`; do for pgac_arg in $pgac_args with_gnu_ld; do if test "$pgac_var" = "$pgac_arg"; then continue 2 fi done pgac_txt=`echo $pgac_var | sed 's/_/-/g'` AC_MSG_WARN([option ignored: --$pgac_txt]) done])# PGAC_ARG_CHECK # PGAC_ARG_BOOL(TYPE, NAME, DEFAULT, HELP-STRING-RHS, # [ACTION-IF-YES], [ACTION-IF-NO]) # --------------------------------------------------- # Accept a boolean option, that is, one that only takes yes or no. # ("no" is equivalent to "disable" or "without"). DEFAULT is what # should be done if the option is omitted; it should be "yes" or "no". # (Consequently, one of ACTION-IF-YES and ACTION-IF-NO will always # execute.) AC_DEFUN([PGAC_ARG_BOOL], [dnl The following hack is necessary because in a few instances this dnl macro is called twice for the same option with different default dnl values. But we only want it to appear once in the help. We achieve dnl that by making the help string look the same, which is why we need to dnl save the default that was passed in previously. m4_define([_pgac_helpdefault], m4_ifdef([pgac_defined_$1_$2_bool], [m4_defn([pgac_defined_$1_$2_bool])], [$3]))dnl PGAC_ARG([$1], [$2], [m4_if(_pgac_helpdefault, yes, -)], [$4], [$5], [$6], [AC_MSG_ERROR([no argument expected for --$1-$2 option])], [m4_case([$3], yes, [pgac_arg_to_variable([$1], [$2])=yes $5], no, [pgac_arg_to_variable([$1], [$2])=no $6], [m4_fatal([third argument of $0 must be 'yes' or 'no', not '$3'])])])[]dnl m4_define([pgac_defined_$1_$2_bool], [$3])dnl ])# PGAC_ARG_BOOL # PGAC_ARG_REQ(TYPE, NAME, HELP-ARGNAME, HELP-STRING-RHS, # [ACTION-IF-GIVEN], [ACTION-IF-NOT-GIVEN]) # ------------------------------------------------------- # This option will require an argument; "yes" or "no" will not be # accepted. HELP-ARGNAME is a name for the argument for the help output. AC_DEFUN([PGAC_ARG_REQ], [PGAC_ARG([$1], [$2], [=$3], [$4], [AC_MSG_ERROR([argument required for --$1-$2 option])], [AC_MSG_ERROR([argument required for --$1-$2 option])], [$5], [$6])])# PGAC_ARG_REQ # PGAC_ARG_OPTARG(TYPE, NAME, HELP-ARGNAME, HELP-STRING-RHS, # [DEFAULT-ACTION], [ARG-ACTION], # [ACTION-ENABLED], [ACTION-DISABLED]) # ---------------------------------------------------------- # This will create an option that behaves as follows: If omitted, or # called with "no", then set the enable_variable to "no" and do # nothing else. If called with "yes", then execute DEFAULT-ACTION. If # called with argument, set enable_variable to "yes" and execute # ARG-ACTION. Additionally, execute ACTION-ENABLED if we ended up with # "yes" either way, else ACTION-DISABLED. # # The intent is to allow enabling a feature, and optionally pass an # additional piece of information. AC_DEFUN([PGAC_ARG_OPTARG], [PGAC_ARG([$1], [$2], [@<:@=$3@:>@], [$4], [$5], [], [pgac_arg_to_variable([$1], [$2])=yes $6], [pgac_arg_to_variable([$1], [$2])=no]) dnl Add this code only if there's a ACTION-ENABLED or ACTION-DISABLED. m4_ifval([$7[]$8], [ if test "[$]pgac_arg_to_variable([$1], [$2])" = yes; then m4_default([$7], :) m4_ifval([$8], [else $8 ])[]dnl fi ])[]dnl ])# PGAC_ARG_OPTARG pgpool-II-3.3.2/config.guess0000775000076400007640000013010612245576256012610 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. timestamp='2007-01-15' # This file 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 2 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, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown if [ "${UNAME_SYSTEM}" = "Linux" ] ; then eval $set_cc_for_build cat << EOF > $dummy.c #include #ifdef __UCLIBC__ # ifdef __UCLIBC_CONFIG_VERSION__ LIBC=uclibc __UCLIBC_CONFIG_VERSION__ # else LIBC=uclibc # endif #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep LIBC= | sed -e 's: ::g'` fi # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[3456]*) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T:Interix*:[3456]* | authenticamd:Interix*:[3456]*) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo cris-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo frv-unknown-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-${LIBC} exit ;; xtensa:Linux:*:*) echo xtensa-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-${LIBC}" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-${LIBC}aout" exit ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-${LIBC}coff" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-${LIBC}oldld" exit ;; esac # This should get integrated into the C code below, but now we hack if [ "$LIBC" != "gnu" ] ; then echo "$TENTATIVE" && exit 0 ; fi # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: pgpool-II-3.3.2/pool_timestamp.h0000664000076400007640000000266412245576267013506 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2011 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_timestamp.h.: header file for pool_timestamp.c, * pool_process_query.c, pool_proto_modules.c * */ #ifndef POOL_TIMESTAMP_H #define POOL_TIMESTAMP_H #include "pool.h" #include "pool_proto_modules.h" #include "parser/nodes.h" #include "pool_session_context.h" extern char *rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, bool rewrite_to_params, POOL_SENT_MESSAGE *message); extern char *bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, POOL_SENT_MESSAGE *message, const char *orig_msg, int *len); extern bool isSystemType(Node *node, const char *name); #endif /* POOL_TIMESTAMP_H */ pgpool-II-3.3.2/m4/0000775000076400007640000000000012245776614010667 500000000000000pgpool-II-3.3.2/m4/libtool.m40000664000076400007640000077341112245576256012532 00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool 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 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 56 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl _LT_PROG_ECHO_BACKSLASH case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\[$]0 --fallback-echo"')dnl " lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` ;; esac _LT_OUTPUT_LIBTOOL_INIT ]) # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) cat >"$CONFIG_LT" <<_LTEOF #! $SHELL # Generated by $as_me. # Run this file to recreate a libtool stub with the current configuration. lt_cl_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2008 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. if test "$no_create" != yes; then lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) fi ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_XSI_SHELLFNS sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES # -------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(whole_archive_flag_spec, $1)='' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX # ----------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl AC_LINK_IFELSE(AC_LANG_PROGRAM,[ lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], [AC_DIVERT_PUSH(NOTICE)]) $1 AC_DIVERT_POP ])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Add some code to the start of the generated configure script which # will find an echo command which doesn't interpret backslashes. m4_defun([_LT_PROG_ECHO_BACKSLASH], [_LT_SHELL_INIT([ # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` ;; esac ECHO=${lt_ECHO-echo} if test "X[$]1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X[$]1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} fi if test "X[$]1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF [$]* _LT_EOF exit 0 fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL [$]0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL [$]0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "[$]0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" fi AC_SUBST(lt_ECHO) ]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that does not interpret backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [AC_CHECK_TOOL(AR, ar, false) test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1]) AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line __oline__ "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[123]]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix[[3-9]]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method == "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= AC_MSG_CHECKING([for $compiler option to produce PIC]) m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC*) # IBM XL 8.0 on PPC _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl*) # IBM XL C 8.0/Fortran 10.1 on PPC _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Sun\ F*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag= tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; freebsd1*) _LT_TAGVAR(ld_shlibs, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE(int foo(void) {}, _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ) LDFLAGS="$save_LDFLAGS" else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_MSG_CHECKING([whether -lc should be explicitly linked in]) $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then _LT_TAGVAR(archive_cmds_need_lc, $1)=no else _LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], [[If ld is used when linking, flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [fix_srcfile_path], [1], [Fix the shell variable $srcfile for the compiler]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_PROG_CXX # ------------ # Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ # compiler, we have our own version here. m4_defun([_LT_PROG_CXX], [ pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) AC_PROG_CXX if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_CXX dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_CXX], []) # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [AC_REQUIRE([_LT_PROG_CXX])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd[[12]]*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 will use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; xl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=echo else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ]) dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p in -L* | -R*) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi ;; *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_PROG_F77 # ------------ # Since AC_PROG_F77 is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_F77], [ pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) AC_PROG_F77 if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_F77 dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_F77], []) # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_REQUIRE([_LT_PROG_F77])dnl AC_LANG_PUSH(Fortran 77) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC CC=${F77-"f77"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_PROG_FC # ----------- # Since AC_PROG_FC is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_FC], [ pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) AC_PROG_FC if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_FC dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_FC], []) # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_REQUIRE([_LT_PROG_FC])dnl AC_LANG_PUSH(Fortran) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC CC=${FC-"f95"} compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC="$lt_save_CC" ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC GCC= CC=${RC-"windres"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC="$lt_save_CC" ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_XSI_SHELLFNS # --------------------- # Bourne and XSI compatible variants of some useful shell functions. m4_defun([_LT_PROG_XSI_SHELLFNS], [case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $[*] )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } dnl func_dirname_and_basename dnl A portable version of this function is already defined in general.m4sh dnl so there is no need for it here. # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[[^=]]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$[@]"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]+=\$[2]" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]=\$$[1]\$[2]" } _LT_EOF ;; esac ]) pgpool-II-3.3.2/m4/ltversion.m40000664000076400007640000000127712245576256013105 00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # Generated from ltversion.in. # serial 3017 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.2.6b]) m4_define([LT_PACKAGE_REVISION], [1.3017]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.2.6b' macro_revision='1.3017' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) pgpool-II-3.3.2/m4/lt~obsolete.m40000664000076400007640000001311312245576256013422 00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 4 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) pgpool-II-3.3.2/m4/ltoptions.m40000664000076400007640000002724212245576256013113 00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [0], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) pgpool-II-3.3.2/m4/ltsugar.m40000664000076400007640000001042412063517527012525 00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) pgpool-II-3.3.2/pcp_child.c0000664000076400007640000011550412245576266012367 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2011 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pcp_child.c: PCP child process main * */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_NETINET_TCP_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #include #include #ifdef HAVE_FCNTL_H #include #endif #include "pool.h" #include "pcp/pcp_stream.h" #include "pcp/pcp.h" #include "md5.h" #include "pool_config.h" #include "pool_process_context.h" #include "pool_process_reporting.h" #include "watchdog/wd_ext.h" #define MAX_FILE_LINE_LEN 512 #define MAX_USER_PASSWD_LEN 128 extern void pcp_set_timeout(long sec); volatile sig_atomic_t pcp_exit_request; /* non 0 means SIGTERM(smart shutdown) or SIGINT(fast shutdown) has arrived */ static RETSIGTYPE die(int sig); static PCP_CONNECTION *pcp_do_accept(int unix_fd, int inet_fd); static void unset_nonblock(int fd); static int user_authenticate(char *buf, char *passwd_file, char *salt, int salt_len); static RETSIGTYPE wakeup_handler(int sig); static RETSIGTYPE reload_config_handler(int sig); static RETSIGTYPE restart_handler(int sig); static int pool_detach_node(int node_id, bool gracefully); static int pool_promote_node(int node_id, bool gracefully); extern int myargc; extern char **myargv; static volatile sig_atomic_t pcp_got_sighup = 0; volatile sig_atomic_t pcp_wakeup_request = 0; static volatile sig_atomic_t pcp_restart_request = 0; #define CHECK_RESTART_REQUEST \ do { \ if (pcp_restart_request) \ { \ pool_log("pcp child process received restart request"); \ exit(1); \ } \ else \ { \ pool_initialize_private_backend_status(); \ } \ } while (0) void pcp_do_child(int unix_fd, int inet_fd, char *pcp_conf_file) { PCP_CONNECTION *frontend = NULL; int authenticated = 0; struct timeval uptime; char salt[4]; int random_salt = 0; int i; char tos; int rsize; char *buf = NULL; pool_debug("I am PCP %d", getpid()); /* Identify myself via ps */ init_ps_display("", "", "", ""); gettimeofday(&uptime, NULL); srandom((unsigned int) (getpid() ^ uptime.tv_usec)); /* set pcp_read() timeout */ pcp_set_timeout(pool_config->pcp_timeout); /* set up signal handlers */ signal(SIGTERM, die); signal(SIGINT, die); signal(SIGHUP, reload_config_handler); signal(SIGQUIT, die); signal(SIGCHLD, SIG_DFL); signal(SIGUSR1, restart_handler); signal(SIGUSR2, wakeup_handler); signal(SIGPIPE, SIG_IGN); signal(SIGALRM, SIG_IGN); /* Initialize my backend status */ pool_initialize_private_backend_status(); /* Initialize process context */ pool_init_process_context(); for(;;) { errno = 0; CHECK_RESTART_REQUEST; if (frontend == NULL) { frontend = pcp_do_accept(unix_fd, inet_fd); if (frontend == NULL) continue; unset_nonblock(frontend->fd); } /* read a PCP packet */ if (pcp_read(frontend, &tos, 1)) { if (errorcode == TIMEOUTERR) { pool_debug("pcp_child: pcp_read() has timed out"); authenticated = 0; pcp_close(frontend); frontend = NULL; free(buf); buf = NULL; continue; } pool_error("pcp_child: pcp_read() failed. reason: %s", strerror(errno)); exit(1); } if (pcp_read(frontend, &rsize, sizeof(int))) { if (errorcode == TIMEOUTERR) { pool_debug("pcp_child: pcp_read() has timed out"); authenticated = 0; pcp_close(frontend); frontend = NULL; free(buf); buf = NULL; continue; } pool_error("pcp_child: pcp_read() failed. reason: %s", strerror(errno)); exit(1); } rsize = ntohl(rsize); if ((rsize - sizeof(int)) > 0) { buf = (char *)malloc(rsize - sizeof(int)); if (buf == NULL) { pool_error("pcp_child: malloc() failed. reason: %s", strerror(errno)); exit(1); } if (pcp_read(frontend, buf, rsize - sizeof(int))) { if (errorcode == TIMEOUTERR) { pool_debug("pcp_child: pcp_read() has timed out"); authenticated = 0; pcp_close(frontend); frontend = NULL; free(buf); buf = NULL; continue; } pool_error("pcp_child: pcp_read() failed. reason: %s", strerror(errno)); exit(1); } } /* is this connection authenticated? if not disconnect immediately*/ if ((! authenticated) && (tos != 'R' && tos != 'M')) { pool_debug("pcp_child: connection not authorized"); free(buf); buf = NULL; pcp_close(frontend); frontend = NULL; pool_signal(SIGALRM, SIG_IGN); continue; } /* process a request */ pool_debug("pcp_child: received PCP packet type of service '%c'", tos); set_ps_display("PCP: processing a request", false); if (tos == 'C' || tos == 'd' || tos == 'D' || tos == 'j' || tos == 'J' || tos == 'O' || tos == 'T') { if (Req_info->switching) { int len; int wsize; char *msg; if (Req_info->kind == NODE_UP_REQUEST) msg = "FailbackInProgress"; else if (Req_info->kind == NODE_DOWN_REQUEST) msg = "FailoverInProgress"; else if (Req_info->kind == PROMOTE_NODE_REQUEST) msg = "PromotionInProgress"; else msg = "OperationInProgress"; len = strlen(msg) + 1; pcp_write(frontend, "e", 1); wsize = htonl(sizeof(int) + len); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, msg, len); } } switch (tos) { case 'R': /* authentication */ { int wsize; if (random_salt) { authenticated = user_authenticate(buf, pcp_conf_file, salt, 4); } if (!random_salt || !authenticated) { char code[] = "AuthenticationFailed"; char mesg[] = "username and/or password do not match"; pcp_write(frontend, "r", 1); wsize = htonl(sizeof(code) + sizeof(mesg) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); pcp_write(frontend, mesg, sizeof(mesg)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } pool_error("pcp_child: authentication failed"); pcp_close(frontend); frontend = NULL; random_salt = 0; } else { char code[] = "AuthenticationOK"; pcp_write(frontend, "r", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } random_salt = 0; pool_debug("pcp_child: authentication OK"); } break; } case 'M': /* md5 salt */ { int wsize; pool_random_salt(salt); random_salt = 1; pcp_write(frontend, "m", 1); wsize = htonl(sizeof(int) + 4); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, salt, 4); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } pool_debug("pcp_child: salt sent to the client"); break; } case 'L': /* node count */ { int wsize; int node_count = pool_get_node_count(); char code[] = "CommandComplete"; char mesg[16]; snprintf(mesg, sizeof(mesg), "%d", node_count); pcp_write(frontend, "l", 1); wsize = htonl(sizeof(code) + strlen(mesg)+1 + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); pcp_write(frontend, mesg, strlen(mesg)+1); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } pool_debug("pcp_child: %d node(s) found", node_count); break; } case 'I': /* node info */ { int node_id; int wsize; BackendInfo *bi = NULL; node_id = atoi(buf); bi = pool_get_node_info(node_id); if (bi == NULL) { char code[] = "Invalid Node ID"; pcp_write(frontend, "e", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } pool_debug("pcp_child: invalid node ID"); } else { char code[] = "CommandComplete"; char port_str[6]; char status[2]; char weight_str[20]; snprintf(port_str, sizeof(port_str), "%d", bi->backend_port); snprintf(status, sizeof(status), "%d", bi->backend_status); snprintf(weight_str, sizeof(weight_str), "%f", bi->backend_weight); pcp_write(frontend, "i", 1); wsize = htonl(sizeof(code) + strlen(bi->backend_hostname)+1 + strlen(port_str)+1 + strlen(status)+1 + strlen(weight_str)+1 + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); pcp_write(frontend, bi->backend_hostname, strlen(bi->backend_hostname)+1); pcp_write(frontend, port_str, strlen(port_str)+1); pcp_write(frontend, status, strlen(status)+1); pcp_write(frontend, weight_str, strlen(weight_str)+1); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } pool_debug("pcp_child: retrieved node information from shared memory"); } break; } case 'N': /* process count */ { int wsize; int process_count; char process_count_str[16]; int *process_list = NULL; char code[] = "CommandComplete"; char *mesg = NULL; int i; int total_port_len = 0; process_list = pool_get_process_list(&process_count); mesg = (char *)malloc(6*process_count); /* port# is at most 5 characters long (MAX:65535) */ if (mesg == NULL) { pool_error("pcp_child: malloc() failed. reason: %s", strerror(errno)); exit(1); } snprintf(process_count_str, sizeof(process_count_str), "%d", process_count); for (i = 0; i < process_count; i++) { char port[6]; snprintf(port, sizeof(port), "%d", process_list[i]); snprintf(mesg+total_port_len, strlen(port)+1, "%s", port); total_port_len += strlen(port)+1; } pcp_write(frontend, "n", 1); wsize = htonl(sizeof(code) + strlen(process_count_str)+1 + total_port_len + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); pcp_write(frontend, process_count_str, strlen(process_count_str)+1); pcp_write(frontend, mesg, total_port_len); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } free(process_list); free(mesg); pool_debug("pcp_child: %d process(es) found", process_count); break; } case 'P': /* process info */ { int proc_id; int wsize; int num_proc = pool_config->num_init_children; int i; proc_id = atoi(buf); if ((proc_id != 0) && (pool_get_process_info(proc_id) == NULL)) { char code[] = "InvalidProcessID"; pcp_write(frontend, "e", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } pool_debug("pcp_child: invalid process ID"); } else { /* First, send array size of connection_info */ char arr_code[] = "ArraySize"; char con_info_size[16]; /* Finally, indicate that all data is sent */ char fin_code[] = "CommandComplete"; POOL_REPORT_POOLS *pools = get_pools(&num_proc); if (proc_id == 0) { snprintf(con_info_size, sizeof(con_info_size), "%d", num_proc); } else { snprintf(con_info_size, sizeof(con_info_size), "%d", pool_config->max_pool * NUM_BACKENDS); } pcp_write(frontend, "p", 1); wsize = htonl(sizeof(arr_code) + strlen(con_info_size)+1 + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, arr_code, sizeof(arr_code)); pcp_write(frontend, con_info_size, strlen(con_info_size)+1); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); free(pools); exit(1); } /* Second, send process information for all connection_info */ for (i=0; isystem_db_status = SYSDB_STATUS; snprintf(port, sizeof(port), "%d", si->port); snprintf(status, sizeof(status), "%d", si->system_db_status); snprintf(dist_def_num, sizeof(dist_def_num), "%d", si->dist_def_num); pcp_write(frontend, "s", 1); wsize = htonl(sizeof(code) + strlen(si->hostname)+1 + strlen(port)+1 + strlen(si->user)+1 + strlen(si->password)+1 + strlen(si->schema_name)+1 + strlen(si->database_name)+1 + strlen(dist_def_num)+1 + strlen(status)+1 + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); pcp_write(frontend, si->hostname, strlen(si->hostname)+1); pcp_write(frontend, port, strlen(port)+1); pcp_write(frontend, si->user, strlen(si->user)+1); pcp_write(frontend, si->password, strlen(si->password)+1); pcp_write(frontend, si->schema_name, strlen(si->schema_name)+1); pcp_write(frontend, si->database_name, strlen(si->database_name)+1); pcp_write(frontend, dist_def_num, strlen(dist_def_num)+1); pcp_write(frontend, status, strlen(status)+1); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } /* second, send DistDefInfo if any */ if (si->dist_def_num > 0) { char dist_code[] = "DistDefInfo"; char col_num[16]; int col_list_total_len; int type_list_total_len; char *col_list = NULL; char *type_list = NULL; int col_list_offset; int type_list_offset; DistDefInfo *ddi; int i, j; for (i = 0; i < si->dist_def_num; i++) { ddi = &si->dist_def_slot[i]; snprintf(col_num, sizeof(col_num), "%d", ddi->col_num); col_list_total_len = type_list_total_len = 0; for (j = 0; j < ddi->col_num; j++) { col_list_total_len += strlen(ddi->col_list[j]) + 1; type_list_total_len += strlen(ddi->type_list[j]) + 1; } col_list = (char *)malloc(col_list_total_len); type_list = (char *)malloc(type_list_total_len); if (col_list == NULL || type_list == NULL) { pool_error("pcp_child: malloc() failed. reason: %s", strerror(errno)); exit(1); } col_list_offset = type_list_offset = 0; for (j = 0; j < ddi->col_num; j++) { snprintf(col_list + col_list_offset, strlen(ddi->col_list[j])+1, "%s", ddi->col_list[j]); snprintf(type_list + type_list_offset, strlen(ddi->type_list[j])+1, "%s", ddi->type_list[j]); col_list_offset += strlen(ddi->col_list[j]) + 1; type_list_offset += strlen(ddi->type_list[j]) + 1; } pcp_write(frontend, "s", 1); wsize = htonl(sizeof(dist_code) + strlen(ddi->dbname)+1 + strlen(ddi->schema_name)+1 + strlen(ddi->table_name)+1 + strlen(ddi->dist_key_col_name)+1 + strlen(col_num)+1 + col_list_total_len + type_list_total_len + strlen(ddi->dist_def_func)+1 + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, dist_code, sizeof(dist_code)); pcp_write(frontend, ddi->dbname, strlen(ddi->dbname)+1); pcp_write(frontend, ddi->schema_name, strlen(ddi->schema_name)+1); pcp_write(frontend, ddi->table_name, strlen(ddi->table_name)+1); pcp_write(frontend, ddi->dist_key_col_name, strlen(ddi->dist_key_col_name)+1); pcp_write(frontend, col_num, strlen(col_num)+1); pcp_write(frontend, col_list, col_list_total_len); pcp_write(frontend, type_list, type_list_total_len); pcp_write(frontend, ddi->dist_def_func, strlen(ddi->dist_def_func)+1); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } free(col_list); free(type_list); } } pcp_write(frontend, "s", 1); wsize = htonl(sizeof(fin_code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, fin_code, sizeof(fin_code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } pool_debug("pcp_child: retrieved SystemDB information from shared memory"); } break; } case 'W': /* watchdog info */ { int wd_index; int wsize; WdInfo *wi = NULL; if (!pool_config->use_watchdog) { char code[] = "watchdog not enabled"; pcp_write(frontend, "e", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } pool_debug("pcp_child: watcdhog not enabled"); break; } wd_index = atoi(buf); wi = wd_get_watchdog_info(wd_index); if (wi == NULL) { char code[] = "Invalid watchdog index"; pcp_write(frontend, "e", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } pool_debug("pcp_child: invalid watchdog index"); } else { char code[] = "CommandComplete"; char pgpool_port_str[6]; char wd_port_str[6]; char status[2]; snprintf(pgpool_port_str, sizeof(pgpool_port_str), "%d", wi->pgpool_port); snprintf(wd_port_str, sizeof(wd_port_str), "%d", wi->wd_port); snprintf(status, sizeof(status), "%d", wi->status); pcp_write(frontend, "w", 1); wsize = htonl(sizeof(code) + strlen(wi->hostname)+1 + strlen(pgpool_port_str)+1 + strlen(wd_port_str)+1 + strlen(status)+1 + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); pcp_write(frontend, wi->hostname, strlen(wi->hostname)+1); pcp_write(frontend, pgpool_port_str, strlen(pgpool_port_str)+1); pcp_write(frontend, wd_port_str, strlen(wd_port_str)+1); pcp_write(frontend, status, strlen(status)+1); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } pool_debug("pcp_child: retrieved node information from shared memory"); } break; } case 'D': /* detach node */ case 'd': /* detach node gracefully */ { int node_id; int wsize; char code[] = "CommandComplete"; bool gracefully; if (tos == 'D') gracefully = false; else gracefully = true; node_id = atoi(buf); pool_debug("pcp_child: detaching Node ID %d", node_id); pool_detach_node(node_id, gracefully); pcp_write(frontend, "d", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } break; } case 'C': /* attach node */ { int node_id; int wsize; char code[] = "CommandComplete"; node_id = atoi(buf); pool_debug("pcp_child: attaching Node ID %d", node_id); send_failback_request(node_id); pcp_write(frontend, "c", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } break; } case 'T': { char mode = buf[0]; pid_t ppid = getppid(); if (mode == 's') { pool_debug("pcp_child: sending SIGTERM to the parent process(%d)", ppid); kill(ppid, SIGTERM); } else if (mode == 'f') { pool_debug("pcp_child: sending SIGINT to the parent process(%d)", ppid); kill(ppid, SIGINT); } else if (mode == 'i') { pool_debug("pcp_child: sending SIGQUIT to the parent process(%d)", ppid); kill(ppid, SIGQUIT); } else { pool_debug("pcp_child: invalid shutdown mode %c", mode); } break; } case 'O': /* recovery request */ { int node_id; int wsize; char code[] = "CommandComplete"; int r; node_id = atoi(buf); if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) ) { char code[] = "NodeIdOutOfRange"; pool_error("pcp_child: node id %d is not valid", node_id); pcp_write(frontend, "e", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } exit(1); } if ((!REPLICATION && !(MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))) || (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) && node_id == PRIMARY_NODE_ID)) { int len; char *msg; if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP)) msg = "primary server cannot be recovered by online recovery."; else msg = "recovery request is accepted only in replication mode or stereaming replication mode. "; len = strlen(msg)+1; pcp_write(frontend, "e", 1); wsize = htonl(sizeof(int) + len); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, msg, len); } else { pool_debug("pcp_child: start online recovery"); r = start_recovery(node_id); finish_recovery(); if (r == 0) /* success */ { pcp_write(frontend, "c", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); } else { int len = strlen("recovery failed") + 1; pcp_write(frontend, "e", 1); wsize = htonl(sizeof(int) + len); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, "recovery failed", len); } } if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } } break; case 'B': /* status request*/ { int nrows = 0; POOL_REPORT_CONFIG *status = get_config(&nrows); int len = 0; /* First, send array size of connection_info */ char arr_code[] = "ArraySize"; char code[] = "ProcessConfig"; /* Finally, indicate that all data is sent */ char fin_code[] = "CommandComplete"; pcp_write(frontend, "b", 1); len = htonl(sizeof(arr_code) + sizeof(int) + sizeof(int)); pcp_write(frontend, &len, sizeof(int)); pcp_write(frontend, arr_code, sizeof(arr_code)); len = htonl(nrows); pcp_write(frontend, &len, sizeof(int)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } for (i = 0; i < nrows; i++) { pcp_write(frontend, "b", 1); len = htonl(sizeof(int) + sizeof(code) + strlen(status[i].name) + 1 + strlen(status[i].value) + 1 + strlen(status[i].desc) + 1 ); pcp_write(frontend, &len, sizeof(int)); pcp_write(frontend, code, sizeof(code)); pcp_write(frontend, status[i].name, strlen(status[i].name)+1); pcp_write(frontend, status[i].value, strlen(status[i].value)+1); pcp_write(frontend, status[i].desc, strlen(status[i].desc)+1); } pcp_write(frontend, "b", 1); len = htonl(sizeof(fin_code) + sizeof(int)); pcp_write(frontend, &len, sizeof(int)); pcp_write(frontend, fin_code, sizeof(fin_code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } free(status); pool_debug("pcp_child: retrieved status information"); break; } case 'J': /* promote node */ case 'j': /* promote node gracefully */ { int node_id; int wsize; char code[] = "CommandComplete"; bool gracefully; if (tos == 'J') gracefully = false; else gracefully = true; node_id = atoi(buf); if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) ) { char code[] = "NodeIdOutOfRange"; pool_error("pcp_child: node id %d is not valid", node_id); pcp_write(frontend, "e", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } exit(1); } /* promoting node is reserved to Streaming Replication */ if (!MASTER_SLAVE || (strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) != 0)) { char code[] = "NotInStreamingReplication"; pool_error("pcp_child: not in streaming replication mode, can't promote node id %d", node_id); pcp_write(frontend, "e", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } exit(1); } if (node_id == PRIMARY_NODE_ID) { char code[] = "NodeIdAlreadyPrimary"; pool_error("pcp_child: specified node is already primary node, can't promote node id %d", node_id); pcp_write(frontend, "e", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } exit(1); } pool_debug("pcp_child: promoting Node ID %d", node_id); pool_promote_node(node_id, gracefully); pcp_write(frontend, "d", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); if (pcp_flush(frontend) < 0) { pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno)); exit(1); } break; } case 'F': pool_debug("pcp_child: stop online recovery"); break; case 'X': /* disconnect */ pool_debug("pcp_child: client disconnecting. close connection"); authenticated = 0; pcp_close(frontend); frontend = NULL; break; default: pool_error("pcp_child: unknown packet type %c received", tos); exit(1); } free(buf); buf = NULL; /* seems ok. cancel idle check timer */ pool_signal(SIGALRM, SIG_IGN); } exit(0); } static RETSIGTYPE die(int sig) { pcp_exit_request = 1; pool_debug("PCP child receives shutdown request signal %d", sig); switch (sig) { case SIGTERM: /* smart shutdown */ case SIGINT: /* fast shutdown */ case SIGQUIT: /* immediate shutdown */ exit(0); break; default: break; } /* send_frontend_exits(); */ exit(0); } static RETSIGTYPE wakeup_handler(int sig) { pcp_wakeup_request = 1; } static RETSIGTYPE restart_handler(int sig) { pcp_restart_request = 1; } static PCP_CONNECTION * pcp_do_accept(int unix_fd, int inet_fd) { PCP_CONNECTION *pc = NULL; fd_set readmask; int fds; struct sockaddr addr; socklen_t addrlen; int fd = 0; int afd; int inet = 0; set_ps_display("PCP: wait for connection request", false); FD_ZERO(&readmask); FD_SET(unix_fd, &readmask); if (inet_fd) FD_SET(inet_fd, &readmask); fds = select(Max(unix_fd, inet_fd)+1, &readmask, NULL, NULL, NULL); if (fds == -1) { if (errno == EAGAIN || errno == EINTR) return NULL; pool_error("pcp_child: select() failed. reason: %s", strerror(errno)); return NULL; } if (FD_ISSET(unix_fd, &readmask)) { fd = unix_fd; } if (FD_ISSET(inet_fd, &readmask)) { fd = inet_fd; inet++; } addrlen = sizeof(addr); afd = accept(fd, &addr, &addrlen); if (afd < 0) { /* * "Resource temporarily unavailable" (EAGAIN or EWOULDBLOCK) * can be silently ignored. */ if (errno != EAGAIN && errno != EWOULDBLOCK) pool_error("pcp_child: accept() failed. reason: %s", strerror(errno)); return NULL; } if (pcp_got_sighup) { pool_get_config(get_config_file_name(), RELOAD_CONFIG); pcp_got_sighup = 0; } pool_debug("I am PCP %d accept fd %d", getpid(), afd); if (inet) { int on = 1; if (setsockopt(afd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) { pool_error("pcp_child: setsockopt() failed: %s", strerror(errno)); close(afd); return NULL; } if (setsockopt(afd, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) { pool_error("pcp_child: setsockopt() failed: %s", strerror(errno)); close(afd); return NULL; } } if ((pc = pcp_open(afd)) == NULL) { close(afd); return NULL; } return pc; } /* * unset non-block flag */ static void unset_nonblock(int fd) { int var; /* set fd to non-blocking */ var = fcntl(fd, F_GETFL, 0); if (var == -1) { pool_error("pcp_child: fcntl failed. %s", strerror(errno)); exit(1); } if (fcntl(fd, F_SETFL, var & ~O_NONBLOCK) == -1) { pool_error("pcp_child: fcntl failed. %s", strerror(errno)); exit(1); } } /* * see if received username and password matches with one in the file */ static int user_authenticate(char *buf, char *passwd_file, char *salt, int salt_len) { FILE *fp = NULL; char packet_username[MAX_USER_PASSWD_LEN+1]; char packet_password[MAX_USER_PASSWD_LEN+1]; char encrypt_buf[(MD5_PASSWD_LEN+1)*2]; char file_username[MAX_USER_PASSWD_LEN+1]; char file_password[MAX_USER_PASSWD_LEN+1]; char *index = NULL; static char line[MAX_FILE_LINE_LEN+1]; int i, len; /* strcpy() should be OK, but use strncpy() to be extra careful */ strncpy(packet_username, buf, MAX_USER_PASSWD_LEN); index = (char *) memchr(buf, '\0', MAX_USER_PASSWD_LEN) + 1; if (index == NULL) { pool_debug("pcp_child: error while reading authentication packet"); return 0; } strncpy(packet_password, index, MAX_USER_PASSWD_LEN); fp = fopen(passwd_file, "r"); if (fp == NULL) { pool_error("pcp_child: could not open %s. reason: %s", passwd_file, strerror(errno)); return 0; } /* for now, I don't care if duplicate username exists in the config file */ while ((fgets(line, MAX_FILE_LINE_LEN, fp)) != NULL) { i = 0; len = 0; if (line[0] == '\n') continue; if (line[0] == '#') continue; while (line[i] != ':') { len++; if (++i > MAX_USER_PASSWD_LEN) { pool_error("pcp_child: user name in %s exceeds %d", passwd_file, MAX_USER_PASSWD_LEN); fclose(fp); return 0; } } memcpy(file_username, line, len); file_username[len] = '\0'; if (strcmp(packet_username, file_username) != 0) continue; i++; len = 0; while (line[i] != '\n' && line[i] != '\0') { len++; if (++i > MAX_USER_PASSWD_LEN) { pool_error("pcp_child: password in %s exceeds %d", passwd_file, MAX_USER_PASSWD_LEN); fclose(fp); return 0; } } memcpy(file_password, line+strlen(file_username)+1, len); file_password[len] = '\0'; pool_md5_encrypt(file_password, file_username, strlen(file_username), encrypt_buf + MD5_PASSWD_LEN + 1); encrypt_buf[(MD5_PASSWD_LEN+1)*2-1] = '\0'; pool_md5_encrypt(encrypt_buf+MD5_PASSWD_LEN+1, salt, salt_len, encrypt_buf); encrypt_buf[MD5_PASSWD_LEN] = '\0'; if (strcmp(encrypt_buf, packet_password) == 0) { fclose(fp); return 1; } } fclose(fp); return 0; } /* SIGHUP handler */ static RETSIGTYPE reload_config_handler(int sig) { pcp_got_sighup = 1; } /* Dedatch a node */ static int pool_detach_node(int node_id, bool gracefully) { if (!gracefully) { notice_backend_error(node_id); /* send failover request */ return 0; } /* * Wait until all frontends exit */ *InRecovery = RECOVERY_DETACH; /* This wiil ensure that new incoming * connection requests are blocked */ if (wait_connection_closed()) { /* wait timed out */ finish_recovery(); return -1; } /* * Now all frontends have gone. Let's do failover. */ notice_backend_error(node_id); /* send failover request */ /* * Wait for failover completed. */ pcp_wakeup_request = 0; while (!pcp_wakeup_request) { struct timeval t = {1, 0}; select(0, NULL, NULL, NULL, &t); } pcp_wakeup_request = 0; /* * Start to accept incoming connections and send SIGUSR2 to pgpool * parent to distribute SIGUSR2 all pgpool children. */ finish_recovery(); return 0; } /* Promote a node */ static int pool_promote_node(int node_id, bool gracefully) { if (!gracefully) { promote_backend(node_id); /* send promote request */ return 0; } /* * Wait until all frontends exit */ *InRecovery = RECOVERY_PROMOTE; /* This wiil ensure that new incoming * connection requests are blocked */ if (wait_connection_closed()) { /* wait timed out */ finish_recovery(); return -1; } /* * Now all frontends have gone. Let's do failover. */ promote_backend(node_id); /* send promote request */ /* * Wait for failover completed. */ pcp_wakeup_request = 0; while (!pcp_wakeup_request) { struct timeval t = {1, 0}; select(0, NULL, NULL, NULL, &t); } pcp_wakeup_request = 0; /* * Start to accept incoming connections and send SIGUSR2 to pgpool * parent to distribute SIGUSR2 all pgpool children. */ finish_recovery(); return 0; } pgpool-II-3.3.2/pgpool.conf.sample-master-slave0000664000076400007640000007371512245576266016335 00000000000000# ---------------------------- # pgPool-II configuration file # ---------------------------- # # This file consists of lines of the form: # # name = value # # Whitespace may be used. Comments are introduced with "#" anywhere on a line. # The complete list of parameter names and allowed values can be found in the # pgPool-II documentation. # # This file is read on server startup and when the server receives a SIGHUP # signal. If you edit the file on a running system, you have to SIGHUP the # server for the changes to take effect, or use "pgpool reload". Some # parameters, which are marked below, require a server shutdown and restart to # take effect. # #------------------------------------------------------------------------------ # CONNECTIONS #------------------------------------------------------------------------------ # - pgpool Connection Settings - listen_addresses = 'localhost' # Host name or IP address to listen on: # '*' for all, '' for no TCP/IP connections # (change requires restart) port = 9999 # Port number # (change requires restart) socket_dir = '/tmp' # Unix domain socket path # The Debian package defaults to # /var/run/postgresql # (change requires restart) # - pgpool Communication Manager Connection Settings - pcp_port = 9898 # Port number for pcp # (change requires restart) pcp_socket_dir = '/tmp' # Unix domain socket path for pcp # The Debian package defaults to # /var/run/postgresql # (change requires restart) # - Backend Connection Settings - backend_hostname0 = 'host1' # Host name or IP address to connect to for backend 0 backend_port0 = 5432 # Port number for backend 0 backend_weight0 = 1 # Weight for backend 0 (only in load balancing mode) backend_data_directory0 = '/data' # Data directory for backend 0 backend_flag0 = 'ALLOW_TO_FAILOVER' # Controls various backend behavior # ALLOW_TO_FAILOVER or DISALLOW_TO_FAILOVER #backend_hostname1 = 'host2' #backend_port1 = 5433 #backend_weight1 = 1 #backend_data_directory1 = '/data1' #backend_flag1 = 'ALLOW_TO_FAILOVER' # - Authentication - enable_pool_hba = off # Use pool_hba.conf for client authentication pool_passwd = 'pool_passwd' # File name of pool_passwd for md5 authentication. # "" disables pool_passwd. # (change requires restart) authentication_timeout = 60 # Delay in seconds to complete client authentication # 0 means no timeout. # - SSL Connections - ssl = off # Enable SSL support # (change requires restart) #ssl_key = './server.key' # Path to the SSL private key file # (change requires restart) #ssl_cert = './server.cert' # Path to the SSL public certificate file # (change requires restart) #ssl_ca_cert = '' # Path to a single PEM format file # containing CA root certificate(s) # (change requires restart) #ssl_ca_cert_dir = '' # Directory containing CA root certificate(s) # (change requires restart) #------------------------------------------------------------------------------ # POOLS #------------------------------------------------------------------------------ # - Pool size - num_init_children = 32 # Number of pools # (change requires restart) max_pool = 4 # Number of connections per pool # (change requires restart) # - Life time - child_life_time = 300 # Pool exits after being idle for this many seconds child_max_connections = 0 # Pool exits after receiving that many connections # 0 means no exit connection_life_time = 0 # Connection to backend closes after being idle for this many seconds # 0 means no close client_idle_limit = 0 # Client is disconnected after being idle for that many seconds # (even inside an explicit transactions!) # 0 means no disconnection #------------------------------------------------------------------------------ # LOGS #------------------------------------------------------------------------------ # - Where to log - log_destination = 'stderr' # Where to log # Valid values are combinations of stderr, # and syslog. Default to stderr. # - What to log - print_timestamp = on # Print timestamp on each line # (change requires restart) log_connections = off # Log connections log_hostname = off # Hostname will be shown in ps status # and in logs if connections are logged log_statement = off # Log all statements log_per_node_statement = off # Log all statements # with node and backend informations log_standby_delay = 'none' # Log standby delay # Valid values are combinations of always, # if_over_threshold, none # - Syslog specific - syslog_facility = 'LOCAL0' # Syslog local facility. Default to LOCAL0 syslog_ident = 'pgpool' # Syslog program identification string # Default to 'pgpool' # - Debug - debug_level = 0 # Debug message verbosity level # 0 means no message, 1 or more mean verbose #------------------------------------------------------------------------------ # FILE LOCATIONS #------------------------------------------------------------------------------ pid_file_name = '/var/run/pgpool/pgpool.pid' # PID file name # (change requires restart) logdir = '/tmp' # Directory of pgPool status file # (change requires restart) #------------------------------------------------------------------------------ # CONNECTION POOLING #------------------------------------------------------------------------------ connection_cache = on # Activate connection pools # (change requires restart) # Semicolon separated list of queries # to be issued at the end of a session # The default is for 8.3 and later reset_query_list = 'ABORT; DISCARD ALL' # The following one is for 8.2 and before #reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' #------------------------------------------------------------------------------ # REPLICATION MODE #------------------------------------------------------------------------------ replication_mode = off # Activate replication mode # (change requires restart) replicate_select = off # Replicate SELECT statements # when in replication or parallel mode # replicate_select is higher priority than # load_balance_mode. insert_lock = off # Automatically locks a dummy row or a table # with INSERT statements to keep SERIAL data # consistency # Without SERIAL, no lock will be issued lobj_lock_table = '' # When rewriting lo_creat command in # replication mode, specify table name to # lock # - Degenerate handling - replication_stop_on_mismatch = off # On disagreement with the packet kind # sent from backend, degenerate the node # which is most likely "minority" # If off, just force to exit this session failover_if_affected_tuples_mismatch = off # On disagreement with the number of affected # tuples in UPDATE/DELETE queries, then # degenerate the node which is most likely # "minority". # If off, just abort the transaction to # keep the consistency #------------------------------------------------------------------------------ # LOAD BALANCING MODE #------------------------------------------------------------------------------ load_balance_mode = on # Activate load balancing mode # (change requires restart) ignore_leading_white_space = on # Ignore leading white spaces of each query white_function_list = '' # Comma separated list of function names # that don't write to database # Regexp are accepted black_function_list = 'currval,lastval,nextval,setval' # Comma separated list of function names # that write to database # Regexp are accepted #------------------------------------------------------------------------------ # MASTER/SLAVE MODE #------------------------------------------------------------------------------ master_slave_mode = on # Activate master/slave mode # (change requires restart) master_slave_sub_mode = 'slony' # Master/slave sub mode # Valid values are combinations slony or # stream. Default is slony. # (change requires restart) # - Streaming - sr_check_period = 0 # Streaming replication check period # Disabled (0) by default sr_check_user = 'nobody' # Streaming replication check user # This is neccessary even if you disable streaming # replication delay check by sr_check_period = 0 sr_check_password = '' # Password for streaming replication check user delay_threshold = 0 # Threshold before not dispatching query to standby node # Unit is in bytes # Disabled (0) by default # - Special commands - follow_master_command = '' # Executes this command after master failover # Special values: # %d = node id # %h = host name # %p = port number # %D = database cluster path # %m = new master node id # %H = hostname of the new master node # %M = old master node id # %P = old primary node id # %r = new master port number # %R = new master database cluster path # %% = '%' character #------------------------------------------------------------------------------ # PARALLEL MODE #------------------------------------------------------------------------------ parallel_mode = off # Activates parallel query mode # (change requires restart) pgpool2_hostname = '' # Set pgpool2 hostname # (change requires restart) # - System DB info - #system_db_hostname = 'localhost' # (change requires restart) #system_db_port = 5432 # (change requires restart) #system_db_dbname = 'pgpool' # (change requires restart) #system_db_schema = 'pgpool_catalog' # (change requires restart) #system_db_user = 'pgpool' # (change requires restart) #system_db_password = '' # (change requires restart) #------------------------------------------------------------------------------ # HEALTH CHECK #------------------------------------------------------------------------------ health_check_period = 0 # Health check period # Disabled (0) by default health_check_timeout = 20 # Health check timeout # 0 means no timeout health_check_user = 'nobody' # Health check user health_check_password = '' # Password for health check user health_check_max_retries = 0 # Maximum number of times to retry a failed health check before giving up. health_check_retry_delay = 1 # Amount of time to wait (in seconds) between retries. #------------------------------------------------------------------------------ # FAILOVER AND FAILBACK #------------------------------------------------------------------------------ failover_command = '' # Executes this command at failover # Special values: # %d = node id # %h = host name # %p = port number # %D = database cluster path # %m = new master node id # %H = hostname of the new master node # %M = old master node id # %P = old primary node id # %r = new master port number # %R = new master database cluster path # %% = '%' character failback_command = '' # Executes this command at failback. # Special values: # %d = node id # %h = host name # %p = port number # %D = database cluster path # %m = new master node id # %H = hostname of the new master node # %M = old master node id # %P = old primary node id # %r = new master port number # %R = new master database cluster path # %% = '%' character fail_over_on_backend_error = on # Initiates failover when reading/writing to the # backend communication socket fails # If set to off, pgpool will report an # error and disconnect the session. search_primary_node_timeout = 10 # Timeout in seconds to search for the # primary node when a failover occurs. # 0 means no timeout, keep searching # for a primary node forever. #------------------------------------------------------------------------------ # ONLINE RECOVERY #------------------------------------------------------------------------------ recovery_user = 'nobody' # Online recovery user recovery_password = '' # Online recovery password recovery_1st_stage_command = '' # Executes a command in first stage recovery_2nd_stage_command = '' # Executes a command in second stage recovery_timeout = 90 # Timeout in seconds to wait for the # recovering node's postmaster to start up # 0 means no wait client_idle_limit_in_recovery = 0 # Client is disconnected after being idle # for that many seconds in the second stage # of online recovery # 0 means no disconnection # -1 means immediate disconnection #------------------------------------------------------------------------------ # WATCHDOG #------------------------------------------------------------------------------ # - Enabling - use_watchdog = off # Activates watchdog # (change requires restart) # -Connection to up stream servers - trusted_servers = '' # trusted server list which are used # to confirm network connection # (hostA,hostB,hostC,...) # (change requires restart) ping_path = '/bin' # ping command path # (change requires restart) # - Watchdog communication Settings - wd_hostname = '' # Host name or IP address of this watchdog # (change requires restart) wd_port = 9000 # port number for watchdog service # (change requires restart) wd_authkey = '' # Authentication key for watchdog communication # (change requires restart) # - Virtual IP control Setting - delegate_IP = '' # delegate IP address # If this is empty, virtual IP never bring up. # (change requires restart) ifconfig_path = '/sbin' # ifconfig command path # (change requires restart) if_up_cmd = 'ifconfig eth0:0 inet $_IP_$ netmask 255.255.255.0' # startup delegate IP command # (change requires restart) if_down_cmd = 'ifconfig eth0:0 down' # shutdown delegate IP command # (change requires restart) arping_path = '/usr/sbin' # arping command path # (change requires restart) arping_cmd = 'arping -U $_IP_$ -w 1' # arping command # (change requires restart) # - Behaivor on escalation Setting - clear_memqcache_on_escalation = on # Clear all the query cache on shared memory # when standby pgpool escalate to active pgpool # (= virtual IP holder). # This should be off if client connects to pgpool # not using virtual IP. # (change requires restart) wd_escalation_command = '' # Executes this command at escalation on new active pgpool. # (change requires restart) # - Lifecheck Setting - # -- common -- wd_lifecheck_method = 'heartbeat' # Method of watchdog lifecheck ('heartbeat' or 'query') # (change requires restart) wd_interval = 10 # lifecheck interval (sec) > 0 # (change requires restart) # -- heartbeat mode -- wd_heartbeat_port = 9694 # Port number for receiving heartbeat signal # (change requires restart) wd_heartbeat_keepalive = 2 # Interval time of sending heartbeat signal (sec) # (change requires restart) wd_heartbeat_deadtime = 30 # Deadtime interval for heartbeat signal (sec) # (change requires restart) heartbeat_destination0 = 'host0_ip1' # Host name or IP address of destination 0 # for sending heartbeat signal. # (change requires restart) heartbeat_destination_port0 = 9694 # Port number of destination 0 for sending # heartbeat signal. Usually this is the # same as wd_heartbeat_port. # (change requires restart) heartbeat_device0 = '' # Name of NIC device (such like 'eth0') # used for sending/receiving heartbeat # signal to/from destination 0. # This works only when this is not empty # and pgpool has root privilege. # (change requires restart) #heartbeat_destination1 = 'host0_ip2' #heartbeat_destination_port1 = 9694 #heartbeat_device1 = '' # -- query mode -- wd_life_point = 3 # lifecheck retry times # (change requires restart) wd_lifecheck_query = 'SELECT 1' # lifecheck query to pgpool from watchdog # (change requires restart) wd_lifecheck_dbname = 'template1' # Database name connected for lifecheck # (change requires restart) wd_lifecheck_user = 'nobody' # watchdog user monitoring pgpools in lifecheck # (change requires restart) wd_lifecheck_password = '' # Password for watchdog user in lifecheck # (change requires restart) # - Other pgpool Connection Settings - #other_pgpool_hostname0 = 'host0' # Host name or IP address to connect to for other pgpool 0 # (change requires restart) #other_pgpool_port0 = 5432 # Port number for othet pgpool 0 # (change requires restart) #other_wd_port0 = 9000 # Port number for othet watchdog 0 # (change requires restart) #other_pgpool_hostname1 = 'host1' #other_pgpool_port1 = 5432 #other_wd_port1 = 9000 #------------------------------------------------------------------------------ # OTHERS #------------------------------------------------------------------------------ relcache_expire = 0 # Life time of relation cache in seconds. # 0 means no cache expiration(the default). # The relation cache is used for cache the # query result against PostgreSQL system # catalog to obtain various information # including table structures or if it's a # temporary table or not. The cache is # maintained in a pgpool child local memory # and being kept as long as it survives. # If someone modify the table by using # ALTER TABLE or some such, the relcache is # not consistent anymore. # For this purpose, cache_expiration # controls the life time of the cache. relcache_size = 256 # Number of relation cache # entry. If you see frequently: # "pool_search_relcache: cache replacement happend" # in the pgpool log, you might want to increate this number. check_temp_table = on # If on, enable temporary table check in SELECT statements. # This initiates queries against system catalog of primary/master # thus increases load of master. # If you are absolutely sure that your system never uses temporary tables # and you want to save access to primary/master, you could turn this off. # Default is on. #------------------------------------------------------------------------------ # ON MEMORY QUERY MEMORY CACHE #------------------------------------------------------------------------------ memory_cache_enabled = off # If on, use the memory cache functionality, off by default memqcache_method = 'shmem' # Cache storage method. either 'shmem'(shared memory) or # 'memcached'. 'shmem' by default # (change requires restart) memqcache_memcached_host = 'localhost' # Memcached host name or IP address. Mandatory if # memqcache_method = 'memcached'. # Defaults to localhost. # (change requires restart) memqcache_memcached_port = 11211 # Memcached port number. Mondatory if memqcache_method = 'memcached'. # Defaults to 11211. # (change requires restart) memqcache_total_size = 67108864 # Total memory size in bytes for storing memory cache. # Mandatory if memqcache_method = 'shmem'. # Defaults to 64MB. # (change requires restart) memqcache_max_num_cache = 1000000 # Total number of cache entries. Mandatory # if memqcache_method = 'shmem'. # Each cache entry consumes 48 bytes on shared memory. # Defaults to 1,000,000(45.8MB). # (change requires restart) memqcache_expire = 0 # Memory cache entry life time specified in seconds. # 0 means infinite life time. 0 by default. # (change requires restart) memqcache_auto_cache_invalidation = on # If on, invalidation of query cache is triggered by corresponding # DDL/DML/DCL(and memqcache_expire). If off, it is only triggered # by memqcache_expire. on by default. # (change requires restart) memqcache_maxcache = 409600 # Maximum SELECT result size in bytes. # Must be smaller than memqcache_cache_block_size. Defaults to 400KB. # (change requires restart) memqcache_cache_block_size = 1048576 # Cache block size in bytes. Mandatory if memqcache_method = 'shmem'. # Defaults to 1MB. # (change requires restart) memqcache_oiddir = '/var/log/pgpool/oiddir' # Temporary work directory to record table oids # (change requires restart) white_memqcache_table_list = '' # Comma separated list of table names to memcache # that don't write to database # Regexp are accepted black_memqcache_table_list = '' # Comma separated list of table names not to memcache # that don't write to database # Regexp are accepted pgpool-II-3.3.2/depcomp0000775000076400007640000003554512245576256011660 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2004-05-31.23 # Copyright (C) 1999, 2000, 2003, 2004 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit 0 ;; -v | --v*) echo "depcomp $scriptversion" exit 0 ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test -f "$tmpdepfile"; then : else stripped=`echo "$stripped" | sed 's,^.*/,,'` tmpdepfile="$stripped.u" fi if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then outname="$stripped.o" # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # Dependencies are output in .lo.d with libtool 1.4. # With libtool 1.5 they are output both in $dir.libs/$base.o.d # and in $dir.libs/$base.o.d and $dir$base.o.d. We process the # latter, because the former will be cleaned when $dir.libs is # erased. tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir$base.o.d" tmpdepfile3="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" tmpdepfile3="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" elif test -f "$tmpdepfile2"; then tmpdepfile="$tmpdepfile2" else tmpdepfile="$tmpdepfile3" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: pgpool-II-3.3.2/pgpool.conf.sample0000664000076400007640000007440312245576266013727 00000000000000# ---------------------------- # pgPool-II configuration file # ---------------------------- # # This file consists of lines of the form: # # name = value # # Whitespace may be used. Comments are introduced with "#" anywhere on a line. # The complete list of parameter names and allowed values can be found in the # pgPool-II documentation. # # This file is read on server startup and when the server receives a SIGHUP # signal. If you edit the file on a running system, you have to SIGHUP the # server for the changes to take effect, or use "pgpool reload". Some # parameters, which are marked below, require a server shutdown and restart to # take effect. # #------------------------------------------------------------------------------ # CONNECTIONS #------------------------------------------------------------------------------ # - pgpool Connection Settings - listen_addresses = 'localhost' # Host name or IP address to listen on: # '*' for all, '' for no TCP/IP connections # (change requires restart) port = 9999 # Port number # (change requires restart) socket_dir = '/tmp' # Unix domain socket path # The Debian package defaults to # /var/run/postgresql # (change requires restart) # - pgpool Communication Manager Connection Settings - pcp_port = 9898 # Port number for pcp # (change requires restart) pcp_socket_dir = '/tmp' # Unix domain socket path for pcp # The Debian package defaults to # /var/run/postgresql # (change requires restart) # - Backend Connection Settings - #backend_hostname0 = 'host1' # Host name or IP address to connect to for backend 0 #backend_port0 = 5432 # Port number for backend 0 #backend_weight0 = 1 # Weight for backend 0 (only in load balancing mode) #backend_data_directory0 = '/data' # Data directory for backend 0 #backend_flag0 = 'ALLOW_TO_FAILOVER' # Controls various backend behavior # ALLOW_TO_FAILOVER or DISALLOW_TO_FAILOVER #backend_hostname1 = 'host2' #backend_port1 = 5433 #backend_weight1 = 1 #backend_data_directory1 = '/data1' #backend_flag1 = 'ALLOW_TO_FAILOVER' # - Authentication - enable_pool_hba = off # Use pool_hba.conf for client authentication pool_passwd = 'pool_passwd' # File name of pool_passwd for md5 authentication. # "" disables pool_passwd. # (change requires restart) authentication_timeout = 60 # Delay in seconds to complete client authentication # 0 means no timeout. # - SSL Connections - ssl = off # Enable SSL support # (change requires restart) #ssl_key = './server.key' # Path to the SSL private key file # (change requires restart) #ssl_cert = './server.cert' # Path to the SSL public certificate file # (change requires restart) #ssl_ca_cert = '' # Path to a single PEM format file # containing CA root certificate(s) # (change requires restart) #ssl_ca_cert_dir = '' # Directory containing CA root certificate(s) # (change requires restart) #------------------------------------------------------------------------------ # POOLS #------------------------------------------------------------------------------ # - Pool size - num_init_children = 32 # Number of pools # (change requires restart) max_pool = 4 # Number of connections per pool # (change requires restart) # - Life time - child_life_time = 300 # Pool exits after being idle for this many seconds child_max_connections = 0 # Pool exits after receiving that many connections # 0 means no exit connection_life_time = 0 # Connection to backend closes after being idle for this many seconds # 0 means no close client_idle_limit = 0 # Client is disconnected after being idle for that many seconds # (even inside an explicit transactions!) # 0 means no disconnection #------------------------------------------------------------------------------ # LOGS #------------------------------------------------------------------------------ # - Where to log - log_destination = 'stderr' # Where to log # Valid values are combinations of stderr, # and syslog. Default to stderr. # - What to log - print_timestamp = on # Print timestamp on each line # (change requires restart) log_connections = off # Log connections log_hostname = off # Hostname will be shown in ps status # and in logs if connections are logged log_statement = off # Log all statements log_per_node_statement = off # Log all statements # with node and backend informations log_standby_delay = 'none' # Log standby delay # Valid values are combinations of always, # if_over_threshold, none # - Syslog specific - syslog_facility = 'LOCAL0' # Syslog local facility. Default to LOCAL0 syslog_ident = 'pgpool' # Syslog program identification string # Default to 'pgpool' # - Debug - debug_level = 0 # Debug message verbosity level # 0 means no message, 1 or more mean verbose #------------------------------------------------------------------------------ # FILE LOCATIONS #------------------------------------------------------------------------------ pid_file_name = '/var/run/pgpool/pgpool.pid' # PID file name # (change requires restart) logdir = '/tmp' # Directory of pgPool status file # (change requires restart) #------------------------------------------------------------------------------ # CONNECTION POOLING #------------------------------------------------------------------------------ connection_cache = on # Activate connection pools # (change requires restart) # Semicolon separated list of queries # to be issued at the end of a session # The default is for 8.3 and later reset_query_list = 'ABORT; DISCARD ALL' # The following one is for 8.2 and before #reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' #------------------------------------------------------------------------------ # REPLICATION MODE #------------------------------------------------------------------------------ replication_mode = off # Activate replication mode # (change requires restart) replicate_select = off # Replicate SELECT statements # when in replication or parallel mode # replicate_select is higher priority than # load_balance_mode. insert_lock = on # Automatically locks a dummy row or a table # with INSERT statements to keep SERIAL data # consistency # Without SERIAL, no lock will be issued lobj_lock_table = '' # When rewriting lo_creat command in # replication mode, specify table name to # lock # - Degenerate handling - replication_stop_on_mismatch = off # On disagreement with the packet kind # sent from backend, degenerate the node # which is most likely "minority" # If off, just force to exit this session failover_if_affected_tuples_mismatch = off # On disagreement with the number of affected # tuples in UPDATE/DELETE queries, then # degenerate the node which is most likely # "minority". # If off, just abort the transaction to # keep the consistency #------------------------------------------------------------------------------ # LOAD BALANCING MODE #------------------------------------------------------------------------------ load_balance_mode = off # Activate load balancing mode # (change requires restart) ignore_leading_white_space = on # Ignore leading white spaces of each query white_function_list = '' # Comma separated list of function names # that don't write to database # Regexp are accepted black_function_list = 'nextval,setval' # Comma separated list of function names # that write to database # Regexp are accepted #------------------------------------------------------------------------------ # MASTER/SLAVE MODE #------------------------------------------------------------------------------ master_slave_mode = off # Activate master/slave mode # (change requires restart) master_slave_sub_mode = 'slony' # Master/slave sub mode # Valid values are combinations slony or # stream. Default is slony. # (change requires restart) # - Streaming - sr_check_period = 0 # Streaming replication check period # Disabled (0) by default sr_check_user = 'nobody' # Streaming replication check user # This is necessary even if you disable # streaming replication delay check with # sr_check_period = 0 sr_check_password = '' # Password for streaming replication check user delay_threshold = 0 # Threshold before not dispatching query to standby node # Unit is in bytes # Disabled (0) by default # - Special commands - follow_master_command = '' # Executes this command after master failover # Special values: # %d = node id # %h = host name # %p = port number # %D = database cluster path # %m = new master node id # %H = hostname of the new master node # %M = old master node id # %P = old primary node id # %r = new master port number # %R = new master database cluster path # %% = '%' character #------------------------------------------------------------------------------ # PARALLEL MODE #------------------------------------------------------------------------------ parallel_mode = off # Activates parallel query mode # (change requires restart) pgpool2_hostname = '' # Set pgpool2 hostname # (change requires restart) # - System DB info - system_db_hostname = 'localhost' # (change requires restart) system_db_port = 5432 # (change requires restart) system_db_dbname = 'pgpool' # (change requires restart) system_db_schema = 'pgpool_catalog' # (change requires restart) system_db_user = 'pgpool' # (change requires restart) system_db_password = '' # (change requires restart) #------------------------------------------------------------------------------ # HEALTH CHECK #------------------------------------------------------------------------------ health_check_period = 0 # Health check period # Disabled (0) by default health_check_timeout = 20 # Health check timeout # 0 means no timeout health_check_user = 'nobody' # Health check user health_check_password = '' # Password for health check user health_check_max_retries = 0 # Maximum number of times to retry a failed health check before giving up. health_check_retry_delay = 1 # Amount of time to wait (in seconds) between retries. #------------------------------------------------------------------------------ # FAILOVER AND FAILBACK #------------------------------------------------------------------------------ failover_command = '' # Executes this command at failover # Special values: # %d = node id # %h = host name # %p = port number # %D = database cluster path # %m = new master node id # %H = hostname of the new master node # %M = old master node id # %P = old primary node id # %r = new master port number # %R = new master database cluster path # %% = '%' character failback_command = '' # Executes this command at failback. # Special values: # %d = node id # %h = host name # %p = port number # %D = database cluster path # %m = new master node id # %H = hostname of the new master node # %M = old master node id # %P = old primary node id # %r = new master port number # %R = new master database cluster path # %% = '%' character fail_over_on_backend_error = on # Initiates failover when reading/writing to the # backend communication socket fails # If set to off, pgpool will report an # error and disconnect the session. search_primary_node_timeout = 10 # Timeout in seconds to search for the # primary node when a failover occurs. # 0 means no timeout, keep searching # for a primary node forever. #------------------------------------------------------------------------------ # ONLINE RECOVERY #------------------------------------------------------------------------------ recovery_user = 'nobody' # Online recovery user recovery_password = '' # Online recovery password recovery_1st_stage_command = '' # Executes a command in first stage recovery_2nd_stage_command = '' # Executes a command in second stage recovery_timeout = 90 # Timeout in seconds to wait for the # recovering node's postmaster to start up # 0 means no wait client_idle_limit_in_recovery = 0 # Client is disconnected after being idle # for that many seconds in the second stage # of online recovery # 0 means no disconnection # -1 means immediate disconnection #------------------------------------------------------------------------------ # WATCHDOG #------------------------------------------------------------------------------ # - Enabling - use_watchdog = off # Activates watchdog # (change requires restart) # -Connection to up stream servers - trusted_servers = '' # trusted server list which are used # to confirm network connection # (hostA,hostB,hostC,...) # (change requires restart) ping_path = '/bin' # ping command path # (change requires restart) # - Watchdog communication Settings - wd_hostname = '' # Host name or IP address of this watchdog # (change requires restart) wd_port = 9000 # port number for watchdog service # (change requires restart) wd_authkey = '' # Authentication key for watchdog communication # (change requires restart) # - Virtual IP control Setting - delegate_IP = '' # delegate IP address # If this is empty, virtual IP never bring up. # (change requires restart) ifconfig_path = '/sbin' # ifconfig command path # (change requires restart) if_up_cmd = 'ifconfig eth0:0 inet $_IP_$ netmask 255.255.255.0' # startup delegate IP command # (change requires restart) if_down_cmd = 'ifconfig eth0:0 down' # shutdown delegate IP command # (change requires restart) arping_path = '/usr/sbin' # arping command path # (change requires restart) arping_cmd = 'arping -U $_IP_$ -w 1' # arping command # (change requires restart) # - Behaivor on escalation Setting - clear_memqcache_on_escalation = on # Clear all the query cache on shared memory # when standby pgpool escalate to active pgpool # (= virtual IP holder). # This should be off if client connects to pgpool # not using virtual IP. # (change requires restart) wd_escalation_command = '' # Executes this command at escalation on new active pgpool. # (change requires restart) # - Lifecheck Setting - # -- common -- wd_lifecheck_method = 'heartbeat' # Method of watchdog lifecheck ('heartbeat' or 'query') # (change requires restart) wd_interval = 10 # lifecheck interval (sec) > 0 # (change requires restart) # -- heartbeat mode -- wd_heartbeat_port = 9694 # Port number for receiving heartbeat signal # (change requires restart) wd_heartbeat_keepalive = 2 # Interval time of sending heartbeat signal (sec) # (change requires restart) wd_heartbeat_deadtime = 30 # Deadtime interval for heartbeat signal (sec) # (change requires restart) heartbeat_destination0 = 'host0_ip1' # Host name or IP address of destination 0 # for sending heartbeat signal. # (change requires restart) heartbeat_destination_port0 = 9694 # Port number of destination 0 for sending # heartbeat signal. Usually this is the # same as wd_heartbeat_port. # (change requires restart) heartbeat_device0 = '' # Name of NIC device (such like 'eth0') # used for sending/receiving heartbeat # signal to/from destination 0. # This works only when this is not empty # and pgpool has root privilege. # (change requires restart) #heartbeat_destination1 = 'host0_ip2' #heartbeat_destination_port1 = 9694 #heartbeat_device1 = '' # -- query mode -- wd_life_point = 3 # lifecheck retry times # (change requires restart) wd_lifecheck_query = 'SELECT 1' # lifecheck query to pgpool from watchdog # (change requires restart) wd_lifecheck_dbname = 'template1' # Database name connected for lifecheck # (change requires restart) wd_lifecheck_user = 'nobody' # watchdog user monitoring pgpools in lifecheck # (change requires restart) wd_lifecheck_password = '' # Password for watchdog user in lifecheck # (change requires restart) # - Other pgpool Connection Settings - #other_pgpool_hostname0 = 'host0' # Host name or IP address to connect to for other pgpool 0 # (change requires restart) #other_pgpool_port0 = 5432 # Port number for othet pgpool 0 # (change requires restart) #other_wd_port0 = 9000 # Port number for othet watchdog 0 # (change requires restart) #other_pgpool_hostname1 = 'host1' #other_pgpool_port1 = 5432 #other_wd_port1 = 9000 #------------------------------------------------------------------------------ # OTHERS #------------------------------------------------------------------------------ relcache_expire = 0 # Life time of relation cache in seconds. # 0 means no cache expiration(the default). # The relation cache is used for cache the # query result against PostgreSQL system # catalog to obtain various information # including table structures or if it's a # temporary table or not. The cache is # maintained in a pgpool child local memory # and being kept as long as it survives. # If someone modify the table by using # ALTER TABLE or some such, the relcache is # not consistent anymore. # For this purpose, cache_expiration # controls the life time of the cache. relcache_size = 256 # Number of relation cache # entry. If you see frequently: # "pool_search_relcache: cache replacement happend" # in the pgpool log, you might want to increate this number. check_temp_table = on # If on, enable temporary table check in SELECT statements. # This initiates queries against system catalog of primary/master # thus increases load of master. # If you are absolutely sure that your system never uses temporary tables # and you want to save access to primary/master, you could turn this off. # Default is on. #------------------------------------------------------------------------------ # ON MEMORY QUERY MEMORY CACHE #------------------------------------------------------------------------------ memory_cache_enabled = off # If on, use the memory cache functionality, off by default memqcache_method = 'shmem' # Cache storage method. either 'shmem'(shared memory) or # 'memcached'. 'shmem' by default # (change requires restart) memqcache_memcached_host = 'localhost' # Memcached host name or IP address. Mandatory if # memqcache_method = 'memcached'. # Defaults to localhost. # (change requires restart) memqcache_memcached_port = 11211 # Memcached port number. Mondatory if memqcache_method = 'memcached'. # Defaults to 11211. # (change requires restart) memqcache_total_size = 67108864 # Total memory size in bytes for storing memory cache. # Mandatory if memqcache_method = 'shmem'. # Defaults to 64MB. # (change requires restart) memqcache_max_num_cache = 1000000 # Total number of cache entries. Mandatory # if memqcache_method = 'shmem'. # Each cache entry consumes 48 bytes on shared memory. # Defaults to 1,000,000(45.8MB). # (change requires restart) memqcache_expire = 0 # Memory cache entry life time specified in seconds. # 0 means infinite life time. 0 by default. # (change requires restart) memqcache_auto_cache_invalidation = on # If on, invalidation of query cache is triggered by corresponding # DDL/DML/DCL(and memqcache_expire). If off, it is only triggered # by memqcache_expire. on by default. # (change requires restart) memqcache_maxcache = 409600 # Maximum SELECT result size in bytes. # Must be smaller than memqcache_cache_block_size. Defaults to 400KB. # (change requires restart) memqcache_cache_block_size = 1048576 # Cache block size in bytes. Mandatory if memqcache_method = 'shmem'. # Defaults to 1MB. # (change requires restart) memqcache_oiddir = '/var/log/pgpool/oiddir' # Temporary work directory to record table oids # (change requires restart) white_memqcache_table_list = '' # Comma separated list of table names to memcache # that don't write to database # Regexp are accepted black_memqcache_table_list = '' # Comma separated list of table names not to memcache # that don't write to database # Regexp are accepted pgpool-II-3.3.2/pool_timestamp.c0000664000076400007640000007067312245576267013506 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include "pool.h" #include "pool_timestamp.h" #include "pool_relcache.h" #include "pool_select_walker.h" #include "pool_config.h" #include "parser/parsenodes.h" #include "parser/parser.h" #include "parser/pool_memory.h" typedef struct { char *attrname; /* attribute name */ char *adsrc; /* default value expression */ int use_timestamp; } TSAttr; typedef struct { int relnatts; TSAttr attr[1]; } TSRel; typedef struct { A_Const *ts_const; POOL_CONNECTION_POOL *backend; char *relname; int num_params; /* num of original params (for Parse) */ bool rewrite_to_params; bool rewrite; /* has rewritten? */ List *params; /* list of additional params */ } TSRewriteContext; static void *ts_register_func(POOL_SELECT_RESULT *res); static void *ts_unregister_func(void *data); static TSRel *relcache_lookup(TSRewriteContext *ctx); static bool isStringConst(Node *node, const char *str); static bool rewrite_timestamp_walker(Node *node, void *context); static bool rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx); static bool rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx); static char *get_current_timestamp(POOL_CONNECTION_POOL *backend); static Node *makeTsExpr(TSRewriteContext *ctx); static A_Const *makeStringConstFromQuery(POOL_CONNECTION_POOL *backend, char *expression); bool raw_expression_tree_walker(Node *node, bool (*walker) (), void *context); POOL_RELCACHE *ts_relcache; static void * ts_register_func(POOL_SELECT_RESULT *res) { /* Number of result columns included in res */ #define NUM_COLS 3 TSRel *rel; int i; if (res->numrows == 0) return NULL; rel = (TSRel *) malloc(sizeof(TSRel) + sizeof(TSAttr) * (res->numrows - 1)); for (i = 0; i < res->numrows; i++) { int index = 0; rel->attr[i].attrname = strdup(res->data[i * NUM_COLS + index]); index++; if (res->data[i * NUM_COLS + index]) rel->attr[i].adsrc = strdup(res->data[i * NUM_COLS + index]); else rel->attr[i].adsrc = NULL; index++; rel->attr[i].use_timestamp = *(res->data[i * NUM_COLS + index]) == 't'; pool_debug("attrname %s adsrc %s use_timestamp = %d", rel->attr[i].attrname, (rel->attr[i].adsrc? rel->attr[i].adsrc:"NULL"), rel->attr[i].use_timestamp); } rel->relnatts = res->numrows; return (void *) rel; } static void * ts_unregister_func(void *data) { TSRel *rel = (TSRel *) data; if (rel == NULL) return NULL; free(rel); return rel; } static TSRel* relcache_lookup(TSRewriteContext *ctx) { #define ATTRDEFQUERY "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%')" \ " AND (a.atttypid = 'timestamp'::regtype::oid OR" \ " a.atttypid = 'timestamp with time zone'::regtype::oid OR" \ " a.atttypid = 'date'::regtype::oid OR" \ " a.atttypid = 'time'::regtype::oid OR" \ " a.atttypid = 'time with time zone'::regtype::oid)" \ " , false)" \ " FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \ " LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \ " WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.relname = '%s'" \ " ORDER BY a.attnum" #define ATTRDEFQUERY2 "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%')" \ " AND (a.atttypid = 'timestamp'::regtype::oid OR" \ " a.atttypid = 'timestamp with time zone'::regtype::oid OR" \ " a.atttypid = 'date'::regtype::oid OR" \ " a.atttypid = 'time'::regtype::oid OR" \ " a.atttypid = 'time with time zone'::regtype::oid)" \ " , false)" \ " FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \ " LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \ " WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pgpool_regclass('%s')" \ " ORDER BY a.attnum" char *query; if (pool_has_pgpool_regclass()) { query = ATTRDEFQUERY2; } else { query = ATTRDEFQUERY; } if (!ts_relcache) { ts_relcache = pool_create_relcache(pool_config->relcache_size, query, ts_register_func, ts_unregister_func, false); if (ts_relcache == NULL) { pool_error("relcache_lookup: pool_create_relcache error"); return NULL; } } return (TSRel *) pool_search_relcache(ts_relcache, ctx->backend, ctx->relname); } static Node * makeTsExpr(TSRewriteContext *ctx) { ParamRef *param; if (!ctx->rewrite_to_params) return (Node *) ctx->ts_const; param = makeNode(ParamRef); param->number = 0; ctx->params = lappend(ctx->params, param); return (Node *) param; } static bool isStringConst(Node *node, const char *str) { A_Const *a_const; Value val; if (!IsA(node, A_Const)) return false; a_const = (A_Const *) node; val = a_const->val; if (val.type == T_String && val.val.str && strcmp(str, val.val.str) == 0) return true; return false; } bool isSystemType(Node *node, const char *name) { TypeName *typename; if (!IsA(node, TypeName)) return false; typename = (TypeName *) node; if (list_length(typename->names) == 2 && strcmp("pg_catalog", strVal(linitial(typename->names))) == 0 && strcmp(name, strVal(lsecond(typename->names))) == 0) return true; return false; } static bool isSystemTypeCast(Node *node, const char *name) { TypeCast *typecast; if (!IsA(node, TypeCast)) return false; typecast = (TypeCast *) node; return isSystemType((Node *) typecast->typeName, name); } /* * walker function for raw_expression_tree_walker */ static bool rewrite_timestamp_walker(Node *node, void *context) { TSRewriteContext *ctx = (TSRewriteContext *) context; if (node == NULL) return false; if (nodeTag(node) == T_FuncCall) { /* `now()' FuncCall */ FuncCall *fcall = (FuncCall *) node; if ((list_length(fcall->funcname) == 1 && strcmp("now", strVal(linitial(fcall->funcname))) == 0) || (list_length(fcall->funcname) == 2 && strcmp("pg_catalog", strVal(linitial(fcall->funcname))) == 0 && strcmp("now", strVal(lsecond(fcall->funcname))) == 0)) { TypeCast *tc = makeNode(TypeCast); tc->arg = makeTsExpr(ctx); tc->typeName = SystemTypeName("text"); fcall->funcname = SystemFuncName("timestamptz"); fcall->args = list_make1(tc); ctx->rewrite = true; } } else if (IsA(node, TypeCast)) { /* CURRENT_DATE, CURRENT_TIME, LOCALTIMESTAMP, LOCALTIME etc.*/ TypeCast *tc = (TypeCast *) node; if ((isSystemType((Node *) tc->typeName, "date") || isSystemType((Node *) tc->typeName, "timestamp") || isSystemType((Node *) tc->typeName, "timestamptz") || isSystemType((Node *) tc->typeName, "time") || isSystemType((Node *) tc->typeName, "timetz"))) { /* rewrite `'now'::timestamp' and `'now'::text::timestamp' both */ if (isSystemTypeCast(tc->arg, "text")) tc = (TypeCast *) tc->arg; if (isStringConst(tc->arg, "now")) { tc->arg = (Node *) makeTsExpr(ctx); ctx->rewrite = true; } } } else if (IsA(node, ParamRef)) { ParamRef *param = (ParamRef *) node; /* count how many params in original query */ if (ctx->num_params < param->number) ctx->num_params = param->number; } return raw_expression_tree_walker(node, rewrite_timestamp_walker, context); } /* * Get `now()' from MASTER node */ static char * get_current_timestamp(POOL_CONNECTION_POOL *backend) { POOL_SELECT_RESULT *res; POOL_STATUS status; static char timestamp[64]; status = do_query(MASTER(backend), "SELECT now()", &res, MAJOR(backend)); if (status != POOL_CONTINUE) { pool_error("get_current_timestamp: do_query failed"); free_select_result(res); return NULL; } if (res->numrows != 1) { free_select_result(res); return NULL; } strlcpy(timestamp, res->data[0], sizeof(timestamp)); free_select_result(res); return timestamp; } /* * rewrite InsertStmt */ static bool rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx) { int i; bool rewrite = false; TSRel *relcache; if (i_stmt->selectStmt == NULL) { List *values = NIL; SelectStmt *selectStmt = makeNode(SelectStmt); relcache = relcache_lookup(ctx); if (relcache == NULL) return false; /* * INSERT INTO rel DEFAULT VALUES * rewrite to: * INSERT INTO rel VALUES (DEFAULT, '2009-..',...) */ for (i = 0; i < relcache->relnatts; i++) { if (relcache->attr[i].use_timestamp) { rewrite = true; if (ctx->rewrite_to_params) values = lappend(values, makeTsExpr(ctx)); else values = lappend(values, makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc)); } else values = lappend(values, makeNode(SetToDefault)); } if (rewrite) { selectStmt->valuesLists = list_make1(values); i_stmt->selectStmt = (Node *) selectStmt; } return rewrite; } else if (IsA(i_stmt->selectStmt, SelectStmt)) { SelectStmt *selectStmt = (SelectStmt *) i_stmt->selectStmt; ListCell *lc_row, *lc_val, *lc_col; /* * Rewrite `now()' call to timestamp literal. */ raw_expression_tree_walker( (Node *) selectStmt, rewrite_timestamp_walker, (void *) ctx); rewrite = ctx->rewrite; /* * if `INSERT INTO rel SELECT ...' */ if (selectStmt->valuesLists == NIL) return rewrite; relcache = relcache_lookup(ctx); if (relcache == NULL) return false; if (i_stmt->cols == NIL) { /* * INSERT INTO rel VALUES (...) * * CREATE TABLE r1 ( * i1 int, * t1 timestamp default now(), * i2 int, * t2 timestamp default now(), * ) * * INSERT INTO r1 VALUES (1, DEFAULT); * rewrite to: * INSERT INTO r1 VALUES (1, '20xx-xx-xx...', DEFAULT, '2..') */ foreach (lc_row, selectStmt->valuesLists) { List *values = lfirst(lc_row); i = 0; foreach (lc_val, values) { if (relcache->attr[i].use_timestamp == true && IsA(lfirst(lc_val), SetToDefault)) { rewrite = true; if (ctx->rewrite_to_params) lfirst(lc_val) = makeTsExpr(ctx); else lfirst(lc_val) = makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc); } i++; } /* fill rest columns */ for (; i < relcache->relnatts; i++) { if (relcache->attr[i].use_timestamp == true) { rewrite = true; if (ctx->rewrite_to_params) values = lappend(values, makeTsExpr(ctx)); else values = lappend(values, makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc)); } else values = lappend(values, makeNode(SetToDefault)); } } } else { /* * INSERT INTO rel(col1, col2) VALUES (val, val2) * * if timestamp column is not given by column list * add colname to column list and add timestamp to values list. */ int append_columns = 0; int *append_columns_list; ResTarget *col; append_columns_list = (int *)malloc(sizeof(int)*relcache->relnatts); for (i = 0; i < relcache->relnatts; i++) { if (relcache->attr[i].use_timestamp == false) continue; foreach (lc_col, i_stmt->cols) { col = lfirst(lc_col); if (strcmp(relcache->attr[i].attrname, col->name) == 0) break; } if (lc_col == NULL) { /* column not found in query, append it.*/ rewrite = true; col = makeNode(ResTarget); col->name = relcache->attr[i].attrname; col->indirection = NIL; col->val = NULL; i_stmt->cols = lappend(i_stmt->cols, col); append_columns_list[append_columns++] = i; } } foreach (lc_row, selectStmt->valuesLists) { List *values = lfirst(lc_row); /* replace DEFAULT to literal */ forboth (lc_col, i_stmt->cols, lc_val, values) { col = lfirst(lc_col); for (i = 0; i < relcache->relnatts; i++) { if (strcmp(relcache->attr[i].attrname, col->name) == 0) break; } if (relcache->attr[i].use_timestamp == true && IsA(lfirst(lc_val), SetToDefault)) { rewrite = true; if (ctx->rewrite_to_params) lfirst(lc_val) = makeTsExpr(ctx); else lfirst(lc_val) = makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc); } } /* add ts_const to values list */ for (i = 0; i < append_columns; i++) { if (ctx->rewrite_to_params) values = lappend(values, makeTsExpr(ctx)); else values = lappend(values, makeStringConstFromQuery(ctx->backend, relcache->attr[append_columns_list[i]].adsrc)); } } free(append_columns_list); } } return rewrite; } /* * rewrite UpdateStmt */ static bool rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx) { TSRel *relcache = NULL; ListCell *lc; bool rewrite; /* rewrite "update ... set col1 = now()" */ raw_expression_tree_walker( (Node *) u_stmt->targetList, rewrite_timestamp_walker, (void *) ctx); raw_expression_tree_walker( (Node *) u_stmt->whereClause, rewrite_timestamp_walker, (void *) ctx); raw_expression_tree_walker( (Node *) u_stmt->fromClause, rewrite_timestamp_walker, (void *) ctx); rewrite = ctx->rewrite; /* rewrite "update ... set col1 = default" */ foreach (lc, u_stmt->targetList) { ResTarget *res = (ResTarget *) lfirst(lc); int i; if (IsA(res->val, SetToDefault)) { relcache = relcache_lookup(ctx); if (relcache == NULL) return false; for (i = 0; i < relcache->relnatts; i++) { if (strcmp(relcache->attr[i].attrname, res->name) == 0) { if (relcache->attr[i].use_timestamp) { if (ctx->rewrite_to_params) res->val = (Node *) makeTsExpr(ctx); else res->val = (Node *)makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc); rewrite = true; } break; } } } } return rewrite; } /* * Rewrite `now()' to timestamp literal. * returns query string as palloced string, or NULL if not to need rewrite. */ char * rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, bool rewrite_to_params, POOL_SENT_MESSAGE *message) { TSRewriteContext ctx; Node *stmt; bool rewrite = false; char *timestamp; char *rewrite_query; if (node == NULL) return NULL; if (!REPLICATION) return NULL; /* init context */ ctx.ts_const = makeNode(A_Const); ctx.ts_const->val.type = T_String; ctx.rewrite_to_params = rewrite_to_params; ctx.backend = backend; ctx.num_params = 0; ctx.rewrite = false; ctx.params = NIL; /* * Prepare? */ if (IsA(node, PrepareStmt)) { stmt = ((PrepareStmt *) node)->query; ctx.rewrite_to_params = true; } else stmt = node; if (IsA(stmt, InsertStmt)) { InsertStmt *i_stmt = (InsertStmt *) stmt; ctx.relname = nodeToString(i_stmt->relation); rewrite = rewrite_timestamp_insert(i_stmt, &ctx); } else if (IsA(stmt, UpdateStmt)) { UpdateStmt *u_stmt = (UpdateStmt *) stmt; ctx.relname = nodeToString(u_stmt->relation); rewrite = rewrite_timestamp_update(u_stmt, &ctx); } else if (IsA(stmt, DeleteStmt)) { DeleteStmt *d_stmt = (DeleteStmt *) stmt; raw_expression_tree_walker( (Node *) d_stmt->usingClause, rewrite_timestamp_walker, (void *) &ctx); raw_expression_tree_walker( (Node *) d_stmt->whereClause, rewrite_timestamp_walker, (void *) &ctx); rewrite = ctx.rewrite; } else if (IsA(stmt, ExecuteStmt)) { ExecuteStmt *e_stmt = (ExecuteStmt *) stmt; /* rewrite params */ raw_expression_tree_walker( (Node *) e_stmt->params, rewrite_timestamp_walker, (void *) &ctx); rewrite = ctx.rewrite; /* add params */ if (message) { int i; for (i = 0; i < message->num_tsparams; i++) { e_stmt->params = lappend(e_stmt->params, ctx.ts_const); rewrite = true; } } } else ; if (!rewrite) return NULL; if (ctx.rewrite_to_params && message) { ListCell *lc; int num = ctx.num_params + 1; /* renumber params */ foreach (lc, ctx.params) { ParamRef *param = (ParamRef *) lfirst(lc); param->number = num++; } /* save to portal */ message->num_tsparams = list_length(ctx.params); /* add param type */ if (IsA(node, PrepareStmt)) { int i; PrepareStmt *p_stmt = (PrepareStmt *) node; for (i = 0; i < message->num_tsparams; i++) p_stmt->argtypes = lappend(p_stmt->argtypes, SystemTypeName("timestamptz")); } } else { timestamp = get_current_timestamp(backend); if (timestamp == NULL) { pool_error("rewrite_timestamp: could not get current timestamp"); return NULL; } ctx.ts_const->val.val.str = timestamp; } rewrite_query = nodeToString(node); return rewrite_query; } /* * rewrite Bind message to add parameter */ char * bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, POOL_SENT_MESSAGE *message, const char *orig_msg, int *len) { int16 tmp2, num_params, num_formats; int32 tmp4; int i, ts_len, copy_len; const char *copy_from; char *ts, *copy_to, *new_msg; #ifdef TIMESTAMPDEBUG fprintf(stderr, "message length:%d\n", *len); for(i=0;i<*len;i++) { fprintf(stderr, "%02x ", orig_msg[i]); } #endif ts = get_current_timestamp(backend); if (ts == NULL) { pool_error("bind_rewrite_timestamp: could not get current timestamp"); return NULL; } ts_len = strlen(ts); *len += (strlen(ts) + sizeof(int32)) * message->num_tsparams; new_msg = copy_to = (char *) malloc(*len + message->num_tsparams * sizeof(int16)); copy_from = orig_msg; /* portal_name */ copy_len = strlen(copy_from) + 1; memcpy(copy_to, copy_from, copy_len); copy_to += copy_len; copy_from += copy_len; /* stmt_name */ copy_len = strlen(copy_from) + 1; memcpy(copy_to, copy_from, copy_len); copy_to += copy_len; copy_from += copy_len; /* format code */ memcpy(&tmp2, copy_from, sizeof(int16)); copy_len = sizeof(int16); tmp2 = num_formats = ntohs(tmp2); if (num_formats > 1) { /* enlarge message length */ *len += message->num_tsparams * sizeof(int16); tmp2 += message->num_tsparams; } tmp2 = htons(tmp2); memcpy(copy_to, &tmp2, copy_len); /* copy number of format codes */ copy_to += copy_len; copy_from += copy_len; copy_len = num_formats * sizeof(int16); memcpy(copy_to, copy_from, copy_len); /* copy format codes */ copy_to += copy_len; copy_from += copy_len; if (num_formats > 1) { /* set format codes to zero(text) */ memset(copy_to, 0, message->num_tsparams * 2); copy_to += sizeof(int16) * message->num_tsparams; } /* num params */ memcpy(&tmp2, copy_from, sizeof(int16)); copy_len = sizeof(int16); num_params = ntohs(tmp2); tmp2 = htons(num_params + message->num_tsparams); memcpy(copy_to, &tmp2, sizeof(int16)); copy_to += copy_len; copy_from += copy_len; /* params */ copy_len = 0; for (i = 0; i < num_params; i++) { memcpy(&tmp4, copy_from + copy_len, sizeof(int32)); tmp4 = ntohl(tmp4); /* param length */ copy_len += sizeof(int32); /* If param length is -1, it indicates that the value is NULL * and we don't have value slot. So we don't add up copy_len. */ if (tmp4 > 0) { copy_len += tmp4; } } memcpy(copy_to, copy_from, copy_len); copy_to += copy_len; copy_from += copy_len; tmp4 = htonl(ts_len); for (i = 0; i < message->num_tsparams; i++) { memcpy(copy_to, &tmp4, sizeof(int32)); copy_to += sizeof(int32); memcpy(copy_to, ts, ts_len); copy_to += ts_len; } /* result format code */ memcpy(&tmp2, copy_from, sizeof(int16)); copy_len = sizeof(int16); copy_len += sizeof(int16) * ntohs(tmp2); memcpy(copy_to, copy_from, copy_len); return new_msg; } static A_Const *makeStringConstFromQuery(POOL_CONNECTION_POOL *backend, char *expression) { A_Const *con; POOL_SELECT_RESULT *res; POOL_STATUS status; char query[1024]; int len; char *str; snprintf(query, sizeof(query), "SELECT %s", expression); status = do_query(MASTER(backend), query, &res, MAJOR(backend)); if (status != POOL_CONTINUE) { pool_error("makeStringConstFromQuery: do_query failed"); free_select_result(res); return NULL; } if (res->numrows != 1) { free_select_result(res); return NULL; } len = strlen(res->data[0]) + 1; str = palloc(len); strcpy(str, res->data[0]); free_select_result(res); con = makeNode(A_Const); con->val.type = T_String; con->val.val.str = str; return con; } /* from nodeFuncs.c start */ /* * raw_expression_tree_walker --- walk raw parse trees * * This has exactly the same API as expression_tree_walker, but instead of * walking post-analysis parse trees, it knows how to walk the node types * found in raw grammar output. (There is not currently any need for a * combined walker, so we keep them separate in the name of efficiency.) * Unlike expression_tree_walker, there is no special rule about query * boundaries: we descend to everything that's possibly interesting. * * Currently, the node type coverage extends to SelectStmt and everything * that could appear under it, but not other statement types. */ bool raw_expression_tree_walker(Node *node, bool (*walker) (), void *context) { ListCell *temp; /* * The walker has already visited the current node, and so we need only * recurse into any sub-nodes it has. */ if (node == NULL) return false; /* Guard against stack overflow due to overly complex expressions */ /* check_stack_depth(); */ switch (nodeTag(node)) { case T_SetToDefault: case T_CurrentOfExpr: case T_Integer: case T_Float: case T_String: case T_BitString: case T_Null: case T_ParamRef: case T_A_Const: case T_A_Star: /* primitive node types with no subnodes */ break; case T_Alias: /* we assume the colnames list isn't interesting */ break; case T_RangeVar: return walker(((RangeVar *) node)->alias, context); case T_SubLink: { SubLink *sublink = (SubLink *) node; if (walker(sublink->testexpr, context)) return true; /* we assume the operName is not interesting */ if (walker(sublink->subselect, context)) return true; } break; case T_CaseExpr: { CaseExpr *caseexpr = (CaseExpr *) node; if (walker(caseexpr->arg, context)) return true; /* we assume walker doesn't care about CaseWhens, either */ foreach(temp, caseexpr->args) { CaseWhen *when = (CaseWhen *) lfirst(temp); Assert(IsA(when, CaseWhen)); if (walker(when->expr, context)) return true; if (walker(when->result, context)) return true; } if (walker(caseexpr->defresult, context)) return true; } break; case T_RowExpr: /* Assume colnames isn't interesting */ return walker(((RowExpr *) node)->args, context); case T_CoalesceExpr: return walker(((CoalesceExpr *) node)->args, context); case T_MinMaxExpr: return walker(((MinMaxExpr *) node)->args, context); case T_XmlExpr: { XmlExpr *xexpr = (XmlExpr *) node; if (walker(xexpr->named_args, context)) return true; /* we assume walker doesn't care about arg_names */ if (walker(xexpr->args, context)) return true; } break; case T_NullTest: return walker(((NullTest *) node)->arg, context); case T_BooleanTest: return walker(((BooleanTest *) node)->arg, context); case T_JoinExpr: { JoinExpr *join = (JoinExpr *) node; if (walker(join->larg, context)) return true; if (walker(join->rarg, context)) return true; if (walker(join->quals, context)) return true; if (walker(join->alias, context)) return true; /* using list is deemed uninteresting */ } break; case T_IntoClause: { IntoClause *into = (IntoClause *) node; if (walker(into->rel, context)) return true; /* colNames, options are deemed uninteresting */ } break; case T_List: foreach(temp, (List *) node) { if (walker((Node *) lfirst(temp), context)) return true; } break; case T_SelectStmt: { SelectStmt *stmt = (SelectStmt *) node; if (walker(stmt->distinctClause, context)) return true; if (walker(stmt->intoClause, context)) return true; if (walker(stmt->targetList, context)) return true; if (walker(stmt->fromClause, context)) return true; if (walker(stmt->whereClause, context)) return true; if (walker(stmt->groupClause, context)) return true; if (walker(stmt->havingClause, context)) return true; if (walker(stmt->windowClause, context)) return true; if (walker(stmt->withClause, context)) return true; if (walker(stmt->valuesLists, context)) return true; if (walker(stmt->sortClause, context)) return true; if (walker(stmt->limitOffset, context)) return true; if (walker(stmt->limitCount, context)) return true; if (walker(stmt->lockingClause, context)) return true; if (walker(stmt->larg, context)) return true; if (walker(stmt->rarg, context)) return true; } break; case T_A_Expr: { A_Expr *expr = (A_Expr *) node; if (walker(expr->lexpr, context)) return true; if (walker(expr->rexpr, context)) return true; /* operator name is deemed uninteresting */ } break; case T_ColumnRef: /* we assume the fields contain nothing interesting */ break; case T_FuncCall: { FuncCall *fcall = (FuncCall *) node; if (walker(fcall->args, context)) return true; if (walker(fcall->over, context)) return true; /* function name is deemed uninteresting */ } break; case T_A_Indices: { A_Indices *indices = (A_Indices *) node; if (walker(indices->lidx, context)) return true; if (walker(indices->uidx, context)) return true; } break; case T_A_Indirection: { A_Indirection *indir = (A_Indirection *) node; if (walker(indir->arg, context)) return true; if (walker(indir->indirection, context)) return true; } break; case T_A_ArrayExpr: return walker(((A_ArrayExpr *) node)->elements, context); case T_ResTarget: { ResTarget *rt = (ResTarget *) node; if (walker(rt->indirection, context)) return true; if (walker(rt->val, context)) return true; } break; case T_TypeCast: { TypeCast *tc = (TypeCast *) node; if (walker(tc->arg, context)) return true; if (walker(tc->typeName, context)) return true; } break; case T_SortBy: return walker(((SortBy *) node)->node, context); case T_WindowDef: { WindowDef *wd = (WindowDef *) node; if (walker(wd->partitionClause, context)) return true; if (walker(wd->orderClause, context)) return true; } break; case T_RangeSubselect: { RangeSubselect *rs = (RangeSubselect *) node; if (walker(rs->subquery, context)) return true; if (walker(rs->alias, context)) return true; } break; case T_RangeFunction: { RangeFunction *rf = (RangeFunction *) node; if (walker(rf->funccallnode, context)) return true; if (walker(rf->alias, context)) return true; } break; case T_TypeName: { TypeName *tn = (TypeName *) node; if (walker(tn->typmods, context)) return true; if (walker(tn->arrayBounds, context)) return true; /* type name itself is deemed uninteresting */ } break; case T_ColumnDef: { ColumnDef *coldef = (ColumnDef *) node; if (walker(coldef->typeName, context)) return true; if (walker(coldef->raw_default, context)) return true; /* for now, constraints are ignored */ } break; case T_LockingClause: return walker(((LockingClause *) node)->lockedRels, context); case T_XmlSerialize: { XmlSerialize *xs = (XmlSerialize *) node; if (walker(xs->expr, context)) return true; if (walker(xs->typeName, context)) return true; } break; case T_WithClause: return walker(((WithClause *) node)->ctes, context); case T_CommonTableExpr: return walker(((CommonTableExpr *) node)->ctequery, context); default: /* elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); */ break; } return false; } /* from nodeFuncs.c end */ pgpool-II-3.3.2/config.h.in0000664000076400007640000002206012245776614012312 00000000000000/* config.h.in. Generated from configure.in by autoheader. */ /* Define to the type of arg 1 of 'accept' */ #undef ACCEPT_TYPE_ARG1 /* Define to the type of arg 2 of 'accept' */ #undef ACCEPT_TYPE_ARG2 /* Define to the type of arg 3 of 'accept' */ #undef ACCEPT_TYPE_ARG3 /* Define to the return type of 'accept' */ #undef ACCEPT_TYPE_RETURN /* float4 values are passed by value if 'true', by reference if 'false' */ #undef FLOAT4PASSBYVAL /* float8, int8, and related values are passed by value if 'true', by reference if 'false' */ #undef FLOAT8PASSBYVAL /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_CRYPT_H /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `gai_strerror' function. */ #undef HAVE_GAI_STRERROR /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define to 1 if you have the `hstrerror' function. */ #undef HAVE_HSTRERROR /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `BSD' library (-lBSD). */ #undef HAVE_LIBBSD /* Define to 1 if you have the `crypt' library (-lcrypt). */ #undef HAVE_LIBCRYPT /* Define to 1 if you have the `crypto' library (-lcrypto). */ #undef HAVE_LIBCRYPTO /* Define to 1 if you have the `gen' library (-lgen). */ #undef HAVE_LIBGEN /* Define to 1 if you have the `IPC' library (-lIPC). */ #undef HAVE_LIBIPC /* Define to 1 if you have the `lc' library (-llc). */ #undef HAVE_LIBLC /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `memcached' library (-lmemcached). */ #undef HAVE_LIBMEMCACHED /* Define to 1 if you have the header file. */ #undef HAVE_LIBMEMCACHED_MEMCACHED_H /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* Define to 1 if you have the `pam' library (-lpam). */ #undef HAVE_LIBPAM /* Define to 1 if you have the `pq' library (-lpq). */ #undef HAVE_LIBPQ /* Define to 1 if you have the `PW' library (-lPW). */ #undef HAVE_LIBPW /* Define to 1 if you have the `resolv' library (-lresolv). */ #undef HAVE_LIBRESOLV /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the `ssl' library (-lssl). */ #undef HAVE_LIBSSL /* Define to 1 if constants of type 'long long int' should have the suffix LL. */ #undef HAVE_LL_CONSTANTS /* Define to 1 if `long int' works and is 64 bits. */ #undef HAVE_LONG_INT_64 /* Define to 1 if `long long int' works and is 64 bits. */ #undef HAVE_LONG_LONG_INT_64 /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_TCP_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SSL_H /* Define to 1 if you have the header file. */ #undef HAVE_PAM_PAM_APPL_H /* Define to 1 if you have the `PQprepare' function. */ #undef HAVE_PQPREPARE /* Define to 1 if you have the `pstat' function. */ #undef HAVE_PSTAT /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_PAM_APPL_H /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `setproctitle' function. */ #undef HAVE_SETPROCTITLE /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the `sigprocmask' function. */ #undef HAVE_SIGPROCMASK /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the `strftime' function. */ #undef HAVE_STRFTIME /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strtok' function. */ #undef HAVE_STRTOK /* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ #undef HAVE_STRUCT_SOCKADDR_SA_LEN /* Define to 1 if the system has the type `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE /* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY /* Define to 1 if `ss_len' is a member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN /* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY /* Define to 1 if `__ss_len' is a member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PSTAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SEM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SHM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UN_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if the system has the type `union semun'. */ #undef HAVE_UNION_SEMUN /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vasprintf' function. */ #undef HAVE_VASPRINTF /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* Define to 1 if you have the `vsyslog' function. */ #undef HAVE_VSYSLOG /* Define to 1 if you have the `wait3' system call. Deprecated, you should no longer depend upon `wait3'. */ #undef HAVE_WAIT3 /* Define to the appropriate snprintf format for 64-bit ints, if any. */ #undef INT64_FORMAT /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* The size of `size_t', as computed by sizeof. */ #undef SIZEOF_SIZE_T /* The size of `unsigned long', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_LONG /* The size of `void *', as computed by sizeof. */ #undef SIZEOF_VOID_P /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to the appropriate snprintf format for unsigned 64-bit ints, if any. */ #undef UINT64_FORMAT /* Define to 1 if you want float4 values to be passed by value. (--enable-float4-byval) */ #undef USE_FLOAT4_BYVAL /* Define to 1 if you want float8, int8, etc values to be passed by value. (--enable-float8-byval) */ #undef USE_FLOAT8_BYVAL /* Define to 1 to build with memcached support */ #undef USE_MEMCACHED /* Define to 1 to build with PAM support. (--with-pam) */ #undef USE_PAM /* Use replacement snprintf() functions. */ #undef USE_REPL_SNPRINTF /* Define to 1 if you want to use row lock against the sequence table for insert_lock. (--enable-sequence-lock) */ #undef USE_SEQUENCE_LOCK /* Define to 1 to build with SSL support. (--with-openssl) */ #undef USE_SSL /* Define to 1 if you want to use table lock against the target table for insert_lock. (--enable-table-lock) */ #undef USE_TABLE_LOCK /* Version number of package */ #undef VERSION /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `int' if does not define. */ #undef pid_t pgpool-II-3.3.2/install-sh0000775000076400007640000001273612245576256012304 00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 pgpool-II-3.3.2/strlcpy.c0000664000076400007640000000466312245576257012145 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * This file was imported from PostgreSQL source code. * See below for the copyright and description. * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2008 PgPool Global Development Group * */ /*------------------------------------------------------------------------- * * strlcpy.c * strncpy done right * * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * * * IDENTIFICATION * $PostgreSQL: pgsql/src/port/strlcpy.c,v 1.3 2006/10/04 00:30:14 momjian Exp $ * * This file was taken from OpenBSD and is used on platforms that don't * provide strlcpy(). The OpenBSD copyright terms follow. *------------------------------------------------------------------------- */ /* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include "pool.h" /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. * Function creation history: http://www.gratisoft.us/todd/papers/strlcpy.html */ size_t strlcpy(char *dst, const char *src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0) { while (--n != 0) { if ((*d++ = *s++) == '\0') break; } } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return (s - src - 1); /* count does not include NUL */ } pgpool-II-3.3.2/pool_stream.c0000664000076400007640000004441712245576267012773 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_stream.c: stream I/O modules * */ #include "config.h" #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #ifdef HAVE_FCNTL_H #include #endif #include "pool.h" #include "pool_stream.h" #include "pool_config.h" static int mystrlen(char *str, int upper, int *flag); static int mystrlinelen(char *str, int upper, int *flag); static int save_pending_data(POOL_CONNECTION *cp, void *data, int len); static int consume_pending_data(POOL_CONNECTION *cp, void *data, int len); /* * open read/write file descriptors. * returns POOL_CONNECTION on success otherwise NULL. */ POOL_CONNECTION *pool_open(int fd) { POOL_CONNECTION *cp; cp = (POOL_CONNECTION *)malloc(sizeof(POOL_CONNECTION)); if (cp == NULL) { pool_error("pool_open: malloc failed: %s", strerror(errno)); return NULL; } memset(cp, 0, sizeof(*cp)); /* initialize write buffer */ cp->wbuf = malloc(WRITEBUFSZ); if (cp->wbuf == NULL) { pool_error("pool_open: malloc failed"); return NULL; } cp->wbufsz = WRITEBUFSZ; cp->wbufpo = 0; /* initialize pending data buffer */ cp->hp = malloc(READBUFSZ); if (cp->hp == NULL) { pool_error("pool_open: malloc failed"); free(cp); return NULL; } cp->bufsz = READBUFSZ; cp->po = 0; cp->len = 0; cp->sbuf = NULL; cp->sbufsz = 0; cp->buf2 = NULL; cp->bufsz2 = 0; cp->fd = fd; return cp; } /* * close read/write file descriptors. */ void pool_close(POOL_CONNECTION *cp) { /* * shutdown connection to the client so that pgpool is not blocked */ if (!cp->isbackend) shutdown(cp->fd, 1); close(cp->fd); free(cp->wbuf); free(cp->hp); if (cp->sbuf) free(cp->sbuf); if (cp->buf2) free(cp->buf2); pool_discard_params(&cp->params); pool_ssl_close(cp); free(cp); } /* * read len bytes from cp * returns 0 on success otherwise -1. */ int pool_read(POOL_CONNECTION *cp, void *buf, int len) { static char readbuf[READBUFSZ]; int consume_size; int readlen; consume_size = consume_pending_data(cp, buf, len); len -= consume_size; buf += consume_size; while (len > 0) { if (pool_check_fd(cp)) { if (!IS_MASTER_NODE_ID(cp->db_node_id) && (getpid() != mypid)) { pool_log("pool_read: data is not ready in DB node: %d. abort this session", cp->db_node_id); exit(1); } else { pool_error("pool_read: pool_check_fd failed (%s)", strerror(errno)); return -1; } } if (cp->ssl_active > 0) { readlen = pool_ssl_read(cp, readbuf, READBUFSZ); } else { readlen = read(cp->fd, readbuf, READBUFSZ); } if (readlen == -1) { if (errno == EINTR || errno == EAGAIN) { pool_debug("pool_read: retrying due to %s", strerror(errno)); continue; } pool_error("pool_read: read failed (%s)", strerror(errno)); if (cp->isbackend) { /* if fail_over_on_backend_error is true, then trigger failover */ if (pool_config->fail_over_on_backend_error) { notice_backend_error(cp->db_node_id); child_exit(1); pool_log("pool_read: do not failover because I am the main process"); return -1; } else { pool_log("pool_read: do not failover because fail_over_on_backend_error is off"); return -1; } } else { return -1; } } else if (readlen == 0) { if (cp->isbackend) { pool_error("pool_read: EOF encountered with backend"); return -1; #ifdef NOT_USED /* fatal error, notice to parent and exit */ notice_backend_error(IS_MASTER_NODE_ID(cp->db_node_id)); child_exit(1); #endif } else { /* * if backend offers authentication method, frontend could close connection */ return -1; } } if (len < readlen) { /* overrun. we need to save remaining data to pending buffer */ if (save_pending_data(cp, readbuf+len, readlen-len)) return -1; memmove(buf, readbuf, len); break; } memmove(buf, readbuf, readlen); buf += readlen; len -= readlen; } return 0; } /* * read exactly len bytes from cp * returns buffer address on success otherwise NULL. */ char *pool_read2(POOL_CONNECTION *cp, int len) { char *buf; int req_size; int alloc_size; int consume_size; int readlen; req_size = cp->len + len; if (req_size > cp->bufsz2) { alloc_size = ((req_size+1)/READBUFSZ+1)*READBUFSZ; cp->buf2 = realloc(cp->buf2, alloc_size); if (cp->buf2 == NULL) { pool_error("pool_read2: failed to realloc"); exit(1); } cp->bufsz2 = alloc_size; } buf = cp->buf2; consume_size = consume_pending_data(cp, buf, len); len -= consume_size; buf += consume_size; while (len > 0) { if (pool_check_fd(cp)) { if (!IS_MASTER_NODE_ID(cp->db_node_id)) { pool_log("pool_read2: data is not ready in DB node:%d. abort this session", cp->db_node_id); exit(1); } else { pool_error("pool_read2: pool_check_fd failed (%s)", strerror(errno)); return NULL; } } if (cp->ssl_active > 0) { readlen = pool_ssl_read(cp, buf, len); } else { readlen = read(cp->fd, buf, len); } if (readlen == -1) { if (errno == EINTR || errno == EAGAIN) { pool_debug("pool_read2: retrying due to %s", strerror(errno)); continue; } pool_error("pool_read2: read failed (%s)", strerror(errno)); if (cp->isbackend) { /* if fail_over_on_backend_error is true, then trigger failover */ if (pool_config->fail_over_on_backend_error) { notice_backend_error(cp->db_node_id); child_exit(1); pool_log("pool_read2: do not failover because I am the main process"); return NULL; } else { pool_log("pool_read2: do not failover because fail_over_on_backend_error is off"); return NULL; } } else { return NULL; } } else if (readlen == 0) { if (cp->isbackend) { pool_error("pool_read2: EOF encountered with backend"); return NULL; #ifdef NOT_USED /* fatal error, notice to parent and exit */ notice_backend_error(IS_MASTER_NODE_ID(cp->db_node_id)); child_exit(1); #endif } else { /* * if backend offers authentication method, frontend could close connection */ return NULL; } } buf += readlen; len -= readlen; } return cp->buf2; } /* * write len bytes to cp the write buffer. * returns 0 on success otherwise -1. */ int pool_write(POOL_CONNECTION *cp, void *buf, int len) { if (len < 0) { pool_error("pool_write: invalid request size: %d", len); return -1; } if (cp->no_forward) return 0; while (len > 0) { int remainder = WRITEBUFSZ - cp->wbufpo; if (cp->wbufpo >= WRITEBUFSZ) { /* * Write buffer is full. so flush buffer. * wbufpo is reset in pool_flush_it(). */ if (pool_flush_it(cp) == -1) return -1; remainder = WRITEBUFSZ; } /* check buffer size */ if (remainder >= len) { /* OK, buffer size is enough. */ remainder = len; } memcpy(cp->wbuf+cp->wbufpo, buf, remainder); cp->wbufpo += remainder; buf += remainder; len -= remainder; } return 0; } /* * flush write buffer */ int pool_flush_it(POOL_CONNECTION *cp) { int sts; int wlen; int offset; wlen = cp->wbufpo; if (wlen == 0) { return 0; } offset = 0; for (;;) { errno = 0; #ifdef NOT_USED if (!cp->isbackend) { fd_set writemask; fd_set exceptmask; FD_ZERO(&writemask); FD_ZERO(&exceptmask); FD_SET(cp->fd, &writemask); FD_SET(cp->fd, &exceptmask); sts = select(cp->fd+1, NULL, &writemask, &exceptmask, NULL); if (sts == -1) { if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) continue; pool_error("pool_flush_it: select() failed. reason: %s", strerror(errno)); cp->wbufpo = 0; return -1; } else if (sts == 0) { continue; } else if (FD_ISSET(cp->fd, &exceptmask)) { pool_log("pool_flush_it: exception occurred"); cp->wbufpo = 0; return -1; } } #endif if (cp->ssl_active > 0) { sts = pool_ssl_write(cp, cp->wbuf + offset, wlen); } else { sts = write(cp->fd, cp->wbuf + offset, wlen); } if (sts > 0) { wlen -= sts; if (wlen == 0) { /* write completed */ break; } else if (wlen < 0) { pool_error("pool_flush_it: invalid write size %d", sts); cp->wbufpo = 0; return -1; } else { /* need to write remaining data */ offset += sts; continue; } } else if (errno == EAGAIN || errno == EINTR) { continue; } else { /* If this is the backend stream, report error. Otherwise * just report debug message. */ if (cp->isbackend) pool_error("pool_flush_it: write failed to backend (%d). reason: %s offset: %d wlen: %d", cp->db_node_id, strerror(errno), offset, wlen); else pool_debug("pool_flush_it: write failed to frontend. reason: %s offset: %d wlen: %d", strerror(errno), offset, wlen); cp->wbufpo = 0; return -1; } } cp->wbufpo = 0; return 0; } /* * flush write buffer and degenerate/failover if error occurs */ int pool_flush(POOL_CONNECTION *cp) { if (pool_flush_it(cp) == -1) { if (cp->isbackend) { /* if fail_over_on_backend_error is true, then trigger failover */ if (pool_config->fail_over_on_backend_error) { notice_backend_error(cp->db_node_id); child_exit(1); pool_log("pool_flush: do not failover because I am the main process"); return -1; } else { pool_log("pool_flush: do not failover because fail_over_on_backend_error is off"); return -1; } } else { /* * If we are in replication mode, we need to continue the * processing with backends to keep consistency among * backends, thus ignore error. */ if (REPLICATION) return 0; else return -1; } } return 0; } /* * combo of pool_write and pool_flush */ int pool_write_and_flush(POOL_CONNECTION *cp, void *buf, int len) { if (pool_write(cp, buf, len)) return -1; return pool_flush(cp); } /* * read a string until EOF or NULL is encountered. * if line is not 0, read until new line is encountered. */ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) { int readp; int readsize; int readlen; int strlength; int flag; int consume_size; #ifdef DEBUG static char pbuf[READBUFSZ]; #endif *len = 0; readp = 0; /* initialize read buffer */ if (cp->sbufsz == 0) { cp->sbuf = malloc(READBUFSZ); if (cp->sbuf == NULL) { pool_error("pool_read_string: malloc failed"); return NULL; } cp->sbufsz = READBUFSZ; *cp->sbuf = '\0'; } /* any pending data? */ if (cp->len) { if (line) strlength = mystrlinelen(cp->hp+cp->po, cp->len, &flag); else strlength = mystrlen(cp->hp+cp->po, cp->len, &flag); /* buffer is too small? */ if ((strlength + 1) > cp->sbufsz) { cp->sbufsz = ((strlength+1)/READBUFSZ+1)*READBUFSZ; cp->sbuf = realloc(cp->sbuf, cp->sbufsz); if (cp->sbuf == NULL) { pool_error("pool_read_string: realloc failed"); return NULL; } } /* consume pending and save to read string buffer */ consume_size = consume_pending_data(cp, cp->sbuf, strlength); *len = strlength; /* is the string null terminated? */ if (consume_size == strlength && !flag) { /* not null or line terminated. * we need to read more since we have not encountered NULL or new line yet */ readsize = cp->sbufsz - strlength; readp = strlength; } else { pool_debug("pool_read_string: read all from pending data. po:%d len:%d", cp->po, cp->len); return cp->sbuf; } } else { readsize = cp->sbufsz; } for (;;) { if (pool_check_fd(cp)) { if (!IS_MASTER_NODE_ID(cp->db_node_id)) { pool_log("pool_read_string: data is not ready in DB node:%d. abort this session", cp->db_node_id); exit(1); } else { pool_error("pool_read_string: pool_check_fd failed (%s)", strerror(errno)); return NULL; } } if (cp->ssl_active > 0) { readlen = pool_ssl_read(cp, cp->sbuf+readp, readsize); } else { readlen = read(cp->fd, cp->sbuf+readp, readsize); } if (readlen == -1) { pool_error("pool_read_string: read() failed. reason:%s", strerror(errno)); if (cp->isbackend) { notice_backend_error(cp->db_node_id); child_exit(1); return NULL; } else { return NULL; } } else if (readlen == 0) /* EOF detected */ { /* * just returns an error, not trigger failover or degeneration */ pool_error("pool_read_string: read () EOF detected"); return NULL; } /* check overrun */ if (line) strlength = mystrlinelen(cp->sbuf+readp, readlen, &flag); else strlength = mystrlen(cp->sbuf+readp, readlen, &flag); if (strlength < readlen) { save_pending_data(cp, cp->sbuf+readp+strlength, readlen-strlength); *len += strlength; pool_debug("pool_read_string: total result %d with pending data po:%d len:%d", *len, cp->po, cp->len); return cp->sbuf; } *len += readlen; /* encountered null or newline? */ if (flag) { /* ok we have read all data */ pool_debug("pool_read_string: total result %d ", *len); break; } readp += readlen; readsize = READBUFSZ; if ((*len+readsize) > cp->sbufsz) { cp->sbufsz += READBUFSZ; cp->sbuf = realloc(cp->sbuf, cp->sbufsz); if (cp->sbuf == NULL) { pool_error("pool_read_string: realloc failed"); return NULL; } } } return cp->sbuf; } /* * returns the byte length of str, including \0, no more than upper. * if encountered \0, flag is set to non 0. * example: * mystrlen("abc", 2) returns 2 * mystrlen("abc", 3) returns 3 * mystrlen("abc", 4) returns 4 * mystrlen("abc", 5) returns 4 */ static int mystrlen(char *str, int upper, int *flag) { int len; *flag = 0; for (len = 0;len < upper; len++, str++) { if (!*str) { len++; *flag = 1; break; } } return len; } /* * returns the byte length of str terminated by \n or \0 (including \n or \0), no more than upper. * if encountered \0 or \n, flag is set to non 0. * example: * mystrlinelen("abc", 2) returns 2 * mystrlinelen("abc", 3) returns 3 * mystrlinelen("abc", 4) returns 4 * mystrlinelen("abc", 5) returns 4 * mystrlinelen("abcd\nefg", 4) returns 4 * mystrlinelen("abcd\nefg", 5) returns 5 * mystrlinelen("abcd\nefg", 6) returns 5 */ static int mystrlinelen(char *str, int upper, int *flag) { int len; *flag = 0; for (len = 0;len < upper; len++, str++) { if (!*str || *str == '\n') { len++; *flag = 1; break; } } return len; } /* * save pending data */ static int save_pending_data(POOL_CONNECTION *cp, void *data, int len) { int reqlen; size_t realloc_size; char *p; /* to be safe */ if (cp->len == 0) cp->po = 0; reqlen = cp->po + cp->len + len; /* pending buffer is enough? */ if (reqlen > cp->bufsz) { /* too small, enlarge it */ realloc_size = (reqlen/READBUFSZ+1)*READBUFSZ; p = realloc(cp->hp, realloc_size); if (p == NULL) { pool_error("save_pending_data: realloc failed"); return -1; } cp->bufsz = realloc_size; cp->hp = p; } memmove(cp->hp + cp->po + cp->len, data, len); cp->len += len; return 0; } /* * consume pending data. returns actually consumed data length. */ static int consume_pending_data(POOL_CONNECTION *cp, void *data, int len) { int consume_size; if (cp->len <= 0) return 0; consume_size = Min(len, cp->len); memmove(data, cp->hp + cp->po, consume_size); cp->len -= consume_size; if (cp->len <= 0) cp->po = 0; else cp->po += consume_size; return consume_size; } /* * pool_unread: Put back data to input buffer */ int pool_unread(POOL_CONNECTION *cp, void *data, int len) { void *p = cp->hp; int n = cp->len + len; int realloc_size; if (cp->bufsz < n) { realloc_size = (n/READBUFSZ+1)*READBUFSZ; p = realloc(cp->hp, realloc_size); if (p == NULL) { pool_error("pool_unread: realloc failed"); return -1; } cp->hp = p; } if (cp->len != 0) memmove(p + len, cp->hp + cp->po, cp->len); memmove(p, data, len); cp->len = n; cp->po = 0; return 0; } /* * pool_push: Push data into buffer stack. */ int pool_push(POOL_CONNECTION *cp, void *data, int len) { char *p; pool_debug("pool_push: len: %d", len); if (cp->bufsz3 == 0) { p = cp->buf3 = malloc(len); if (p == NULL) { pool_error("pool_push: malloc failed. len:%d", len); return -1; } } else { p = cp->buf3 + cp->bufsz3; cp->buf3 = realloc(cp->buf3, cp->bufsz3 + len); } memcpy(p, data, len); cp->bufsz3 += len; return 0; } /* * pool_pop: Pop data from buffer stack and put back data using * pool_unread. */ void pool_pop(POOL_CONNECTION *cp, int *len) { if (cp->bufsz3 == 0) { *len = 0; pool_debug("pool_pop: len: %d", *len); return; } pool_unread(cp, cp->buf3, cp->bufsz3); *len = cp->bufsz3; free(cp->buf3); cp->bufsz3 = 0; cp->buf3 = NULL; pool_debug("pool_pop: len: %d", *len); } /* * pool_stacklen: Returns buffer stack length * pool_unread. */ int pool_stacklen(POOL_CONNECTION *cp) { return cp->bufsz3; } /* * set non-block flag */ void pool_set_nonblock(int fd) { int var; /* set fd to none blocking */ var = fcntl(fd, F_GETFL, 0); if (var == -1) { pool_error("fcntl failed. %s", strerror(errno)); child_exit(1); } if (fcntl(fd, F_SETFL, var | O_NONBLOCK) == -1) { pool_error("fcntl failed. %s", strerror(errno)); child_exit(1); } } /* * unset non-block flag */ void pool_unset_nonblock(int fd) { int var; /* set fd to none blocking */ var = fcntl(fd, F_GETFL, 0); if (var == -1) { pool_error("fcntl failed. %s", strerror(errno)); child_exit(1); } if (fcntl(fd, F_SETFL, var & ~O_NONBLOCK) == -1) { pool_error("fcntl failed. %s", strerror(errno)); child_exit(1); } } pgpool-II-3.3.2/ltmain.sh0000775000076400007640000073306012245576256012123 00000000000000# Generated from ltmain.m4sh. # ltmain.sh (GNU libtool) 2.2.6b # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print informational messages (default) # --version print version information # -h, --help print short or long help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.2.6b # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . PROGRAM=ltmain.sh PACKAGE=libtool VERSION=2.2.6b TIMESTAMP="" package_revision=1.3017 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # NLS nuisances: We save the old values to restore during execute mode. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done $lt_unset CDPATH : ${CP="cp -f"} : ${ECHO="echo"} : ${EGREP="/bin/grep -E"} : ${FGREP="/bin/grep -F"} : ${GREP="/bin/grep"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SED="/bin/sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # Generated shell functions inserted here. # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" # The name of this program: # In the unlikely event $progname began with a '-', it would play havoc with # func_echo (imagine progname=-n), so we prepend ./ in that case: func_dirname_and_basename "$progpath" progname=$func_basename_result case $progname in -*) progname=./$progname ;; esac # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=: for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname${mode+: }$mode: $*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` done my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "X$my_tmpdir" | $Xsed } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "X$1" | $Xsed \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_version # Echo version message to standard output and exit. func_version () { $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $SED -n '/^# Usage:/,/# -h/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" $ECHO $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help # Echo long help message to standard output and exit. func_help () { $SED -n '/^# Usage:/,/# Report bugs to/ { s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ p }' < "$progpath" exit $? } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { func_error "missing argument for $1" exit_cmd=exit } exit_cmd=: # Check that we have a working $ECHO. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then # Yippee, $ECHO works! : else # Restart under the correct shell, and then maybe $ECHO will work. exec $SHELL "$progpath" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # Parse options once, thoroughly. This comes as soon as possible in # the script to make things like `libtool --version' happen quickly. { # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Parse non-mode specific arguments: while test "$#" -gt 0; do opt="$1" shift case $opt in --config) func_config ;; --debug) preserve_args="$preserve_args $opt" func_echo "enabling shell trace mode" opt_debug='set -x' $opt_debug ;; -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break execute_dlfiles="$execute_dlfiles $1" shift ;; --dry-run | -n) opt_dry_run=: ;; --features) func_features ;; --finish) mode="finish" ;; --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break case $1 in # Valid mode arguments: clean) ;; compile) ;; execute) ;; finish) ;; install) ;; link) ;; relink) ;; uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac mode="$1" shift ;; --preserve-dup-deps) opt_duplicate_deps=: ;; --quiet|--silent) preserve_args="$preserve_args $opt" opt_silent=: ;; --verbose| -v) preserve_args="$preserve_args $opt" opt_silent=false ;; --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break preserve_args="$preserve_args $opt $1" func_enable_tag "$1" # tagname is set here shift ;; # Separate optargs to long options: -dlopen=*|--mode=*|--tag=*) func_opt_split "$opt" set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} shift ;; -\?|-h) func_usage ;; --help) opt_help=: ;; --version) func_version ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) nonopt="$opt" break ;; esac done case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_duplicate_deps ;; esac # Having warned about all mis-specified options, bail out if # anything was wrong. $exit_cmd $EXIT_FAILURE } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } ## ----------- ## ## Main. ## ## ----------- ## $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi test -z "$mode" && func_fatal_error "error: you must specify a MODE." # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$mode' for more information." } # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_ltwrapper_scriptname_result="" if func_ltwrapper_executable_p "$1"; then func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" fi } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case "$@ " in " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T <?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi removelist="$removelist $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist removelist="$removelist $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir command="$command -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then command="$command -o $obj" fi # Suppress compiler output if we already did a PIC compilation. command="$command$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to building PIC objects only -prefer-non-pic try to building non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$mode'" ;; esac $ECHO $ECHO "Try \`$progname --help' for more information about other modes." exit $? } # Now that we've collected a possible --mode arg, show help if necessary $opt_help && func_mode_help # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $execute_dlfiles; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -*) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_quote_for_eval "$file" args="$args $func_quote_for_eval_result" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" $ECHO "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS $ECHO "X----------------------------------------------------------------------" | $Xsed $ECHO "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done $ECHO $ECHO "If you ever happen to want to link against installed libraries" $ECHO "in a given directory, LIBDIR, you must either use libtool, and" $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" $ECHO "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" $ECHO " during execution" fi if test -n "$runpath_var"; then $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" $ECHO " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi $ECHO $ECHO "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" $ECHO "pages." ;; *) $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac $ECHO "X----------------------------------------------------------------------" | $Xsed exit $EXIT_SUCCESS } test "$mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $ECHO "X$nonopt" | $GREP shtool >/dev/null; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" install_prog="$install_prog$func_quote_for_eval_result" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) case " $install_prog " in *[\\\ /]cp\ *) ;; *) prev=$arg ;; esac ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" install_prog="$install_prog $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" dir="$dir$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for progfile in $progfiles; do func_verbose "extracting global C symbols from \`$progfile'" $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" } done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" fi $ECHO >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; " case $host in *cygwin* | *mingw* | *cegcc* ) $ECHO >> "$output_objdir/$my_dlsyms" "\ /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */" lt_dlsym_const= ;; *osf5*) echo >> "$output_objdir/$my_dlsyms" "\ /* This system does not cope well with relocations in const data */" lt_dlsym_const= ;; *) lt_dlsym_const=const ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ extern $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) symtab_cflags="$symtab_cflags $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then win32_nmres=`eval $NM -f posix -A $1 | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper_part1 [arg=no] # # Emit the first part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part1 () { func_emit_wrapper_part1_arg1=no if test -n "$1" ; then func_emit_wrapper_part1_arg1=$1 fi $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='${SED} -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then ECHO=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then # Yippee, \$ECHO works! : else # Restart under the correct shell, and then maybe \$ECHO will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $ECHO "\ # Find the directory that this script lives in. thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done " } # end: func_emit_wrapper_part1 # func_emit_wrapper_part2 [arg=no] # # Emit the second part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part2 () { func_emit_wrapper_part2_arg1=no if test -n "$1" ; then func_emit_wrapper_part2_arg1=$1 fi $ECHO "\ # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # end: func_emit_wrapper_part2 # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=no if test -n "$1" ; then func_emit_wrapper_arg1=$1 fi # split this up so that func_emit_cwrapperexe_src # can call each part independently. func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" } # func_to_host_path arg # # Convert paths to host format when used with build tools. # Intended for use with "native" mingw (where libtool itself # is running under the msys shell), or in the following cross- # build environments: # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # where wine is equipped with the `winepath' executable. # In the native mingw case, the (msys) shell automatically # converts paths for any non-msys applications it launches, # but that facility isn't available from inside the cwrapper. # Similar accommodations are necessary for $host mingw and # $build cygwin. Calling this function does no harm for other # $host/$build combinations not listed above. # # ARG is the path (on $build) that should be converted to # the proper representation for $host. The result is stored # in $func_to_host_path_result. func_to_host_path () { func_to_host_path_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' case $build in *mingw* ) # actually, msys # awkward: cmd appends spaces to result lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_path_tmp1=`( cmd //c echo "$1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_path_tmp1=`cygpath -w "$1"` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # Unfortunately, winepath does not exit with a non-zero # error code, so we are forced to check the contents of # stdout. On the other hand, if the command is not # found, the shell will set an exit code of 127 and print # *an error message* to stdout. So we must check for both # error code of zero AND non-empty stdout, which explains # the odd construction: func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` else # Allow warning below. func_to_host_path_result="" fi ;; esac if test -z "$func_to_host_path_result" ; then func_error "Could not determine host path corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_path_result="$1" fi ;; esac fi } # end: func_to_host_path # func_to_host_pathlist arg # # Convert pathlists to host format when used with build tools. # See func_to_host_path(), above. This function supports the # following $build/$host combinations (but does no harm for # combinations not listed here): # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # # Path separators are also converted from $build format to # $host format. If ARG begins or ends with a path separator # character, it is preserved (but converted to $host format) # on output. # # ARG is a pathlist (on $build) that should be converted to # the proper representation on $host. The result is stored # in $func_to_host_pathlist_result. func_to_host_pathlist () { func_to_host_pathlist_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_to_host_pathlist_tmp2="$1" # Once set for this call, this variable should not be # reassigned. It is used in tha fallback case. func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e 's|^:*||' -e 's|:*$||'` case $build in *mingw* ) # Actually, msys. # Awkward: cmd appends spaces to result. lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # unfortunately, winepath doesn't convert pathlists func_to_host_pathlist_result="" func_to_host_pathlist_oldIFS=$IFS IFS=: for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do IFS=$func_to_host_pathlist_oldIFS if test -n "$func_to_host_pathlist_f" ; then func_to_host_path "$func_to_host_pathlist_f" if test -n "$func_to_host_path_result" ; then if test -z "$func_to_host_pathlist_result" ; then func_to_host_pathlist_result="$func_to_host_path_result" else func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" fi fi fi IFS=: done IFS=$func_to_host_pathlist_oldIFS ;; esac if test -z "$func_to_host_pathlist_result" ; then func_error "Could not determine the host path(s) corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This may break if $1 contains DOS-style drive # specifications. The fix is not to complicate the expression # below, but for the user to provide a working wine installation # with winepath so that path translation in the cross-to-mingw # case works properly. lt_replace_pathsep_nix_to_dos="s|:|;|g" func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_replace_pathsep_nix_to_dos"` fi # Now, add the leading and trailing path separators back case "$1" in :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" ;; esac case "$1" in *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" ;; esac ;; esac fi } # end: func_to_host_pathlist # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include # define setmode _setmode #else # include # include # ifdef __CYGWIN__ # include # define HAVE_SETENV # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif # endif #endif #include #include #include #include #include #include #include #include #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif #ifdef _MSC_VER # define S_IXUSR _S_IEXEC # define stat _stat # ifndef _INTPTR_T_DEFINED # define intptr_t int # endif #endif #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifdef __CYGWIN__ # define FOPEN_WB "wb" #endif #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #undef LTWRAPPER_DEBUGPRINTF #if defined DEBUGWRAPPER # define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args static void ltwrapper_debugprintf (const char *fmt, ...) { va_list args; va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } #else # define LTWRAPPER_DEBUGPRINTF(args) #endif const char *program_name = NULL; void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_fatal (const char *message, ...); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_opt_process_env_set (const char *arg); void lt_opt_process_env_prepend (const char *arg); void lt_opt_process_env_append (const char *arg); int lt_split_name_value (const char *arg, char** name, char** value); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); static const char *script_text_part1 = EOF func_emit_wrapper_part1 yes | $SED -e 's/\([\\"]\)/\\\1/g' \ -e 's/^/ "/' -e 's/$/\\n"/' echo ";" cat <"))); for (i = 0; i < newargc; i++) { LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); } EOF case $host_os in mingw*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); if (rval == -1) { /* failed to start process */ LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); return 127; } return rval; EOF ;; *) cat <<"EOF" execv (lt_argv_zero, newargz); return rval; /* =127, but avoids unused variable warning */ EOF ;; esac cat <<"EOF" } void * xmalloc (size_t num) { void *p = (void *) malloc (num); if (!p) lt_fatal ("Memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL; } const char * base_name (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha ((unsigned char) name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return base; } int check_executable (const char *path) { struct stat st; LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); if ((!path) || (!*path)) return 0; if ((stat (path, &st) >= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", tmp_pathspec)); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { char *errstr = strerror (errno); lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal ("Could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } static void lt_error_core (int exit_status, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s: %s: ", program_name, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, "FATAL", message, ap); va_end (ap); } void lt_setenv (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", (name ? name : ""), (value ? value : ""))); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } int lt_split_name_value (const char *arg, char** name, char** value) { const char *p; int len; if (!arg || !*arg) return 1; p = strchr (arg, (int)'='); if (!p) return 1; *value = xstrdup (++p); len = strlen (arg) - strlen (*value); *name = XMALLOC (char, len); strncpy (*name, arg, len-1); (*name)[len - 1] = '\0'; return 0; } void lt_opt_process_env_set (const char *arg) { char *name = NULL; char *value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); } lt_setenv (name, value); XFREE (name); XFREE (value); } void lt_opt_process_env_prepend (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); } new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_opt_process_env_append (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); } new_value = lt_extend_str (getenv (name), value, 1); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_update_exe_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? value : ""))); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? value : ""))); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF } # end: func_emit_cwrapperexe_src # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) deplibs="$deplibs $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # moreargs="$moreargs $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) weak_libs="$weak_libs $arg" prev= continue ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname '-L' '' "$arg" dir=$func_stripname_result if test -z "$dir"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) dllsearchpath="$dllsearchpath:$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs="$deplibs System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" linker_flags="$linker_flags $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # -64, -mips[0-9] enable 64-bit mode on the SGI compiler # -r[0-9][0-9]* specifies the processor on the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler # +DA*, +DD* enable 64-bit mode on the HP compiler # -q* pass through compiler args for the IBM compiler # -m*, -t[45]*, -txscale* pass through architecture-specific # compiler args for GCC # -F/path gives path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC # @file GCC response files -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" compiler_flags="$compiler_flags $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. objs="$objs $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_duplicate_deps ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; esac pre_post_deps="$pre_post_deps $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= case $lib in *.la) func_source "$lib" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` case " $weak_libs " in *" $deplib_base "*) ;; *) deplibs="$deplibs $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags="$compiler_flags $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" dir=$func_stripname_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then $ECHO $ECHO "*** Warning: Trying to link with static lib archive $deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because the file extensions .$libext of this argument makes me believe" $ECHO "*** that it is just a static archive that I should not use here." else $ECHO $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. dlprefiles="$dlprefiles $lib $dependency_libs" else newdlfiles="$newdlfiles $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$newdlprefiles $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) temp_rpath="$temp_rpath$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded notinst_deplibs="$notinst_deplibs $lib" need_relink=no ;; *) if test "$installed" = no; then notinst_deplibs="$notinst_deplibs $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then $ECHO if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then $ECHO $ECHO "*** And there doesn't seem to be a static archive available" $ECHO "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. $ECHO $ECHO "*** Warning: This system can not link to static lib archive $lib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then $ECHO "*** But as you try to build a module library, libtool will still create " $ECHO "*** a static module, that should work as long as the dlopening application" $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then $ECHO $ECHO "*** However, this would only work if libtool was able to extract symbol" $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" $ECHO "*** not find such a program. So, this module is probably useless." $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do case $deplib in -L*) path="$deplib" ;; *.la) func_dirname "$deplib" "" "." dir="$func_dirname_result" # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then tmp_libs="$tmp_libs $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs="$objs$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else $ECHO $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" libobjs="$libobjs $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" libobjs="$libobjs $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist="$removelist $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles="$dlfiles $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$deplibs System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then deplibs="$deplibs -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $ECHO $ECHO "*** Warning: linker path does not have real file for library $a_deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs="$newdeplibs $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $ECHO $ECHO "*** Warning: linker path does not have real file for library $a_deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` done fi if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | $GREP . >/dev/null; then $ECHO if test "X$deplibs_check_method" = "Xnone"; then $ECHO "*** Warning: inter-library dependencies are not supported in this platform." else $ECHO "*** Warning: inter-library dependencies are not known to be supported." fi $ECHO "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then $ECHO $ECHO "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" $ECHO "*** a static module, that should work as long as the dlopening" $ECHO "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then $ECHO $ECHO "*** However, this would only work if libtool was able to extract symbol" $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" $ECHO "*** not find such a program. So, this module is probably useless." $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else $ECHO "*** The inter-library dependencies that have been dropped here will be" $ECHO "*** automatically added whenever a program is linked with this library" $ECHO "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then $ECHO $ECHO "*** Since this library must not contain undefined symbols," $ECHO "*** because either the platform does not support them or" $ECHO "*** it was explicitly requested with -no-undefined," $ECHO "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do linknames="$linknames $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" delfiles="$delfiles $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" func_len " $cmd" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then func_show_eval "$cmd" 'exit $?' skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) tmp_deplibs="$tmp_deplibs $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $convenience libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output output_la=`$ECHO "X$output" | $Xsed -e "$basename"` # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" $ECHO 'INPUT (' > $output for obj in $save_libobjs do $ECHO "$obj" >> $output done $ECHO ')' >> $output delfiles="$delfiles $output" elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do $ECHO "$obj" >> $output done delfiles="$delfiles $output" output=$firstobj\"$file_list_spec$output\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else # All subsequent reloadable object files will link in # the last one created. eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=$obj func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi delfiles="$delfiles $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` else gentop="$output_objdir/${obj}x" generated="$generated $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) compile_command="$compile_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done compile_deplibs="$new_libs" compile_command="$compile_command $compile_deplibs" finalize_command="$finalize_command $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) dllsearchpath="$dllsearchpath:$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *cegcc) # Disable wrappers for cegcc, we are cross compiling anyway. wrappers_required=no ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $ECHO for shipping. if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then case $progpath in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; esac qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then oldobjs="$oldobjs $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $addlibs oldobjs="$oldobjs $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles oldobjs="$oldobjs $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else $ECHO "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" oldobjs="$oldobjs $gentop/$newobj" ;; *) oldobjs="$oldobjs $obj" ;; esac done fi eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" newdependency_libs="$newdependency_libs $libdir/$name" ;; *) newdependency_libs="$newdependency_libs $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlfiles="$newdlfiles $libdir/$name" ;; *) newdlfiles="$newdlfiles $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlprefiles="$newdlprefiles $libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlfiles="$newdlfiles $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles="$newdlprefiles $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$mode" = link || test "$mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) RM="$RM $arg"; rmforce=yes ;; -*) RM="$RM $arg" ;; *) files="$files $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= origobjdir="$objdir" for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then objdir="$origobjdir" else objdir="$dir/$origobjdir" fi func_basename "$file" name="$func_basename_result" test "$mode" = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" case "$mode" in clean) case " $library_names " in # " " in the beginning catches empty $dlname *" $dlname "*) ;; *) rmfiles="$rmfiles $objdir/$dlname" ;; esac test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then rmfiles="$rmfiles $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then rmfiles="$rmfiles $dir/$non_pic_object" fi fi ;; *) if test "$mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe rmfiles="$rmfiles $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result rmfiles="$rmfiles $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done objdir="$origobjdir" # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$mode" = uninstall || test "$mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 pgpool-II-3.3.2/pool_proto_modules.c0000664000076400007640000025673712245576267014405 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * *--------------------------------------------------------------------- * pool_proto_modules.c: modules corresponding to message protocols. * used by pool_process_query() *--------------------------------------------------------------------- */ #include "config.h" #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #include "pool.h" #include "pool_signal.h" #include "pool_timestamp.h" #include "pool_proto_modules.h" #include "pool_rewrite_query.h" #include "pool_relcache.h" #include "pool_stream.h" #include "pool_config.h" #include "parser/pool_string.h" #include "pool_session_context.h" #include "pool_query_context.h" #include "pool_lobj.h" #include "pool_select_walker.h" #include "pool_memqcache.h" char *copy_table = NULL; /* copy table name */ char *copy_schema = NULL; /* copy table name */ char copy_delimiter; /* copy delimiter char */ char *copy_null = NULL; /* copy null string */ /* * Non 0 if allow to close internal transaction. This variable was * introduced on 2008/4/3 not to close an internal transaction when * Sync message is received after receiving Parse message. This hack * is for PHP-PDO. */ static int allow_close_transaction = 1; int is_select_pgcatalog = 0; int is_select_for_update = 0; /* 1 if SELECT INTO or SELECT FOR UPDATE */ bool is_parallel_table = false; /* * last query string sent to simpleQuery() */ char query_string_buffer[QUERY_STRING_BUFFER_LEN]; /* * query string produced by nodeToString() in simpleQuery(). * this variable only useful when enable_query_cache is true. */ char *parsed_query = NULL; static int check_errors(POOL_CONNECTION_POOL *backend, int backend_id); static void generate_error_message(char *prefix, int specific_error, char *query); static POOL_STATUS parse_before_bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, POOL_SENT_MESSAGE *message); static int* find_victim_nodes(int *ntuples, int nmembers, int master_node, int *number_of_nodes); static int extract_ntuples(char *message); static POOL_STATUS close_standby_transactions(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); /* * Process Query('Q') message * Query messages include an SQL string. */ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len, char *contents) { static char *sq_config = "pool_status"; static char *sq_pools = "pool_pools"; static char *sq_processes = "pool_processes"; static char *sq_nodes = "pool_nodes"; static char *sq_version = "pool_version"; static char *sq_cache = "pool_cache"; int commit; List *parse_tree_list; Node *node = NULL; POOL_STATUS status; char *string; int lock_kind; bool is_likely_select = false; int specific_error = 0; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; POOL_MEMORY_POOL *old_context; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("SimpleQuery: cannot get session context"); return POOL_END; } /* save last query string for logging purpose */ strlcpy(query_string_buffer, contents, sizeof(query_string_buffer)); /* show ps status */ query_ps_status(contents, backend); /* log query to log file if necessary */ if (pool_config->log_statement) { pool_log("statement: %s", contents); } else { pool_debug("statement2: %s", contents); } /* * Fetch memory cache if possible */ is_likely_select = pool_is_likely_select(contents); /* * If memory query cache enabled and the query seems to be a * SELECT use query cache if possible. However if we are in an * explicit transaction and we had writing query before, we should * not use query cache. This means that even the writing query is * not anything related to the table which is used the SELECT, we * do not use cache. Of course we could analyze the SELECT to see * if it uses the table modified in the transaction, but it will * need parsing query and accessing to system catalog, which will * add significant overhead. Moreover if we are in aborted * transaction, commands should be ignored, so we should not use * query cache. */ if (pool_config->memory_cache_enabled && is_likely_select && !pool_is_writing_transaction() && TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID) != 'E') { bool foundp; /* If the query is SELECT from table to cache, try to fetch cached result. */ status = pool_fetch_from_memory_cache(frontend, backend, contents, &foundp); if (status != POOL_CONTINUE) return status; if (foundp) { pool_ps_idle_display(backend); pool_set_skip_reading_from_backends(); pool_stats_count_up_num_cache_hits(); return POOL_CONTINUE; } } /* Create query context */ query_context = pool_init_query_context(); if (!query_context) { pool_error("SimpleQuery: pool_init_query_context failed"); return POOL_END; } /* switch memory context */ if (pool_memory == NULL) pool_memory = pool_memory_create(PARSER_BLOCK_SIZE); old_context = pool_memory_context_switch_to(query_context->memory_context); /* parse SQL string */ parse_tree_list = raw_parser(contents); if (parse_tree_list == NIL) { /* is the query empty? */ if (*contents == '\0' || *contents == ';') { /* * JBoss sends empty queries for checking connections. * We replace the empty query with SELECT command not * to affect load balance. * [Pgpool-general] Confused about JDBC and load balancing */ parse_tree_list = raw_parser(POOL_DUMMY_READ_QUERY); } else { /* * Unable to parse the query. Probably syntax error or the * query is too new and our parser cannot understand. Treat as * if it were an DELETE command. Note that the DELETE command * does not execute, instead the original query will be sent * to backends, which may or may not cause an actual syntax errors. * The command will be sent to all backends in replication mode * or master/primary in master/slave mode. */ if (!strcmp(remote_host, "[local]")) { pool_log("SimpleQuery: Unable to parse the query: \"%s\" from local client", contents); } else { pool_log("SimpleQuery: Unable to parse the query: \"%s\" from client %s(%s)", contents, remote_host, remote_port); } parse_tree_list = raw_parser(POOL_DUMMY_WRITE_QUERY); query_context->is_parse_error = true; } } if (parse_tree_list != NIL) { /* * XXX: Currently we only process the first element of the parse tree. * rest of multiple statements are silently discarded. */ node = (Node *) lfirst(list_head(parse_tree_list)); if (pool_config->enable_query_cache && SYSDB_STATUS == CON_UP && IsA(node, SelectStmt) && !(is_select_pgcatalog = IsSelectpgcatalog(node, backend))) { /* * POOL_CONTINUE of here represent cache found, and messages were * sent to frontend already. */ if (pool_execute_query_cache_lookup(frontend, backend, node) == POOL_CONTINUE) { pool_query_context_destroy(query_context); pool_set_skip_reading_from_backends(); pool_memory_context_switch_to(old_context); return POOL_CONTINUE; } } /* * Start query context */ pool_start_query(query_context, contents, len, node); /* * If the query is DROP DATABASE, after executing it, cache files directory must be discarded. * So we have to get the DB's oid before it will be DROPped. */ if (pool_config->memory_cache_enabled && is_drop_database(node)) { DropdbStmt *stmt = (DropdbStmt *)node; query_context->dboid = pool_get_database_oid_from_dbname(stmt->dbname); if (query_context->dboid != 0) { pool_debug("DB's oid to discard its cache directory: dboid = %d", query_context->dboid); } } /* * Check if multi statement query */ if (parse_tree_list && list_length(parse_tree_list) > 1) { query_context->is_multi_statement = true; } else { query_context->is_multi_statement = false; } if (PARALLEL_MODE) { bool parallel = true; is_parallel_table = is_partition_table(backend,node); status = pool_do_parallel_query(frontend, backend, node, ¶llel, &contents, &len); if (parallel) { pool_query_context_destroy(query_context); pool_memory_context_switch_to(old_context); return status; } } /* check COPY FROM STDIN * if true, set copy_* variable */ check_copy_from_stdin(node); /* status reporting? */ if (IsA(node, VariableShowStmt)) { bool is_valid_show_command = false; VariableShowStmt *vnode = (VariableShowStmt *)node; if (!strcmp(sq_config, vnode->name)) { is_valid_show_command = true; pool_debug("config reporting"); config_reporting(frontend, backend); } else if (!strcmp(sq_pools, vnode->name)) { is_valid_show_command = true; pool_debug("pools reporting"); pools_reporting(frontend, backend); } else if (!strcmp(sq_processes, vnode->name)) { is_valid_show_command = true; pool_debug("processes reporting"); processes_reporting(frontend, backend); } else if (!strcmp(sq_nodes, vnode->name)) { is_valid_show_command = true; pool_debug("nodes reporting"); nodes_reporting(frontend, backend); } else if (!strcmp(sq_version, vnode->name)) { is_valid_show_command = true; pool_debug("version reporting"); version_reporting(frontend, backend); } else if (!strcmp(sq_cache, vnode->name)) { is_valid_show_command = true; pool_debug("cache reporting"); cache_reporting(frontend, backend); } if (is_valid_show_command) { pool_ps_idle_display(backend); pool_query_context_destroy(query_context); pool_set_skip_reading_from_backends(); pool_memory_context_switch_to(old_context); return POOL_CONTINUE; } } /* * If the table is to be cached, set is_cache_safe TRUE and register table oids. */ if (pool_config->memory_cache_enabled && query_context->is_multi_statement == false) { bool is_select_query = false; int num_oids; int *oids; int i; /* Check if the query is actually SELECT */ if (is_likely_select && IsA(node, SelectStmt)) { is_select_query = true; } /* Switch the flag of is_cache_safe in session_context */ if (is_select_query && !query_context->is_parse_error && pool_is_allow_to_cache(query_context->parse_tree, query_context->original_query)) { pool_set_cache_safe(); } else { pool_unset_cache_safe(); } /* If table is to be cached and the query is DML, save the table oid */ if (!is_select_query && !query_context->is_parse_error) { num_oids = pool_extract_table_oids(node, &oids); if (num_oids > 0) { /* Save to oid buffer */ for (i=0;ioriginal_query, query_context->parse_tree); /* * if this is DROP DATABASE command, send USR1 signal to parent and * ask it to close all idle connections. * XXX This is overkill. It would be better to close the idle * connection for the database which DROP DATABASE command tries * to drop. This is impossible at this point, since we have no way * to pass such info to other processes. */ if (is_drop_database(node)) { int stime = 5; /* XXX give arbitrary time to allow closing idle connections */ pool_debug("Query: sending SIGUSR1 signal to parent"); Req_info->kind = CLOSE_IDLE_REQUEST; kill(getppid(), SIGUSR1); /* send USR1 signal to parent */ /* we need to loop over here since we will get USR1 signal while sleeping */ while (stime > 0) { stime = sleep(stime); } } /* * determine if we need to lock the table * to keep SERIAL data consistency among servers * conditions: * - replication is enabled * - protocol is V3 * - statement is INSERT * - either "INSERT LOCK" comment exists or insert_lock directive specified */ if (!RAW_MODE) { /* * If there's only one node to send the command, there's no * point to start a transaction. */ if (pool_multi_node_to_be_sent(query_context)) { /* start a transaction if needed */ if (start_internal_transaction(frontend, backend, (Node *)node) != POOL_CONTINUE) return POOL_END; /* check if need lock */ lock_kind = need_insert_lock(backend, contents, node); if (lock_kind) { /* if so, issue lock command */ status = insert_lock(frontend, backend, contents, (InsertStmt *)node, lock_kind); if (status != POOL_CONTINUE) { pool_query_context_destroy(query_context); return status; } } } } else if (REPLICATION && contents == NULL && start_internal_transaction(frontend, backend, node)) { pool_query_context_destroy(query_context); return POOL_ERROR; } } if (MAJOR(backend) == PROTO_MAJOR_V2 && is_start_transaction_query(node)) { int i; for (i=0;iname, query_context); if (!msg) { pool_error("SimpleQuery: cannot create query message: %s", strerror(errno)); return POOL_END; } session_context->uncompleted_message = msg; } } string = query_context->original_query; if (!RAW_MODE) { /* check if query is "COMMIT" or "ROLLBACK" */ commit = is_commit_or_rollback_query(node); /* * Query is not commit/rollback */ if (!commit) { char *rewrite_query; if (node) { POOL_SENT_MESSAGE *msg = NULL; if (IsA(node, PrepareStmt)) { msg = session_context->uncompleted_message; } else if (IsA(node, ExecuteStmt)) { msg = pool_get_sent_message('Q', ((ExecuteStmt *)node)->name); if (!msg) msg = pool_get_sent_message('P', ((ExecuteStmt *)node)->name); } /* rewrite `now()' to timestamp literal */ rewrite_query = rewrite_timestamp(backend, query_context->parse_tree, false, msg); /* * If the query is BEGIN READ WRITE or * BEGIN ... SERIALIZABLE in master/slave mode, * we send BEGIN to slaves/standbys instead. * original_query which is BEGIN READ WRITE is sent to primary. * rewritten_query which is BEGIN is sent to standbys. */ if (pool_need_to_treat_as_if_default_transaction(query_context)) { rewrite_query = pstrdup("BEGIN"); } if (rewrite_query != NULL) { query_context->rewritten_query = rewrite_query; query_context->rewritten_length = strlen(rewrite_query) + 1; } } /* * Optimization effort: If there's only one session, we do * not need to wait for the master node's response, and * could execute the query concurrently. */ if (pool_config->num_init_children == 1) { /* Send query to all DB nodes at once */ status = pool_send_and_wait(query_context, 0, 0); /* free_parser(); */ return status; } /* Send the query to master node */ if (pool_send_and_wait(query_context, 1, MASTER_NODE_ID) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; } /* Check specific errors */ specific_error = check_errors(backend, MASTER_NODE_ID); if (specific_error) { /* log error message */ generate_error_message("SimpleQuery: ", specific_error, contents); } } if (specific_error) { char msg[1024] = POOL_ERROR_QUERY; /* large enough */ int len = strlen(msg); memset(msg + len, 0, sizeof(int)); /* send query to other nodes */ query_context->rewritten_query = msg; query_context->rewritten_length = len; if (pool_send_and_wait(query_context, -1, MASTER_NODE_ID) != POOL_CONTINUE) return POOL_END; } else { /* * Send the query to other than master node. */ if (pool_send_and_wait(query_context, -1, MASTER_NODE_ID) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; } } /* Send "COMMIT" or "ROLLBACK" to only master node if query is "COMMIT" or "ROLLBACK" */ if (commit) { if (pool_send_and_wait(query_context, 1, MASTER_NODE_ID) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; } } /* free_parser(); */ } else { if (pool_send_and_wait(query_context, 1, MASTER_NODE_ID) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; } /* free_parser(); */ } /* switch memory context */ pool_memory_context_switch_to(old_context); return POOL_CONTINUE; } /* * process EXECUTE (V3 only) */ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len, char *contents) { int commit = 0; char *query = NULL; Node *node; int specific_error = 0; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; POOL_SENT_MESSAGE *bind_msg; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("Execute: cannot get session context"); return POOL_END; } pool_debug("Execute: portal name <%s>", contents); bind_msg = pool_get_sent_message('B', contents); if (!bind_msg) { pool_error("Execute: cannot get bind message"); return POOL_END; } if(!bind_msg->query_context) { pool_error("Execute: cannot get query context"); return POOL_END; } if (!bind_msg->query_context->original_query) { pool_error("Execute: cannot get original query"); return POOL_END; } if (!bind_msg->query_context->parse_tree) { pool_error("Execute: cannot get parse tree"); return POOL_END; } query_context = bind_msg->query_context; node = bind_msg->query_context->parse_tree; query = bind_msg->query_context->original_query; strlcpy(query_string_buffer, query, sizeof(query_string_buffer)); pool_debug("Execute: query string = <%s>", query); /* * Fetch memory cache if possible */ if (pool_config->memory_cache_enabled && pool_is_likely_select(query)) { bool foundp; POOL_STATUS status; char *search_query = NULL; int len; char *tmp; #define STR_ALLOC_SIZE 1024 len = strlen(query)+1; search_query = (char *)malloc(len); if (search_query == NULL) { pool_error("Execute: malloc failed"); return POOL_END; } strcpy(search_query, query); /* * Add bind message's info to query to search. */ if (query_context->is_cache_safe && bind_msg->param_offset && bind_msg->contents) { /* Extract binary contents from bind message */ char *query_in_bind_msg = bind_msg->contents + bind_msg->param_offset; char hex_str[4]; /* 02X chars + white space + null end */ int i; int alloc_len; alloc_len = (len/STR_ALLOC_SIZE+1)*STR_ALLOC_SIZE; search_query = realloc(search_query, alloc_len); if (search_query == NULL) { pool_error("Execute: realloc failed"); return POOL_END; } for (i = 0; i < bind_msg->len - bind_msg->param_offset; i++) { int hexlen; snprintf(hex_str, sizeof(hex_str), (i == 0) ? " %02X" : "%02X", 0xff & query_in_bind_msg[i]); hexlen = strlen(hex_str); if ((len+hexlen) >= alloc_len) { alloc_len += STR_ALLOC_SIZE; search_query = realloc(search_query, alloc_len); if (search_query == NULL) { pool_error("Execute: realloc failed"); return POOL_END; } } strcat(search_query, hex_str); len += hexlen; } query_context->query_w_hex = search_query; /* * When a transaction is committed, query_context->temp_cache->query is used * to create md5 hash to search for query cache. * So overwrite the query text in temp cache to the one with the hex of bind message. * If not, md5 hash will be created by the query text without bind message, and * it will happen to find cache never or to get a wrong result. * * However, It is possible that temp_cache does not exist. * Consider following scenario: * - In the previous execute cache is overflowed, and * temp_cache discarded. * - In the subsequent bind/execute uses the same portal */ if (query_context->temp_cache) { tmp = (char *)malloc(sizeof(char) * strlen(search_query) + 1); if (tmp == NULL) { pool_error("Execute: malloc failed"); return POOL_END; } free(query_context->temp_cache->query); query_context->temp_cache->query = tmp; strcpy(query_context->temp_cache->query, search_query); } } /* If the query is SELECT from table to cache, try to fetch cached result. */ status = pool_fetch_from_memory_cache(frontend, backend, search_query, &foundp); if (status != POOL_CONTINUE) return status; if (foundp) { pool_ps_idle_display(backend); pool_set_skip_reading_from_backends(); pool_stats_count_up_num_cache_hits(); pool_unset_query_in_progress(); return POOL_CONTINUE; } } session_context->query_context = query_context; /* * Calling pool_where_to_send here is dangerous because the node * parse/bind has been sent could be change by * pool_where_to_send() and it leads to "portal not found" * etc. errors. */ /* check if query is "COMMIT" or "ROLLBACK" */ commit = is_commit_or_rollback_query(node); if (REPLICATION || PARALLEL_MODE) { /* * Query is not commit/rollback */ if (!commit) { /* Send the query to master node */ if (pool_extended_send_and_wait(query_context, "E", len, contents, 1, MASTER_NODE_ID) != POOL_CONTINUE) { return POOL_END; } /* Check specific errors */ specific_error = check_errors(backend, MASTER_NODE_ID); if (specific_error) { /* log error message */ generate_error_message("Execute: ", specific_error, contents); } } if (specific_error) { char msg[1024] = "pgpool_error_portal"; /* large enough */ int len = strlen(msg); memset(msg + len, 0, sizeof(int)); /* send query to other nodes */ if (pool_extended_send_and_wait(query_context, "E", len, msg, -1, MASTER_NODE_ID) != POOL_CONTINUE) return POOL_END; } else { if (pool_extended_send_and_wait(query_context, "E", len, contents, -1, MASTER_NODE_ID) != POOL_CONTINUE) return POOL_END; } /* send "COMMIT" or "ROLLBACK" to only master node if query is "COMMIT" or "ROLLBACK" */ if (commit) { if (pool_extended_send_and_wait(query_context, "E", len, contents, 1, MASTER_NODE_ID) != POOL_CONTINUE) { return POOL_END; } } } else { if (pool_extended_send_and_wait(query_context, "E", len, contents, 1, MASTER_NODE_ID) != POOL_CONTINUE) { return POOL_END; } if (pool_extended_send_and_wait(query_context, "E", len, contents, -1, MASTER_NODE_ID) != POOL_CONTINUE) { return POOL_END; } } return POOL_CONTINUE; } /* * process Parse (V3 only) */ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len, char *contents) { int deadlock_detected = 0; int insert_stmt_with_lock = 0; char *name; char *stmt; List *parse_tree_list; Node *node = NULL; POOL_SENT_MESSAGE *msg; POOL_STATUS status; POOL_MEMORY_POOL *old_context; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("Parse: cannot get session context"); return POOL_END; } /* Create query context */ query_context = pool_init_query_context(); pool_debug("Parse: statement name <%s>", contents); name = contents; stmt = contents + strlen(contents) + 1; /* switch memory context */ if (pool_memory == NULL) pool_memory = pool_memory_create(PARSER_BLOCK_SIZE); old_context = pool_memory_context_switch_to(query_context->memory_context); /* parse SQL string */ parse_tree_list = raw_parser(stmt); if (parse_tree_list == NIL) { /* is the query empty? */ if (*stmt == '\0' || *stmt == ';') { /* * JBoss sends empty queries for checking connections. * We replace the empty query with SELECT command not * to affect load balance. * [Pgpool-general] Confused about JDBC and load balancing */ parse_tree_list = raw_parser(POOL_DUMMY_READ_QUERY); } else { /* * Unable to parse the query. Probably syntax error or the * query is too new and our parser cannot understand. Treat as * if it were an DELETE command. Note that the DELETE command * does not execute, instead the original query will be sent * to backends, which may or may not cause an actual syntax errors. * The command will be sent to all backends in replication mode * or master/primary in master/slave mode. */ if (!strcmp(remote_host, "[local]")) { pool_log("Parse: Unable to parse the query: \"%s\" from local client", stmt); } else { pool_log("Parse: Unable to parse the query: \"%s\" from client %s(%s)", stmt, remote_host, remote_port); } parse_tree_list = raw_parser(POOL_DUMMY_WRITE_QUERY); query_context->is_parse_error = true; } } if (parse_tree_list != NIL) { /* Save last query string for logging purpose */ snprintf(query_string_buffer, sizeof(query_string_buffer), "Parse: %s", stmt); node = (Node *) lfirst(list_head(parse_tree_list)); insert_stmt_with_lock = need_insert_lock(backend, stmt, node); /* * Start query context */ pool_start_query(query_context, pstrdup(stmt), strlen(stmt) + 1, node); msg = pool_create_sent_message('P', len, contents, 0, name, query_context); if (!msg) { pool_error("Parse: cannot create parse message: %s", strerror(errno)); return POOL_END; } session_context->uncompleted_message = msg; /* * If the table is to be cached, set is_cache_safe TRUE and register table oids. */ if (pool_config->memory_cache_enabled) { bool is_likely_select = false; bool is_select_query = false; int num_oids; int *oids; int i; /* Check if the query is actually SELECT */ is_likely_select = pool_is_likely_select(query_context->original_query); if (is_likely_select && IsA(node, SelectStmt)) { is_select_query = true; } /* Switch the flag of is_cache_safe in session_context */ if (is_select_query && !query_context->is_parse_error && pool_is_allow_to_cache(query_context->parse_tree, query_context->original_query)) { pool_set_cache_safe(); } else { pool_unset_cache_safe(); } /* If table is to be cached and the query is DML, save the table oid */ if (!is_select_query && !query_context->is_parse_error) { num_oids = pool_extract_table_oids(node, &oids); if (num_oids > 0) { /* Save to oid buffer */ for (i=0;ioriginal_query, query_context->parse_tree); if (REPLICATION) { char *rewrite_query; bool rewrite_to_params = true; /* * rewrite `now()'. * if stmt is unnamed, we rewrite `now()' to timestamp constant. * else we rewrite `now()' to params and expand that at Bind * message. */ if (*name == '\0') rewrite_to_params = false; msg->num_tsparams = 0; rewrite_query = rewrite_timestamp(backend, node, rewrite_to_params, msg); if (rewrite_query != NULL) { int alloc_len = len - strlen(stmt) + strlen(rewrite_query); contents = pool_memory_realloc(session_context->memory_context, msg->contents, alloc_len); strcpy(contents, name); strcpy(contents + strlen(name) + 1, rewrite_query); memcpy(contents + strlen(name) + strlen(rewrite_query) + 2, stmt + strlen(stmt) + 1, len - (strlen(name) + strlen(stmt) + 2)); len = alloc_len; name = contents; stmt = contents + strlen(name) + 1; pool_debug("Parse: rewrite query %s %s len=%d", name, stmt, len); msg->len = len; msg->contents = contents; query_context->rewritten_query = rewrite_query; } } /* * If the query is BEGIN READ WRITE in master/slave mode, * we send BEGIN instead of it to slaves/standbys. * original_query which is BEGIN READ WRITE is sent to primary. * rewritten_query which is BEGIN is sent to standbys. */ if (is_start_transaction_query(query_context->parse_tree) && is_read_write((TransactionStmt *)query_context->parse_tree) && MASTER_SLAVE) { query_context->rewritten_query = pstrdup("BEGIN"); } } pool_memory_context_switch_to(old_context); /* * If in replication mode, send "SYNC" message if not in a transaction. */ if (REPLICATION) { char kind; if (TSTATE(backend, MASTER_NODE_ID) != 'T') { int i; /* synchronize transaction state */ for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; /* send sync message */ send_extended_protocol_message(backend, i, "S", 0, ""); } kind = pool_read_kind(backend); if (kind != 'Z') { pool_query_context_destroy(query_context); return POOL_END; } /* * SYNC message returns "Ready for Query" message. */ if (ReadyForQuery(frontend, backend, 0, false) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; } /* * set in_progress flag, because ReadyForQuery unset it. * in_progress flag influences VALID_BACKEND. */ if (!pool_is_query_in_progress()) pool_set_query_in_progress(); } if (is_strict_query(query_context->parse_tree)) { start_internal_transaction(frontend, backend, query_context->parse_tree); allow_close_transaction = 1; } if (insert_stmt_with_lock) { /* start a transaction if needed and lock the table */ status = insert_lock(frontend, backend, stmt, (InsertStmt *)query_context->parse_tree, insert_stmt_with_lock); if (status != POOL_CONTINUE) { pool_query_context_destroy(query_context); return status; } } } /* * Cannot call free_parser() here. Since "string" might be allocated in parser context. * free_parser(); */ if (REPLICATION || PARALLEL_MODE || MASTER_SLAVE) { /* * We must synchronize because Parse message acquires table * locks. */ pool_debug("Parse: waiting for master completing the query"); if (pool_extended_send_and_wait(query_context, "P", len, contents, 1, MASTER_NODE_ID) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; } /* * We must check deadlock error because a aborted transaction * by detecting deadlock isn't same on all nodes. * If a transaction is aborted on master node, pgpool send a * error query to another nodes. */ deadlock_detected = detect_deadlock_error(MASTER(backend), MAJOR(backend)); if (deadlock_detected < 0) { pool_query_context_destroy(query_context); return POOL_END; } else { /* * Check if other than deadlock error detected. If so, emit * log. This is useful when invalid encoding error occurs. In * this case, PostgreSQL does not report what statement caused * that error and make users confused. */ per_node_error_log(backend, MASTER_NODE_ID, stmt, "Parse: Error or notice message from backend: ", true); } if (deadlock_detected) { POOL_QUERY_CONTEXT *error_qc; error_qc = pool_init_query_context(); pool_start_query(error_qc, POOL_ERROR_QUERY, strlen(POOL_ERROR_QUERY) + 1, node); pool_copy_prep_where(query_context->where_to_send, error_qc->where_to_send); pool_log("Parse: received deadlock error message from master node"); if (pool_send_and_wait(error_qc, -1, MASTER_NODE_ID) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; } pool_query_context_destroy(error_qc); pool_set_query_in_progress(); session_context->query_context = query_context; } else { if (pool_extended_send_and_wait(query_context, "P", len, contents, -1, MASTER_NODE_ID) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; } } } else { if (pool_extended_send_and_wait(query_context, "P", len, contents, 1, MASTER_NODE_ID) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; } } /* * Ok. we are safe to call free_parser(); */ /* free_parser(); */ return POOL_CONTINUE; } POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len, char *contents) { char *pstmt_name; char *portal_name; char *rewrite_msg; POOL_SENT_MESSAGE *parse_msg; POOL_SENT_MESSAGE *bind_msg; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; int insert_stmt_with_lock = 0; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("Bind: cannot get session context"); return POOL_END; } /* * Rewrite message */ portal_name = contents; pstmt_name = contents + strlen(portal_name) + 1; parse_msg = pool_get_sent_message('Q', pstmt_name); if (!parse_msg) parse_msg = pool_get_sent_message('P', pstmt_name); if (!parse_msg) { pool_error("Bind: cannot get parse message \"%s\"", pstmt_name); return POOL_END; } bind_msg = pool_create_sent_message('B', len, contents, parse_msg->num_tsparams, portal_name, parse_msg->query_context); if (!bind_msg) { pool_error("Bind: cannot create bind message: %s", strerror(errno)); return POOL_END; } query_context = parse_msg->query_context; if (!query_context) { pool_error("Bind: cannot get query context"); return POOL_END; } /* * If the query can be cached, save its offset of query text in bind message's content. */ if (query_context->is_cache_safe) { bind_msg->param_offset = sizeof(char) * (strlen(portal_name) + strlen(pstmt_name) + 2); } session_context->uncompleted_message = bind_msg; /* rewrite bind message */ if (REPLICATION && bind_msg->num_tsparams > 0) { rewrite_msg = bind_rewrite_timestamp(backend, bind_msg, contents, &len); if (rewrite_msg != NULL) contents = rewrite_msg; } session_context->query_context = query_context; if (pool_config->load_balance_mode && pool_is_writing_transaction()) { pool_where_to_send(query_context, query_context->original_query, query_context->parse_tree); if (parse_before_bind(frontend, backend, parse_msg) != POOL_CONTINUE) return POOL_END; } /* * Start a transaction if necessary */ pool_debug("Bind: checking strict query"); if (is_strict_query(query_context->parse_tree)) { pool_debug("Bind: strict query"); start_internal_transaction(frontend, backend, query_context->parse_tree); allow_close_transaction = 1; } pool_debug("Bind: checking insert lock"); insert_stmt_with_lock = need_insert_lock(backend, query_context->original_query, query_context->parse_tree); if (insert_stmt_with_lock) { pool_debug("Bind: issuing insert lock"); /* issue a LOCK command to keep consistency */ if (insert_lock(frontend, backend, query_context->original_query, (InsertStmt *)query_context->parse_tree, insert_stmt_with_lock) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; } } pool_debug("Bind: waiting for master completing the query"); if (pool_extended_send_and_wait(query_context, "B", len, contents, 1, MASTER_NODE_ID) != POOL_CONTINUE) { return POOL_END; } if (pool_extended_send_and_wait(query_context, "B", len, contents, -1, MASTER_NODE_ID) != POOL_CONTINUE) { return POOL_END; } return POOL_CONTINUE; } POOL_STATUS Describe(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len, char *contents) { POOL_SENT_MESSAGE *msg; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("Describe: cannot get session context"); return POOL_END; } /* Prepared Statement */ if (*contents == 'S') { msg = pool_get_sent_message('Q', contents+1); if (!msg) msg = pool_get_sent_message('P', contents+1); if (!msg) { pool_error("Describe: cannot get parse message"); return POOL_END; } } /* Portal */ else { msg = pool_get_sent_message('B', contents+1); if (!msg) { pool_error("Describe: cannot get bind message"); return POOL_END; } } query_context = msg->query_context; if (query_context == NULL) { pool_error("Describe: cannot get query context"); return POOL_END; } session_context->query_context = query_context; /* * Calling pool_where_to_send here is dangerous because the node * parse/bind has been sent could be change by * pool_where_to_send() and it leads to "portal not found" * etc. errors. */ pool_debug("Describe: waiting for master completing the query"); if (pool_extended_send_and_wait(query_context, "D", len, contents, 1, MASTER_NODE_ID) != POOL_CONTINUE) return POOL_END; if (pool_extended_send_and_wait(query_context, "D", len, contents, -1, MASTER_NODE_ID) != POOL_CONTINUE) return POOL_END; return POOL_CONTINUE; } POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len, char *contents) { POOL_SENT_MESSAGE *msg; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("Close: cannot get session context"); return POOL_END; } /* Prepared Statement */ if (*contents == 'S') { msg = pool_get_sent_message('Q', contents+1); if (!msg) msg = pool_get_sent_message('P', contents+1); if (!msg) { pool_error("Close: cannot get parse message"); return POOL_END; } } /* Portal */ else if (*contents == 'P') { msg = pool_get_sent_message('B', contents+1); if (!msg) { pool_error("Close: cannot get bind message"); return POOL_END; } } else { pool_error("Close: invalid message"); return POOL_END; } session_context->uncompleted_message = msg; query_context = msg->query_context; if (!query_context) { pool_error("Close: cannot get query context"); return POOL_END; } session_context->query_context = query_context; /* pool_where_to_send(query_context, query_context->original_query, query_context->parse_tree); */ pool_debug("Close: waiting for master completing the query"); if (pool_extended_send_and_wait(query_context, "C", len, contents, 1, MASTER_NODE_ID) != POOL_CONTINUE) return POOL_END; if (pool_extended_send_and_wait(query_context, "C", len, contents, -1, MASTER_NODE_ID) != POOL_CONTINUE) return POOL_END; return POOL_CONTINUE; } POOL_STATUS FunctionCall3(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len, char *contents) { /* * If Function call message for lo_creat, rewrite it */ char *rewrite_lo; int rewrite_len; rewrite_lo = pool_rewrite_lo_creat('F', contents, len, frontend, backend, &rewrite_len); if (rewrite_lo != NULL) { contents = rewrite_lo; len = rewrite_len; } return SimpleForwardToBackend('F', frontend, backend, len, contents); } /* * Process ReadyForQuery('Z') message. * If send_ready is true, send 'Z' message to frontend. * If cache_commit is true, commit or discard query cache according to * transaction state. * * - if the error status "mismatch_ntuples" is set, send an error query * to all DB nodes to abort transaction or do failover. * - internal transaction is closed */ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, bool send_ready, bool cache_commit) { int i; int len; signed char kind; signed char state; POOL_SESSION_CONTEXT *session_context; Node *node = NULL; char *query = NULL; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("ReadyForQuery: cannot get session context"); return POOL_END; } /* * If the numbers of update tuples are differ and * failover_if_affected_tuples_mismatch is false, we abort * transactions by using do_error_command. If * failover_if_affected_tuples_mismatch is true, trigger failover. * This only works with PROTO_MAJOR_V3. */ if (session_context->mismatch_ntuples && MAJOR(backend) == PROTO_MAJOR_V3) { int i; char kind; /* * If failover_if_affected_tuples_mismatch, is true, then * decide victim nodes by using find_victim_nodes and * degenerate them. */ if (pool_config->failover_if_affected_tuples_mismatch) { int *victim_nodes; int number_of_nodes; char msgbuf[128]; victim_nodes = find_victim_nodes(session_context->ntuples, NUM_BACKENDS, MASTER_NODE_ID, &number_of_nodes); if (victim_nodes) { int i; String *msg; POOL_MEMORY_POOL *old_context; if (session_context->query_context) old_context = pool_memory_context_switch_to(session_context->query_context->memory_context); else old_context = pool_memory_context_switch_to(session_context->memory_context); msg = init_string("ReadyForQuery: Degenerate backends:"); for (i=0;idata); free_string(msg); msg = init_string("ReadyForQuery: Number of affected tuples are:"); for (i=0;intuples[i]); string_append_char(msg, msgbuf); } pool_log("%s", msg->data); free_string(msg); pool_memory_context_switch_to(old_context); degenerate_backend_set(victim_nodes, number_of_nodes); child_exit(1); } else { pool_error("ReadyForQuery: find_victim_nodes returned no victim node"); } } /* * XXX: discard rest of ReadyForQuery packet */ if (pool_read_message_length(backend) < 0) return POOL_END; state = pool_read_kind(backend); if (state < 0) return POOL_END; for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { /* abort transaction on all nodes. */ do_error_command(CONNECTION(backend, i), PROTO_MAJOR_V3); } } /* loop through until we get ReadyForQuery */ for(;;) { kind = pool_read_kind(backend); if (kind < 0) return POOL_END; if (kind == 'Z') break; /* put the message back to read buffer */ for (i=0;imismatch_ntuples = false; } /* * if a transaction is started for insert lock, we need to close * the transaction. */ /* if (pool_is_query_in_progress() && allow_close_transaction) */ if (allow_close_transaction) { if (end_internal_transaction(frontend, backend) != POOL_CONTINUE) return POOL_END; } if (MAJOR(backend) == PROTO_MAJOR_V3) { if ((len = pool_read_message_length(backend)) < 0) return POOL_END; /* * Set transaction state for each node */ state = TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID); for (i=0;irelation->relpersistence) discard_temp_table_relcache(); } } } /* Memory cache enabled? */ if (cache_commit && pool_config->memory_cache_enabled) { /* If we are doing extended query and the state is after EXECUTE, * then we can commit cache. * We check latter condition by looking at query_context->query_w_hex. * This check is necessary for certain frame work such as PHP PDO. * It sends Sync message right after PARSE and it produces * "Ready for query" message from backend. */ if (pool_is_doing_extended_query_message()) { if (session_context->query_context->query_state[MASTER_NODE_ID] == POOL_EXECUTE_COMPLETE) { pool_handle_query_cache(backend, session_context->query_context->query_w_hex, node, state); free(session_context->query_context->query_w_hex); session_context->query_context->query_w_hex = NULL; } } else { if (MAJOR(backend) != PROTO_MAJOR_V3) { state = 'I'; /* XXX I don't think query cache works with PROTO2 protocol */ } pool_handle_query_cache(backend, query, node, state); } } } /* * If PREPARE or extended query protocol commands caused error, * remove the temporary saved message. * (except when ReadyForQuery() is called during Parse() of extended queries) */ else { if ((pool_is_doing_extended_query_message() && session_context->query_context->query_state[MASTER_NODE_ID] != POOL_UNPARSED && session_context->uncompleted_message) || (!pool_is_doing_extended_query_message() && session_context->uncompleted_message)) { pool_add_sent_message(session_context->uncompleted_message); pool_remove_sent_message(session_context->uncompleted_message->kind, session_context->uncompleted_message->name); session_context->uncompleted_message = NULL; } } pool_unset_query_in_progress(); } if (!pool_is_doing_extended_query_message()) { if (!(node && IsA(node, PrepareStmt))) pool_query_context_destroy(pool_get_session_context()->query_context); } /* * Show ps idle status */ pool_ps_idle_display(backend); return POOL_CONTINUE; } /* * Close running transactions on standbys. */ static POOL_STATUS close_standby_transactions(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { int i; for (i=0;ipid, MASTER_CONNECTION(backend)->key, 0) != POOL_CONTINUE) { return POOL_END; } } } return POOL_CONTINUE; } POOL_STATUS ParseComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { POOL_SESSION_CONTEXT *session_context; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("ParseComplete: cannot get session context"); return POOL_END; } if (session_context->uncompleted_message) { POOL_QUERY_CONTEXT *qc; pool_add_sent_message(session_context->uncompleted_message); qc = session_context->uncompleted_message->query_context; if (qc) pool_set_query_state(qc, POOL_PARSE_COMPLETE); session_context->uncompleted_message = NULL; } return SimpleForwardToFrontend('1', frontend, backend); } POOL_STATUS BindComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { POOL_SESSION_CONTEXT *session_context; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("BindComplete: cannot get session context"); return POOL_END; } if (session_context->uncompleted_message) { POOL_QUERY_CONTEXT *qc; pool_add_sent_message(session_context->uncompleted_message); qc = session_context->uncompleted_message->query_context; if (qc) pool_set_query_state(qc, POOL_BIND_COMPLETE); session_context->uncompleted_message = NULL; } return SimpleForwardToFrontend('2', frontend, backend); } POOL_STATUS CloseComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { POOL_SESSION_CONTEXT *session_context; POOL_STATUS status; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("CloseComplete: cannot get session context"); return POOL_END; } /* Send CloseComplete(3) to frontend before removing the target message */ status = SimpleForwardToFrontend('3', frontend, backend); /* Remove the target message */ if (session_context->uncompleted_message) { pool_remove_sent_message(session_context->uncompleted_message->kind, session_context->uncompleted_message->name); session_context->uncompleted_message = NULL; } else { pool_error("CloseComplete: uncompleted message not found"); return POOL_END; } return status; } POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { int i; int len, len1, sendlen; int status; int rows; char *p, *p1, *p2; bool update_or_delete = false; POOL_SESSION_CONTEXT *session_context; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("CommandComplete: cannot get session context"); return POOL_END; } if (session_context->query_context != NULL) { Node *node = session_context->query_context->parse_tree; if (IsA(node, PrepareStmt)) { if (session_context->uncompleted_message) { pool_add_sent_message(session_context->uncompleted_message); session_context->uncompleted_message = NULL; } } else if (IsA(node, DeallocateStmt)) { char *name; name = ((DeallocateStmt *)node)->name; if (name == NULL) { pool_remove_sent_messages('Q'); pool_remove_sent_messages('P'); } else { pool_remove_sent_message('Q', name); pool_remove_sent_message('P', name); } } else if (IsA(node, DiscardStmt)) { DiscardStmt *stmt = (DiscardStmt *)node; if (stmt->target == DISCARD_PLANS) { pool_remove_sent_messages('Q'); pool_remove_sent_messages('P'); } else if (stmt->target == DISCARD_ALL) { pool_clear_sent_message_list(); } } /* * JDBC driver sends "BEGIN" query internally if * setAutoCommit(false). But it does not send Sync message * after "BEGIN" query. In extended query protocol, * PostgreSQL returns ReadyForQuery when a client sends Sync * message. Problem is, pgpool can't know the transaction * state without receiving ReadyForQuery. So we remember that * we need to send Sync message internally afterward, whenever * we receive BEGIN in extended protocol. */ else if (IsA(node, TransactionStmt)) { TransactionStmt *stmt = (TransactionStmt *) node; if (stmt->kind == TRANS_STMT_BEGIN || stmt->kind == TRANS_STMT_START) { int i; for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; TSTATE(backend, i) = 'T'; } pool_unset_writing_transaction(); pool_unset_failed_transaction(); pool_unset_transaction_isolation(); } } } status = pool_read(MASTER(backend), &len, sizeof(len)); if (status < 0) { pool_error("CommandComplete: error while reading message length"); return POOL_END; } len = ntohl(len); len -= 4; len1 = len; p = pool_read2(MASTER(backend), len); if (p == NULL) return POOL_END; p1 = malloc(len); if (p1 == NULL) { pool_error("CommandComplete: malloc failed"); return POOL_ERROR; } memcpy(p1, p, len); rows = extract_ntuples(p); /* * Save number of affected tuples of master node. */ session_context->ntuples[MASTER_NODE_ID] = rows; if (strstr(p, "UPDATE") || strstr(p, "DELETE")) update_or_delete = true; for (i=0;intuples[i] = -1; continue; } status = pool_read(CONNECTION(backend, i), &len, sizeof(len)); if (status < 0) { pool_error("CommandComplete: error while reading message length"); return POOL_END; } len = ntohl(len); len -= 4; p = pool_read2(CONNECTION(backend, i), len); if (p == NULL) return POOL_END; if (len != len1) { pool_debug("CommandComplete: length does not match between backends master(%d) %d th backend(%d)", len, i, len1); } int n = extract_ntuples(p); /* * Save number of affected tuples. */ session_context->ntuples[i] = n; /* * if we are in the parallel mode, we have to sum up the number * of affected rows */ if (PARALLEL_MODE && is_parallel_table && update_or_delete) { rows += n; } else { if (rows != n) { /* * Remember that we have different number of UPDATE/DELETE * affected tuples in backends. */ session_context->mismatch_ntuples = true; } } } } if (session_context->mismatch_ntuples) { char msgbuf[128]; POOL_MEMORY_POOL *old_context; if (session_context->query_context) old_context = pool_memory_context_switch_to(session_context->query_context->memory_context); else old_context = pool_memory_context_switch_to(session_context->memory_context); String *msg = init_string("pgpool detected difference of the number of inserted, updated or deleted tuples. Possible last query was: \""); string_append_char(msg, query_string_buffer); string_append_char(msg, "\""); pool_send_error_message(frontend, MAJOR(backend), "XX001", msg->data, "", "check data consistency between master and other db node", __FILE__, __LINE__); pool_error("%s", msg->data); free_string(msg); msg = init_string("CommandComplete: Number of affected tuples are:"); for (i=0;intuples[i]); string_append_char(msg, msgbuf); } pool_log("%s", msg->data); free_string(msg); pool_memory_context_switch_to(old_context); } else { if (PARALLEL_MODE && is_parallel_table && update_or_delete) { char tmp[32]; strncpy(tmp, p1, 7); sprintf(tmp+7, "%d", rows); p2 = strdup(tmp); if (p2 == NULL) { pool_error("CommandComplete: malloc failed"); free(p1); return POOL_ERROR; } free(p1); p1 = p2; len1 = strlen(p2) + 1; } pool_write(frontend, "C", 1); sendlen = htonl(len1+4); pool_write(frontend, &sendlen, sizeof(sendlen)); pool_write_and_flush(frontend, p1, len1); } /* save the received result for each kind */ if (pool_config->enable_query_cache && SYSDB_STATUS == CON_UP) { query_cache_register('C', frontend, backend->info->database, p1, len1); } /* Save the received result to buffer for each kind */ if (pool_config->memory_cache_enabled) { if (pool_is_cache_safe() && !pool_is_cache_exceeded()) { memqcache_register('C', frontend, p1, len1); } } free(p1); if (pool_is_doing_extended_query_message()) { pool_set_query_state(session_context->query_context, POOL_EXECUTE_COMPLETE); } return POOL_CONTINUE; } POOL_STATUS ErrorResponse3(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { POOL_STATUS ret; ret = SimpleForwardToFrontend('E', frontend, backend); if (ret != POOL_CONTINUE) return ret; ret = raise_intentional_error_if_need(backend); if (ret != POOL_CONTINUE) return ret; #ifdef NOT_USED for (i = 0;i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { POOL_CONNECTION *cp = CONNECTION(backend, i); /* We need to send "sync" message to backend in extend mode * so that it accepts next command. * Note that this may be overkill since client may send * it by itself. Moreover we do not need it in non-extend mode. * At this point we regard it is not harmful since error response * will not be sent too frequently. */ pool_write(cp, "S", 1); res1 = htonl(4); if (pool_write_and_flush(cp, &res1, sizeof(res1)) < 0) { return POOL_END; } } } while ((ret = read_kind_from_backend(frontend, backend, &kind1)) == POOL_CONTINUE) { if (kind1 == 'Z') /* ReadyForQuery? */ break; ret = SimpleForwardToFrontend(kind1, frontend, backend); if (ret != POOL_CONTINUE) return ret; pool_flush(frontend); } if (ret != POOL_CONTINUE) return ret; for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { status = pool_read(CONNECTION(backend, i), &res1, sizeof(res1)); if (status < 0) { pool_error("SimpleForwardToFrontend: error while reading message length"); return POOL_END; } res1 = ntohl(res1) - sizeof(res1); p1 = pool_read2(CONNECTION(backend, i), res1); if (p1 == NULL) return POOL_END; } } #endif return POOL_CONTINUE; } POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { char dummy[2]; int oid; int argn; int i; for (i=0;ino_forward != 0) return POOL_CONTINUE; if (pool_read(frontend, &fkind, 1) < 0) { pool_log("ProcessFrontendResponse: failed to read kind from frontend. frontend abnormally exited"); return POOL_END; } pool_debug("ProcessFrontendResponse: kind from frontend %c(%02x)", fkind, fkind); if (MAJOR(backend) == PROTO_MAJOR_V3) { if (pool_read(frontend, &len, sizeof(len)) < 0) return POOL_END; len = ntohl(len) - 4; if (len > 0) bufp = pool_read2(frontend, len); } else { if (fkind != 'F') bufp = pool_read_string(frontend, &len, 0); } if (len > 0 && bufp == NULL) return POOL_END; if (fkind != 'S' && pool_is_ignore_till_sync()) { /* * Flag setting for calling ProcessBackendResponse() * in pool_process_query(). */ if (!pool_is_query_in_progress()) pool_set_query_in_progress(); return POOL_CONTINUE; } pool_unset_doing_extended_query_message(); /* * Allocate buffer and copy the packet contents. Because inside * these protocol modules, pool_read2 maybe called and modify its * buffer contents. */ contents = malloc(len); if (contents == NULL) { pool_error("ProcessFrontendResponse: cannot allocate memory. request size:%d", len); return POOL_ERROR; } memcpy(contents, bufp, len); switch (fkind) { POOL_QUERY_CONTEXT *query_context; char *query; Node *node; List *parse_tree_list; POOL_MEMORY_POOL *old_context; case 'X': /* Terminate */ free(contents); return POOL_END; case 'Q': /* Query */ allow_close_transaction = 1; status = SimpleQuery(frontend, backend, len, contents); break; case 'E': /* Execute */ allow_close_transaction = 1; pool_set_doing_extended_query_message(); if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync()) pool_set_query_in_progress(); status = Execute(frontend, backend, len, contents); break; case 'P': /* Parse */ allow_close_transaction = 0; pool_set_doing_extended_query_message(); if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync()) pool_set_query_in_progress(); status = Parse(frontend, backend, len, contents); break; case 'B': /* Bind */ pool_set_doing_extended_query_message(); if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync()) pool_set_query_in_progress(); status = Bind(frontend, backend, len, contents); break; case 'C': /* Close */ if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync()) pool_set_query_in_progress(); status = Close(frontend, backend, len, contents); break; case 'D': /* Describe */ pool_set_doing_extended_query_message(); if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync()) pool_set_query_in_progress(); status = Describe(frontend, backend, len, contents); break; case 'S': /* Sync */ pool_set_doing_extended_query_message(); if (pool_is_ignore_till_sync()) pool_unset_ignore_till_sync(); if (!pool_is_query_in_progress()) pool_set_query_in_progress(); status = SimpleForwardToBackend(fkind, frontend, backend, len, contents); break; case 'F': /* FunctionCall */ /* * Create dummy query context as if it were an INSERT. */ query_context = pool_init_query_context(); if (!query_context) { pool_error("ProcessFrontendResponse: pool_init_query_context failed"); free(contents); return POOL_END; } old_context = pool_memory_context_switch_to(query_context->memory_context); query = "INSERT INTO foo VALUES(1)"; parse_tree_list = raw_parser(query); node = (Node *) lfirst(list_head(parse_tree_list)); pool_start_query(query_context, query, strlen(query) + 1, node); pool_where_to_send(query_context, query_context->original_query, query_context->parse_tree); if (MAJOR(backend) == PROTO_MAJOR_V3) status = FunctionCall3(frontend, backend, len, contents); else status = FunctionCall(frontend, backend); pool_memory_context_switch_to(old_context); break; case 'c': /* CopyDone */ case 'd': /* CopyData */ case 'f': /* CopyFail */ case 'H': /* Flush */ if (MAJOR(backend) == PROTO_MAJOR_V3) { status = SimpleForwardToBackend(fkind, frontend, backend, len, contents); break; } default: pool_error("ProcessFrontendResponse: unknown message type %c(%02x)", fkind, fkind); status = POOL_ERROR; } free(contents); if (status != POOL_CONTINUE) status = POOL_ERROR; return status; } POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int *state, short *num_fields) { int status; char kind; POOL_SESSION_CONTEXT *session_context; /* Get session context */ session_context = pool_get_session_context(); if (!session_context) { pool_error("ProcessBackendResponse: cannot get session context"); return POOL_END; } if (pool_is_ignore_till_sync()) { if (pool_is_query_in_progress()) pool_unset_query_in_progress(); return POOL_CONTINUE; } if (pool_is_skip_reading_from_backends()) { pool_unset_skip_reading_from_backends(); return POOL_CONTINUE; } status = read_kind_from_backend(frontend, backend, &kind); if (status != POOL_CONTINUE) return status; /* * Sanity check */ if (kind == 0) { pool_error("ProcessBackendResponse: kind is 0!"); return POOL_ERROR; } pool_debug("ProcessBackendResponse: kind from backend: %c", kind); if (MAJOR(backend) == PROTO_MAJOR_V3) { switch (kind) { case 'G': /* CopyInResponse */ status = CopyInResponse(frontend, backend); break; case 'S': /* ParameterStatus */ status = ParameterStatus(frontend, backend); break; case 'Z': /* ReadyForQuery */ status = ReadyForQuery(frontend, backend, true, true); pool_debug("ProcessBackendResponse: Ready For Query"); break; case '1': /* ParseComplete */ status = ParseComplete(frontend, backend); pool_set_command_success(); pool_unset_query_in_progress(); break; case '2': /* BindComplete */ status = BindComplete(frontend, backend); pool_set_command_success(); pool_unset_query_in_progress(); break; case '3': /* CloseComplete */ status = CloseComplete(frontend, backend); pool_set_command_success(); pool_unset_query_in_progress(); break; case 'E': /* ErrorResponse */ status = ErrorResponse3(frontend, backend); pool_unset_command_success(); if (TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID) != 'I') pool_set_failed_transaction(); if (pool_is_doing_extended_query_message()) { pool_set_ignore_till_sync(); pool_unset_query_in_progress(); } break; case 'C': /* CommandComplete */ status = CommandComplete(frontend, backend); pool_set_command_success(); if (pool_is_doing_extended_query_message()) pool_unset_query_in_progress(); break; case 'I': /* EmptyQueryResponse */ status = SimpleForwardToFrontend(kind, frontend, backend); if (pool_is_doing_extended_query_message()) pool_unset_query_in_progress(); break; case 'T': /* RowDescription */ status = SimpleForwardToFrontend(kind, frontend, backend); if (pool_is_doing_extended_query_message()) pool_unset_query_in_progress(); break; case 'n': /* NoData */ status = SimpleForwardToFrontend(kind, frontend, backend); if (pool_is_doing_extended_query_message()) pool_unset_query_in_progress(); break; case 's': /* PortalSuspended */ status = SimpleForwardToFrontend(kind, frontend, backend); if (pool_is_doing_extended_query_message()) pool_unset_query_in_progress(); break; default: status = SimpleForwardToFrontend(kind, frontend, backend); if (pool_flush(frontend)) return POOL_END; break; } } else { switch (kind) { case 'A': /* NotificationResponse */ status = NotificationResponse(frontend, backend); break; case 'B': /* BinaryRow */ status = BinaryRow(frontend, backend, *num_fields); break; case 'C': /* CompletedResponse */ status = CompletedResponse(frontend, backend); break; case 'D': /* AsciiRow */ status = AsciiRow(frontend, backend, *num_fields); break; case 'E': /* ErrorResponse */ status = ErrorResponse(frontend, backend); if (TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID) != 'I') pool_set_failed_transaction(); break; case 'G': /* CopyInResponse */ status = CopyInResponse(frontend, backend); break; case 'H': /* CopyOutResponse */ status = CopyOutResponse(frontend, backend); break; case 'I': /* EmptyQueryResponse */ status = EmptyQueryResponse(frontend, backend); break; case 'N': /* NoticeResponse */ status = NoticeResponse(frontend, backend); break; case 'P': /* CursorResponse */ status = CursorResponse(frontend, backend); break; case 'T': /* RowDescription */ status = RowDescription(frontend, backend, num_fields); break; case 'V': /* FunctionResultResponse and FunctionVoidResponse */ status = FunctionResultResponse(frontend, backend); break; case 'Z': /* ReadyForQuery */ status = ReadyForQuery(frontend, backend, true, true); break; default: pool_error("Unknown message type %c(%02x)", kind, kind); exit(1); } } /* Do we receive ready for query while processing reset * request? */ if (kind == 'Z' && frontend->no_forward && *state == 1) { *state = 0; } if (status != POOL_CONTINUE) status = POOL_ERROR; return status; } POOL_STATUS CopyInResponse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { POOL_STATUS status; /* forward to the frontend */ if (MAJOR(backend) == PROTO_MAJOR_V3) { if (SimpleForwardToFrontend('G', frontend, backend) != POOL_CONTINUE) return POOL_END; if (pool_flush(frontend) != POOL_CONTINUE) return POOL_END; } else if (pool_write_and_flush(frontend, "G", 1) < 0) return POOL_END; status = CopyDataRows(frontend, backend, 1); return status; } POOL_STATUS CopyOutResponse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { POOL_STATUS status; /* forward to the frontend */ if (MAJOR(backend) == PROTO_MAJOR_V3) { if (SimpleForwardToFrontend('H', frontend, backend) != POOL_CONTINUE) return POOL_END; if (pool_flush(frontend) != POOL_CONTINUE) return POOL_END; } else if (pool_write_and_flush(frontend, "H", 1) < 0) return POOL_END; status = CopyDataRows(frontend, backend, 0); return status; } POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int copyin) { char *string = NULL; int len; int i; DistDefInfo *info = NULL; #ifdef DEBUG int j = 0; char buf[1024]; #endif if (copyin && pool_config->parallel_mode == TRUE) { info = pool_get_dist_def_info(MASTER_CONNECTION(backend)->sp->database, copy_schema, copy_table); } for (;;) { if (copyin) { if (MAJOR(backend) == PROTO_MAJOR_V3) { char kind; int sendlen; char *p, *p1; if (pool_read(frontend, &kind, 1) < 0) return POOL_END; if (info && kind == 'd') { int id; if (pool_read(frontend, &sendlen, sizeof(sendlen))) { return POOL_END; } len = ntohl(sendlen) - 4; if (len <= 0) return POOL_CONTINUE; p = pool_read2(frontend, len); if (p == NULL) return POOL_END; /* copy end ? */ if (len == 3 && memcmp(p, "\\.\n", 3) == 0) { for (i=0;idist_key_col_id); if (!p1) { pool_error("CopyDataRow: cannot parse data"); return POOL_END; } else if (strcmp(p1, copy_null) == 0) { pool_error("CopyDataRow: key parameter is NULL"); free(p1); return POOL_END; } id = pool_get_id(info, p1); pool_debug("CopyDataRow: copying id: %d", id); free(p1); if (id < 0 || !VALID_BACKEND(id)) { pool_error("CopyDataRow: pool_get_id returns invalid id: %d", id); exit(1); } if (pool_write(CONNECTION(backend, id), &kind, 1)) { return POOL_END; } if (pool_write(CONNECTION(backend, id), &sendlen, sizeof(sendlen))) { return POOL_END; } if (pool_write_and_flush(CONNECTION(backend, id), p, len)) { return POOL_END; } } } else { char *contents = NULL; pool_debug("CopyDataRows: read kind from frontend %c(%02x)", kind, kind); if (pool_read(frontend, &len, sizeof(len)) < 0) return POOL_END; len = ntohl(len) - 4; if (len > 0) contents = pool_read2(frontend, len); SimpleForwardToBackend(kind, frontend, backend, len, contents); } /* CopyData? */ if (kind == 'd') continue; else { pool_debug("CopyDataRows: copyin kind other than d (%c)", kind); break; } } else string = pool_read_string(frontend, &len, 1); } else { /* CopyOut */ if (MAJOR(backend) == PROTO_MAJOR_V3) { signed char kind; if ((kind = pool_read_kind(backend)) < 0) return POOL_END; SimpleForwardToFrontend(kind, frontend, backend); /* CopyData? */ if (kind == 'd') continue; else break; } else { for (i=0;iquery_context; if (MASTER_SLAVE && TSTATE(backend, PRIMARY_NODE_ID) == 'T' && PRIMARY_NODE_ID != MASTER_NODE_ID && query_context && is_select_query(query_context->parse_tree, query_context->original_query)) { pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); if (pool_is_doing_extended_query_message()) { ret = do_error_execute_command(backend, PRIMARY_NODE_ID, PROTO_MAJOR_V3); if (ret != POOL_CONTINUE) return ret; } else { ret = do_error_command(CONNECTION(backend, PRIMARY_NODE_ID), MAJOR(backend)); if (ret != POOL_CONTINUE) return ret; } pool_debug("raise_intentional_error: intentional error occurred"); } if (REPLICATION && TSTATE(backend, REAL_MASTER_NODE_ID) == 'T' && !pool_config->replicate_select && query_context && is_select_query(query_context->parse_tree, query_context->original_query)) { pool_setall_node_to_be_sent(query_context); for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i) && REAL_MASTER_NODE_ID != i) { /* * We must abort transaction to sync transaction state. * If the error was caused by an Execute message, * we must send invalid Execute message to abort * transaction. * * Because extended query protocol ignores all * messages before receiving Sync message inside error state. */ if (pool_is_doing_extended_query_message()) { ret = do_error_execute_command(backend, i, PROTO_MAJOR_V3); if (ret != POOL_CONTINUE) return ret; } else { ret = do_error_command(CONNECTION(backend, i), MAJOR(backend)); if (ret != POOL_CONTINUE) return ret; } } } } return POOL_CONTINUE; } void query_cache_register(char kind, POOL_CONNECTION *frontend, char *database, char *data, int data_len) { static int inside_T; /* flag to see the result data sequence */ int result; if (is_select_pgcatalog || is_select_for_update) return; if (kind == 'T' && parsed_query) { result = pool_query_cache_register(kind, frontend, database, data, data_len, parsed_query); if (result < 0) { pool_error("pool_query_cache_register: query cache registration failed"); inside_T = 0; } else { inside_T = 1; } } else if ((kind == 'D' || kind == 'C' || kind == 'E') && inside_T) { result = pool_query_cache_register(kind, frontend, database, data, data_len, NULL); if (kind == 'C' || kind == 'E' || result < 0) { if (result < 0) pool_error("pool_query_cache_register: query cache registration failed"); else pool_debug("pool_query_cache_register: query cache saved"); inside_T = 0; free(parsed_query); parsed_query = NULL; } } } /* * Check various errors from backend. return values: 0: no error 1: * deadlock detected 2: serialization error detected 3: query cancel * detected: 4 */ static int check_errors(POOL_CONNECTION_POOL *backend, int backend_id) { /* * Check dead lock error on the master node and abort * transactions on all nodes if so. */ if (detect_deadlock_error(CONNECTION(backend, backend_id), MAJOR(backend)) == SPECIFIED_ERROR) return 1; /* * Check serialization failure error and abort * transactions on all nodes if so. Otherwise we allow * data inconsistency among DB nodes. See following * scenario: (M:master, S:slave) * * M:S1:BEGIN; * M:S2:BEGIN; * S:S1:BEGIN; * S:S2:BEGIN; * M:S1:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; * M:S2:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; * S:S1:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; * S:S2:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; * M:S1:UPDATE t1 SET i = i + 1; * S:S1:UPDATE t1 SET i = i + 1; * M:S2:UPDATE t1 SET i = i + 1; <-- blocked * S:S1:COMMIT; * M:S1:COMMIT; * M:S2:ERROR: could not serialize access due to concurrent update * S:S2:UPDATE t1 SET i = i + 1; <-- success in UPDATE and data becomes inconsistent! */ if (detect_serialization_error(CONNECTION(backend, backend_id), MAJOR(backend), true) == SPECIFIED_ERROR) return 2; /* * check "SET TRANSACTION ISOLATION LEVEL must be called before any query" error. * This happens in following scenario: * * M:S1:BEGIN; * S:S1:BEGIN; * M:S1:SELECT 1; <-- only sent to MASTER * M:S1:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; * S:S1:SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; * M: <-- error * S: <-- ok since no previous SELECT is sent. kind mismatch error occurs! */ if (detect_active_sql_transaction_error(CONNECTION(backend, backend_id), MAJOR(backend)) == SPECIFIED_ERROR) return 3; /* check query cancel error */ if (detect_query_cancel_error(CONNECTION(backend, backend_id), MAJOR(backend)) == SPECIFIED_ERROR) return 4; return 0; } static void generate_error_message(char *prefix, int specific_error, char *query) { POOL_SESSION_CONTEXT *session_context; POOL_MEMORY_POOL *old_context; session_context = pool_get_session_context(); if (!session_context) return; static char *error_messages[] = { "received deadlock error message from master node. query: %s", "received serialization failure error message from master node. query: %s", "received SET TRANSACTION ISOLATION LEVEL must be called before any query error. query: %s", "received query cancel error message from master node. query: %s" }; String *msg; if (specific_error < 1 || specific_error > sizeof(error_messages)/sizeof(char *)) { pool_error("generate_error_message: invalid specific_error: %d", specific_error); return; } specific_error--; if (session_context->query_context) old_context = pool_memory_context_switch_to(session_context->query_context->memory_context); else old_context = pool_memory_context_switch_to(session_context->memory_context); msg = init_string(prefix); string_append_char(msg, error_messages[specific_error]); pool_error(msg->data, query); free_string(msg); pool_memory_context_switch_to(old_context); } /* * Make per DB node statement log */ void per_node_statement_log(POOL_CONNECTION_POOL *backend, int node_id, char *query) { POOL_CONNECTION_POOL_SLOT *slot = backend->slots[node_id]; if (pool_config->log_per_node_statement) pool_log("DB node id: %d backend pid: %d statement: %s", node_id, ntohl(slot->pid), query); } /* * Check kind and produce error message * All data read in this function is returned to stream. */ void per_node_error_log(POOL_CONNECTION_POOL *backend, int node_id, char *query, char *prefix, bool unread) { POOL_CONNECTION_POOL_SLOT *slot = backend->slots[node_id]; char *message; if (pool_extract_error_message(true, CONNECTION(backend, node_id), MAJOR(backend), true, &message) > 0) { pool_log("%s: DB node id: %d backend pid: %d statement: %s message: %s", prefix, node_id, ntohl(slot->pid), query, message); } } static POOL_STATUS parse_before_bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, POOL_SENT_MESSAGE *message) { int i; int len = message->len; char kind = '\0'; char *contents = message->contents; bool parse_was_sent = false; bool backup[MAX_NUM_BACKENDS]; POOL_STATUS status; POOL_QUERY_CONTEXT *qc = message->query_context; memcpy(backup, qc->where_to_send, sizeof(qc->where_to_send)); /* expect to send to master node only */ for (i = 0; i < NUM_BACKENDS; i++) { if (qc->where_to_send[i] && statecmp(qc->query_state[i], POOL_PARSE_COMPLETE) < 0) { pool_debug("parse_before_bind: waiting for backend %d completing parse", i); if (pool_extended_send_and_wait(qc, "P", len, contents, 1, i) != POOL_CONTINUE) return POOL_END; } else { qc->where_to_send[i] = 0; } } for (i = 0; i < NUM_BACKENDS; i++) { if (qc->where_to_send[i]) { parse_was_sent = true; break; } } if (parse_was_sent) { while (kind != '1') { status = read_kind_from_backend(frontend, backend, &kind); if (status != POOL_CONTINUE) { memcpy(qc->where_to_send, backup, sizeof(backup)); return status; } status = pool_discard_packet_contents(backend); if (status != POOL_CONTINUE) { memcpy(qc->where_to_send, backup, sizeof(backup)); return status; } } } memcpy(qc->where_to_send, backup, sizeof(backup)); return POOL_CONTINUE; } /* * Find victim nodes by "decide by majority" rule and returns array * of victim node ids. If no victim is found, return NULL. * * Arguments: * ntuples: Array of number of affected tuples. -1 represents down node. * nmembers: Number of elements in ntuples. * master_node: The master node id. Less than 0 means ignore this parameter. * number_of_nodes: Number of elements in victim nodes array. * * Note: If no one wins and master_node >= 0, winner would be the * master and other nodes who has same number of tuples as the master. * * Caution: Returned victim node array is allocated in static memory * of this function. Subsequent calls to this function will overwrite * the memory. */ static int* find_victim_nodes(int *ntuples, int nmembers, int master_node, int *number_of_nodes) { static int victim_nodes[MAX_NUM_BACKENDS]; static int votes[MAX_NUM_BACKENDS]; int maxvotes; int majority_ntuples; int me; int cnt; int healthy_nodes; int i, j; healthy_nodes = 0; *number_of_nodes = 0; maxvotes = 0; majority_ntuples = 0; for (i=0;i maxvotes) { maxvotes = votes[i]; majority_ntuples = me; } } } } /* Everyone is different */ if (maxvotes == 1) { /* Master node is specified? */ if (master_node < 0) return NULL; /* * If master node is specified, let it and others who has same * ntuples win. */ majority_ntuples = ntuples[master_node]; } else { /* Find number of majority */ cnt = 0; for (i=0;i= 0 && ntuples[i] != majority_ntuples) { victim_nodes[(*number_of_nodes)++] = i; } } return victim_nodes; } /* * Extract the number of tuples from CommandComplete message */ static int extract_ntuples(char *message) { char *rows; if ((rows = strstr(message, "UPDATE")) || (rows = strstr(message, "DELETE"))) rows +=7; else if ((rows = strstr(message, "INSERT"))) { rows += 7; while (*rows && *rows != ' ') rows++; } else return 0; return atoi(rows); } pgpool-II-3.3.2/md5.h0000664000076400007640000000133412245576256011126 00000000000000/*------------------------------------------------------------------------- * * md5.h * Interface to md5.c * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * $Header$ * *------------------------------------------------------------------------- */ /* * This file is imported from PostgreSQL 8.1.3. * Modified by Taiki Yamaguchi */ #ifndef MD5_H #define MD5_H #define MAX_USER_NAME_LEN 128 #define MD5_PASSWD_LEN 32 extern int pool_md5_hash(const void *buff, size_t len, char *hexsum); extern int pool_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf); #endif pgpool-II-3.3.2/pg_md5.c0000664000076400007640000001560412245576266011615 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pg_md5 command main * */ #include "pool.h" #include "pool_config.h" #include "pool_passwd.h" #include "md5.h" #include #include #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include #include /* Maximum number of characters allowed for input. */ #define MAX_INPUT_SIZE MAX_USER_NAME_LEN static void print_usage(const char prog[], int exit_code); static void set_tio_attr(int enable); static void update_pool_passwd(char *conf_file, char *username, char *password); int main(int argc, char *argv[]) { #define PRINT_USAGE(exit_code) print_usage(argv[0], exit_code) char conf_file[POOLMAXPATHLEN+1]; char username[MAX_INPUT_SIZE+1]; int opt; int optindex; bool md5auth = false; bool prompt = false; static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"prompt", no_argument, NULL, 'p'}, {"md5auth", no_argument, NULL, 'm'}, {"username", required_argument, NULL, 'u'}, {"config-file", required_argument, NULL, 'f'}, {NULL, 0, NULL, 0} }; snprintf(conf_file, sizeof(conf_file), "%s/%s", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME); /* initialize username buffer with zeros so that we can use strlen on it later to check if a username was given on the command line */ memset(username, 0, MAX_INPUT_SIZE+1); while ((opt = getopt_long(argc, argv, "hpmf:u:", long_options, &optindex)) != -1) { switch (opt) { case 'p': /* prompt for password */ prompt = true; break; case 'm': /* produce md5 authentication password */ md5auth = true; break; case 'f': /* specify configuration file */ if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); } strlcpy(conf_file, optarg, sizeof(conf_file)); break; case 'u': if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); } /* check the input limit early */ if (strlen(optarg) > MAX_INPUT_SIZE) { fprintf(stderr, "Error: input exceeds maximum username length!\n\n"); exit(EXIT_FAILURE); } strlcpy(username, optarg, sizeof(username)); break; default: PRINT_USAGE(EXIT_SUCCESS); break; } } /* Prompt for password. */ if (prompt) { char md5[MD5_PASSWD_LEN+1]; char buf[MAX_INPUT_SIZE+1]; int len; set_tio_attr(1); printf("password: "); if (!fgets(buf, (MAX_INPUT_SIZE+1), stdin)) { int eno = errno; fprintf(stderr, "Couldn't read input from stdin. (fgets(): %s)", strerror(eno)); exit(EXIT_FAILURE); } printf("\n"); set_tio_attr(0); /* Remove LF at the end of line, if there is any. */ len = strlen(buf); if (len > 0 && buf[len-1] == '\n') { buf[len-1] = '\0'; len--; } if (md5auth) { update_pool_passwd(conf_file, username, buf); } else { pool_md5_hash(buf, len, md5); printf("%s\n", md5); } } /* Read password from argv. */ else { char md5[POOL_PASSWD_LEN+1]; int len; if (optind >= argc) { PRINT_USAGE(EXIT_FAILURE); } len = strlen(argv[optind]); if (len > MAX_INPUT_SIZE) { fprintf(stderr, "Error: Input exceeds maximum password length!\n\n"); PRINT_USAGE(EXIT_FAILURE); } if (md5auth) { update_pool_passwd(conf_file, username, argv[optind]); } else { pool_md5_hash(argv[optind], len, md5); printf("%s\n", md5); } } return EXIT_SUCCESS; } static void update_pool_passwd(char *conf_file, char *username, char *password) { struct passwd *pw; char md5[POOL_PASSWD_LEN+1]; char pool_passwd[POOLMAXPATHLEN+1]; char dirnamebuf[POOLMAXPATHLEN+1]; char *dirp; if (pool_init_config()) { fprintf(stderr, "pool_init_config() failed\n\n"); exit(EXIT_FAILURE); } if (pool_get_config(conf_file, INIT_CONFIG)) { fprintf(stderr, "Unable to get configuration. Exiting..."); exit(EXIT_FAILURE); } strlcpy(dirnamebuf, conf_file, sizeof(dirnamebuf)); dirp = dirname(dirnamebuf); snprintf(pool_passwd, sizeof(pool_passwd), "%s/%s", dirp, pool_config->pool_passwd); pool_init_pool_passwd(pool_passwd); if (strlen(username)) { /* generate the hash for the given username */ pg_md5_encrypt(password, username, strlen(username), md5); pool_create_passwdent(username, md5); } else { /* get the user information from the current uid */ pw = getpwuid(getuid()); if (!pw) { fprintf(stderr, "getpwuid() failed\n\n"); exit(EXIT_FAILURE); } pg_md5_encrypt(password, pw->pw_name, strlen(pw->pw_name), md5); pool_create_passwdent(pw->pw_name, md5); } pool_finish_pool_passwd(); } static void print_usage(const char prog[], int exit_code) { fprintf(((exit_code == EXIT_SUCCESS) ? stdout : stderr), "Usage:\n\ \n\ %s [OPTIONS]\n\ %s \n\ \n\ --prompt, -p Prompt password using standard input.\n\ --md5auth, -m Produce md5 authentication password.\n\ --username, -u USER When producing a md5 authentication password,\n\ create the pool_passwd entry for USER.\n\ --config-file, -f CONFIG-FILE Specify pgpool.conf.\n\ --help, -h This help menu.\n\ \n\ Warning: At most %d characters are allowed for input.\n\ Warning: Plain password argument is deprecated for security concerns\n\ and kept for compatibility. Please prefer using password\n\ prompt.\n", prog, prog, MAX_INPUT_SIZE); exit(exit_code); } static void set_tio_attr(int set) { struct termios tio; static struct termios tio_save; if (!isatty(0)) { fprintf(stderr, "stdin is not tty\n"); exit(EXIT_FAILURE); } if (set) { if (tcgetattr(0, &tio) < 0) { fprintf(stderr, "set_tio_attr(set): tcgetattr failed\n"); exit(EXIT_FAILURE); } tio_save = tio; tio.c_iflag &= ~(BRKINT|ISTRIP|IXON); tio.c_lflag &= ~(ICANON|IEXTEN|ECHO|ECHOE|ECHOK|ECHONL); tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; if (tcsetattr(0, TCSANOW, &tio) < 0) { fprintf(stderr, "(set_tio_attr(set): tcsetattr failed\n"); exit(EXIT_FAILURE); } } else { if (tcsetattr(0, TCSANOW, &tio_save) < 0) { fprintf(stderr, "set_tio_attr(reset): tcsetattr failed\n"); exit(EXIT_FAILURE); } } } pgpool-II-3.3.2/pcp/0000775000076400007640000000000012245776616011133 500000000000000pgpool-II-3.3.2/pcp/md5.c0000664000076400007640000002506712245576256011714 00000000000000/* * md5.c * * Implements the MD5 Message-Digest Algorithm as specified in * RFC 1321. This implementation is a simple one, in that it * needs every input byte to be buffered before doing any * calculations. I do not expect this file to be used for * general purpose MD5'ing of large amounts of data, only for * generating hashed passwords from limited input. * * Sverre H. Huseby * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * This file is imported from PostgreSQL 8.1.3., and modified by * Taiki Yamaguchi * * IDENTIFICATION * $Header$ */ #include #include #include #include #include "pool.h" #include "md5.h" #ifdef NOT_USED typedef unsigned char uint8; /* == 8 bits */ typedef unsigned int uint32; /* == 32 bits */ #endif #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) #define FF(a, b, c, d, x, s, ac) { \ (a) += F((b), (c), (d)) + (x) + (uint32)(ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G((b), (c), (d)) + (x) + (uint32)(ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H((b), (c), (d)) + (x) + (uint32)(ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I((b), (c), (d)) + (x) + (uint32)(ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ } const uint32 T[64] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; /* * PRIVATE FUNCTIONS */ /* * The returned array is allocated using malloc. the caller should free it * when it is no longer needed. */ static uint8 * createPaddedCopyWithLength(uint8 *b, uint32 *l) { /* * uint8 *b - message to be digested * uint32 *l - length of b */ uint8 *ret; uint32 q; uint32 len, newLen448; uint32 len_high, len_low; /* 64-bit value split into 32-bit sections */ len = ((b == NULL) ? 0 : *l); newLen448 = len + 64 - (len % 64) - 8; if (newLen448 <= len) newLen448 += 64; *l = newLen448 + 8; if ((ret = (uint8 *) malloc(sizeof(uint8) * *l)) == NULL) return NULL; if (b != NULL) memcpy(ret, b, sizeof(uint8) * len); /* pad */ ret[len] = 0x80; for (q = len + 1; q < newLen448; q++) ret[q] = 0x00; /* append length as a 64 bit bitcount */ len_low = len; /* split into two 32-bit values */ /* we only look at the bottom 32-bits */ len_high = len >> 29; len_low <<= 3; q = newLen448; ret[q++] = (len_low & 0xff); len_low >>= 8; ret[q++] = (len_low & 0xff); len_low >>= 8; ret[q++] = (len_low & 0xff); len_low >>= 8; ret[q++] = (len_low & 0xff); ret[q++] = (len_high & 0xff); len_high >>= 8; ret[q++] = (len_high & 0xff); len_high >>= 8; ret[q++] = (len_high & 0xff); len_high >>= 8; ret[q] = (len_high & 0xff); return ret; } static void doTheRounds(uint32 X[16], uint32 state[4]) { uint32 a, b, c, d; a = state[0]; b = state[1]; c = state[2]; d = state[3]; /* round 1 */ FF(a, b, c, d, X[ 0], S11, T[ 0]); FF(d, a, b, c, X[ 1], S12, T[ 1]); FF(c, d, a, b, X[ 2], S13, T[ 2]); FF(b, c, d, a, X[ 3], S14, T[ 3]); FF(a, b, c, d, X[ 4], S11, T[ 4]); FF(d, a, b, c, X[ 5], S12, T[ 5]); FF(c, d, a, b, X[ 6], S13, T[ 6]); FF(b, c, d, a, X[ 7], S14, T[ 7]); FF(a, b, c, d, X[ 8], S11, T[ 8]); FF(d, a, b, c, X[ 9], S12, T[ 9]); FF(c, d, a, b, X[10], S13, T[10]); FF(b, c, d, a, X[11], S14, T[11]); FF(a, b, c, d, X[12], S11, T[12]); FF(d, a, b, c, X[13], S12, T[13]); FF(c, d, a, b, X[14], S13, T[14]); FF(b, c, d, a, X[15], S14, T[15]); GG(a, b, c, d, X[ 1], S21, T[16]); GG(d, a, b, c, X[ 6], S22, T[17]); GG(c, d, a, b, X[11], S23, T[18]); GG(b, c, d, a, X[ 0], S24, T[19]); GG(a, b, c, d, X[ 5], S21, T[20]); GG(d, a, b, c, X[10], S22, T[21]); GG(c, d, a, b, X[15], S23, T[22]); GG(b, c, d, a, X[ 4], S24, T[23]); GG(a, b, c, d, X[ 9], S21, T[24]); GG(d, a, b, c, X[14], S22, T[25]); GG(c, d, a, b, X[ 3], S23, T[26]); GG(b, c, d, a, X[ 8], S24, T[27]); GG(a, b, c, d, X[13], S21, T[28]); GG(d, a, b, c, X[ 2], S22, T[29]); GG(c, d, a, b, X[ 7], S23, T[30]); GG(b, c, d, a, X[12], S24, T[31]); HH(a, b, c, d, X[ 5], S31, T[32]); HH(d, a, b, c, X[ 8], S32, T[33]); HH(c, d, a, b, X[11], S33, T[34]); HH(b, c, d, a, X[14], S34, T[35]); HH(a, b, c, d, X[ 1], S31, T[36]); HH(d, a, b, c, X[ 4], S32, T[37]); HH(c, d, a, b, X[ 7], S33, T[38]); HH(b, c, d, a, X[10], S34, T[39]); HH(a, b, c, d, X[13], S31, T[40]); HH(d, a, b, c, X[ 0], S32, T[41]); HH(c, d, a, b, X[ 3], S33, T[42]); HH(b, c, d, a, X[ 6], S34, T[43]); HH(a, b, c, d, X[ 9], S31, T[44]); HH(d, a, b, c, X[12], S32, T[45]); HH(c, d, a, b, X[15], S33, T[46]); HH(b, c, d, a, X[ 2], S34, T[47]); II(a, b, c, d, X[ 0], S41, T[48]); II(d, a, b, c, X[ 7], S42, T[49]); II(c, d, a, b, X[14], S43, T[50]); II(b, c, d, a, X[ 5], S44, T[51]); II(a, b, c, d, X[12], S41, T[52]); II(d, a, b, c, X[ 3], S42, T[53]); II(c, d, a, b, X[10], S43, T[54]); II(b, c, d, a, X[ 1], S44, T[55]); II(a, b, c, d, X[ 8], S41, T[56]); II(d, a, b, c, X[15], S42, T[57]); II(c, d, a, b, X[ 6], S43, T[58]); II(b, c, d, a, X[13], S44, T[59]); II(a, b, c, d, X[ 4], S41, T[60]); II(d, a, b, c, X[11], S42, T[61]); II(c, d, a, b, X[ 2], S43, T[62]); II(b, c, d, a, X[ 9], S44, T[63]); state[0] += a; state[1] += b; state[2] += c; state[3] += d; } static int calculateDigestFromBuffer(uint8 *b, uint32 len, uint8 sum[16]) { /* * uint8 *b - message to be digested * uint32 len - length of b * uint8 sum[16] - md5 digest calculated from b */ register uint32 i, j, k, newI; uint32 l; uint8 *input; register uint32 *wbp; uint32 workBuff[16], state[4]; l = len; state[0] = 0x67452301; state[1] = 0xEFCDAB89; state[2] = 0x98BADCFE; state[3] = 0x10325476; if ((input = createPaddedCopyWithLength(b, &l)) == NULL) return 0; for (i = 0;;) { if ((newI = i + 16 * 4) > l) break; k = i + 3; for (j = 0; j < 16; j++) { wbp = (workBuff + j); *wbp = input[k--]; *wbp <<= 8; *wbp |= input[k--]; *wbp <<= 8; *wbp |= input[k--]; *wbp <<= 8; *wbp |= input[k]; k += 7; } doTheRounds(workBuff, state); i = newI; } free(input); j = 0; for (i = 0; i < 4; i++) { k = state[i]; sum[j++] = (k & 0xff); k >>= 8; sum[j++] = (k & 0xff); k >>= 8; sum[j++] = (k & 0xff); k >>= 8; sum[j++] = (k & 0xff); } return 1; } static void bytesToHex(uint8 b[16], char *s) { static const char *hex = "0123456789abcdef"; int q, w; for (q = 0, w = 0; q < 16; q++) { s[w++] = hex[(b[q] >> 4) & 0x0F]; s[w++] = hex[b[q] & 0x0F]; } s[w] = '\0'; } /* * PUBLIC FUNCTIONS */ /* * pool_md5_hash * * Calculates the MD5 sum of the bytes in a buffer. * * SYNOPSIS int pool_md5_hash(const void *buff, size_t len, char *hexsum) * * INPUT buff the buffer containing the bytes that you want * the MD5 sum of. * len number of bytes in the buffer. * * OUTPUT hexsum the MD5 sum as a '\0'-terminated string of * hexadecimal digits. an MD5 sum is 16 bytes long. * each byte is represented by two heaxadecimal * characters. you thus need to provide an array * of 33 characters, including the trailing '\0'. * * RETURNS false on failure (out of memory for internal buffers) or * true on success. * * STANDARDS MD5 is described in RFC 1321. * * AUTHOR Sverre H. Huseby * MODIFIED by Taiki Yamaguchi * */ int pool_md5_hash(const void *buff, size_t len, char *hexsum) { uint8 sum[16]; if (!calculateDigestFromBuffer((uint8 *) buff, len, sum)) return 0; /* failed */ bytesToHex(sum, hexsum); return 1; /* success */ } /* * Computes MD5 checksum of "passwd" (a null-terminated string) followed * by "salt" (which need not be null-terminated). * * Output format is a 32-hex-digit MD5 checksum. * Hence, the output buffer "buf" must be at least 33 bytes long. * * Returns 1 if okay, 0 on error (out of memory). */ int pool_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf) { size_t passwd_len = strlen(passwd); char *crypt_buf = malloc(passwd_len + salt_len); int ret; if (!crypt_buf) return 0; /* failed */ /* * Place salt at the end because it may be known by users trying to crack * the MD5 output. */ strcpy(crypt_buf, passwd); memcpy(crypt_buf + passwd_len, salt, salt_len); ret = pool_md5_hash(crypt_buf, passwd_len + salt_len, buf); free(crypt_buf); return ret; } /* * Computes MD5 checksum of "passwd" (a null-terminated string) followed * by "salt" (which need not be null-terminated). * * Output format is "md5" followed by a 32-hex-digit MD5 checksum. * Hence, the output buffer "buf" must be at least 36 bytes long. * * Returns TRUE if okay, FALSE on error (out of memory). */ bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf) { size_t passwd_len = strlen(passwd); /* +1 here is just to avoid risk of unportable malloc(0) */ char *crypt_buf = malloc(passwd_len + salt_len + 1); bool ret; if (!crypt_buf) return false; /* * Place salt at the end because it may be known by users trying to crack * the MD5 output. */ memcpy(crypt_buf, passwd, passwd_len); memcpy(crypt_buf + passwd_len, salt, salt_len); strcpy(buf, "md5"); ret = pool_md5_hash(crypt_buf, passwd_len + salt_len, buf + 3); free(crypt_buf); return ret; } pgpool-II-3.3.2/pcp/pcp_stop_pgpool.c0000664000076400007640000000762312245576266014435 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "stop pgpool" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; char mode; int ch; int optindex; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hd", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (argc != 6) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); if (strlen(argv[5]) != 1) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } mode = argv[5][0]; if (mode != 's' && mode != 'f' && mode != 'i') { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if (pcp_terminate_pgpool(mode)) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_stop_pgpool - terminate pgpool-II\n\n"); fprintf(stderr, "Usage: pcp_stop_pgpool [-d] timeout hostname port# username password mode\n"); fprintf(stderr, "Usage: pcp_stop_pgpool -h\n\n"); fprintf(stderr, " -d, --debug : enable debug message (optional)\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " mode : shutdown mode\n"); fprintf(stderr, " s - smart shutdown f - fast shutdown i - immediate shutdown\n"); fprintf(stderr, " -h, --help : print this help\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pcp/libpcp_ext.h0000664000076400007640000002003012245576266013347 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2011 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * * libpcpcp_ext.h - * This file contains definitions for structures and * externs for functions used by frontend libpcp applications. */ #ifndef LIBPCP_EXT_H #define LIBPCP_EXT_H /* * startup packet definitions (v2) stolen from PostgreSQL */ #define SM_DATABASE 64 #define SM_USER 32 #define SM_OPTIONS 64 #define SM_UNUSED 64 #define SM_TTY 64 #define MAX_NUM_BACKENDS 128 #define MAX_CONNECTION_SLOTS MAX_NUM_BACKENDS #define MAX_DB_HOST_NAMELEN 128 #define MAX_PATH_LENGTH 256 typedef enum { CON_UNUSED, /* unused slot */ CON_CONNECT_WAIT, /* waiting for connection starting */ CON_UP, /* up and running */ CON_DOWN /* down, disconnected */ } BACKEND_STATUS; /* * PostgreSQL backend descriptor. Placed on shared memory area. */ typedef struct { char backend_hostname[MAX_DB_HOST_NAMELEN]; /* backend host name */ int backend_port; /* backend port numbers */ BACKEND_STATUS backend_status; /* backend status */ double backend_weight; /* normalized backend load balance ratio */ double unnormalized_weight; /* descripted parameter */ char backend_data_directory[MAX_PATH_LENGTH]; unsigned short flag; /* various flags */ unsigned long long int standby_delay; /* The replication delay against the primary */ } BackendInfo; typedef struct { int num_backends; /* number of used PostgreSQL backends */ BackendInfo backend_info[MAX_NUM_BACKENDS]; } BackendDesc; /* * Connection pool information. Placed on shared memory area. */ typedef struct { int backend_id; /* backend id */ char database[SM_DATABASE]; /* Database name */ char user[SM_USER]; /* User name */ int major; /* protocol major version */ int minor; /* protocol minor version */ int pid; /* backend process id */ int key; /* cancel key */ int counter; /* used counter */ time_t create_time; /* connection creation time */ int load_balancing_node; /* load balancing node */ char connected; /* True if frontend connected. Please note * that we use "char" instead of "bool". * Since 3.1, we need to export this * structure so that PostgreSQL C * functions can use. Problem is, * PostgreSQL defines bool itself, and if * we use bool, the size of the structure * might be out of control of * pgpool-II. So we use "char" here. */ } ConnectionInfo; /* * process information * This object put on shared memory. */ typedef struct { pid_t pid; /* OS's process id */ time_t start_time; /* fork() time */ ConnectionInfo *connection_info; /* head of the connection info for this process */ char need_to_restart; /* If non 0, exit this child process * as soon as current session ends. * Typical case this flag being set is * failback a node in streaming * replication mode. */ } ProcessInfo; /* * * system db structure */ typedef struct { char *dbname; /* database name */ char *schema_name; /* schema name */ char *table_name; /* table name */ char *dist_key_col_name;/* column name for dist key */ int dist_key_col_id; /* column index id for dist key */ int col_num; /* number of column*/ char **col_list; /* column list */ char **type_list; /* type list */ char *dist_def_func; /* function name of distribution rule */ char *prepare_name; /* prepared statement name */ int is_created_prepare; /* is prepare statement created? */ } DistDefInfo; typedef struct { char *dbname; /* database name */ char *schema_name; /* schema name */ char *table_name; /* table name */ int col_num; /* number of column*/ char **col_list; /* column list */ char **type_list; /* type list */ char *prepare_name; /* prepared statement name */ int is_created_prepare; /* is prepare statement created? */ } RepliDefInfo; typedef struct { int has_prepared_statement; /* true if the current session has prepared statement created */ char *register_prepared_statement; /* prepared statement name for cache register */ } QueryCacheTableInfo; typedef struct { char *hostname; /* host name */ int port; /* port number */ char *user; /* login user name */ char *password; /* login password */ char *schema_name; /* schema name */ char *database_name; /* database name */ int repli_def_num; /* number of replication table */ int dist_def_num; /* number of distribution table */ RepliDefInfo *repli_def_slot; /* replication rule list */ DistDefInfo *dist_def_slot; /* distribution rule list */ QueryCacheTableInfo query_cache_table_info; /* query cache db session info */ BACKEND_STATUS system_db_status; } SystemDBInfo; /* * reporting types */ /* some length definitions */ #define POOLCONFIG_MAXNAMELEN 64 #define POOLCONFIG_MAXVALLEN 512 #define POOLCONFIG_MAXDESCLEN 64 #define POOLCONFIG_MAXIDENTLEN 63 #define POOLCONFIG_MAXPORTLEN 6 #define POOLCONFIG_MAXSTATLEN 2 #define POOLCONFIG_MAXWEIGHTLEN 20 #define POOLCONFIG_MAXDATELEN 128 #define POOLCONFIG_MAXCOUNTLEN 16 /* config report struct*/ typedef struct { char name[POOLCONFIG_MAXNAMELEN+1]; char value[POOLCONFIG_MAXVALLEN+1]; char desc[POOLCONFIG_MAXDESCLEN+1]; } POOL_REPORT_CONFIG; /* nodes report struct */ typedef struct { char node_id[POOLCONFIG_MAXSTATLEN+1]; char hostname[POOLCONFIG_MAXIDENTLEN+1]; char port[POOLCONFIG_MAXIDENTLEN+1]; char status[POOLCONFIG_MAXSTATLEN+1]; char lb_weight[POOLCONFIG_MAXWEIGHTLEN+1]; char role[POOLCONFIG_MAXWEIGHTLEN+1]; } POOL_REPORT_NODES; /* processes report struct */ typedef struct { char pool_pid[POOLCONFIG_MAXCOUNTLEN+1]; char start_time[POOLCONFIG_MAXDATELEN+1]; char database[POOLCONFIG_MAXIDENTLEN+1]; char username[POOLCONFIG_MAXIDENTLEN+1]; char create_time[POOLCONFIG_MAXDATELEN+1]; char pool_counter[POOLCONFIG_MAXCOUNTLEN+1]; } POOL_REPORT_PROCESSES; /* pools reporting struct */ typedef struct { int pool_pid; time_t start_time; int pool_id; int backend_id; char database[POOLCONFIG_MAXIDENTLEN+1]; char username[POOLCONFIG_MAXIDENTLEN+1]; time_t create_time; int pool_majorversion; int pool_minorversion; int pool_counter; int pool_backendpid; int pool_connected; } POOL_REPORT_POOLS; /* version struct */ typedef struct { char version[POOLCONFIG_MAXVALLEN+1]; } POOL_REPORT_VERSION; struct WdInfo; extern int pcp_connect(char *hostname, int port, char *username, char *password); extern void pcp_disconnect(void); extern int pcp_terminate_pgpool(char mode); extern int pcp_node_count(void); extern BackendInfo *pcp_node_info(int nid); extern int *pcp_process_count(int *process_count); extern ProcessInfo *pcp_process_info(int pid, int *array_size); extern SystemDBInfo *pcp_systemdb_info(void); extern void free_systemdb_info(SystemDBInfo * si); extern int pcp_detach_node(int nid); extern int pcp_detach_node_gracefully(int nid); extern int pcp_attach_node(int nid); extern POOL_REPORT_CONFIG* pcp_pool_status(int *array_size); extern void pcp_set_timeout(long sec); extern int pcp_recovery_node(int nid); extern void pcp_enable_debug(void); extern void pcp_disable_debug(void); extern int pcp_promote_node(int nid); extern int pcp_promote_node_gracefully(int nid); extern struct WdInfo *pcp_watchdog_info(int nid); /* ------------------------------ * pcp_error.c * ------------------------------ */ //extern ErrorCode errorcode; //extern void pcp_errorstr(ErrorCode e); #endif /* LIBPCP_EXT_H */ pgpool-II-3.3.2/pcp/Makefile.am0000664000076400007640000000375012245576266013113 00000000000000AM_CPPFLAGS = -D_GNU_SOURCE -I .. -I @PGSQL_INCLUDE_DIR@ lib_LTLIBRARIES = libpcp.la libpcp_la_SOURCES = pcp.h ../pool_type.h md5.h pcp.c pcp_stream.h pcp_stream.c pcp_error.c md5.c libpcp_la_LIBS = include_HEADERS = pcp.h libpcp_ext.h ../pool_type.h ../pool_process_reporting.h md5.c: ../md5.c rm -f $@ && ln -s $< . md5.h: ../md5.h rm -f $@ && ln -s $< . bin_PROGRAMS = pcp_stop_pgpool pcp_node_count pcp_node_info pcp_proc_count pcp_proc_info \ pcp_systemdb_info pcp_detach_node pcp_attach_node pcp_recovery_node pcp_promote_node \ pcp_pool_status pcp_watchdog_info pcp_stop_pgpool_SOURCES = pcp_stop_pgpool.c pcp.h ../getopt_long.c ../getopt_long.h pcp_stop_pgpool_LDADD = libpcp.la pcp_stop_pgpool_LDFLAGS = pcp_node_count_SOURCES = pcp_node_count.c pcp.h ../getopt_long.c ../getopt_long.h pcp_node_count_LDADD = libpcp.la pcp_node_info_SOURCES = pcp_node_info.c pcp.h ../getopt_long.c ../getopt_long.h pcp_node_info_LDADD = libpcp.la pcp_proc_count_SOURCES = pcp_proc_count.c pcp.h ../getopt_long.c ../getopt_long.h pcp_proc_count_LDADD = libpcp.la pcp_proc_info_SOURCES = pcp_proc_info.c pcp.h ../getopt_long.c ../getopt_long.h pcp_proc_info_LDADD = libpcp.la pcp_systemdb_info_SOURCES = pcp_systemdb_info.c pcp.h ../getopt_long.c ../getopt_long.h pcp_systemdb_info_LDADD = libpcp.la pcp_detach_node_SOURCES = pcp_detach_node.c pcp.h ../getopt_long.c ../getopt_long.h pcp_detach_node_LDADD = libpcp.la pcp_attach_node_SOURCES = pcp_attach_node.c pcp.h ../getopt_long.c ../getopt_long.h pcp_attach_node_LDADD = libpcp.la pcp_recovery_node_SOURCES = pcp_recovery_node.c pcp.h ../getopt_long.c ../getopt_long.h pcp_recovery_node_LDADD = libpcp.la pcp_pool_status_SOURCES = pcp_pool_status.c pcp.h ../getopt_long.c ../getopt_long.h pcp_pool_status_LDADD = libpcp.la pcp_promote_node_SOURCES = pcp_promote_node.c pcp.h ../getopt_long.c ../getopt_long.h pcp_promote_node_LDADD = libpcp.la pcp_watchdog_info_SOURCES = pcp_watchdog_info.c pcp.h ../getopt_long.c ../getopt_long.h pcp_watchdog_info_LDADD = libpcp.la pgpool-II-3.3.2/pcp/pcp_recovery_node.c0000664000076400007640000000732312245576256014727 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "attach node" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; int nodeID; int ch; int optindex; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hd", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (argc != 6) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); nodeID = atoi(argv[5]); if (nodeID < 0 || nodeID > MAX_NUM_BACKENDS) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if (pcp_recovery_node(nodeID)) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_recovery_node - recovery a node\n\n"); fprintf(stderr, "Usage: pcp_recovery_node [-d] timeout hostname port# username password nodeID\n"); fprintf(stderr, "Usage: pcp_recovery_node -h\n\n"); fprintf(stderr, " -d, --debug : enable debug message (optional)\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " nodeID : ID of a node to recover\n"); fprintf(stderr, " -h, --help : print this help\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pcp/pcp_systemdb_info.c0000664000076400007640000001060312245576256014724 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "systemDB info" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; SystemDBInfo *systemdb_info; int i, j; int ch; int optindex; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hd", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (argc != 5) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if ((systemdb_info = pcp_systemdb_info()) == NULL) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } else { printf("%s %d %s %s %s %s %d %d\n", systemdb_info->hostname, systemdb_info->port, systemdb_info->user, systemdb_info->password[0] == '\0' ? "''" : systemdb_info->password, systemdb_info->schema_name, systemdb_info->database_name, systemdb_info->dist_def_num, systemdb_info->system_db_status); for (i = 0; i < systemdb_info->dist_def_num; i++) { DistDefInfo *ddi = &systemdb_info->dist_def_slot[i]; printf("%s %s %s %s %d ", ddi->dbname, ddi->schema_name, ddi->table_name, ddi->dist_key_col_name, ddi->col_num); for (j = 0; j < ddi->col_num; j++) printf("%s ", ddi->col_list[j]); for (j = 0; j < ddi->col_num; j++) printf("%s ", ddi->type_list[j]); printf("%s\n", ddi->dist_def_func); } free_systemdb_info(systemdb_info); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_systemdb_info - display the pgpool-II systemDB information\n\n"); fprintf(stderr, "Usage: pcp_systemdb_info [-d] timeout hostname port# username password\n"); fprintf(stderr, "Usage: pcp_systemdb_info -h\n\n"); fprintf(stderr, " -d, --debug : enable debug message (optional)\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " -h, --help : print this help\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pcp/pcp_detach_node.c0000664000076400007640000001004412245576256014313 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2010 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "detach node" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; int nodeID; int ch; int optindex; bool gracefully = false; int sts; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"gracefully", no_argument, NULL, 'g'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hdg", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'g': gracefully = true; break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (argc != 6) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); nodeID = atoi(argv[5]); if (nodeID < 0 || nodeID > MAX_NUM_BACKENDS) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if (gracefully) sts = pcp_detach_node_gracefully(nodeID); else sts = pcp_detach_node(nodeID); if (sts) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_detach_node - detach a node from pgpool-II\n\n"); fprintf(stderr, "Usage: pcp_detach_node [-d][-g] timeout hostname port# username password nodeID\n"); fprintf(stderr, "Usage: pcp_detach_node -h\n\n"); fprintf(stderr, " -d, --debug : enable debug message (optional)\n"); fprintf(stderr, " -g, --gracefully : detach gracefully(optional)\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " nodeID : ID of a node to be detached\n"); fprintf(stderr, " -h, --help : print this help\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pcp/pcp_stream.h0000664000076400007640000000324012245576256013356 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pcp_stream.h - master header file. */ #ifndef PCP_STREAM_H #define PCP_STREAM_H #include "pool.h" #define READBUFSZ 1024 #define WRITEBUFSZ 8192 typedef struct { int fd; /* fd for connection */ char *wbuf; /* write buffer for the connection */ int wbufsz; /* write buffer size */ int wbufpo; /* buffer offset */ char *hp; /* pending data buffer head address */ int po; /* pending data offset */ int bufsz; /* pending data buffer size */ int len; /* pending data length */ } PCP_CONNECTION; extern PCP_CONNECTION *pcp_open(int fd); extern void pcp_close(PCP_CONNECTION *pc); extern int pcp_read(PCP_CONNECTION *pc, void *buf, int len); extern int pcp_write(PCP_CONNECTION *pc, void *buf, int len); extern int pcp_flush(PCP_CONNECTION *pc); #define UNIX_DOMAIN_PATH "/tmp" #endif /* PCP_STREAM_H */ pgpool-II-3.3.2/pcp/pcp.c0000664000076400007640000010747712245576266012020 00000000000000/* * $Header$ * * Handles PCP connection, and protocol communication with pgpool-II * These are client APIs. Server program should use APIs in pcp_stream.c * * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include #include #include #include #include #include #include #include #include "pool.h" #include "pcp.h" #include "pcp_stream.h" #include "pool_process_reporting.h" #include "md5.h" struct timeval pcp_timeout; static PCP_CONNECTION *pc; #ifdef DEBUG static int debug = 1; #else static int debug = 0; #endif static int pcp_authorize(char *username, char *password); static int _pcp_detach_node(int nid, bool gracefully); static int _pcp_promote_node(int nid, bool gracefully); /* -------------------------------- * pcp_connect - open connection to pgpool using given arguments * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_connect(char *hostname, int port, char *username, char *password) { struct sockaddr_in addr; struct sockaddr_un unix_addr; struct hostent *hp; int fd; int on = 1; int len; if (pc != NULL) { if (debug) fprintf(stderr, "DEBUG: connection to backend \"%s\" already exists\n", hostname); return 0; } if (hostname == NULL || *hostname == '\0' || *hostname == '/') { char *path; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { if (debug) fprintf(stderr, "DEBUG: could not create socket\n"); errorcode = SOCKERR; return -1; } memset(&unix_addr, 0, sizeof(unix_addr)); unix_addr.sun_family = AF_UNIX; if (hostname == NULL || *hostname == '\0') { path = UNIX_DOMAIN_PATH; } else { path = hostname; } snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path), "%s/.s.PGSQL.%d", path, port); if (connect(fd, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) < 0) { if (debug) fprintf(stderr, "DEBUG: could not connect to \"%s\"\n", unix_addr.sun_path); close(fd); errorcode = CONNERR; return -1; } } else { fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { if (debug) fprintf(stderr, "DEBUG: could not create socket\n"); errorcode = SOCKERR; return -1; } if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) { if (debug) fprintf(stderr, "DEBUG: could not set socket option\n"); close(fd); errorcode = SOCKERR; return -1; } memset((char *) &addr, 0, sizeof(addr)); addr.sin_family = AF_INET; hp = gethostbyname(hostname); if ((hp == NULL) || (hp->h_addrtype != AF_INET)) { if (debug) fprintf(stderr, "DEBUG: could not retrieve hostname\n"); close(fd); errorcode = HOSTERR; return -1; } memmove((char *) &(addr.sin_addr), (char *) hp->h_addr, hp->h_length); addr.sin_port = htons(port); len = sizeof(struct sockaddr_in); if (connect(fd, (struct sockaddr *) &addr, len) < 0) { if (debug) fprintf(stderr, "DEBUG: could not connect to \"%s\"\n", hostname); close(fd); errorcode = CONNERR; return -1; } } pc = pcp_open(fd); if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: could not allocate buffer space\n"); close(fd); return -1; } if (pcp_authorize(username, password) < 0) { pcp_close(pc); pc = NULL; return -1; } return 0; } /* -------------------------------- * pcp_authorize - authenticate with pgpool using username and password * * return 0 on success, -1 otherwise * -------------------------------- */ static int pcp_authorize(char *username, char *password) { char tos; char *buf = NULL; int wsize; int rsize; char salt[4]; char encrypt_buf[(MD5_PASSWD_LEN+1)*2]; char md5[MD5_PASSWD_LEN+1]; /* request salt */ pcp_write(pc, "M", 1); wsize = htonl(sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return -1; } if (pcp_read(pc, &tos, 1)) return -1; if (pcp_read(pc, &rsize, sizeof(int))) return -1; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return -1; } if (pcp_read(pc, buf, rsize - sizeof(int))) return -1; memcpy(salt, buf, 4); free(buf); /* encrypt password */ pool_md5_hash(password, strlen(password), md5); md5[MD5_PASSWD_LEN] = '\0'; pool_md5_encrypt(md5, username, strlen(username), encrypt_buf + MD5_PASSWD_LEN + 1); encrypt_buf[(MD5_PASSWD_LEN+1)*2-1] = '\0'; pool_md5_encrypt(encrypt_buf+MD5_PASSWD_LEN+1, salt, 4, encrypt_buf); encrypt_buf[MD5_PASSWD_LEN] = '\0'; pcp_write(pc, "R", 1); wsize = htonl((strlen(username)+1 + strlen(encrypt_buf)+1) + sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); pcp_write(pc, username, strlen(username)+1); pcp_write(pc, encrypt_buf, strlen(encrypt_buf)+1); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return -1; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"R\", len=%d\n", ntohl(wsize)); if (pcp_read(pc, &tos, 1)) return -1; if (pcp_read(pc, &rsize, sizeof(int))) return -1; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return -1; } if (pcp_read(pc, buf, rsize - sizeof(int))) return -1; if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); errorcode = BACKENDERR; } else if (tos == 'r') { if (strcmp(buf, "AuthenticationOK") == 0) { free(buf); return 0; } if (debug) fprintf(stderr, "DEBUG: authentication failed. reason=%s\n", buf); errorcode = AUTHERR; } free(buf); return -1; } /* -------------------------------- * pcp_disconnect - close connection to pgpool * -------------------------------- */ void pcp_disconnect(void) { int wsize; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); return; } pcp_write(pc, "X", 1); wsize = htonl(sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); if (pcp_flush(pc) < 0) { /* backend had closed connection already */ } if (debug) fprintf(stderr, "DEBUG: send: tos=\"X\", len=%d\n", (int) sizeof(int)); pcp_close(pc); pc = NULL; } /* -------------------------------- * pcp_terminate_pgpool - send terminate packet * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_terminate_pgpool(char mode) { int wsize; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return -1; } pcp_write(pc, "T", 1); wsize = htonl(sizeof(int) + sizeof(char)); pcp_write(pc, &wsize, sizeof(int)); pcp_write(pc, &mode, sizeof(char)); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return -1; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"T\", len=%d\n", ntohl(wsize)); return 0; } /* -------------------------------- * pcp_node_count - get number of nodes currently connected to pgpool * * return array of node IDs on success, -1 otherwise * -------------------------------- */ int pcp_node_count(void) { char tos; char *buf = NULL; int wsize; int rsize; char *index = NULL; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return -1; } pcp_write(pc, "L", 1); wsize = htonl(sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return -1; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"L\", len=%d\n", ntohl(wsize)); if (pcp_read(pc, &tos, 1)) return -1; if (pcp_read(pc, &rsize, sizeof(int))) return -1; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return -1; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return -1; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); errorcode = BACKENDERR; } else if (tos == 'l') { if (strcmp(buf, "CommandComplete") == 0) { index = (char *) memchr(buf, '\0', rsize) + 1; if (index != NULL) { int ret = atoi(index); free(buf); return ret; } } } free(buf); return -1; } /* -------------------------------- * pcp_node_info - get information of node pointed by given argument * * return structure of node information on success, -1 otherwise * -------------------------------- */ BackendInfo * pcp_node_info(int nid) { int wsize; char node_id[16]; char tos; char *buf = NULL; int rsize; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return NULL; } snprintf(node_id, sizeof(node_id), "%d", nid); pcp_write(pc, "I", 1); wsize = htonl(strlen(node_id)+1 + sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); pcp_write(pc, node_id, strlen(node_id)+1); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return NULL; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"I\", len=%d\n", ntohl(wsize)); if (pcp_read(pc, &tos, 1)) return NULL; if (pcp_read(pc, &rsize, sizeof(int))) return NULL; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return NULL; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return NULL; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); errorcode = BACKENDERR; free(buf); return NULL; } else if (tos == 'i') { if (strcmp(buf, "CommandComplete") == 0) { char *index = NULL; BackendInfo* backend_info = NULL; backend_info = (BackendInfo *)malloc(sizeof(BackendInfo)); if (backend_info == NULL) { errorcode = NOMEMERR; free(buf); return NULL; } index = (char *) memchr(buf, '\0', rsize) + 1; if (index != NULL) strcpy(backend_info->backend_hostname, index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) backend_info->backend_port = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) backend_info->backend_status = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) backend_info->backend_weight = atof(index); free(buf); return backend_info; } } free(buf); return NULL; } /* -------------------------------- * pcp_node_count - get number of nodes currently connected to pgpool * * return array of pids on success, NULL otherwise * -------------------------------- */ int * pcp_process_count(int *pnum) { char tos; char *buf = NULL; int wsize; int rsize; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return NULL; } pcp_write(pc, "N", 1); wsize = htonl(sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return NULL; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"N\", len=%d\n", ntohl(wsize)); if (pcp_read(pc, &tos, 1)) return NULL; if (pcp_read(pc, &rsize, sizeof(int))) return NULL; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return NULL; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return NULL; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); free(buf); errorcode = BACKENDERR; return NULL; } else if (tos == 'n') { if (strcmp(buf, "CommandComplete") == 0) { int process_count; int *process_list = NULL; char *index = NULL; int i; index = (char *) memchr(buf, '\0', rsize) + 1; process_count = atoi(index); process_list = (int *)malloc(sizeof(int) * process_count); if (process_list == NULL) { free(buf); errorcode = NOMEMERR; return NULL; } for (i = 0; i < process_count; i++) { index = (char *) memchr(index, '\0', rsize) + 1; process_list[i] = atoi(index); } *pnum = process_count; free(buf); return process_list; } } free(buf); return NULL; } /* -------------------------------- * pcp_process_info - get information of node pointed by given argument * * return structure of process information on success, -1 otherwise * -------------------------------- */ ProcessInfo * pcp_process_info(int pid, int *array_size) { int wsize; char process_id[16]; char tos; char *buf = NULL; int rsize; ProcessInfo *process_info = NULL; ConnectionInfo *conn_info = NULL; int ci_size = 0; int offset = 0; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return NULL; } snprintf(process_id, sizeof(process_id), "%d", pid); pcp_write(pc, "P", 1); wsize = htonl(strlen(process_id)+1 + sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); pcp_write(pc, process_id, strlen(process_id)+1); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return NULL; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"P\", len=%d\n", ntohl(wsize)); while (1) { if (pcp_read(pc, &tos, 1)) return NULL; if (pcp_read(pc, &rsize, sizeof(int))) return NULL; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return NULL; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return NULL; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); free(buf); errorcode = BACKENDERR; return NULL; } else if (tos == 'p') { char *index; if (strcmp(buf, "ArraySize") == 0) { index = (char *) memchr(buf, '\0', rsize) + 1; if (index != NULL) ci_size = atoi(index); *array_size = ci_size; process_info = (ProcessInfo *)malloc(sizeof(ProcessInfo) * ci_size); if (process_info == NULL) { free(buf); errorcode = NOMEMERR; return NULL; } conn_info = (ConnectionInfo *)malloc(sizeof(ConnectionInfo) * ci_size); if (conn_info == NULL) { free(buf); free(process_info); errorcode = NOMEMERR; return NULL; } continue; } else if (strcmp(buf, "ProcessInfo") == 0) { process_info[offset].connection_info = &conn_info[offset]; index = (char *) memchr(buf, '\0', rsize) + 1; if (index != NULL) process_info[offset].pid = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) strcpy(process_info[offset].connection_info->database, index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) strcpy(process_info[offset].connection_info->user, index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) process_info[offset].start_time = atol(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) process_info[offset].connection_info->create_time = atol(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) process_info[offset].connection_info->major = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) process_info[offset].connection_info->minor = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) process_info[offset].connection_info->counter = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) process_info[offset].connection_info->backend_id = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) process_info[offset].connection_info->pid = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) process_info[offset].connection_info->connected = atoi(index); offset++; } else if (strcmp(buf, "CommandComplete") == 0) { free(buf); return process_info; } else { /* never reached */ } } } free(buf); return NULL; } /* -------------------------------- * pcp_systemdb_info - get information of system DB * * return structure of system DB information on success, -1 otherwise * -------------------------------- */ SystemDBInfo * pcp_systemdb_info(void) { char tos; char *buf = NULL; int wsize; int rsize; SystemDBInfo *systemdb_info = NULL; int offset = 0; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return NULL; } pcp_write(pc, "S", 1); wsize = htonl(sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return NULL; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"S\", len=%d\n", ntohl(wsize)); while (1) { if (pcp_read(pc, &tos, 1)) return NULL; if (pcp_read(pc, &rsize, sizeof(int))) return NULL; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return NULL; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return NULL; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); free(buf); errorcode = BACKENDERR; return NULL; } else if (tos == 's') { char *index; if (strcmp(buf, "SystemDBInfo") == 0) { systemdb_info = (SystemDBInfo *)malloc(sizeof(SystemDBInfo)); if (systemdb_info == NULL) { free(buf); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(buf, '\0', rsize) + 1; if (index != NULL) systemdb_info->hostname = strdup(index); if (systemdb_info->hostname == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) systemdb_info->port = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) systemdb_info->user = strdup(index); if (systemdb_info->user == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) systemdb_info->password = strdup(index); if (systemdb_info->password == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) systemdb_info->schema_name = strdup(index); if (systemdb_info->schema_name == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) systemdb_info->database_name = strdup(index); if (systemdb_info->database_name == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) systemdb_info->dist_def_num = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) systemdb_info->system_db_status = atoi(index); if (systemdb_info->dist_def_num > 0) { systemdb_info->dist_def_slot = NULL; systemdb_info->dist_def_slot = (DistDefInfo *)malloc(sizeof(DistDefInfo) * systemdb_info->dist_def_num); if (systemdb_info->dist_def_slot == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } } } else if (strcmp(buf, "DistDefInfo") == 0) { DistDefInfo *dist_def_info = NULL; int i; dist_def_info = (DistDefInfo *)malloc(sizeof(DistDefInfo)); if (dist_def_info == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(buf, '\0', rsize) + 1; if (index != NULL) dist_def_info->dbname = strdup(index); if (dist_def_info->dbname == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) dist_def_info->schema_name = strdup(index); if (dist_def_info->schema_name == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) dist_def_info->table_name = strdup(index); if (dist_def_info->table_name == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) dist_def_info->dist_key_col_name = strdup(index); if (dist_def_info->dist_key_col_name == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) dist_def_info->col_num = atoi(index); dist_def_info->col_list = NULL; dist_def_info->col_list = (char **)malloc(sizeof(char *) * dist_def_info->col_num); if (dist_def_info->col_list == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } for (i = 0; i < dist_def_info->col_num; i++) { index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) dist_def_info->col_list[i] = strdup(index); if (dist_def_info->col_list[i] == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } } dist_def_info->type_list = NULL; dist_def_info->type_list = (char **)malloc(sizeof(char *) * dist_def_info->col_num); if (dist_def_info->type_list == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } for (i = 0; i < dist_def_info->col_num; i++) { index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) dist_def_info->type_list[i] = strdup(index); if (dist_def_info->type_list[i] == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } } index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) dist_def_info->dist_def_func = strdup(index); if (dist_def_info->dist_def_func == NULL) { free(buf); free_systemdb_info(systemdb_info); errorcode = NOMEMERR; return NULL; } memcpy(&systemdb_info->dist_def_slot[offset++], dist_def_info, sizeof(DistDefInfo)); } else if (strcmp(buf, "CommandComplete") == 0) { free(buf); return systemdb_info; } else { /* never reached */ } } } free(buf); return NULL; } void free_systemdb_info(SystemDBInfo * si) { int i, j; free(si->hostname); free(si->user); free(si->password); free(si->schema_name); free(si->database_name); if (si->dist_def_slot != NULL) { for (i = 0; i < si->dist_def_num; i++) { DistDefInfo *di = &si->dist_def_slot[i]; free(di->dbname); free(di->schema_name); free(di->table_name); free(di->dist_def_func); for (j = 0; j < di->col_num; j++) { free(di->col_list[j]); free(di->type_list[j]); } } } free(si); } /* -------------------------------- * pcp_detach_node - detach a node given by the argument from pgpool's control * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_detach_node(int nid) { return _pcp_detach_node(nid, FALSE); } /* -------------------------------- * and detach a node given by the argument from pgpool's control * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_detach_node_gracefully(int nid) { return _pcp_detach_node(nid, TRUE); } static int _pcp_detach_node(int nid, bool gracefully) { int wsize; char node_id[16]; char tos; char *buf = NULL; int rsize; char *sendchar; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return -1; } snprintf(node_id, sizeof(node_id), "%d", nid); if (gracefully) sendchar = "d"; else sendchar = "D"; pcp_write(pc, sendchar, 1); wsize = htonl(strlen(node_id)+1 + sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); pcp_write(pc, node_id, strlen(node_id)+1); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return -1; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize)); if (pcp_read(pc, &tos, 1)) return -1; if (pcp_read(pc, &rsize, sizeof(int))) return -1; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return -1; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return -1; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); errorcode = BACKENDERR; } else if (tos == 'd') { /* strcmp() for success message, or fail */ if(strcmp(buf, "CommandComplete") == 0) { free(buf); return 0; } } free(buf); return -1; } /* -------------------------------- * pcp_attach_node - attach a node given by the argument from pgpool's control * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_attach_node(int nid) { int wsize; char node_id[16]; char tos; char *buf = NULL; int rsize; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return -1; } snprintf(node_id, sizeof(node_id), "%d", nid); pcp_write(pc, "C", 1); wsize = htonl(strlen(node_id)+1 + sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); pcp_write(pc, node_id, strlen(node_id)+1); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return -1; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize)); if (pcp_read(pc, &tos, 1)) return -1; if (pcp_read(pc, &rsize, sizeof(int))) return -1; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return -1; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return -1; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); errorcode = BACKENDERR; } else if (tos == 'c') { /* strcmp() for success message, or fail */ if(strcmp(buf, "CommandComplete") == 0) { free(buf); return 0; } } free(buf); return -1; } /* -------------------------------- * pcp_pool_status - return setup parameters and status * * returns and array of POOL_REPORT_CONFIG, NULL otherwise * -------------------------------- */ POOL_REPORT_CONFIG* pcp_pool_status(int *array_size) { char tos; char *buf = NULL; int wsize; int rsize; POOL_REPORT_CONFIG *status = NULL; int ci_size = 0; int offset = 0; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return NULL; } pcp_write(pc, "B", 1); wsize = htonl(sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return NULL; } if (debug) fprintf(stderr, "DEBUG pcp_pool_status: send: tos=\"B\", len=%d\n", ntohl(wsize)); while (1) { if (pcp_read(pc, &tos, 1)) return NULL; if (pcp_read(pc, &rsize, sizeof(int))) return NULL; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return NULL; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return NULL; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); free(buf); errorcode = BACKENDERR; return NULL; } else if (tos == 'b') { char *index; if (strcmp(buf, "ArraySize") == 0) { index = (char *) memchr(buf, '\0', rsize) + 1; ci_size = ntohl(*((int *)index)); *array_size = ci_size; status = (POOL_REPORT_CONFIG *) malloc(ci_size * sizeof(POOL_REPORT_CONFIG)); continue; } else if (strcmp(buf, "ProcessConfig") == 0) { index = (char *) memchr(buf, '\0', rsize) + 1; if (index != NULL) strcpy(status[offset].name, index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) strcpy(status[offset].value, index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) strcpy(status[offset].desc, index); offset++; } else if (strcmp(buf, "CommandComplete") == 0) { free(buf); return status; } else { /* never reached */ } } } free(buf); return NULL; } void pcp_set_timeout(long sec) { /* disable timeout (wait forever!) (2008/02/08 yamaguti) */ sec = 0; pcp_timeout.tv_sec = sec; } int pcp_recovery_node(int nid) { int wsize; char node_id[16]; char tos; char *buf = NULL; int rsize; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return -1; } snprintf(node_id, sizeof(node_id), "%d", nid); pcp_write(pc, "O", 1); wsize = htonl(strlen(node_id)+1 + sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); pcp_write(pc, node_id, strlen(node_id)+1); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return -1; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize)); if (pcp_read(pc, &tos, 1)) return -1; if (pcp_read(pc, &rsize, sizeof(int))) return -1; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return -1; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return -1; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); errorcode = BACKENDERR; } else if (tos == 'c') { /* strcmp() for success message, or fail */ if(strcmp(buf, "CommandComplete") == 0) { free(buf); return 0; } } free(buf); return -1; } void pcp_enable_debug(void) { debug = 1; } void pcp_disable_debug(void) { debug = 0; } /* -------------------------------- * pcp_promote_node - promote a node given by the argument as new pgpool's master * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_promote_node(int nid) { return _pcp_promote_node(nid, FALSE); } /* -------------------------------- * and promote a node given by the argument as new pgpool's master * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_promote_node_gracefully(int nid) { return _pcp_promote_node(nid, TRUE); } static int _pcp_promote_node(int nid, bool gracefully) { int wsize; char node_id[16]; char tos; char *buf = NULL; int rsize; char *sendchar; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return -1; } snprintf(node_id, sizeof(node_id), "%d", nid); if (gracefully) sendchar = "j"; else sendchar = "J"; pcp_write(pc, sendchar, 1); wsize = htonl(strlen(node_id)+1 + sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); pcp_write(pc, node_id, strlen(node_id)+1); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return -1; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"E\", len=%d\n", ntohl(wsize)); if (pcp_read(pc, &tos, 1)) return -1; if (pcp_read(pc, &rsize, sizeof(int))) return -1; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return -1; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return -1; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); errorcode = BACKENDERR; } else if (tos == 'd') { /* strcmp() for success message, or fail */ if(strcmp(buf, "CommandComplete") == 0) { free(buf); return 0; } } free(buf); return -1; } /* -------------------------------- * pcp_watchdog_info - get information of watchdog * * return structure of watchdog information on success, -1 otherwise * -------------------------------- */ WdInfo * pcp_watchdog_info(int nid) { int wsize; char wd_index[16]; char tos; char *buf = NULL; int rsize; if (pc == NULL) { if (debug) fprintf(stderr, "DEBUG: connection does not exist\n"); errorcode = NOCONNERR; return NULL; } snprintf(wd_index, sizeof(wd_index), "%d", nid); pcp_write(pc, "W", 1); wsize = htonl(strlen(wd_index)+1 + sizeof(int)); pcp_write(pc, &wsize, sizeof(int)); pcp_write(pc, wd_index, strlen(wd_index)+1); if (pcp_flush(pc) < 0) { if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n"); return NULL; } if (debug) fprintf(stderr, "DEBUG: send: tos=\"W\", len=%d\n", ntohl(wsize)); if (pcp_read(pc, &tos, 1)) return NULL; if (pcp_read(pc, &rsize, sizeof(int))) return NULL; rsize = ntohl(rsize); buf = (char *)malloc(rsize); if (buf == NULL) { errorcode = NOMEMERR; return NULL; } if (pcp_read(pc, buf, rsize - sizeof(int))) { free(buf); return NULL; } if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf); if (tos == 'e') { if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf); errorcode = BACKENDERR; free(buf); return NULL; } else if (tos == 'w') { if (strcmp(buf, "CommandComplete") == 0) { char *index = NULL; WdInfo* watchdog_info = NULL; watchdog_info = (WdInfo *)malloc(sizeof(WdInfo)); if (watchdog_info == NULL) { errorcode = NOMEMERR; free(buf); return NULL; } index = (char *) memchr(buf, '\0', rsize) + 1; if (index != NULL) strcpy(watchdog_info->hostname, index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) watchdog_info->pgpool_port = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) watchdog_info->wd_port = atoi(index); index = (char *) memchr(index, '\0', rsize) + 1; if (index != NULL) watchdog_info->status = atof(index); free(buf); return watchdog_info; } } free(buf); return NULL; } pgpool-II-3.3.2/pcp/md5.h0000664000076400007640000000133412245576256011710 00000000000000/*------------------------------------------------------------------------- * * md5.h * Interface to md5.c * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * $Header$ * *------------------------------------------------------------------------- */ /* * This file is imported from PostgreSQL 8.1.3. * Modified by Taiki Yamaguchi */ #ifndef MD5_H #define MD5_H #define MAX_USER_NAME_LEN 128 #define MD5_PASSWD_LEN 32 extern int pool_md5_hash(const void *buff, size_t len, char *hexsum); extern int pool_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf); #endif pgpool-II-3.3.2/pcp/pcp_attach_node.c0000664000076400007640000000733612245576256014341 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "attach node" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; int nodeID; int ch; int optindex; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hd", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (argc != 6) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); nodeID = atoi(argv[5]); if (nodeID < 0 || nodeID > MAX_NUM_BACKENDS) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if (pcp_attach_node(nodeID)) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_attach_node - attach a node from pgpool-II\n\n"); fprintf(stderr, "Usage: pcp_attach_node [-d] timeout hostname port# username password nodeID\n"); fprintf(stderr, "Usage: pcp_attach_node -h\n\n"); fprintf(stderr, " -d, --debug : enable debug message (optional)\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " nodeID : ID of a node to be attached\n"); fprintf(stderr, " -h, --help : print this help\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pcp/pcp.h0000664000076400007640000000352312245576266012010 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * * pcp.h - master header file. */ #ifndef PCP_H #define PCP_H #include "pool_type.h" #include "watchdog/watchdog.h" #define MAX_USER_PASSWD_LEN 128 typedef enum { UNKNOWNERR = 1, /* shouldn't happen */ EOFERR, /* EOF read by read() */ NOMEMERR, /* could not allocate memory */ READERR, /* read() error */ WRITEERR, /* flush() error */ TIMEOUTERR, /* select() timeout */ INVALERR, /* invalid command-line argument(s) number, length, range, etc. */ CONNERR, /* thrown by connect() */ NOCONNERR, /* not connected to server */ SOCKERR, /* thrown by socket() or setsockopt() */ HOSTERR, /* thrown by gethostbyname() */ BACKENDERR, /* server dependent error */ AUTHERR /* authorization failure */ } ErrorCode; /* -------------------------------- * pcp.c * -------------------------------- */ extern struct timeval pcp_timeout; /* ------------------------------ * pcp_error.c * ------------------------------ */ extern ErrorCode errorcode; extern void pcp_errorstr(ErrorCode e); #endif /* PCP_H */ pgpool-II-3.3.2/pcp/pcp_proc_info.c0000664000076400007640000001411712245576266014042 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "process info" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; int processID; ProcessInfo *process_info; int array_size; int ch; int optindex; char * frmt; bool verbose = false; bool all = false; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hdva", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'v': verbose = true; break; case 'a': all = true; break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (verbose) { if (all) frmt = "Database : %s\n" "Username : %s\n" "Start time : %s\n" "Creation time: %s\n" "Major : %d\n" "Minor : %d\n" "Counter : %d\n" "Backend PID : %d\n" "Connected : %d\n" "PID : %d\n" "Backend ID : %d\n"; else frmt = "Database : %s\n" "Username : %s\n" "Start time : %s\n" "Creation time: %s\n" "Major : %d\n" "Minor : %d\n" "Counter : %d\n" "Backend PID : %d\n" "Connected : %d\n"; } else { if (all) frmt = "%s %s %s %s %d %d %d %d %d %d %d\n"; else frmt = "%s %s %s %s %d %d %d %d %d\n"; } if (!(argc == 5 || argc == 6)) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); if (argc == 6) { processID = atoi(argv[5]); if (processID < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } } else { processID = 0; } pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if ((process_info = pcp_process_info(processID, &array_size)) == NULL) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } else { int i; char strcreatetime[128]; char strstarttime[128]; for (i = 0; i < array_size; i++) { if ((!all) && (process_info[i].connection_info->database[0] == '\0')) continue; *strcreatetime = *strstarttime = '\0'; if (process_info[i].start_time) strftime(strstarttime, 128, "%Y-%m-%d %H:%M:%S", localtime(&process_info[i].start_time)); if (process_info[i].connection_info->create_time) strftime(strcreatetime, 128, "%Y-%m-%d %H:%M:%S", localtime(&process_info[i].connection_info->create_time)); printf(frmt, process_info[i].connection_info->database, process_info[i].connection_info->user, strstarttime, strcreatetime, process_info[i].connection_info->major, process_info[i].connection_info->minor, process_info[i].connection_info->counter, process_info[i].connection_info->pid, process_info[i].connection_info->connected, process_info[i].pid, process_info[i].connection_info->backend_id); } free(process_info->connection_info); free(process_info); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_proc_info - display a pgpool-II child process' information\n\n"); fprintf(stderr, "Usage: pcp_proc_info [-d] timeout hostname port# username password [PID]\n"); fprintf(stderr, " -d, --debug : enable debug message (optional)\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " PID : if given, PID of the only child process to get information for\n\n"); fprintf(stderr, "Usage: pcp_proc_info [options]\n"); fprintf(stderr, " Options available are:\n"); fprintf(stderr, " -h, --help : print this help\n"); fprintf(stderr, " -v, --verbose : display one line per information with a header\n"); fprintf(stderr, " -a, --all : display all child processes and their available connection slots.\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pcp/pcp_stream.c0000664000076400007640000001745712245576266013371 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2010 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * PCP buffer management module. */ #include #include #include #include #include #include #include #include #include "pcp.h" #include "pcp_stream.h" static int consume_pending_data(PCP_CONNECTION *pc, void *data, int len); static int save_pending_data(PCP_CONNECTION *pc, void *data, int len); static int pcp_check_fd(PCP_CONNECTION *pc, int notimeout); /* -------------------------------- * pcp_open - allocate read & write buffers for PCP_CONNECTION * * return newly allocated PCP_CONNECTION on success, NULL if malloc() fails * -------------------------------- */ PCP_CONNECTION * pcp_open(int fd) { PCP_CONNECTION *pc; pc = (PCP_CONNECTION *)malloc(sizeof(PCP_CONNECTION)); if (pc == NULL) { errorcode = NOMEMERR; return NULL; } memset(pc, 0, sizeof(*pc)); /* initialize write buffer */ pc->wbuf = malloc(WRITEBUFSZ); if (pc->wbuf == NULL) return NULL; pc->wbufsz = WRITEBUFSZ; pc->wbufpo = 0; /* initialize pending data buffer */ pc->hp = malloc(READBUFSZ); if (pc->hp == NULL) { errorcode = NOMEMERR; return NULL; } pc->bufsz = READBUFSZ; pc->po = 0; pc->len = 0; pc->fd = fd; return pc; } /* -------------------------------- * pcp_close - deallocate read & write buffers for PCP_CONNECTION * -------------------------------- */ void pcp_close(PCP_CONNECTION *pc) { close(pc->fd); free(pc->wbuf); free(pc->hp); free(pc); } /* -------------------------------- * pcp_read - read 'len' bytes from 'pc' * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_read(PCP_CONNECTION *pc, void *buf, int len) { static char readbuf[READBUFSZ]; int consume_size; int readlen; int notimeout = 0; consume_size = consume_pending_data(pc, buf, len); len -= consume_size; buf += consume_size; while (len > 0) { if (pcp_check_fd(pc, notimeout)) { errorcode = TIMEOUTERR; return -1; } readlen = read(pc->fd, readbuf, READBUFSZ); if (readlen == -1) { if (errno == EAGAIN || errno == EINTR) continue; errorcode = READERR; return -1; } else if (readlen == 0) { errorcode = EOFERR; return -1; } if (len < readlen) { /* overrun. we need to save remaining data to pending buffer */ if (save_pending_data(pc, readbuf+len, readlen-len)) { errorcode = NOMEMERR; return -1; } memmove(buf, readbuf, len); break; } memmove(buf, readbuf, readlen); buf += readlen; len -= readlen; } return 0; } /* -------------------------------- * pcp_write - write 'len' bytes to 'pc' buffer * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_write(PCP_CONNECTION *pc, void *buf, int len) { int reqlen; if (len < 0) { errorcode = INVALERR; return -1; } /* check buffer size */ reqlen = pc->wbufpo + len; if (reqlen > pc->wbufsz) { char *p; reqlen = (reqlen/WRITEBUFSZ+1)*WRITEBUFSZ; p = realloc(pc->wbuf, reqlen); if (p == NULL) { errorcode = NOMEMERR; return -1; } pc->wbuf = p; pc->wbufsz = reqlen; } memcpy(pc->wbuf+pc->wbufpo, buf, len); pc->wbufpo += len; return 0; } /* -------------------------------- * pcp_flush - send pending data in buffer to 'pc' * * return 0 on success, -1 otherwise * -------------------------------- */ int pcp_flush(PCP_CONNECTION *pc) { int sts; int wlen; int offset; wlen = pc->wbufpo; if (wlen == 0) { return 0; } offset = 0; for (;;) { errno = 0; sts = write(pc->fd, pc->wbuf + offset, wlen); if (sts > 0) { wlen -= sts; if (wlen == 0) { /* write completed */ break; } else if (wlen < 0) { errorcode = WRITEERR; return -1; } else { /* need to write remaining data */ offset += sts; continue; } } else if (errno == EAGAIN || errno == EINTR) { continue; } else { errorcode = WRITEERR; return -1; } } pc->wbufpo = 0; return 0; } /* -------------------------------- * consume_pending_data - read pending data from 'pc' buffer * * return the size of data read in * -------------------------------- */ static int consume_pending_data(PCP_CONNECTION *pc, void *data, int len) { int consume_size; if (pc->len <= 0) return 0; consume_size = Min(len, pc->len); memmove(data, pc->hp + pc->po, consume_size); pc->len -= consume_size; if (pc->len <= 0) pc->po = 0; else pc->po += consume_size; return consume_size; } /* -------------------------------- * save_pending_data - save excessively read data into 'pc' buffer * * return 0 on success, -1 otherwise * -------------------------------- */ static int save_pending_data(PCP_CONNECTION *pc, void *data, int len) { int reqlen; size_t realloc_size; char *p; /* to be safe */ if (pc->len == 0) pc->po = 0; reqlen = pc->po + pc->len + len; /* pending buffer is enough? */ if (reqlen > pc->bufsz) { /* too small, enlarge it */ realloc_size = (reqlen/READBUFSZ+1)*READBUFSZ; p = realloc(pc->hp, realloc_size); if (p == NULL) { errorcode = NOMEMERR; return -1; } pc->bufsz = realloc_size; pc->hp = p; } memmove(pc->hp + pc->po + pc->len, data, len); pc->len += len; return 0; } /* -------------------------------- * pcp_check_fd - watch for fd which is ready to be read * * return 0 on success, -1 otherwise * -------------------------------- */ static int pcp_check_fd(PCP_CONNECTION *pc, int notimeout) { fd_set readmask; fd_set exceptmask; int fd; int fds; struct timeval timeout; struct timeval *tp; fd = pc->fd; for (;;) { FD_ZERO(&readmask); FD_ZERO(&exceptmask); FD_SET(fd, &readmask); FD_SET(fd, &exceptmask); if (notimeout || (pcp_timeout.tv_sec + pcp_timeout.tv_usec) == 0) tp = NULL; else { /***** haven't got timeout option yet. hard-code it *****/ timeout.tv_sec = pcp_timeout.tv_sec; timeout.tv_usec = pcp_timeout.tv_usec; tp = &timeout; } fds = select(fd+1, &readmask, NULL, &exceptmask, tp); if (fds == -1) { if (errno == EAGAIN || errno == EINTR) continue; break; } if (FD_ISSET(fd, &exceptmask)) break; if (fds == 0) break; return 0; } return -1; } pgpool-II-3.3.2/pcp/pcp_node_count.c0000664000076400007640000000711212245576256014215 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "node count" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; int node_count; int ch; int optindex; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hd", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (argc != 5) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if ((node_count = pcp_node_count()) < 0) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } else { printf("%d\n", node_count); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_node_count - display the total number of nodes under pgpool-II's control\n\n"); fprintf(stderr, "Usage: pcp_node_count [-d] timeout hostname port# username password\n"); fprintf(stderr, "Usage: pcp_node_count -h\n\n"); fprintf(stderr, " -d, --debug : enable debug message (optional)\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " -h, --help : print this help\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pcp/Makefile.in0000664000076400007640000007331212245776600013117 00000000000000# Makefile.in generated by automake 1.11.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = pcp_stop_pgpool$(EXEEXT) pcp_node_count$(EXEEXT) \ pcp_node_info$(EXEEXT) pcp_proc_count$(EXEEXT) \ pcp_proc_info$(EXEEXT) pcp_systemdb_info$(EXEEXT) \ pcp_detach_node$(EXEEXT) pcp_attach_node$(EXEEXT) \ pcp_recovery_node$(EXEEXT) pcp_promote_node$(EXEEXT) \ pcp_pool_status$(EXEEXT) pcp_watchdog_info$(EXEEXT) subdir = pcp DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/c-compiler.m4 $(top_srcdir)/c-library.m4 \ $(top_srcdir)/general.m4 \ $(top_srcdir)/ac_func_accept_argtypes.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libpcp_la_LIBADD = am_libpcp_la_OBJECTS = pcp.lo pcp_stream.lo pcp_error.lo md5.lo libpcp_la_OBJECTS = $(am_libpcp_la_OBJECTS) PROGRAMS = $(bin_PROGRAMS) am_pcp_attach_node_OBJECTS = pcp_attach_node.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_attach_node_OBJECTS = $(am_pcp_attach_node_OBJECTS) pcp_attach_node_DEPENDENCIES = libpcp.la am_pcp_detach_node_OBJECTS = pcp_detach_node.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_detach_node_OBJECTS = $(am_pcp_detach_node_OBJECTS) pcp_detach_node_DEPENDENCIES = libpcp.la am_pcp_node_count_OBJECTS = pcp_node_count.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_node_count_OBJECTS = $(am_pcp_node_count_OBJECTS) pcp_node_count_DEPENDENCIES = libpcp.la am_pcp_node_info_OBJECTS = pcp_node_info.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_node_info_OBJECTS = $(am_pcp_node_info_OBJECTS) pcp_node_info_DEPENDENCIES = libpcp.la am_pcp_pool_status_OBJECTS = pcp_pool_status.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_pool_status_OBJECTS = $(am_pcp_pool_status_OBJECTS) pcp_pool_status_DEPENDENCIES = libpcp.la am_pcp_proc_count_OBJECTS = pcp_proc_count.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_proc_count_OBJECTS = $(am_pcp_proc_count_OBJECTS) pcp_proc_count_DEPENDENCIES = libpcp.la am_pcp_proc_info_OBJECTS = pcp_proc_info.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_proc_info_OBJECTS = $(am_pcp_proc_info_OBJECTS) pcp_proc_info_DEPENDENCIES = libpcp.la am_pcp_promote_node_OBJECTS = pcp_promote_node.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_promote_node_OBJECTS = $(am_pcp_promote_node_OBJECTS) pcp_promote_node_DEPENDENCIES = libpcp.la am_pcp_recovery_node_OBJECTS = pcp_recovery_node.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_recovery_node_OBJECTS = $(am_pcp_recovery_node_OBJECTS) pcp_recovery_node_DEPENDENCIES = libpcp.la am_pcp_stop_pgpool_OBJECTS = pcp_stop_pgpool.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_stop_pgpool_OBJECTS = $(am_pcp_stop_pgpool_OBJECTS) pcp_stop_pgpool_DEPENDENCIES = libpcp.la pcp_stop_pgpool_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pcp_stop_pgpool_LDFLAGS) $(LDFLAGS) -o $@ am_pcp_systemdb_info_OBJECTS = pcp_systemdb_info.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_systemdb_info_OBJECTS = $(am_pcp_systemdb_info_OBJECTS) pcp_systemdb_info_DEPENDENCIES = libpcp.la am_pcp_watchdog_info_OBJECTS = pcp_watchdog_info.$(OBJEXT) \ getopt_long.$(OBJEXT) pcp_watchdog_info_OBJECTS = $(am_pcp_watchdog_info_OBJECTS) pcp_watchdog_info_DEPENDENCIES = libpcp.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libpcp_la_SOURCES) $(pcp_attach_node_SOURCES) \ $(pcp_detach_node_SOURCES) $(pcp_node_count_SOURCES) \ $(pcp_node_info_SOURCES) $(pcp_pool_status_SOURCES) \ $(pcp_proc_count_SOURCES) $(pcp_proc_info_SOURCES) \ $(pcp_promote_node_SOURCES) $(pcp_recovery_node_SOURCES) \ $(pcp_stop_pgpool_SOURCES) $(pcp_systemdb_info_SOURCES) \ $(pcp_watchdog_info_SOURCES) DIST_SOURCES = $(libpcp_la_SOURCES) $(pcp_attach_node_SOURCES) \ $(pcp_detach_node_SOURCES) $(pcp_node_count_SOURCES) \ $(pcp_node_info_SOURCES) $(pcp_pool_status_SOURCES) \ $(pcp_proc_count_SOURCES) $(pcp_proc_info_SOURCES) \ $(pcp_promote_node_SOURCES) $(pcp_recovery_node_SOURCES) \ $(pcp_stop_pgpool_SOURCES) $(pcp_systemdb_info_SOURCES) \ $(pcp_watchdog_info_SOURCES) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MEMCACHED_DIR = @MEMCACHED_DIR@ MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PGCONFIG = @PGCONFIG@ PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -D_GNU_SOURCE -I .. -I @PGSQL_INCLUDE_DIR@ lib_LTLIBRARIES = libpcp.la libpcp_la_SOURCES = pcp.h ../pool_type.h md5.h pcp.c pcp_stream.h pcp_stream.c pcp_error.c md5.c libpcp_la_LIBS = include_HEADERS = pcp.h libpcp_ext.h ../pool_type.h ../pool_process_reporting.h pcp_stop_pgpool_SOURCES = pcp_stop_pgpool.c pcp.h ../getopt_long.c ../getopt_long.h pcp_stop_pgpool_LDADD = libpcp.la pcp_stop_pgpool_LDFLAGS = pcp_node_count_SOURCES = pcp_node_count.c pcp.h ../getopt_long.c ../getopt_long.h pcp_node_count_LDADD = libpcp.la pcp_node_info_SOURCES = pcp_node_info.c pcp.h ../getopt_long.c ../getopt_long.h pcp_node_info_LDADD = libpcp.la pcp_proc_count_SOURCES = pcp_proc_count.c pcp.h ../getopt_long.c ../getopt_long.h pcp_proc_count_LDADD = libpcp.la pcp_proc_info_SOURCES = pcp_proc_info.c pcp.h ../getopt_long.c ../getopt_long.h pcp_proc_info_LDADD = libpcp.la pcp_systemdb_info_SOURCES = pcp_systemdb_info.c pcp.h ../getopt_long.c ../getopt_long.h pcp_systemdb_info_LDADD = libpcp.la pcp_detach_node_SOURCES = pcp_detach_node.c pcp.h ../getopt_long.c ../getopt_long.h pcp_detach_node_LDADD = libpcp.la pcp_attach_node_SOURCES = pcp_attach_node.c pcp.h ../getopt_long.c ../getopt_long.h pcp_attach_node_LDADD = libpcp.la pcp_recovery_node_SOURCES = pcp_recovery_node.c pcp.h ../getopt_long.c ../getopt_long.h pcp_recovery_node_LDADD = libpcp.la pcp_pool_status_SOURCES = pcp_pool_status.c pcp.h ../getopt_long.c ../getopt_long.h pcp_pool_status_LDADD = libpcp.la pcp_promote_node_SOURCES = pcp_promote_node.c pcp.h ../getopt_long.c ../getopt_long.h pcp_promote_node_LDADD = libpcp.la pcp_watchdog_info_SOURCES = pcp_watchdog_info.c pcp.h ../getopt_long.c ../getopt_long.h pcp_watchdog_info_LDADD = libpcp.la all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pcp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pcp/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libpcp.la: $(libpcp_la_OBJECTS) $(libpcp_la_DEPENDENCIES) $(LINK) -rpath $(libdir) $(libpcp_la_OBJECTS) $(libpcp_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list pcp_attach_node$(EXEEXT): $(pcp_attach_node_OBJECTS) $(pcp_attach_node_DEPENDENCIES) @rm -f pcp_attach_node$(EXEEXT) $(LINK) $(pcp_attach_node_OBJECTS) $(pcp_attach_node_LDADD) $(LIBS) pcp_detach_node$(EXEEXT): $(pcp_detach_node_OBJECTS) $(pcp_detach_node_DEPENDENCIES) @rm -f pcp_detach_node$(EXEEXT) $(LINK) $(pcp_detach_node_OBJECTS) $(pcp_detach_node_LDADD) $(LIBS) pcp_node_count$(EXEEXT): $(pcp_node_count_OBJECTS) $(pcp_node_count_DEPENDENCIES) @rm -f pcp_node_count$(EXEEXT) $(LINK) $(pcp_node_count_OBJECTS) $(pcp_node_count_LDADD) $(LIBS) pcp_node_info$(EXEEXT): $(pcp_node_info_OBJECTS) $(pcp_node_info_DEPENDENCIES) @rm -f pcp_node_info$(EXEEXT) $(LINK) $(pcp_node_info_OBJECTS) $(pcp_node_info_LDADD) $(LIBS) pcp_pool_status$(EXEEXT): $(pcp_pool_status_OBJECTS) $(pcp_pool_status_DEPENDENCIES) @rm -f pcp_pool_status$(EXEEXT) $(LINK) $(pcp_pool_status_OBJECTS) $(pcp_pool_status_LDADD) $(LIBS) pcp_proc_count$(EXEEXT): $(pcp_proc_count_OBJECTS) $(pcp_proc_count_DEPENDENCIES) @rm -f pcp_proc_count$(EXEEXT) $(LINK) $(pcp_proc_count_OBJECTS) $(pcp_proc_count_LDADD) $(LIBS) pcp_proc_info$(EXEEXT): $(pcp_proc_info_OBJECTS) $(pcp_proc_info_DEPENDENCIES) @rm -f pcp_proc_info$(EXEEXT) $(LINK) $(pcp_proc_info_OBJECTS) $(pcp_proc_info_LDADD) $(LIBS) pcp_promote_node$(EXEEXT): $(pcp_promote_node_OBJECTS) $(pcp_promote_node_DEPENDENCIES) @rm -f pcp_promote_node$(EXEEXT) $(LINK) $(pcp_promote_node_OBJECTS) $(pcp_promote_node_LDADD) $(LIBS) pcp_recovery_node$(EXEEXT): $(pcp_recovery_node_OBJECTS) $(pcp_recovery_node_DEPENDENCIES) @rm -f pcp_recovery_node$(EXEEXT) $(LINK) $(pcp_recovery_node_OBJECTS) $(pcp_recovery_node_LDADD) $(LIBS) pcp_stop_pgpool$(EXEEXT): $(pcp_stop_pgpool_OBJECTS) $(pcp_stop_pgpool_DEPENDENCIES) @rm -f pcp_stop_pgpool$(EXEEXT) $(pcp_stop_pgpool_LINK) $(pcp_stop_pgpool_OBJECTS) $(pcp_stop_pgpool_LDADD) $(LIBS) pcp_systemdb_info$(EXEEXT): $(pcp_systemdb_info_OBJECTS) $(pcp_systemdb_info_DEPENDENCIES) @rm -f pcp_systemdb_info$(EXEEXT) $(LINK) $(pcp_systemdb_info_OBJECTS) $(pcp_systemdb_info_LDADD) $(LIBS) pcp_watchdog_info$(EXEEXT): $(pcp_watchdog_info_OBJECTS) $(pcp_watchdog_info_DEPENDENCIES) @rm -f pcp_watchdog_info$(EXEEXT) $(LINK) $(pcp_watchdog_info_OBJECTS) $(pcp_watchdog_info_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt_long.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_attach_node.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_detach_node.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_node_count.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_node_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_pool_status.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_proc_count.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_proc_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_promote_node.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_recovery_node.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_stop_pgpool.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_stream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_systemdb_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_watchdog_info.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< getopt_long.o: ../getopt_long.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getopt_long.o -MD -MP -MF $(DEPDIR)/getopt_long.Tpo -c -o getopt_long.o `test -f '../getopt_long.c' || echo '$(srcdir)/'`../getopt_long.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/getopt_long.Tpo $(DEPDIR)/getopt_long.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../getopt_long.c' object='getopt_long.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getopt_long.o `test -f '../getopt_long.c' || echo '$(srcdir)/'`../getopt_long.c getopt_long.obj: ../getopt_long.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getopt_long.obj -MD -MP -MF $(DEPDIR)/getopt_long.Tpo -c -o getopt_long.obj `if test -f '../getopt_long.c'; then $(CYGPATH_W) '../getopt_long.c'; else $(CYGPATH_W) '$(srcdir)/../getopt_long.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/getopt_long.Tpo $(DEPDIR)/getopt_long.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../getopt_long.c' object='getopt_long.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getopt_long.obj `if test -f '../getopt_long.c'; then $(CYGPATH_W) '../getopt_long.c'; else $(CYGPATH_W) '$(srcdir)/../getopt_long.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) install-binPROGRAMS: install-libLTLIBRARIES installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-includeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \ uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libLTLIBRARIES clean-libtool ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-includeHEADERS install-info install-info-am \ install-libLTLIBRARIES install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-includeHEADERS uninstall-libLTLIBRARIES md5.c: ../md5.c rm -f $@ && ln -s $< . md5.h: ../md5.h rm -f $@ && ln -s $< . # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: pgpool-II-3.3.2/pcp/pcp_error.c0000664000076400007640000000350612245576256013214 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Handles errors occured in PCP modules. */ #include #include "pcp.h" ErrorCode errorcode; void pcp_errorstr(ErrorCode e) { switch (e) { case EOFERR: fprintf(stdout, "EOFError\n"); break; case NOMEMERR: fprintf(stdout, "NoMemoryError\n"); break; case READERR: fprintf(stdout, "ReadError\n"); break; case WRITEERR: fprintf(stdout, "WriteError\n"); break; case TIMEOUTERR: fprintf(stdout, "TimeoutError\n"); break; case INVALERR: fprintf(stdout, "InvalidArgumentError\n"); break; case CONNERR: fprintf(stdout, "ConnectionError\n"); break; case NOCONNERR: fprintf(stdout, "NoConnectionError\n"); break; case SOCKERR: fprintf(stdout, "SocketError\n"); break; case HOSTERR: fprintf(stdout, "HostError\n"); break; case BACKENDERR: fprintf(stdout, "BackendError\n"); break; case AUTHERR: fprintf(stdout, "AuthorizationError\n"); break; case UNKNOWNERR: default: fprintf(stdout, "UnknownError\n"); break; } } pgpool-II-3.3.2/pcp/pcp_proc_count.c0000664000076400007640000000720212245576256014233 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "process count" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; int process_count; int *process_list = NULL; int ch; int optindex; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hd", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (argc != 5) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if ((process_list = pcp_process_count(&process_count)) == NULL) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } else { int i; for (i = 0; i < process_count; i++) printf("%d ", process_list[i]); printf("\n"); free(process_list); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_proc_count - display the list of pgpool-II child process PIDs\n\n"); fprintf(stderr, "Usage: pcp_proc_count timeout hostname port# username password\n"); fprintf(stderr, "Usage: pcp_node_info -h\n\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " -h, --help : print this help\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pcp/pcp_node_info.c0000664000076400007640000001111012245576256014011 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "node info" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; int nodeID; BackendInfo *backend_info; int ch; int optindex; bool verbose = false; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hdv", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'v': verbose = true; break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (argc != 6) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); nodeID = atoi(argv[5]); if (nodeID < 0 || nodeID > MAX_NUM_BACKENDS) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if ((backend_info = pcp_node_info(nodeID)) == NULL) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } else { if (verbose) { printf("Hostname: %s\nPort : %d\nStatus : %d\nWeight : %f\n", backend_info->backend_hostname, backend_info->backend_port, backend_info->backend_status, backend_info->backend_weight/RAND_MAX); } else { printf("%s %d %d %f\n", backend_info->backend_hostname, backend_info->backend_port, backend_info->backend_status, backend_info->backend_weight/RAND_MAX); } free(backend_info); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_node_info - display a pgpool-II node's information\n\n"); fprintf(stderr, "Usage: pcp_node_info [-d] timeout hostname port# username password nodeID\n"); fprintf(stderr, " -d, --debug : enable debug message (optional)\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " nodeID : ID of a node to get information for\n\n"); fprintf(stderr, "Usage: pcp_node_info [options]\n"); fprintf(stderr, " Options available are:\n"); fprintf(stderr, " -h, --help : print this help\n"); fprintf(stderr, " -v, --verbose : display one line per information with a header\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pcp/pcp_pool_status.c0000664000076400007640000000735012245576266014441 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2011 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "pool status" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; POOL_REPORT_CONFIG *status; int ch; int i; int optindex; int array_size = 0; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hd", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (argc != 5) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if ((status = pcp_pool_status(&array_size)) == NULL) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } else { for (i=0; i #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; int nodeID; int ch; int optindex; bool gracefully = false; int sts; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"gracefully", no_argument, NULL, 'g'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hdg", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'g': gracefully = true; break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (argc != 6) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); nodeID = atoi(argv[5]); if (nodeID < 0 || nodeID > MAX_NUM_BACKENDS) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if (gracefully) sts = pcp_promote_node_gracefully(nodeID); else sts = pcp_promote_node(nodeID); if (sts) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_promote_node - promote a node as new master from pgpool-II\n\n"); fprintf(stderr, "Usage: pcp_promote_node [-d][-g] timeout hostname port# username password nodeID\n"); fprintf(stderr, "Usage: pcp_promote_node -h\n\n"); fprintf(stderr, " -d, --debug : enable debug message (optional)\n"); fprintf(stderr, " -g, --gracefully : promote gracefully(optional)\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " nodeID : ID of a node to be promoted\n"); fprintf(stderr, " -h, --help : print this help\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pcp/pcp_watchdog_info.c0000664000076400007640000001133012245576266014671 00000000000000/* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * Client program to send "watchdog info" command. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt_long.h" #endif #include "pcp.h" static void usage(void); static void myexit(ErrorCode e); int main(int argc, char **argv) { long timeout; char host[MAX_DB_HOST_NAMELEN]; int port; char user[MAX_USER_PASSWD_LEN]; char pass[MAX_USER_PASSWD_LEN]; int wd_index; WdInfo *watchdog_info; int ch; int optindex; bool verbose = false; static struct option long_options[] = { {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; while ((ch = getopt_long(argc, argv, "hdv", long_options, &optindex)) != -1) { switch (ch) { case 'd': pcp_enable_debug(); break; case 'v': verbose = true; break; case 'h': case '?': default: usage(); exit(0); } } argc -= optind; argv += optind; if (!(argc == 5 || argc == 6)) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } timeout = atol(argv[0]); if (timeout < 0) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(host, argv[1]); port = atoi(argv[2]); if (port <= 1024 || port > 65535) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(user, argv[3]); if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } strcpy(pass, argv[4]); if (argc == 6) { wd_index = atoi(argv[5]); if (wd_index < 0 || wd_index > MAX_WATCHDOG_NUM) { errorcode = INVALERR; pcp_errorstr(errorcode); myexit(errorcode); } wd_index++; } else { wd_index = 0; } pcp_set_timeout(timeout); if (pcp_connect(host, port, user, pass)) { pcp_errorstr(errorcode); myexit(errorcode); } if ((watchdog_info = pcp_watchdog_info(wd_index)) == NULL) { pcp_errorstr(errorcode); pcp_disconnect(); myexit(errorcode); } else { if (verbose) { printf("Hostname : %s\nPgpool port : %d\nWatchdog port: %d\nStatus : %d\n", watchdog_info->hostname, watchdog_info->pgpool_port, watchdog_info->wd_port, watchdog_info->status); } else { printf("%s %d %d %d\n", watchdog_info->hostname, watchdog_info->pgpool_port, watchdog_info->wd_port, watchdog_info->status); } free(watchdog_info); } pcp_disconnect(); return 0; } static void usage(void) { fprintf(stderr, "pcp_watchdog_info - display a pgpool-II watchdog's information\n\n"); fprintf(stderr, "Usage: pcp_watchdog_info [-d] timeout hostname port# username password [watchdogID]\n"); fprintf(stderr, " -d, --debug : enable debug message (optional)\n"); fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n"); fprintf(stderr, " hostname : pgpool-II hostname\n"); fprintf(stderr, " port# : PCP port number\n"); fprintf(stderr, " username : username for PCP authentication\n"); fprintf(stderr, " password : password for PCP authentication\n"); fprintf(stderr, " watchdogID : ID of a other pgpool to get information for\n"); fprintf(stderr, " If omitted then get one's self information\n\n"); fprintf(stderr, "Usage: pcp_watchdog_info [options]\n"); fprintf(stderr, " Options available are:\n"); fprintf(stderr, " -h, --help : print this help\n"); fprintf(stderr, " -v, --verbose : display one line per information with a header\n"); } static void myexit(ErrorCode e) { if (e == INVALERR) { usage(); exit(e); } exit(e); } pgpool-II-3.3.2/pool_config.c0000664000076400007640000036525612245576266012753 00000000000000 #line 3 "pool_config.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define yywrap(n) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 11 #define YY_END_OF_BUFFER 12 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[38] = { 0, 0, 0, 12, 10, 2, 1, 10, 10, 10, 8, 7, 7, 9, 4, 2, 0, 3, 0, 5, 0, 8, 7, 7, 8, 0, 0, 6, 4, 4, 0, 5, 0, 0, 8, 7, 6, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 4, 1, 1, 1, 5, 1, 1, 1, 6, 1, 7, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 9, 1, 1, 12, 1, 1, 1, 13, 13, 13, 13, 14, 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 16, 1, 1, 17, 1, 13, 13, 13, 13, 14, 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 15, 15, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 } ; static yyconst flex_int32_t yy_meta[19] = { 0, 1, 1, 2, 1, 1, 1, 3, 3, 3, 4, 4, 1, 5, 4, 3, 1, 3, 3 } ; static yyconst flex_int16_t yy_base[45] = { 0, 0, 0, 61, 86, 58, 86, 55, 14, 23, 43, 10, 46, 86, 28, 47, 40, 86, 16, 86, 22, 28, 0, 0, 0, 40, 0, 24, 45, 0, 24, 39, 43, 12, 14, 0, 22, 86, 62, 67, 22, 70, 75, 77, 80 } ; static yyconst flex_int16_t yy_def[45] = { 0, 37, 1, 37, 37, 37, 37, 38, 39, 37, 40, 9, 9, 37, 41, 37, 38, 37, 39, 37, 42, 40, 11, 12, 21, 37, 43, 44, 41, 28, 39, 39, 42, 37, 37, 43, 44, 0, 37, 37, 37, 37, 37, 37, 37 } ; static yyconst flex_int16_t yy_nxt[105] = { 0, 4, 5, 6, 7, 8, 9, 9, 10, 4, 11, 12, 13, 14, 14, 14, 4, 14, 14, 19, 23, 19, 34, 34, 34, 34, 24, 31, 26, 19, 20, 21, 20, 22, 23, 27, 27, 27, 32, 36, 20, 36, 25, 17, 19, 29, 33, 33, 31, 15, 34, 34, 27, 27, 27, 20, 23, 25, 17, 32, 15, 37, 29, 16, 16, 16, 16, 16, 18, 37, 18, 18, 18, 28, 28, 28, 30, 37, 30, 30, 30, 35, 35, 27, 27, 27, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37 } ; static yyconst flex_int16_t yy_chk[105] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 11, 18, 33, 33, 34, 34, 40, 20, 11, 30, 8, 9, 18, 9, 9, 14, 14, 14, 20, 36, 30, 27, 21, 16, 31, 14, 25, 25, 32, 15, 25, 25, 28, 28, 28, 31, 12, 10, 7, 32, 5, 3, 28, 38, 38, 38, 38, 38, 39, 0, 39, 39, 39, 41, 41, 41, 42, 0, 42, 42, 42, 43, 43, 44, 44, 44, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "pool_config.l" /* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_config.l: read configuration file * */ #line 27 "pool_config.l" #include "pool.h" #include "pool_config.h" #include #include #include #define CHECK_CONTEXT(mask, context) ((mask) & (context)) /* to shut off compiler warnings */ int yylex(void); POOL_CONFIG *pool_config; /* configuration values */ POOL_SYSTEMDB_CONNECTION_POOL *system_db_info; static unsigned Lineno; static char *default_reset_query_list[] = {"ABORT", "DISCARD ALL"}; static char *default_black_function_list[] = {"nextval", "setval"}; typedef enum { POOL_KEY = 1, POOL_INTEGER, POOL_REAL, POOL_STRING, POOL_UNQUOTED_STRING, POOL_EQUALS, POOL_EOL, POOL_PARSE_ERROR } POOL_TOKEN; static char *extract_string(char *value, POOL_TOKEN token); static char **extract_string_tokens(char *str, char *delim, int *n); static void clear_host_entry(int slot); #line 545 "pool_config.c" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy (void ); int yyget_debug (void ); void yyset_debug (int debug_flag ); YY_EXTRA_TYPE yyget_extra (void ); void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); void yyset_in (FILE * in_str ); FILE *yyget_out (void ); void yyset_out (FILE * out_str ); int yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); void yyset_lineno (int line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ unsigned n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 85 "pool_config.l" #line 728 "pool_config.c" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 38 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_current_state != 37 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_find_action: yy_act = yy_accept[yy_current_state]; YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 87 "pool_config.l" Lineno++; return POOL_EOL; YY_BREAK case 2: YY_RULE_SETUP #line 88 "pool_config.l" /* eat whitespace */ YY_BREAK case 3: *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 89 "pool_config.l" /* eat comment */ YY_BREAK case 4: YY_RULE_SETUP #line 91 "pool_config.l" return POOL_KEY; YY_BREAK case 5: YY_RULE_SETUP #line 92 "pool_config.l" return POOL_STRING; YY_BREAK case 6: YY_RULE_SETUP #line 93 "pool_config.l" return POOL_UNQUOTED_STRING; YY_BREAK case 7: YY_RULE_SETUP #line 94 "pool_config.l" return POOL_INTEGER; YY_BREAK case 8: YY_RULE_SETUP #line 95 "pool_config.l" return POOL_REAL; YY_BREAK case 9: YY_RULE_SETUP #line 96 "pool_config.l" return POOL_EQUALS; YY_BREAK case 10: YY_RULE_SETUP #line 98 "pool_config.l" return POOL_PARSE_ERROR; YY_BREAK case 11: YY_RULE_SETUP #line 100 "pool_config.l" ECHO; YY_BREAK #line 866 "pool_config.c" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 38 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 38 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 37); return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { int num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param bytes the byte buffer to scan * @param len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param line_number * */ void yyset_lineno (int line_number ) { yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * in_str ) { yyin = in_str ; } void yyset_out (FILE * out_str ) { yyout = out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int bdebug ) { yy_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 100 "pool_config.l" int pool_init_config(void) { int res; static char localhostname[256]; int i; pool_config = malloc(sizeof(POOL_CONFIG)); if (pool_config == NULL) { pool_error("failed to allocate pool_config"); return(-1); } memset(pool_config, 0, sizeof(POOL_CONFIG)); #ifndef POOL_PRIVATE pool_config->backend_desc = pool_shared_memory_create(sizeof(BackendDesc)); if (pool_config->backend_desc == NULL) { pool_error("failed to allocate pool_config->backend_desc"); return -1; } #else pool_config->backend_desc = malloc(sizeof(BackendDesc)); if (pool_config->backend_desc == NULL) { pool_error("failed to allocate pool_config->backend_desc"); return -1; } #endif /* * add for watchdog */ pool_config->other_wd = malloc(sizeof(WdDesc)); if (pool_config->other_wd == NULL) { pool_error("failed to allocate pool_config->cwother_wd"); return -1; } memset(pool_config->other_wd, 0, sizeof(WdDesc)); /* set hardcoded default values */ pool_config->listen_addresses = "localhost"; pool_config->port = 9999; pool_config->pcp_port = 9898; pool_config->socket_dir = DEFAULT_SOCKET_DIR; pool_config->pcp_socket_dir = DEFAULT_SOCKET_DIR; pool_config->backend_socket_dir = NULL; pool_config->pcp_timeout = 10; pool_config->num_init_children = 32; pool_config->max_pool = 4; pool_config->child_life_time = 300; pool_config->client_idle_limit = 0; pool_config->connection_life_time = 0; pool_config->child_max_connections = 0; pool_config->authentication_timeout = 60; pool_config->logdir = DEFAULT_LOGDIR; pool_config->logsyslog = 0; pool_config->log_destination = "stderr"; pool_config->syslog_facility = LOG_LOCAL0; pool_config->syslog_ident = "pgpool"; pool_config->pid_file_name = DEFAULT_PID_FILE_NAME; pool_config->log_statement = 0; pool_config->log_per_node_statement = 0; pool_config->log_connections = 0; pool_config->log_hostname = 0; pool_config->enable_pool_hba = 0; pool_config->pool_passwd = "pool_passwd"; pool_config->replication_mode = 0; pool_config->load_balance_mode = 0; pool_config->replication_stop_on_mismatch = 0; pool_config->failover_if_affected_tuples_mismatch = 0; pool_config->replicate_select = 0; pool_config->reset_query_list = default_reset_query_list; pool_config->num_reset_queries = sizeof(default_reset_query_list)/sizeof(char *); pool_config->white_function_list = NULL; pool_config->num_white_function_list = 0; pool_config->black_function_list = default_black_function_list; pool_config->num_black_function_list = sizeof(default_black_function_list)/sizeof(char *); pool_config->print_timestamp = 1; pool_config->master_slave_mode = 0; pool_config->master_slave_sub_mode = "slony"; pool_config->delay_threshold = 0; pool_config->log_standby_delay = "none"; pool_config->connection_cache = 1; pool_config->health_check_timeout = 20; pool_config->health_check_period = 0; pool_config->health_check_user = "nobody"; pool_config->health_check_password = ""; pool_config->health_check_max_retries = 0; pool_config->health_check_retry_delay = 1; pool_config->sr_check_period = 0; pool_config->sr_check_user = "nobody"; pool_config->sr_check_password = ""; pool_config->failover_command = ""; pool_config->follow_master_command = ""; pool_config->failback_command = ""; pool_config->fail_over_on_backend_error = 1; pool_config->insert_lock = 1; pool_config->ignore_leading_white_space = 1; pool_config->parallel_mode = 0; pool_config->enable_query_cache = 0; pool_config->system_db_hostname = "localhost"; pool_config->system_db_port = 5432; pool_config->system_db_dbname = "pgpool"; pool_config->system_db_schema = "pgpool_catalog"; pool_config->system_db_user = "pgpool"; pool_config->system_db_password = ""; pool_config->backend_desc->num_backends = 0; pool_config->recovery_user = ""; pool_config->recovery_password = ""; pool_config->recovery_1st_stage_command = ""; pool_config->recovery_2nd_stage_command = ""; pool_config->recovery_timeout = 90; pool_config->search_primary_node_timeout = 10; pool_config->client_idle_limit_in_recovery = 0; pool_config->lobj_lock_table = ""; pool_config->ssl = 0; pool_config->ssl_cert = ""; pool_config->ssl_key = ""; pool_config->ssl_ca_cert = ""; pool_config->ssl_ca_cert_dir = ""; pool_config->debug_level = 0; pool_config->relcache_expire = 0; pool_config->relcache_size = 256; pool_config->check_temp_table = 1; pool_config->lists_patterns = NULL; pool_config->pattc = 0; pool_config->current_pattern_size = 0; /* * add for watchdog */ pool_config->use_watchdog = 0; pool_config->wd_lifecheck_method = MODE_HEARTBEAT; pool_config->clear_memqcache_on_escalation = 1; pool_config->wd_escalation_command = ""; pool_config->trusted_servers = ""; pool_config->delegate_IP = ""; res = gethostname(localhostname,sizeof(localhostname)); if(res !=0 ) { pool_debug("failed to get this hostname"); } pool_config->wd_hostname = localhostname; pool_config->wd_port = 9000; pool_config->other_wd->num_wd = 0; pool_config->wd_interval = 10; pool_config->wd_authkey = ""; pool_config->ping_path = "/bin"; pool_config->ifconfig_path = "/sbin"; pool_config->if_up_cmd = "ifconfig eth0:0 inet $_IP_$ netmask 255.255.255.0"; pool_config->if_down_cmd = "ifconfig eth0:0 down"; pool_config->arping_path = "/usr/sbin"; pool_config->arping_cmd = "arping -U $_IP_$ -w 1"; pool_config->wd_life_point = 3; pool_config->wd_lifecheck_query = "SELECT 1"; pool_config->wd_lifecheck_dbname = "template1"; pool_config->wd_lifecheck_user = "nobody"; pool_config->wd_lifecheck_password = ""; pool_config->wd_heartbeat_port = 9694; pool_config->wd_heartbeat_keepalive = 2; pool_config->wd_heartbeat_deadtime = 30; pool_config->num_hb_if = 0; pool_config->memory_cache_enabled = 0; pool_config->memqcache_method = "shmem"; pool_config->memqcache_memcached_host = "localhost"; pool_config->memqcache_memcached_port = 11211; pool_config->memqcache_total_size = 67108864; pool_config->memqcache_max_num_cache = 1000000; pool_config->memqcache_expire = 0; pool_config->memqcache_auto_cache_invalidation = 1; pool_config->memqcache_maxcache = 409600; pool_config->memqcache_cache_block_size = 1048576; pool_config->memqcache_oiddir = "/var/log/pgpool/oiddir"; pool_config->white_memqcache_table_list = NULL; pool_config->num_white_memqcache_table_list = 0; pool_config->black_memqcache_table_list = NULL; pool_config->num_black_memqcache_table_list = 0; pool_config->lists_memqcache_table_patterns = NULL; pool_config->memqcache_table_pattc = 0; pool_config->current_memqcache_table_pattern_size = 0; res = gethostname(localhostname,sizeof(localhostname)); if(res !=0 ) { pool_debug("failed to get this hostname"); } pool_config->pgpool2_hostname = localhostname; for (i=0;ipattc == pool_config->current_pattern_size) { pool_config->current_pattern_size += PATTERN_ARR_SIZE; _tmp = realloc(pool_config->lists_patterns, (pool_config->current_pattern_size * sizeof(RegPattern))); if (!_tmp) { return(-1); } pool_config->lists_patterns = (RegPattern*)_tmp; } pool_config->lists_patterns[pool_config->pattc] = item; pool_config->pattc++; return(pool_config->pattc); } int growMemqcacheTablePatternArray(RegPattern item) { void *_tmp = NULL; if (pool_config->memqcache_table_pattc == pool_config->current_memqcache_table_pattern_size) { pool_config->current_memqcache_table_pattern_size += PATTERN_ARR_SIZE; _tmp = realloc(pool_config->lists_memqcache_table_patterns, (pool_config->current_memqcache_table_pattern_size * sizeof(RegPattern))); if (!_tmp) { return(-1); } pool_config->lists_memqcache_table_patterns = (RegPattern*)_tmp; } pool_config->lists_memqcache_table_patterns[pool_config->memqcache_table_pattc] = item; pool_config->memqcache_table_pattc++; return(pool_config->memqcache_table_pattc); } int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context) { FILE *fd; int token; char key[1024]; double total_weight; int i; bool log_destination_changed = false; #ifdef USE_MEMCACHED bool use_memcached = true; #else bool use_memcached = false; #endif #define PARSE_ERROR() pool_error("pool_config: parse error at line %d '%s'", Lineno, yytext) /* open config file */ fd = fopen(confpath, "r"); if (!fd) { fprintf(stderr, "pool_config: could not open configuration file (%s)\n", POOL_CONF_FILE_NAME); fprintf(stderr, "pool_config: using default values...\n"); return 0; } yyin = fd; Lineno = 1; for(;;) { token = yylex(); if (token == 0) { break; } if (token == POOL_PARSE_ERROR) { PARSE_ERROR(); fclose(fd); return(-1); } if (token == POOL_EOL) continue; if (token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } strlcpy(key, yytext, sizeof(key)); pool_debug("key: %s", key); token = yylex(); if (token == POOL_EQUALS) token = yylex(); pool_debug("value: %s kind: %d", yytext, token); if (!strcmp(key, "allow_inet_domain_socket") && CHECK_CONTEXT(INIT_CONFIG, context)) { /* for backward compatibility */ int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } if (v) pool_config->listen_addresses = strdup("*"); else pool_config->listen_addresses = strdup(""); } else if (!strcmp(key, "listen_addresses") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->listen_addresses = str; } else if (!strcmp(key, "port") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 1024) { pool_error("pool_config: %s must be 1024 or higher numeric value", key); fclose(fd); return(-1); } pool_config->port = v; } else if (!strcmp(key, "pcp_port") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 1024) { pool_error("pool_config: %s must be 1024 or higher numeric value", key); fclose(fd); return(-1); } pool_config->pcp_port = v; } else if (!strcmp(key, "socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->socket_dir = str; } else if (!strcmp(key, "pcp_socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->pcp_socket_dir = str; } else if (!strcmp(key, "pcp_timeout") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or greater or equal to 0 numeric value", key); fclose(fd); return(-1); } pool_config->pcp_timeout = v; } else if (!strcmp(key, "num_init_children") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 1) { pool_error("pool_config: %s must be higher than 1 numeric value", key); fclose(fd); return(-1); } pool_config->num_init_children = v; } else if (!strcmp(key, "child_life_time") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be greater or equal to 0 numeric value", key); fclose(fd); return(-1); } pool_config->child_life_time = v; } else if (!strcmp(key, "client_idle_limit") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be greater or equal to 0 numeric value", key); fclose(fd); return(-1); } pool_config->client_idle_limit = v; } else if (!strcmp(key, "connection_life_time") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be greater or equal to 0 numeric value", key); fclose(fd); return(-1); } pool_config->connection_life_time = v; } else if (!strcmp(key, "child_max_connections") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be greater or equal to 0 numeric value", key); fclose(fd); return(-1); } pool_config->child_max_connections = v; } else if (!strcmp(key, "authentication_timeout") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->authentication_timeout = v; } else if (!strcmp(key, "max_pool") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be greater or equal to 0 numeric value", key); fclose(fd); return(-1); } pool_config->max_pool = v; } else if (!strcmp(key, "logdir") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->logdir = str; } else if (!strcmp(key, "log_destination") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } log_destination_changed = pool_config->log_destination != str; pool_config->log_destination = str; } else if (!strcmp(key, "syslog_facility") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->syslog_facility = set_syslog_facility(str); } else if (!strcmp(key, "syslog_ident") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } log_destination_changed = log_destination_changed || pool_config->syslog_ident != str; pool_config->syslog_ident = str; } else if (!strcmp(key, "pid_file_name") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->pid_file_name = str; } else if (!strcmp(key, "log_connections") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->log_connections = v; } else if (!strcmp(key, "log_hostname") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->log_hostname = v; } else if (!strcmp(key, "enable_pool_hba") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->enable_pool_hba = v; } else if (!strcmp(key, "pool_passwd") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->pool_passwd = str; } else if (!strcmp(key, "backend_socket_dir") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; pool_log("pool_config: backend_socket_dir is deprecated, please use backend_hostname"); if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->backend_socket_dir = str; } else if (!strcmp(key, "replication_mode") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->replication_mode = v; if (pool_config->master_slave_mode && pool_config->replication_mode) { pool_error("pool_config: replication_mode and master_slave_mode cannot be enabled at the same time"); fclose(fd); return(-1); } } else if (!strcmp(key, "load_balance_mode") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->load_balance_mode = v; } else if (!strcmp(key, "replication_stop_on_mismatch") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_debug("replication_stop_on_mismatch: %d", v); pool_config->replication_stop_on_mismatch = v; } else if (!strcmp(key, "failover_if_affected_tuples_mismatch") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_debug("failover_if_affected_tuples_mismatch: %d", v); pool_config->failover_if_affected_tuples_mismatch = v; } else if (!strcmp(key, "replicate_select") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_debug("replicate_select: %d", v); pool_config->replicate_select = v; } else if (!strcmp(key, "reset_query_list") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->reset_query_list = extract_string_tokens(str, ";", &pool_config->num_reset_queries); if (pool_config->reset_query_list == NULL) { fclose(fd); return(-1); } } else if (!strcmp(key, "white_function_list") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->white_function_list = extract_string_tokens(str, ",", &pool_config->num_white_function_list); if (pool_config->white_function_list == NULL) { fclose(fd); return(-1); } for (i=0;inum_white_function_list;i++) { add_regex_pattern("white_function_list", pool_config->white_function_list[i]); } } else if (!strcmp(key, "black_function_list") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->black_function_list = extract_string_tokens(str, ",", &pool_config->num_black_function_list); if (pool_config->black_function_list == NULL) { fclose(fd); return(-1); } for (i=0;inum_black_function_list;i++) { add_regex_pattern("black_function_list", pool_config->black_function_list[i]); } } else if (!strcmp(key, "print_timestamp") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->print_timestamp = v; } else if (!strcmp(key, "master_slave_mode") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->master_slave_mode = v; if (pool_config->master_slave_mode && pool_config->replication_mode) { pool_error("pool_config: replication_mode and master_slave_mode cannot be enabled at the same time"); fclose(fd); return(-1); } } else if (!strcmp(key, "master_slave_sub_mode") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if (strcmp(str, MODE_SLONY) && strcmp(str, MODE_STREAMREP)) { pool_error("pool_config: %s must be either \"slony\" or \"stream\"", key); fclose(fd); return(-1); } pool_config->master_slave_sub_mode = str; } else if (!strcmp(key, "delay_threshold") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { long long int v = atol(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be greater or equal to 0 numeric value", key); fclose(fd); return(-1); } pool_config->delay_threshold = v; } else if (!strcmp(key, "log_standby_delay") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if (strcmp(str, "always") && strcmp(str, "if_over_threshold") && strcmp(str, "none")) { pool_error("pool_config: invalid log_standby_delay %s", key); fclose(fd); return(-1); } pool_config->log_standby_delay = str; } else if (!strcmp(key, "connection_cache") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->connection_cache = v; } else if (!strcmp(key, "health_check_timeout") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->health_check_timeout = v; } else if (!strcmp(key, "health_check_period") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->health_check_period = v; } else if (!strcmp(key, "health_check_user") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->health_check_user = str; } else if (!strcmp(key, "health_check_password") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->health_check_password = str; } else if (!strcmp(key, "health_check_max_retries") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->health_check_max_retries = v; } else if (!strcmp(key, "health_check_retry_delay") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->health_check_retry_delay = v; } else if (!strcmp(key, "sr_check_period") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->sr_check_period = v; } else if (!strcmp(key, "sr_check_user") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->sr_check_user = str; } else if (!strcmp(key, "sr_check_password") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->sr_check_password = str; } else if (!strcmp(key, "failover_command") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->failover_command = str; } else if (!strcmp(key, "follow_master_command") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->follow_master_command = str; } else if (!strcmp(key, "failback_command") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->failback_command = str; } else if (!strcmp(key, "fail_over_on_backend_error") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->fail_over_on_backend_error = v; } else if (!strcmp(key, "recovery_user") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->recovery_user = str; } else if (!strcmp(key, "recovery_password") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->recovery_password = str; } else if (!strcmp(key, "recovery_1st_stage_command") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->recovery_1st_stage_command = str; } else if (!strcmp(key, "recovery_2nd_stage_command") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->recovery_2nd_stage_command = str; } else if (!strcmp(key, "recovery_timeout") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->recovery_timeout = v; } else if (!strcmp(key, "search_primary_node_timeout") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->search_primary_node_timeout = v; } else if (!strcmp(key, "client_idle_limit_in_recovery") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < -1) { pool_error("pool_config: %s must be greater or equal to -1 numeric value", key); fclose(fd); return(-1); } pool_config->client_idle_limit_in_recovery = v; } else if (!strcmp(key, "insert_lock") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->insert_lock = v; } else if (!strcmp(key, "ignore_leading_white_space") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->ignore_leading_white_space = v; } else if (!strcmp(key, "parallel_mode") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->parallel_mode = v; } else if (!strcmp(key, "enable_query_cache") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->enable_query_cache = v; } else if (!strcmp(key, "pgpool2_hostname") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->pgpool2_hostname = str; } else if (!strcmp(key, "system_db_hostname") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->system_db_hostname = str; } else if (!strcmp(key, "system_db_port") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->system_db_port = v; } else if (!strcmp(key, "system_db_dbname") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->system_db_dbname = str; } else if (!strcmp(key, "system_db_schema") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->system_db_schema = str; } else if (!strcmp(key, "system_db_user") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->system_db_user = str; } else if (!strcmp(key, "system_db_password") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->system_db_password = str; } else if (!strncmp(key, "backend_hostname", 16) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { int slot; char *str; slot = atoi(key + 16); if (slot < 0 || slot >= MAX_CONNECTION_SLOTS) { pool_error("pool_config: backend number %s for backend_hostname out of range", key); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if (context == INIT_CONFIG || (context == RELOAD_CONFIG && BACKEND_INFO(slot).backend_status == CON_UNUSED)) strlcpy(BACKEND_INFO(slot).backend_hostname, str, MAX_DB_HOST_NAMELEN); } else if (!strncmp(key, "backend_port", 12) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { int slot; slot = atoi(key + 12); if (slot < 0 || slot >= MAX_CONNECTION_SLOTS) { pool_error("pool_config: host number %s for port number out of range", key); fclose(fd); return(-1); } pool_debug("pool_config: port slot number %d ", slot); if (context == INIT_CONFIG) { BACKEND_INFO(slot).backend_port = atoi(yytext); BACKEND_INFO(slot).backend_status = CON_CONNECT_WAIT; } else if (context == RELOAD_CONFIG && BACKEND_INFO(slot).backend_status == CON_UNUSED) { BACKEND_INFO(slot).backend_port = atoi(yytext); BACKEND_INFO(slot).backend_status = CON_DOWN; } } else if (!strncmp(key, "backend_weight", 14) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { int slot; double v; BACKEND_STATUS status; slot = atoi(key + 14); if (slot < 0 || slot >= MAX_CONNECTION_SLOTS) { pool_error("pool_config: weight number %s for port number out of range", key); fclose(fd); return(-1); } v = atof(yytext); if (v < 0.0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_debug("pool_config: weight slot number %d weight: %f", slot, v); status = BACKEND_INFO(slot).backend_status; if (context == INIT_CONFIG || context == RELOAD_CONFIG) { double old_v = BACKEND_INFO(slot).unnormalized_weight; BACKEND_INFO(slot).unnormalized_weight = v; /* * Log weight change event only when context is * reloading of pgpool.conf and weight is actually * changed */ if (context == RELOAD_CONFIG && old_v != v) { pool_log("Backend weight for backend%d changed from %f to %f. This will take effect from next client session.", slot, old_v, v); } } } else if (!strncmp(key, "backend_data_directory", 22) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { int slot; char *str; BACKEND_STATUS status; slot = atoi(key + 22); if (slot < 0 || slot >= MAX_CONNECTION_SLOTS) { pool_error("pool_config: backend number %s for backend_data_directory out of range", key); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } status = BACKEND_INFO(slot).backend_status; if (context == INIT_CONFIG || (context == RELOAD_CONFIG && (status == CON_UNUSED || status == CON_DOWN))) strlcpy(BACKEND_INFO(slot).backend_data_directory, str, MAX_PATH_LENGTH); } else if (!strncmp(key, "backend_flag", 12) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { char *str; char **flags; int n; int i; int slot; unsigned short flag = 0; bool allow_to_failover_is_specified = 0; bool disallow_to_failover_is_specified = 0; str = extract_string(yytext, token); if (str == NULL) { pool_error("pool_config: extract_string failed: %s", yytext); fclose(fd); return(-1); } flags = extract_string_tokens(str, "|", &n); if (!flags || n < 0) { pool_debug("pool_config: unable to get backend flags"); fclose(fd); return(-1); } for (i=0;i= MAX_CONNECTION_SLOTS) { pool_error("pool_config: slot number %s for flag out of range", key); fclose(fd); return(-1); } BACKEND_INFO(slot).flag = flag; pool_debug("pool_config: slot number %d flag: %04x", slot, flag); } else if (!strcmp(key, "log_statement") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); return(-1); } pool_config->log_statement = v; } else if (!strcmp(key, "log_per_node_statement") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); return(-1); } pool_config->log_per_node_statement = v; } else if (!strcmp(key, "lobj_lock_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->lobj_lock_table = str; } /* * add for watchdog */ else if (!strncmp(key, "other_pgpool_hostname", 21) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { int slot; char *str; slot = atoi(key + 21) ; if (slot < 0 || slot >= MAX_CONNECTION_SLOTS) { pool_error("pool_config: pgpool number %s for other_pgpool_hostname out of range", key); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if (context == INIT_CONFIG || (context == RELOAD_CONFIG )) strlcpy(WD_INFO(slot).hostname, str, WD_MAX_HOST_NAMELEN); } else if (!strncmp(key, "other_pgpool_port", 17) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { int slot; slot = atoi(key + 17); if (slot < 0 || slot >= MAX_CONNECTION_SLOTS) { pool_error("pool_config: pgpool number %s for other_pgpool_port out of range", key); fclose(fd); return(-1); } if (context == INIT_CONFIG || (context == RELOAD_CONFIG )) WD_INFO(slot).pgpool_port = atoi(yytext); } else if (!strncmp(key, "other_wd_port", 13) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { int slot; slot = atoi(key + 13); if (slot < 0 || slot >= MAX_CONNECTION_SLOTS) { pool_error("pool_config: pgpool number %s for other_wd_port out of range", key); fclose(fd); return(-1); } if (context == INIT_CONFIG || (context == RELOAD_CONFIG )) { WD_INFO(slot).wd_port = atoi(yytext); WD_INFO(slot).status = WD_INIT; pool_config->other_wd->num_wd = slot + 1; } } else if (!strcmp(key, "use_watchdog") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->use_watchdog = v; } else if (!strcmp(key, "clear_memqcache_on_escalation") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->clear_memqcache_on_escalation = v; } else if (!strcmp(key, "wd_escalation_command") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->wd_escalation_command = str; } else if (!strcmp(key, "trusted_servers") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->trusted_servers = str; } else if (!strcmp(key, "delegate_IP") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->delegate_IP = str; } else if (!strcmp(key, "wd_hostname") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->wd_hostname = str; } else if (!strcmp(key, "wd_port") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v <= 0) { pool_error("pool_config: %s must be higher than 1 numeric value", key); fclose(fd); return(-1); } pool_config->wd_port = v; } else if (!strcmp(key, "wd_interval") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v <= 0) { pool_error("pool_config: %s must be higher than 1 numeric value", key); fclose(fd); return(-1); } pool_config->wd_interval = v; } else if (!strcmp(key, "ping_path") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->ping_path = str; } else if (!strcmp(key, "ifconfig_path") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->ifconfig_path = str; } else if (!strcmp(key, "if_up_cmd") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->if_up_cmd = str; } else if (!strcmp(key, "if_down_cmd") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->if_down_cmd = str; } else if (!strcmp(key, "arping_path") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->arping_path = str; } else if (!strcmp(key, "arping_cmd") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->arping_cmd = str; } else if (!strcmp(key, "wd_life_point") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v <= 0) { pool_error("pool_config: %s must be higher than 1 numeric value", key); fclose(fd); return(-1); } pool_config->wd_life_point = v; } else if (!strcmp(key, "wd_lifecheck_query") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if(strlen(str)) pool_config->wd_lifecheck_query = str; } else if (!strcmp(key, "wd_lifecheck_dbname") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->wd_lifecheck_dbname = str; } else if (!strcmp(key, "wd_lifecheck_user") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->wd_lifecheck_user = str; } else if (!strcmp(key, "wd_lifecheck_password") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->wd_lifecheck_password = str; } else if (!strcmp(key, "wd_lifecheck_method") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if (strcmp(str, MODE_HEARTBEAT) && strcmp(str, MODE_QUERY)) { pool_error("pool_config: %s must be either \"heartbeat\" or \"query\"", key); fclose(fd); return(-1); } pool_config->wd_lifecheck_method = str; } else if (!strcmp(key, "wd_heartbeat_port") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v <= 0) { pool_error("pool_config: %s must be higher than 1 numeric value", key); fclose(fd); return(-1); } pool_config->wd_heartbeat_port = v; } else if (!strcmp(key, "wd_heartbeat_keepalive") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v <= 0) { pool_error("pool_config: %s must be higher than 1 numeric value", key); fclose(fd); return(-1); } pool_config->wd_heartbeat_keepalive = v; } else if (!strcmp(key, "wd_heartbeat_deadtime") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v <= 0) { pool_error("pool_config: %s must be higher than 1 numeric value", key); fclose(fd); return(-1); } pool_config->wd_heartbeat_deadtime = v; } else if (!strcmp(key, "wd_authkey") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->wd_authkey = str; } else if (!strncmp(key, "heartbeat_device", 16) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { int slot; char *str; slot = atoi(key + 16) ; if (slot < 0 || slot >= WD_MAX_IF_NUM) { pool_error("pool_config: pgpool number %s for heartbeat_device out of range", key); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if (context == INIT_CONFIG || (context == RELOAD_CONFIG )) strlcpy(WD_HB_IF(slot).if_name, str, WD_MAX_IF_NAME_LEN); } /* this must be prior to hertbeat_destination */ else if (!strncmp(key, "heartbeat_destination_port", 26) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { int slot; slot = atoi(key + 26) ; if (slot < 0 || slot >= WD_MAX_IF_NUM) { pool_error("pool_config: pgpool number %s for heartbeat_destination_port out of range", key); fclose(fd); return(-1); } if (context == INIT_CONFIG || (context == RELOAD_CONFIG )) { WD_HB_IF(slot).dest_port = atoi(yytext); pool_config->num_hb_if = slot + 1; } } else if (!strncmp(key, "heartbeat_destination", 21) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid()) /* this parameter must be modified by parent pid */ { int slot; char *str; slot = atoi(key + 21) ; if (slot < 0 || slot >= WD_MAX_IF_NUM) { pool_error("pool_config: pgpool number %s for heartbeat_destination out of range", key); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if (context == INIT_CONFIG || (context == RELOAD_CONFIG )) strlcpy(WD_HB_IF(slot).addr, str, WD_MAX_HOST_NAMELEN); } else if (!strcmp(key, "ssl") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); return(-1); } pool_config->ssl = v; } else if (!strcmp(key, "ssl_cert") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->ssl_cert = str; } else if (!strcmp(key, "ssl_key") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->ssl_key = str; } else if (!strcmp(key, "ssl_ca_cert") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->ssl_ca_cert = str; } else if (!strcmp(key, "ssl_ca_cert_dir") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->ssl_ca_cert_dir = str; } else if (!strcmp(key, "debug_level") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->debug_level = v; } else if (!strcmp(key, "relcache_expire") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->relcache_expire = v; } else if (!strcmp(key, "relcache_size") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 1) { pool_error("pool_config: %s must be equal or higher than 1 numeric value", key); fclose(fd); return(-1); } pool_config->relcache_size = v; } else if (!strcmp(key, "check_temp_table") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); return(-1); } pool_config->check_temp_table = v; } else if (!strcmp(key, "memory_cache_enabled") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->memory_cache_enabled = v; } else if (!strcmp(key, "memqcache_method") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } if (!strcmp(str, "memcached") && !use_memcached) { pool_error("memqcached_method cannot be memcached because pgpool-II is not built with MEMCACHED enabled"); fclose(fd); return -1; } if (strcmp(str, "memcached") && strcmp(str, "shmem")) { pool_error("memqcached_method must be either shmem or memcached"); fclose(fd); return -1; } pool_config->memqcache_method = str; } else if (!strcmp(key, "memqcache_memcached_host") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->memqcache_memcached_host = str; } else if (!strcmp(key, "memqcache_memcached_port") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->memqcache_memcached_port = v; } else if (!strcmp(key, "memqcache_total_size") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->memqcache_total_size = v; } else if (!strcmp(key, "memqcache_max_num_cache") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->memqcache_max_num_cache = v; } else if (!strcmp(key, "memqcache_expire") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->memqcache_expire = v; } else if (!strcmp(key, "memqcache_auto_cache_invalidation") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = eval_logical(yytext); if (v < 0) { pool_error("pool_config: invalid value %s for %s", yytext, key); fclose(fd); return(-1); } pool_config->memqcache_auto_cache_invalidation = v; } else if (!strcmp(key, "memqcache_maxcache") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 0) { pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); fclose(fd); return(-1); } pool_config->memqcache_maxcache = v; } else if (!strcmp(key, "memqcache_cache_block_size") && CHECK_CONTEXT(INIT_CONFIG, context)) { int v = atoi(yytext); if (token != POOL_INTEGER || v < 512) { pool_error("pool_config: %s must be equal or higher than 512 numeric value", key); fclose(fd); return(-1); } pool_config->memqcache_cache_block_size = v; } else if (!strcmp(key, "memqcache_oiddir") && CHECK_CONTEXT(INIT_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->memqcache_oiddir = str; } else if (!strcmp(key, "white_memqcache_table_list") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->white_memqcache_table_list = extract_string_tokens(str, ",", &pool_config->num_white_memqcache_table_list); if (pool_config->white_memqcache_table_list == NULL) { fclose(fd); return(-1); } for (i=0;inum_white_memqcache_table_list;i++) { add_regex_pattern("white_memqcache_table_list", pool_config->white_memqcache_table_list[i]); } } else if (!strcmp(key, "black_memqcache_table_list") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)) { char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) { PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL) { fclose(fd); return(-1); } pool_config->black_memqcache_table_list = extract_string_tokens(str, ",", &pool_config->num_black_memqcache_table_list); if (pool_config->black_memqcache_table_list == NULL) { fclose(fd); return(-1); } for (i=0;inum_black_memqcache_table_list;i++) { add_regex_pattern("black_memqcache_table_list", pool_config->black_memqcache_table_list[i]); } } } fclose(fd); if (log_destination_changed) { /* log_destination has changed, we need to open syslog or close it */ if (!strcmp(pool_config->log_destination, "stderr")) { closelog(); pool_config->logsyslog = 0; } else { openlog(pool_config->syslog_ident, LOG_PID|LOG_NDELAY|LOG_NOWAIT, pool_config->syslog_facility); pool_config->logsyslog = 1; } } pool_config->backend_desc->num_backends = 0; total_weight = 0.0; for (i=0;ibackend_desc->num_backends = i+1; /* initialize backend_hostname with a default socket path if empty */ if (*(BACKEND_INFO(i).backend_hostname) == '\0') { if (pool_config->backend_socket_dir == NULL) { pool_debug("pool_config: empty backend_hostname%d, use PostgreSQL's default unix socket path (%s)", i, DEFAULT_SOCKET_DIR); strlcpy(BACKEND_INFO(i).backend_hostname, DEFAULT_SOCKET_DIR, MAX_DB_HOST_NAMELEN); } else /* DEPRECATED. backward compatibility with older version. Use backend_socket_dir*/ { pool_debug("pool_config: empty backend_hostname%d, use backend_socket_dir as unix socket path (%s)", i, pool_config->backend_socket_dir); strlcpy(BACKEND_INFO(i).backend_hostname, pool_config->backend_socket_dir, MAX_DB_HOST_NAMELEN); } } } } pool_debug("num_backends: %d total_weight: %f", pool_config->backend_desc->num_backends, total_weight); /* * Normalize load balancing weights. What we are doing here is, * assign 0 to RAND_MAX to each backend's weight according to the * value weightN. For example, if two backends are assigned 1.0, * then each backend will get RAND_MAX/2 normalized weight. */ for (i=0;iparallel_mode || pool_config->enable_query_cache) { #ifndef POOL_PRIVATE int dist_num; #endif SystemDBInfo *info; system_db_info = malloc(sizeof(POOL_SYSTEMDB_CONNECTION_POOL)); if (system_db_info == NULL) { pool_error("failed to allocate system_db_info"); return -1; } memset(system_db_info, 0, sizeof(*system_db_info)); #ifndef POOL_PRIVATE system_db_info->system_db_status = pool_shared_memory_create(sizeof(BACKEND_STATUS)); #else system_db_info->system_db_status = malloc(sizeof(BACKEND_STATUS)); #endif if (system_db_info->system_db_status == NULL) { pool_error("failed to allocate system_db_info->system_db_status"); return -1; } *system_db_info->system_db_status = CON_CONNECT_WAIT; /* which is the same as SYSDB_STATUS = CON_CONNECT_WAIT */ info = malloc(sizeof(SystemDBInfo)); if (info == NULL) { pool_error("failed to allocate info"); return -1; } system_db_info->info = info; info->hostname = pool_config->system_db_hostname; info->port = pool_config->system_db_port; info->user = pool_config->system_db_user; info->password = pool_config->system_db_password; info->database_name = pool_config->system_db_dbname; info->schema_name = pool_config->system_db_schema; info->dist_def_num = 0; info->dist_def_slot = NULL; #ifndef POOL_PRIVATE if (pool_config->parallel_mode) { dist_num = pool_memset_system_db_info(info); if(dist_num < 0) { pool_error("failed to get systemdb info"); return(-1); } if (!pool_config->replication_mode && !pool_config->load_balance_mode) { pool_error("pool_config: parallel_mode requires replication_mode or load_balance_mode turned on"); return(-1); } } if (pool_config->enable_query_cache) { info->query_cache_table_info.register_prepared_statement = NULL; if (! pool_query_cache_table_exists()) { pool_error("failed to locate query_cache table. perhaps it's not defined?"); return -1; } } SYSDB_STATUS = CON_UP; #endif } if (strcmp(pool_config->recovery_1st_stage_command, "") || strcmp(pool_config->recovery_2nd_stage_command, "")) { for (i=0;ibackend_desc->backend_info[i].backend_port != 0 && !strcmp(pool_config->backend_desc->backend_info[i].backend_data_directory, "")) { pool_error("pool_config: recovery_1st_stage_command and recovery_2nd_stage_command requires backend_data_directory to be set"); return -1; } } } return 0; } static char *extract_string(char *value, POOL_TOKEN token) { char *ret; ret = strdup(value); if (!ret) { pool_error("extract_string: out of memory"); return NULL; } if (token == POOL_STRING) { ret[strlen(ret)-1] = '\0'; return (ret+1); } return ret; } /* * Try to interpret value as boolean value. Valid values are: true, * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof. * If the string parses okay, return true, else false. * If okay and result is not NULL, return the value in *result. * This function copied from PostgreSQL source code. */ static bool parse_bool_with_len(const char *value, size_t len, bool *result) { switch (*value) { case 't': case 'T': if (strncasecmp(value, "true", len) == 0) { if (result) *result = true; return true; } break; case 'f': case 'F': if (strncasecmp(value, "false", len) == 0) { if (result) *result = false; return true; } break; case 'y': case 'Y': if (strncasecmp(value, "yes", len) == 0) { if (result) *result = true; return true; } break; case 'n': case 'N': if (strncasecmp(value, "no", len) == 0) { if (result) *result = false; return true; } break; case 'o': case 'O': /* 'o' is not unique enough */ if (strncasecmp(value, "on", (len > 2 ? len : 2)) == 0) { if (result) *result = true; return true; } else if (strncasecmp(value, "off", (len > 2 ? len : 2)) == 0) { if (result) *result = false; return true; } break; case '1': if (len == 1) { if (result) *result = true; return true; } break; case '0': if (len == 1) { if (result) *result = false; return true; } break; default: break; } if (result) *result = false; /* suppress compiler warning */ return false; } int eval_logical(char *str) { bool result; if (!parse_bool_with_len(str, strlen(str), &result)) return -1; return (result ? 1 : 0); } /* * Extract tokens separated by delimi from str. Return value is an * array of pointers to malloced strings. number of tokens is set to * n; note that str will be destroyed by strtok(). */ #define MAXTOKENS 1024 static char **extract_string_tokens(char *str, char *delimi, int *n) { char *token; static char **tokens; *n = 0; tokens = malloc(MAXTOKENS*sizeof(char *)); if (tokens == NULL) { pool_error("extract_string_tokens: out of memory"); return NULL; } for (token = strtok(str, delimi); token != NULL && *n < MAXTOKENS; token = strtok(NULL, delimi)) { tokens[*n] = strdup(token); if (tokens[*n] == NULL) { pool_error("extract_string_tokens: out of memory"); return NULL; } pool_debug("extract_string_tokens: token: %s", tokens[*n]); (*n)++; } return tokens; } static void clear_host_entry(int slot) { *pool_config->backend_desc->backend_info[slot].backend_hostname = '\0'; pool_config->backend_desc->backend_info[slot].backend_port = 0; pool_config->backend_desc->backend_info[slot].backend_status = CON_UNUSED; pool_config->backend_desc->backend_info[slot].backend_weight = 0.0; } #ifdef DEBUG static void print_host_entry(int slot) { pool_debug("slot: %d host: %s port: %d status: %d weight: %f", slot, pool_config->server_hostnames[slot], pool_config->server_ports[slot], pool_config->server_status[slot], pool_config->server_weights[slot]); } #endif /* Use to set the syslog facility level if logsyslog is activated */ int set_syslog_facility(char *value) { int facility = LOG_LOCAL0; if (value == NULL) return facility; if (strncmp(value, "LOCAL", 5) == 0 && strlen(value) == 6) { switch (value[5]) { case '0': facility = LOG_LOCAL0; break; case '1': facility = LOG_LOCAL1; break; case '2': facility = LOG_LOCAL2; break; case '3': facility = LOG_LOCAL3; break; case '4': facility = LOG_LOCAL4; break; case '5': facility = LOG_LOCAL5; break; case '6': facility = LOG_LOCAL6; break; case '7': facility = LOG_LOCAL7; break; } } return facility; } /* * Translate binary form of backend flag to string. * The returned data is in static buffer, and it will be destroyed * at the next call to this function. */ char *pool_flag_to_str(unsigned short flag) { static char buf[1024]; /* should be large enough */ if (POOL_ALLOW_TO_FAILOVER(flag)) snprintf(buf, sizeof(buf), "ALLOW_TO_FAILOVER"); else if (POOL_DISALLOW_TO_FAILOVER(flag)) snprintf(buf, sizeof(buf), "DISALLOW_TO_FAILOVER"); return buf; } pgpool-II-3.3.2/pool_params.c0000664000076400007640000000701312245576266012751 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * params.c: Parameter Status handling routines * */ #include "config.h" #include #include #include "pool.h" #include "parser/parser.h" #define MAX_PARAM_ITEMS 128 /* * initialize parameter structure */ int pool_init_params(ParamStatus *params) { params->num = 0; params->names = malloc(MAX_PARAM_ITEMS*sizeof(char *)); if (params->names == NULL) { pool_error("pool_init_params: cannot allocate memory"); return -1; } params->values = malloc(MAX_PARAM_ITEMS*sizeof(char *)); if (params->values == NULL) { pool_error("pool_init_params: cannot allocate memory"); return -1; } return 0; } /* * discard parameter structure */ void pool_discard_params(ParamStatus *params) { int i; for (i=0;inum;i++) { free(params->names[i]); free(params->values[i]); } free(params->names); free(params->values); } /* * find param value by name. if found, its value is returned * also, pos is set * if not found, NULL is returned */ char *pool_find_name(ParamStatus *params, char *name, int *pos) { int i; for (i=0;inum;i++) { if (!strcmp(name, params->names[i])) { *pos = i; return params->values[i]; } } return NULL; } /* * return name and value by index. */ int pool_get_param(ParamStatus *params, int index, char **name, char **value) { if (index < 0 || index >= params->num) return -1; *name = params->names[index]; *value = params->values[index]; return 0; } /* * add or replace name/value pair */ int pool_add_param(ParamStatus *params, char *name, char *value) { int pos; if (pool_find_name(params, name, &pos)) { /* name already exists */ if (strlen(params->values[pos]) < strlen(value)) { params->values[pos] = realloc(params->values[pos], strlen(value) + 1); if (params->values[pos] == NULL) { pool_error("pool_init_params: cannot allocate memory"); return -1; } } strcpy(params->values[pos], value); } else { int num; /* add name/value pair */ if (params->num >= MAX_PARAM_ITEMS) { pool_error("pool_add_param: no more room for num"); return -1; } num = params->num; params->names[num] = strdup(name); if (params->names[num] == NULL) { pool_error("pool_init_params: cannot allocate memory"); return -1; } params->values[num] = strdup(value); if (params->values[num] == NULL) { pool_error("pool_init_params: cannot allocate memory"); return -1; } params->num++; } parser_set_param(name, value); return 0; } void pool_param_debug_print(ParamStatus *params) { int i; for (i=0;inum;i++) { pool_debug("No.%d: name: %s value: %s", i, params->names[i], params->values[i]); } } pgpool-II-3.3.2/pool_config_md5.c0000664000076400007640000000204612245576256013500 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2010 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_config_md5.c: Stub file to import pool_config.c. * This file is intended to be linked against pg_md5. Thus * it needs not to use shared memory staffs. * */ #define POOL_PRIVATE #include "pool_config.c" pgpool-II-3.3.2/pool_lobj.c0000664000076400007640000001555512245576256012425 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2010 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_lobj.c: Transparently translate lo_creat call to lo_create so * that large objects replicated safely. * lo_create anyway. */ #include "config.h" #include #include #include #include #include "pool.h" #include "pool_lobj.h" #include "pool_relcache.h" #include "pool_config.h" /* * Rewrite lo_creat call to lo_create call if: * 1) it's a lo_creat function call * 2) PostgreSQL has lo_create * 3) In replication mode * 4) lobj_lock_table exists and writable to everyone * * The argument for lo_create is created by fetching max(loid)+1 from * pg_largeobject. To avoid race condition, we lock lobj_lock_table. * * Caller should call this only if protocol is V3 or higher(for * now. There's no reason for this function not working with V2 * protocol). Return value is a rewritten packet without kind and * length. This is allocated in a static memory. New packet length is * set to *len. */ char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int* len) { #define LO_CREAT_OID_QUERY "SELECT oid FROM pg_catalog.pg_proc WHERE proname = 'lo_creat' and pronamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')" #define LO_CREATE_OID_QUERY "SELECT oid FROM pg_catalog.pg_proc WHERE proname = 'lo_create' and pronamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')" #define LO_CREATE_PACKET_LENGTH sizeof(int32)*3+sizeof(int16)*4 #define LOCK_QUERY "LOCK TABLE %s IN SHARE ROW EXCLUSIVE MODE" #define GET_MAX_LOBJ_KEY "SELECT coalesce(max(loid)::INTEGER, 0)+1 FROM pg_catalog.pg_largeobject" static char rewritten_packet[LO_CREATE_PACKET_LENGTH]; static POOL_RELCACHE *relcache_lo_creat; static POOL_RELCACHE *relcache_lo_create; int lo_creat_oid; int lo_create_oid; int orig_fcall_oid; POOL_STATUS status; char qbuf[1024]; char *p; POOL_SELECT_RESULT *result; int lobjid; int32 int32val; int16 int16val; int16 result_format_code; if (kind != 'F') return NULL; /* not function call */ if (!strcmp(pool_config->lobj_lock_table,"")) return NULL; /* no lock table */ if (!REPLICATION) return NULL; /* not in replication mode */ /* * If relcache does not exist, create it. */ if (!relcache_lo_creat) { relcache_lo_creat = pool_create_relcache(1, LO_CREAT_OID_QUERY, int_register_func, int_unregister_func, false); if (relcache_lo_creat == NULL) { pool_error("pool_check_lo_creat: pool_create_relcache error"); return NULL; } } /* * Get lo_creat oid */ lo_creat_oid = (int)(intptr_t)pool_search_relcache(relcache_lo_creat, backend, "pg_proc"); memmove(&orig_fcall_oid, packet, sizeof(int32)); orig_fcall_oid = ntohl(orig_fcall_oid); pool_debug("orig_fcall_oid:% d lo_creat_oid: %d", orig_fcall_oid, lo_creat_oid); /* * This function call is calling lo_creat? */ if (orig_fcall_oid != lo_creat_oid) return NULL; /* * If relcache does not exist, create it. */ if (!relcache_lo_create) { relcache_lo_create = pool_create_relcache(1, LO_CREATE_OID_QUERY, int_register_func, int_unregister_func, false); if (relcache_lo_create == NULL) { pool_error("pool_check_lo_creat: pool_create_relcache error"); return NULL; } } /* * Get lo_create oid */ lo_create_oid = (int)(intptr_t)pool_search_relcache(relcache_lo_create, backend, "pg_proc"); pool_debug("pool_check_lo_creat: lo_creat_oid: %d lo_create_oid: %d", lo_creat_oid, lo_create_oid); /* * Parse input packet */ memmove(&int16val, packet+packet_len-sizeof(int16), sizeof(int16)); result_format_code = ntohs(int16val); /* sanity check */ if (result_format_code != 0 && result_format_code != 1) { pool_error("pool_rewrite_lo_creat: wrong return format code: %d", int16val); return NULL; } pool_debug("pool_rewrite_lo_creat: return format code: %d", int16val); /* * Ok, do it... */ /* issue lock table command to lob_lock_table */ snprintf(qbuf, sizeof(qbuf), "LOCK TABLE %s IN SHARE ROW EXCLUSIVE MODE", pool_config->lobj_lock_table); per_node_statement_log(backend, MASTER_NODE_ID, qbuf); status = do_command(frontend, MASTER(backend), qbuf, MAJOR(backend), MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 0); if (status == POOL_END) { pool_error("pool_rewrite_lo_creat: failed to execute LOCK"); return NULL; } /* * If transaction state is E, do_command failed to execute command */ if (TSTATE(backend, MASTER_NODE_ID) == 'E') { pool_log("pool_check_lo_creat: failed to execute: %s", qbuf); return NULL; } /* get max lobj id */ per_node_statement_log(backend, MASTER_NODE_ID, GET_MAX_LOBJ_KEY); status = do_query(MASTER(backend), GET_MAX_LOBJ_KEY, &result, MAJOR(backend)); if (status == POOL_END) { pool_error("pool_rewrite_lo_creat: do_query failed"); return NULL; } if (!result) { pool_log("pool_check_lo_creat: failed to execute: %s", GET_MAX_LOBJ_KEY); return NULL; } lobjid = atoi(result->data[0]); pool_debug("lobjid:%d", lobjid); free_select_result(result); /* sanity check */ if (lobjid <= 0) { pool_error("pool_rewrite_lo_creat: wrong lob id: %d", lobjid); return NULL; } /* * Create lo_create call packet */ p = rewritten_packet; *len = LO_CREATE_PACKET_LENGTH; int32val = htonl(lo_create_oid); memmove(p,&int32val, sizeof(int32)); /* lo_create oid */ p += sizeof(int32); int16val = htons(1); memmove(p,&int16val, sizeof(int16)); /* number of argument format code */ p += sizeof(int16); int16val = htons(1); memmove(p,&int16val, sizeof(int16)); /* format code */ p += sizeof(int16); int16val = htons(1); memmove(p,&int16val, sizeof(int16)); /* number of arguments */ p += sizeof(int16); int32val = htonl(4); memmove(p,&int32val, sizeof(int32)); /* argument length */ p += sizeof(int32); int32val = htonl(lobjid); memmove(p,&int32val, sizeof(int32)); /* argument(lobj id) */ p += sizeof(int32); int16val = htons(result_format_code); memmove(p,&int16val, sizeof(int16)); /* result format code */ return rewritten_packet; } pgpool-II-3.3.2/watchdog/0000775000076400007640000000000012245776616012151 500000000000000pgpool-II-3.3.2/watchdog/wd_heartbeat.c0000664000076400007640000003312412245576267014671 00000000000000/* * $Header$ * * Handles watchdog connection, and protocol communication with pgpool-II * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(SO_BINDTODEVICE) #include #endif #include "pool.h" #include "pool_config.h" #include "md5.h" #include "watchdog.h" #include "wd_ext.h" #define MAX_BIND_TRIES 5 static RETSIGTYPE hb_sender_exit(int sig); static RETSIGTYPE hb_receiver_exit(int sig); static int hton_wd_hb_packet(WdHbPacket *to, WdHbPacket *from); static int ntoh_wd_hb_packet(WdHbPacket *to, WdHbPacket *from); static int packet_to_string_hb(WdHbPacket *pkt, char * str, int maxlen); /* create socket for sending heartbeat */ int wd_create_hb_send_socket(WdHbIf *hb_if) { int sock; int tos; /* create socket */ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { /* socket create failed */ pool_error("wd_create_hb_send_socket: Failed to create socket. reason: %s", strerror(errno)); return -1; } /* set socket option */ tos = IPTOS_LOWDELAY; if (setsockopt(sock, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) == -1 ) { pool_error("wd_create_hb_send_socket: setsockopt(IP_TOS) failed. reason: %s", strerror(errno)); close(sock); return -1; } if (hb_if->if_name[0] != '\0') { #if defined(SO_BINDTODEVICE) { if (geteuid() == 0) /* check root privileges */ { struct ifreq i; strlcpy(i.ifr_name, hb_if->if_name, sizeof(i.ifr_name)); if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &i, sizeof(i)) == -1) { pool_error("wd_create_hb_send_socket: setsockopt(SO_BINDTODEVICE) failed. reason: %s, device: %s", strerror(errno), i.ifr_name); close(sock); return -1; } pool_log("wd_create_hb_send_socket: bind send socket to device: %s", i.ifr_name); } else pool_log("wd_create_hb_send_socket: setsockopt(SO_BINDTODEVICE) requies root privilege"); } #else pool_log("wd_create_hb_send_socket: couldn't setsockopt(SO_BINDTODEVICE) on this platform"); #endif } #if defined(SO_REUSEPORT) { int one = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) == -1) { pool_error("wd_create_hb_send_socket: setsockopt(SO_REUSEPORT) failed. reason: %s", strerror(errno)); close(sock); return -1; } pool_log("wd_create_hb_send_socket: set SO_REUSEPORT"); } #endif if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) { pool_error("wd_create_hb_send_socket: setting close-on-exec flag failed. reason: %s", strerror(errno)); close(sock); return -1; } return sock; } /* create socket for receiving heartbeat */ int wd_create_hb_recv_socket(WdHbIf *hb_if) { struct sockaddr_in addr; int sock; const int one = 1; int bind_tries; int bind_is_done; memset(&(addr), 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(pool_config->wd_heartbeat_port); addr.sin_addr.s_addr = INADDR_ANY; /* create socket */ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { /* socket create failed */ pool_error("wd_create_hb_recv_socket: Failed to create socket. reason: %s", strerror(errno)); return -1; } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1 ) { pool_error("wd_create_hb_recv_socket: setsockopt(SO_REUSEADDR) failed. reason: %s", strerror(errno)); close(sock); return -1; } if (hb_if->if_name[0] != '\0') { #if defined(SO_BINDTODEVICE) { if (geteuid() == 0) /* check root privileges */ { struct ifreq i; strlcpy(i.ifr_name, hb_if->if_name, sizeof(i.ifr_name)); if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &i, sizeof(i)) == -1) { pool_error("wd_create_hb_recv_socket: setsockopt(SO_BINDTODEVICE) failed. reason: %s, devise: %s", strerror(errno), i.ifr_name); close(sock); return -1; } pool_log("wd_create_hb_recv_socket: bind receive socket to device: %s", i.ifr_name); } else pool_log("wd_create_hb_send_socket: setsockopt(SO_BINDTODEVICE) requies root privilege"); } #else pool_log("wd_create_hb_send_socket: couldn't setsockopt(SO_BINDTODEVICE) on this platform"); #endif } #if defined(SO_REUSEPORT) { if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) == -1) { pool_error("wd_create_hb_recv_socket: setsockopt(SO_REUSEPORT) failed. reason: %s", strerror(errno)); close(sock); return -1; } pool_log("wd_create_hb_recv_socket: set SO_REUSEPORT"); } #endif bind_is_done = 0; for (bind_tries = 0; !bind_is_done && bind_tries < MAX_BIND_TRIES; bind_tries++) { if (bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr)) < 0) { pool_log("wd_crate_hb_recv_socket: bind failed. reason: %s ... retrying", strerror(errno)); sleep(1); } else { bind_is_done = 1; } } /* bind failed finally */ if (!bind_is_done) { pool_error("wd_crate_hb_recv_socket: unable to bind socket. reason: %s", strerror(errno)); close(sock); return -1; } if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) { pool_error("wd_create_hb_recv_socket: setting close-on-exec flag failed. reason: %s", strerror(errno)); close(sock); return -1; } return sock; } /* send heartbeat signal */ int wd_hb_send(int sock, WdHbPacket * pkt, int len, const char * host, const int port) { int rtn; struct sockaddr_in addr; struct hostent *hp; WdHbPacket buf; if (!host || !strlen(host)) { pool_error("wd_hb_send: host name is empty"); return -1; } hp = gethostbyname(host); if ((hp == NULL) || (hp->h_addrtype != AF_INET)) { pool_error("wd_hb_send: gethostbyname() failed: %s host: %s", hstrerror(h_errno), host); return -1; } memmove((char *) &(addr.sin_addr), (char *) hp->h_addr, hp->h_length); addr.sin_family = AF_INET; addr.sin_port = htons(port); hton_wd_hb_packet(&buf, pkt); if ((rtn = sendto(sock, &buf, sizeof(WdHbPacket), 0, (struct sockaddr *)&addr, sizeof(addr))) != len) { pool_error("wd_hb_send: failed to sent packet to %s", host); return WD_NG; } pool_debug("wd_hb_send: send %d byte packet", rtn); return WD_OK; } /* receive heartbeat signal */ int wd_hb_recv(int sock, WdHbPacket * pkt) { int rtn; struct sockaddr_in senderinfo; socklen_t addrlen; WdHbPacket buf; addrlen = sizeof(senderinfo); rtn = recvfrom(sock, &buf, sizeof(WdHbPacket), 0, (struct sockaddr *)&senderinfo, &addrlen); if (rtn < 0) { pool_error("wd_hb_recv: failed to receive packet"); return WD_NG; } else if (rtn == 0) { pool_error("wd_hb_recv: received zero bytes"); return WD_NG; } else { pool_debug("wd_hb_recv: received %d byte packet", rtn); } ntoh_wd_hb_packet(pkt, &buf); return WD_OK; } /* fork heartbeat receiver child */ pid_t wd_hb_receiver(int fork_wait_time, WdHbIf *hb_if) { int sock; pid_t pid = 0; WdHbPacket pkt; struct timeval tv; char from[WD_MAX_HOST_NAMELEN]; int from_pgpool_port; char buf[(MD5_PASSWD_LEN+1)*2]; char pack_str[WD_MAX_PACKET_STRING]; int pack_str_len; WdInfo * p; pid = fork(); if (pid != 0) { if (pid == -1) pool_error("wd_hb_receiver: fork() failed."); return pid; } if (fork_wait_time > 0) { sleep(fork_wait_time); } myargv = save_ps_display_args(myargc, myargv); POOL_SETMASK(&UnBlockSig); signal(SIGTERM, hb_receiver_exit); signal(SIGINT, hb_receiver_exit); signal(SIGQUIT, hb_receiver_exit); signal(SIGCHLD, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGALRM, SIG_IGN); init_ps_display("", "", "", ""); if ( (sock = wd_create_hb_recv_socket(hb_if)) < 0) { pool_error("wd_hb_receiver: socket create failed"); hb_receiver_exit(SIGTERM); } set_ps_display("heartbeat receiver", false); for(;;) { /* receive heartbeat signal */ if (wd_hb_recv(sock, &pkt) == WD_OK) { /* authentication */ if (strlen(pool_config->wd_authkey)) { /* calculate hash from packet */ pack_str_len = packet_to_string_hb(&pkt, pack_str, sizeof(pack_str)); wd_calc_hash(pack_str, pack_str_len, buf); if (strcmp(pkt.hash, buf)) { pool_log("wd_hb_receiver: authentication failed"); continue; } } /* get current time */ gettimeofday(&tv, NULL); /* who send this packet? */ strlcpy(from, pkt.from, sizeof(from)); from_pgpool_port = pkt.from_pgpool_port; p = WD_List; while (p->status != WD_END) { if (!strcmp(p->hostname, from) && p->pgpool_port == from_pgpool_port) { /* ignore the packet from down pgpool */ if (pkt.status == WD_DOWN) { pool_debug("wd_hb_receiver: heatbeat signal from down pgpool (%s) is ignored", from); break; } /* this is the first packet or the latest packet */ if (!WD_TIME_ISSET(p->hb_send_time) || WD_TIME_BEFORE(p->hb_send_time, pkt.send_time)) { pool_debug("wd_hb_receiver: received heartbeat signal from %s:%d", from, from_pgpool_port); p->hb_send_time = pkt.send_time; p->hb_last_recv_time = tv; } break; } p++; } } } return pid; } /* fork heartbeat sender child */ pid_t wd_hb_sender(int fork_wait_time, WdHbIf *hb_if) { int sock; pid_t pid = 0; WdHbPacket pkt; WdInfo * p = WD_List; char pack_str[WD_MAX_PACKET_STRING]; int pack_str_len; pid = fork(); if (pid != 0) { if (pid == -1) pool_error("wd_hb_sender: fork() failed."); return pid; } if (fork_wait_time > 0) { sleep(fork_wait_time); } myargv = save_ps_display_args(myargc, myargv); POOL_SETMASK(&UnBlockSig); signal(SIGTERM, hb_sender_exit); signal(SIGINT, hb_sender_exit); signal(SIGQUIT, hb_sender_exit); signal(SIGCHLD, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGALRM, SIG_IGN); init_ps_display("", "", "", ""); if ( (sock = wd_create_hb_send_socket(hb_if)) < 0) { pool_error("wd_hb_sender: socket create failed"); hb_sender_exit(SIGTERM); } set_ps_display("heartbeat sender", false); for(;;) { /* contents of packet */ gettimeofday(&pkt.send_time, NULL); strlcpy(pkt.from, pool_config->wd_hostname, sizeof(pkt.from)); pkt.from_pgpool_port = pool_config->port; pkt.status = p->status; /* authentication key */ if (strlen(pool_config->wd_authkey)) { /* calculate hash from packet */ pack_str_len = packet_to_string_hb(&pkt, pack_str, sizeof(pack_str)); wd_calc_hash(pack_str, pack_str_len, pkt.hash); } /* send heartbeat signal */ wd_hb_send(sock, &pkt, sizeof(pkt), hb_if->addr, hb_if->dest_port); pool_debug("wd_hb_sender: send heartbeat signal to %s:%d", hb_if->addr, hb_if->dest_port); sleep(pool_config->wd_heartbeat_keepalive); } return pid; } static RETSIGTYPE hb_sender_exit(int sig) { switch (sig) { case SIGTERM: /* smart shutdown */ case SIGINT: /* fast shutdown */ case SIGQUIT: /* immediate shutdown */ pool_debug("hb_sender child receives shutdown request signal %d", sig); break; default: pool_error("hb_sender child receives unknown signal %d", sig); } exit(0); } static RETSIGTYPE hb_receiver_exit(int sig) { switch (sig) { case SIGTERM: /* smart shutdown */ case SIGINT: /* fast shutdown */ case SIGQUIT: /* immediate shutdown */ pool_debug("hb_receiver child receives shutdown request signal %d", sig); break; default: pool_error("hb_receiver child receives unknown signal %d", sig); } exit(0); } static int hton_wd_hb_packet(WdHbPacket * to, WdHbPacket * from) { if ((to == NULL) || (from == NULL)) { return WD_NG; } to->status = htonl(from->status); to->send_time.tv_sec = htonl(from->send_time.tv_sec); to->send_time.tv_usec = htonl(from->send_time.tv_usec); memcpy(to->from, from->from, sizeof(to->from)); to->from_pgpool_port = htonl(from->from_pgpool_port); memcpy(to->hash, from->hash, sizeof(to->hash)); return WD_OK; } static int ntoh_wd_hb_packet(WdHbPacket * to, WdHbPacket * from) { if ((to == NULL) || (from == NULL)) { return WD_NG; } to->status = ntohl(from->status); to->send_time.tv_sec = ntohl(from->send_time.tv_sec); to->send_time.tv_usec = ntohl(from->send_time.tv_usec); memcpy(to->from, from->from, sizeof(to->from)); to->from_pgpool_port = ntohl(from->from_pgpool_port); memcpy(to->hash, from->hash, sizeof(to->hash)); return WD_OK; } /* convert packet to string and return length of the string */ static int packet_to_string_hb(WdHbPacket *pkt, char *str, int maxlen) { int len; len = snprintf(str, maxlen, "status=%d tv_sec=%ld tv_usec=%ld from=%s", pkt->status, pkt->send_time.tv_sec, pkt->send_time.tv_usec, pkt->from); return len; } pgpool-II-3.3.2/watchdog/wd_if.c0000664000076400007640000000773612245576267013342 00000000000000/* * $Header$ * * Handles watchdog connection, and protocol communication with pgpool-II * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include #include #include #include #include #include #include #include #include "pool.h" #include "pool_config.h" #include "watchdog.h" #include "wd_ext.h" int wd_IP_up(void); int wd_IP_down(void); int wd_get_cmd(char * buf, char * cmd); static int exec_ifconfig(char * path,char * command); int wd_IP_up(void) { int rtn = WD_OK; char path[WD_MAX_PATH_LEN]; char cmd[128]; if (strlen(pool_config->delegate_IP) == 0) return WD_NG; if (WD_List->delegate_ip_flag == 0) { WD_List->delegate_ip_flag = 1; wd_get_cmd(cmd,pool_config->if_up_cmd); snprintf(path,sizeof(path),"%s/%s",pool_config->ifconfig_path,cmd); rtn = exec_ifconfig(path,pool_config->if_up_cmd); wd_get_cmd(cmd,pool_config->arping_cmd); snprintf(path,sizeof(path),"%s/%s",pool_config->arping_path,cmd); rtn = exec_ifconfig(path,pool_config->arping_cmd); } return rtn; } int wd_IP_down(void) { int rtn = WD_OK; char path[WD_MAX_PATH_LEN]; char cmd[128]; int i; if (strlen(pool_config->delegate_IP) == 0) return WD_NG; if (WD_List->delegate_ip_flag == 1) { WD_List->delegate_ip_flag = 0; wd_get_cmd(cmd,pool_config->if_down_cmd); snprintf(path, sizeof(path), "%s/%s", pool_config->ifconfig_path, cmd); rtn = exec_ifconfig(path,pool_config->if_down_cmd); if (rtn == WD_OK) { for (i = 0; i < 3; i++) { if (wd_is_unused_ip(pool_config->delegate_IP)) break; } if (i >= 3) rtn = WD_NG; } if (rtn == WD_OK) pool_log("wd_IP_down: ifconfig down succeeded"); else pool_error("wd_IP_down: ifconfig down failed"); } else { pool_debug("wd_IP_down: not delegate IP holder"); } return rtn; } int wd_get_cmd(char * buf, char * cmd) { int i,j; i = 0; while(isspace(cmd[i]) != 0) { i++; } j = 0; while(isspace(cmd[i]) == 0) { buf[j++] = cmd[i++]; } buf[j] = '\0'; return strlen(buf); } static int exec_ifconfig(char * path,char * command) { int pfd[2]; int status; char * args[24]; int pid, i = 0; char buf[256]; char *bp, *ep; if (pipe(pfd) == -1) { pool_error("exec_ifconfig: pipe open error:%s",strerror(errno)); return WD_NG; } memset(buf,0,sizeof(buf)); strlcpy(buf,command,sizeof(buf)); bp = buf; while (*bp == ' ') { bp ++; } while (*bp != '\0') { ep = strchr(bp,' '); if (ep != NULL) { *ep = '\0'; } if (!strncmp(bp,"$_IP_$",5)) { args[i++] = pool_config->delegate_IP; } else { args[i++] = bp; } if (ep != NULL) { bp = ep +1; while (*bp == ' ') { bp ++; } } else { break; } } args[i++] = NULL; pid = fork(); if (pid == 0) { close(STDOUT_FILENO); dup2(pfd[1], STDOUT_FILENO); close(pfd[0]); status = execv(path,args); exit(0); } else { close(pfd[1]); for (;;) { int result; result = wait(&status); if (result < 0) { if (errno == EINTR) continue; return WD_NG; } if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) return WD_NG; else break; } close(pfd[0]); } return WD_OK; } pgpool-II-3.3.2/watchdog/wd_packet.c0000664000076400007640000006237312245576267014211 00000000000000/* * $Header$ * * Handles watchdog connection, and protocol communication with pgpool-II * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pool.h" #include "pool_config.h" #include "watchdog.h" #include "wd_ext.h" #include "pool_memqcache.h" typedef enum { WD_SEND_TO_MASTER = 0, WD_SEND_WITHOUT_MASTER, WD_SEND_ALL_NODES } WD_SEND_TYPE; int wd_startup(void); int wd_declare(void); int wd_stand_for_master(void); int wd_notice_server_down(void); int wd_update_info(void); int wd_authentication_failed(int sock); int wd_create_send_socket(char * hostname, int port); int wd_create_recv_socket(int port); int wd_accept(int sock); int wd_send_packet(int sock, WdPacket * snd_pack); int wd_recv_packet(int sock, WdPacket * buf); int wd_escalation(void); int wd_start_recovery(void); int wd_end_recovery(void); int wd_send_failback_request(int node_id); int wd_degenerate_backend_set(int *node_id_set, int count); int wd_promote_backend(int node_id); int wd_set_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count); int wd_send_packet_no(WD_PACKET_NO packet_no ); int wd_send_lock_packet(WD_PACKET_NO packet_no, WD_LOCK_ID lock_id); static int wd_send_node_packet(WD_PACKET_NO packet_no, int *node_id_set, int count); static int wd_chk_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count); void wd_calc_hash(const char *str, int len, char *buf); int wd_packet_to_string(WdPacket *pkt, char *str, int maxlen); static void * wd_thread_negotiation(void * arg); static int send_packet_for_all(WdPacket *packet); static int send_packet_4_nodes(WdPacket *packet, WD_SEND_TYPE type); static int hton_wd_packet(WdPacket * to, WdPacket * from); static int ntoh_wd_packet(WdPacket * to, WdPacket * from); static int hton_wd_node_packet(WdPacket * to, WdPacket * from); static int ntoh_wd_node_packet(WdPacket * to, WdPacket * from); static int hton_wd_lock_packet(WdPacket * to, WdPacket * from); static int ntoh_wd_lock_packet(WdPacket * to, WdPacket * from); int wd_startup(void) { int rtn; /* send add request packet */ rtn = wd_send_packet_no(WD_ADD_REQ); return rtn; } int wd_declare(void) { int rtn; /* send declare new master packet */ pool_debug("wd_declare: send the packet to declare the new master"); rtn = wd_send_packet_no(WD_DECLARE_NEW_MASTER); return rtn; } int wd_stand_for_master(void) { int rtn; /* send stand for master packet */ pool_debug("wd_stand_for_master: send the packet to be the new master"); rtn = wd_send_packet_no(WD_STAND_FOR_MASTER); return rtn; } int wd_notice_server_down(void) { int rtn; wd_IP_down(); /* send notice server down packet */ rtn = wd_send_packet_no(WD_SERVER_DOWN); return rtn; } int wd_update_info(void) { int rtn; /* send info request packet */ rtn = wd_send_packet_no(WD_INFO_REQ); return rtn; } /* send authentication failed packet */ int wd_authentication_failed(int sock) { int rtn; WdPacket send_packet; memset(&send_packet, 0, sizeof(WdPacket)); send_packet.packet_no = WD_AUTH_FAILED; memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); rtn = wd_send_packet(sock, &send_packet); return rtn; } int wd_send_packet_no(WD_PACKET_NO packet_no ) { int rtn = WD_OK; WdPacket packet; memset(&packet, 0, sizeof(WdPacket)); /* set packet no and self information */ packet.packet_no = packet_no; memcpy(&(packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); /* send packet for all watchdogs */ rtn = send_packet_for_all(&packet); return rtn; } int wd_create_send_socket(char * hostname, int port) { int sock; int one = 1; size_t len = 0; struct sockaddr_in addr; struct hostent * hp; /* create socket */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { /* socket create failed */ pool_error("wd_create_send_socket: Failed to create socket. reason: %s", strerror(errno)); return -1; } /* set socket option */ if ( setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1 ) { pool_error("wd_create_send_socket: setsockopt(TCP_NODELAY) failed. reason: %s", strerror(errno)); close(sock); return -1; } if ( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) == -1 ) { pool_error("wd_create_send_socket: setsockopt(SO_KEEPALIVE) failed. reason: %s", strerror(errno)); close(sock); return -1; } /* set sockaddr_in */ memset(&addr,0,sizeof(addr)); addr.sin_family = AF_INET; hp = gethostbyname(hostname); if ((hp == NULL) || (hp->h_addrtype != AF_INET)) { hp = gethostbyaddr(hostname,strlen(hostname),AF_INET); if ((hp == NULL) || (hp->h_addrtype != AF_INET)) { pool_error("gethostbyname() failed: %s host: %s", hstrerror(h_errno), hostname); close(sock); return -1; } } memmove((char *)&(addr.sin_addr), (char *)hp->h_addr, hp->h_length); addr.sin_port = htons(port); len = sizeof(struct sockaddr_in); /* try to connect */ for (;;) { if (connect(sock,(struct sockaddr*)&addr, len) < 0) { if (errno == EINTR) continue; else if (errno == EISCONN) { return sock; } pool_log("wd_create_send_socket: connect() reports failure (%s). You can safely ignore this while starting up.", strerror(errno)); break; } return sock; } close(sock); return -1; } int wd_create_recv_socket(int port) { size_t len = 0; struct sockaddr_in addr; int one = 1; int sock = -1; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { /* socket create failed */ pool_error("wd_create_recv_socket: Failed to create socket. reason: %s", strerror(errno)); return -1; } if ( fcntl(sock, F_SETFL, O_NONBLOCK) == -1) { /* failed to set nonblock */ pool_error("wd_create_recv_socket: Failed to set nonblock. reason: %s", strerror(errno)); close(sock); return -1; } if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1 ) { /* setsockopt(SO_REUSEADDR) failed */ pool_error("wd_create_recv_socket: setspockopt(SO_REUSEADDR) failed. reason: %s", strerror(errno)); close(sock); return -1; } if ( setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1 ) { /* setsockopt(TCP_NODELAY) failed */ pool_error("wd_create_recv_socket: setsockopt(TCP_NODELAY) failed. reason: %s", strerror(errno)); close(sock); return -1; } if ( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) == -1 ) { /* setsockopt(SO_KEEPALIVE) failed */ pool_error("wd_create_recv_socket: setsockopt(SO_KEEPALIVE) failed. reason: %s", strerror(errno)); close(sock); return -1; } addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); len = sizeof(struct sockaddr_in); if ( bind(sock, (struct sockaddr *) & addr, len) < 0 ) { /* bind failed */ char *host = "", *serv = ""; char hostname[NI_MAXHOST], servname[NI_MAXSERV]; if (getnameinfo((struct sockaddr *) &addr, len, hostname, sizeof(hostname), servname, sizeof(servname), 0) == 0) { host = hostname; serv = servname; } pool_error("wd_create_recv_socket: bind(%s:%s) failed. reason: %s", host, serv, strerror(errno)); close(sock); return -1; } if ( listen(sock, MAX_WATCHDOG_NUM * 2) < 0 ) { /* listen failed */ pool_error("wd_create_recv_socket: listen() failed. reason: %s", strerror(errno)); close(sock); return -1; } return sock; } int wd_accept(int sock) { int fd = -1; fd_set rmask; fd_set emask; int rtn; struct sockaddr addr; socklen_t addrlen = sizeof(struct sockaddr); for (;;) { FD_ZERO(&rmask); FD_ZERO(&emask); FD_SET(sock,&rmask); FD_SET(sock,&emask); rtn = select(sock+1, &rmask, NULL, &emask, NULL ); if ( rtn < 0 ) { if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK ) { continue; } /* connection failed */ break; } else if ( rtn == 0 ) { /* connection failed */ break; } else if ( FD_ISSET(sock, &emask) ) { /* socket exception occurred */ break; } else if ( FD_ISSET(sock, &rmask) ) { fd = accept(sock, &addr, &addrlen); if (fd < 0) { if ( errno == EINTR || errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK ) { /* nothing to accept now */ continue; } /* accept failed */ return -1; } return fd; } } return -1; } int wd_send_packet(int sock, WdPacket * snd_pack) { fd_set wmask; struct timeval timeout; char * send_ptr = NULL; int send_size= 0; int buf_size = 0; int s = 0; int flag = 0; int rtn; WdPacket buf; memset(&buf,0,sizeof(WdPacket)); if ((snd_pack->packet_no >= WD_INVALID) && (snd_pack->packet_no <= WD_READY )) { hton_wd_packet((WdPacket *)&buf,snd_pack); } else if ((snd_pack->packet_no >= WD_START_RECOVERY) && (snd_pack->packet_no <= WD_NODE_FAILED)) { hton_wd_node_packet((WdPacket *)&buf,snd_pack); } else { hton_wd_lock_packet((WdPacket *)&buf,snd_pack); } send_ptr = (char*)&buf; buf_size = sizeof(WdPacket); for (;;) { timeout.tv_sec = WD_SEND_TIMEOUT; timeout.tv_usec = 0; FD_ZERO(&wmask); FD_SET(sock,&wmask); rtn = select(sock+1, (fd_set *)NULL, &wmask, (fd_set *)NULL, &timeout); if (rtn < 0 ) { if (errno == EAGAIN || errno == EINTR) { continue; } return WD_NG; } else if (rtn & FD_ISSET(sock, &wmask)) { s = send(sock,send_ptr + send_size,buf_size - send_size ,flag); if (s < 0) { if (errno == EINTR || errno == EAGAIN) continue; else { /* send failed */ return WD_NG; } } else if (s == 0) { /* send failed */ return WD_NG; } else /* s > 0 */ { send_size += s; if (send_size == buf_size) { return WD_OK; } } } } return WD_NG; } int wd_recv_packet(int sock, WdPacket * recv_pack) { int r = 0; WdPacket buf; char * read_ptr = (char *)&buf; int read_size = 0; int len = sizeof(WdPacket); memset(&buf,0,sizeof(WdPacket)); for (;;) { r = recv(sock,read_ptr + read_size ,len - read_size, 0); if (r < 0) { if (errno == EINTR || errno == EAGAIN) continue; else { pool_error("wd_recv_packet: recv failed"); return WD_NG; } } else if (r > 0) { read_size += r; if (read_size == len) { if (ntohl(buf.packet_no) <= WD_READY) { ntoh_wd_packet(recv_pack,&buf); } else if (ntohl((buf.packet_no) >= WD_START_RECOVERY) && (ntohl(buf.packet_no) <= WD_NODE_FAILED)) { ntoh_wd_node_packet(recv_pack,&buf); } else { ntoh_wd_lock_packet(recv_pack,&buf); } return WD_OK; } } else /* r == 0 */ { return WD_NG; } } return WD_NG; } static void * wd_thread_negotiation(void * arg) { WdPacketThreadArg * thread_arg; int sock; uintptr_t rtn; WdPacket recv_packet; WdInfo * p; char pack_str[WD_MAX_PACKET_STRING]; int pack_str_len; thread_arg = (WdPacketThreadArg *)arg; sock = thread_arg->sock; gettimeofday(&(thread_arg->packet->send_time), NULL); if (strlen(pool_config->wd_authkey)) { /* calculate hash from packet */ pack_str_len = wd_packet_to_string(thread_arg->packet, pack_str, sizeof(pack_str)); wd_calc_hash(pack_str, pack_str_len, thread_arg->packet->hash); } /* packet send to target watchdog */ rtn = (uintptr_t)wd_send_packet(sock, thread_arg->packet); if (rtn != WD_OK) { close(sock); pthread_exit((void *)rtn); } /* receive response packet */ memset(&recv_packet,0,sizeof(WdPacket)); rtn = (uintptr_t)wd_recv_packet(sock, &recv_packet); if (rtn != WD_OK) { close(sock); pthread_exit((void *)rtn); } rtn = WD_OK; switch (thread_arg->packet->packet_no) { case WD_ADD_REQ: if (recv_packet.packet_no == WD_ADD_ACCEPT) { memcpy(thread_arg->target, &(recv_packet.wd_body.wd_info),sizeof(WdInfo)); } else { rtn = WD_NG; } break; case WD_STAND_FOR_MASTER: if (recv_packet.packet_no == WD_MASTER_EXIST) { p = &(recv_packet.wd_body.wd_info); wd_set_wd_info(p); rtn = WD_NG; } break; case WD_STAND_FOR_LOCK_HOLDER: case WD_DECLARE_LOCK_HOLDER: if (recv_packet.packet_no == WD_LOCK_HOLDER_EXIST) { rtn = WD_NG; } break; case WD_DECLARE_NEW_MASTER: case WD_RESIGN_LOCK_HOLDER: if (recv_packet.packet_no != WD_READY) { rtn = WD_NG; } break; case WD_START_RECOVERY: case WD_FAILBACK_REQUEST: case WD_DEGENERATE_BACKEND: case WD_PROMOTE_BACKEND: rtn = (recv_packet.packet_no == WD_NODE_FAILED) ? WD_NG : WD_OK; break; case WD_UNLOCK_REQUEST: rtn = (recv_packet.packet_no == WD_LOCK_FAILED) ? WD_NG : WD_OK; break; case WD_AUTH_FAILED: pool_log("wd_thread_negotiation: watchdog authentication failed"); rtn = WD_NG; break; default: break; } close(sock); pthread_exit((void *)rtn); } static int send_packet_for_all(WdPacket *packet) { int rtn = WD_OK; /* send packet to master watchdog */ if (WD_MYSELF->status != WD_MASTER) rtn = send_packet_4_nodes(packet, WD_SEND_TO_MASTER ); /* send packet to other watchdogs */ if (rtn == WD_OK) { rtn = send_packet_4_nodes(packet, WD_SEND_WITHOUT_MASTER); } return rtn; } static int send_packet_4_nodes(WdPacket *packet, WD_SEND_TYPE type) { int rtn; WdInfo * p = WD_List; int i,cnt; int sock; int rc; pthread_attr_t attr; pthread_t thread[MAX_WATCHDOG_NUM]; WdPacketThreadArg thread_arg[MAX_WATCHDOG_NUM]; if (packet == NULL) { return WD_NG; } /* thread init */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); /* skip myself */ p++; WD_MYSELF->is_contactable = true; /* send packet to other watchdogs */ cnt = 0; while (p->status != WD_END) { /* don't send packet to pgpool in down */ if (p->status == WD_DOWN || (packet->packet_no != WD_ADD_REQ && p->status == WD_INIT)) { p->is_contactable = false; p++; continue; } if (type == WD_SEND_TO_MASTER ) { if (p->status != WD_MASTER) { p++; continue; } } else if (type == WD_SEND_WITHOUT_MASTER ) { if (p->status == WD_MASTER) { p++; continue; } } sock = wd_create_send_socket(p->hostname, p->wd_port); if (sock == -1) { pool_log("send_packet_4_nodes: packet for %s:%d is canceled", p->hostname, p->wd_port); p->is_contactable = false; p++; continue; } else { p->is_contactable = true; } thread_arg[cnt].sock = sock; thread_arg[cnt].target = p; thread_arg[cnt].packet = packet; rc = pthread_create(&thread[cnt], &attr, wd_thread_negotiation, (void*)&thread_arg[cnt]); cnt ++; p++; } pthread_attr_destroy(&attr); /* no packet is sent */ if (cnt == 0) { return WD_OK; } /* default return value */ if ((packet->packet_no == WD_STAND_FOR_MASTER) || (packet->packet_no == WD_STAND_FOR_LOCK_HOLDER) || (packet->packet_no == WD_DECLARE_LOCK_HOLDER) || (packet->packet_no == WD_START_RECOVERY)) { rtn = WD_OK; } else { rtn = WD_NG; } /* receive the results */ for (i=0; ipacket_no == WD_STAND_FOR_MASTER) || (packet->packet_no == WD_STAND_FOR_LOCK_HOLDER) || (packet->packet_no == WD_DECLARE_LOCK_HOLDER) || (packet->packet_no == WD_START_RECOVERY)) { /* if any result is NG then return NG */ if (result == WD_NG) { rtn = WD_NG; } } else { /* if any result is OK then return OK */ if (result == WD_OK) { rtn = WD_OK; } } i++; } return rtn; } static int hton_wd_packet(WdPacket * to, WdPacket * from) { WdInfo * to_info = NULL; WdInfo * from_info = NULL; if ((to == NULL) || (from == NULL)) { return WD_NG; } to_info = &(to->wd_body.wd_info); from_info = &(from->wd_body.wd_info); to->packet_no = htonl(from->packet_no); to->send_time.tv_sec = htonl(from->send_time.tv_sec); to->send_time.tv_usec = htonl(from->send_time.tv_usec); memcpy(to->hash, from->hash, sizeof(to->hash)); to_info->status = htonl(from_info->status); to_info->tv.tv_sec = htonl(from_info->tv.tv_sec); to_info->tv.tv_usec = htonl(from_info->tv.tv_usec); to_info->pgpool_port = htonl(from_info->pgpool_port); to_info->wd_port = htonl(from_info->wd_port); memcpy(to_info->hostname, from_info->hostname, sizeof(to_info->hostname)); memcpy(to_info->delegate_ip, from_info->delegate_ip, sizeof(to_info->delegate_ip)); return WD_OK; } static int ntoh_wd_packet(WdPacket * to, WdPacket * from) { WdInfo * to_info = NULL; WdInfo * from_info = NULL; if ((to == NULL) || (from == NULL)) { return WD_NG; } to_info = &(to->wd_body.wd_info); from_info = &(from->wd_body.wd_info); to->packet_no = ntohl(from->packet_no); to->send_time.tv_sec = ntohl(from->send_time.tv_sec); to->send_time.tv_usec = ntohl(from->send_time.tv_usec); memcpy(to->hash, from->hash, sizeof(to->hash)); to_info->status = ntohl(from_info->status); to_info->tv.tv_sec = ntohl(from_info->tv.tv_sec); to_info->tv.tv_usec = ntohl(from_info->tv.tv_usec); to_info->pgpool_port = ntohl(from_info->pgpool_port); to_info->wd_port = ntohl(from_info->wd_port); memcpy(to_info->hostname, from_info->hostname, sizeof(to_info->hostname)); memcpy(to_info->delegate_ip, from_info->delegate_ip, sizeof(to_info->delegate_ip)); return WD_OK; } static int hton_wd_node_packet(WdPacket * to, WdPacket * from) { WdNodeInfo * to_info = NULL; WdNodeInfo * from_info = NULL; int i; if ((to == NULL) || (from == NULL)) { return WD_NG; } to_info = &(to->wd_body.wd_node_info); from_info = &(from->wd_body.wd_node_info); to->packet_no = htonl(from->packet_no); to->send_time.tv_sec = htonl(from->send_time.tv_sec); to->send_time.tv_usec = htonl(from->send_time.tv_usec); memcpy(to->hash, from->hash, sizeof(to->hash)); to_info->node_num = htonl(from_info->node_num); for (i = 0 ; i < from_info->node_num ; i ++) { to_info->node_id_set[i] = htonl(from_info->node_id_set[i]); } return WD_OK; } static int ntoh_wd_node_packet(WdPacket * to, WdPacket * from) { WdNodeInfo * to_info = NULL; WdNodeInfo * from_info = NULL; int i; if ((to == NULL) || (from == NULL)) { return WD_NG; } to_info = &(to->wd_body.wd_node_info); from_info = &(from->wd_body.wd_node_info); to->packet_no = ntohl(from->packet_no); to->send_time.tv_sec = ntohl(from->send_time.tv_sec); to->send_time.tv_usec = ntohl(from->send_time.tv_usec); memcpy(to->hash, from->hash, sizeof(to->hash)); to_info->node_num = ntohl(from_info->node_num); for (i = 0 ; i < to_info->node_num ; i ++) { to_info->node_id_set[i] = ntohl(from_info->node_id_set[i]); } return WD_OK; } static int hton_wd_lock_packet(WdPacket * to, WdPacket * from) { WdLockInfo * to_info = NULL; WdLockInfo * from_info = NULL; if ((to == NULL) || (from == NULL)) { return WD_NG; } to_info = &(to->wd_body.wd_lock_info); from_info = &(from->wd_body.wd_lock_info); to->packet_no = htonl(from->packet_no); to->send_time.tv_sec = htonl(from->send_time.tv_sec); to->send_time.tv_usec = htonl(from->send_time.tv_usec); memcpy(to->hash, from->hash, sizeof(to->hash)); to_info->lock_id = htonl(from_info->lock_id); return WD_OK; } static int ntoh_wd_lock_packet(WdPacket * to, WdPacket * from) { WdLockInfo * to_info = NULL; WdLockInfo * from_info = NULL; if ((to == NULL) || (from == NULL)) { return WD_NG; } to_info = &(to->wd_body.wd_lock_info); from_info = &(from->wd_body.wd_lock_info); to->packet_no = ntohl(from->packet_no); to->send_time.tv_sec = ntohl(from->send_time.tv_sec); to->send_time.tv_usec = ntohl(from->send_time.tv_usec); memcpy(to->hash, from->hash, sizeof(to->hash)); to_info->lock_id = ntohl(from_info->lock_id); return WD_OK; } int wd_escalation(void) { int rtn; pool_log("wd_escalation: escalating to master pgpool"); /* clear shared memory cache */ if (pool_config->memory_cache_enabled && pool_is_shmem_cache() && pool_config->clear_memqcache_on_escalation) { pool_log("wd_escalation: clear all the query cache on shared memory"); pool_clear_memory_cache(); } /* execute escalation command */ if (strlen(pool_config->wd_escalation_command)) { system(pool_config->wd_escalation_command); } /* interface up as delegate IP */ if (strlen(pool_config->delegate_IP) != 0) wd_IP_up(); /* set master status to the wd list */ wd_set_wd_list(pool_config->wd_hostname, pool_config->port, pool_config->wd_port, pool_config->delegate_IP, NULL, WD_MASTER); /* send declare packet */ rtn = wd_declare(); if (rtn == WD_OK) { pool_log("wd_escalation: escalated to master pgpool successfully"); } return rtn; } int wd_start_recovery(void) { int rtn; /* send start recovery packet */ rtn = wd_send_packet_no(WD_START_RECOVERY); return rtn; } int wd_end_recovery(void) { int rtn; /* send end recovery packet */ rtn = wd_send_packet_no(WD_END_RECOVERY); return rtn; } int wd_send_failback_request(int node_id) { int rtn = 0; int n = node_id; /* if failback packet is received already, do nothing */ if (wd_chk_node_mask(WD_FAILBACK_REQUEST,&n,1)) { return WD_OK; } /* send failback packet */ rtn = wd_send_node_packet(WD_FAILBACK_REQUEST, &n, 1); return rtn; } int wd_degenerate_backend_set(int *node_id_set, int count) { int rtn = 0; /* if degenerate packet is received already, do nothing */ if (wd_chk_node_mask(WD_DEGENERATE_BACKEND,node_id_set,count)) { return WD_OK; } /* send degenerate packet */ rtn = wd_send_node_packet(WD_DEGENERATE_BACKEND, node_id_set, count); return rtn; } int wd_promote_backend(int node_id) { int rtn = 0; int n = node_id; /* if promote packet is received already, do nothing */ if (wd_chk_node_mask(WD_PROMOTE_BACKEND,&n,1)) { return WD_OK; } /* send promote packet */ rtn = wd_send_node_packet(WD_PROMOTE_BACKEND, &n, 1); return rtn; } static int wd_send_node_packet(WD_PACKET_NO packet_no, int *node_id_set, int count) { int rtn = 0; WdPacket packet; memset(&packet, 0, sizeof(WdPacket)); /* set add request packet */ packet.packet_no = packet_no; memcpy(packet.wd_body.wd_node_info.node_id_set,node_id_set,sizeof(int)*count); packet.wd_body.wd_node_info.node_num = count; /* send packet to all watchdogs */ rtn = send_packet_for_all(&packet); return rtn; } int wd_send_lock_packet(WD_PACKET_NO packet_no, WD_LOCK_ID lock_id) { int rtn = 0; WdPacket packet; memset(&packet, 0, sizeof(WdPacket)); /* set add request packet */ packet.packet_no = packet_no; packet.wd_body.wd_lock_info.lock_id= lock_id; /* send packet to all watchdogs */ rtn = send_packet_for_all(&packet); return rtn; } /* check mask, and if maskted return 1 and clear it, otherwise return 0 */ static int wd_chk_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count) { int rtn = 0; unsigned char mask = 0; int i; int offset = 0; mask = 1 << (packet_no - WD_START_RECOVERY); for ( i = 0 ; i < count ; i ++) { offset = *(node_id_set+i); if ((*(WD_Node_List + offset) & mask) != 0) { *(WD_Node_List + offset) ^= mask; rtn = 1; } } return rtn; } /* set mask */ int wd_set_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count) { int rtn = 0; unsigned char mask = 0; int i; int offset = 0; mask = 1 << (packet_no - WD_START_RECOVERY); for ( i = 0 ; i < count ; i ++) { offset = *(node_id_set+i); *(WD_Node_List + offset) |= mask; } return rtn; } /* calculate hash for authentication using packet contents */ void wd_calc_hash(const char *str, int len, char *buf) { char pass[(MAX_PASSWORD_SIZE + 1) / 2]; char username[(MAX_PASSWORD_SIZE + 1) / 2]; size_t pass_len; size_t username_len; size_t authkey_len; /* use first half of authkey as username, last half as password */ authkey_len = strlen(pool_config->wd_authkey); username_len = authkey_len / 2; pass_len = authkey_len - username_len; snprintf(username, username_len + 1, "%s", pool_config->wd_authkey); snprintf(pass, pass_len + 1, "%s", pool_config->wd_authkey + username_len); /* calculate hash using md5 encrypt */ pool_md5_encrypt(pass, username, strlen(username), buf + MD5_PASSWD_LEN + 1); buf[(MD5_PASSWD_LEN+1)*2-1] = '\0'; pool_md5_encrypt(buf+MD5_PASSWD_LEN+1, str, len, buf); buf[MD5_PASSWD_LEN] = '\0'; } int wd_packet_to_string(WdPacket *pkt, char *str, int maxlen) { int len; len = snprintf(str, maxlen, "no=%d tv_sec=%ld tv_usec=%ld", pkt->packet_no, pkt->send_time.tv_sec, pkt->send_time.tv_usec); return len; } pgpool-II-3.3.2/watchdog/wd_interlock.c0000664000076400007640000001644312245576267014731 00000000000000/* * $Header$ * * Handles watchdog connection, and protocol communication with pgpool-II * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include #include "pool.h" #include "pool_config.h" #include "watchdog.h" #include "wd_ext.h" static volatile bool * WD_Locks; int wd_init_interlock(void); void wd_start_interlock(bool by_health_check); void wd_end_interlock(void); void wd_leave_interlock(void); void wd_wait_for_lock(WD_LOCK_ID lock_id); bool wd_am_I_lock_holder(void); bool wd_is_locked(WD_LOCK_ID lock_id); void wd_set_lock(WD_LOCK_ID lock_id, bool value); int wd_unlock(WD_LOCK_ID lock_id); static void wd_update_lock_holder(void); static int wd_assume_lock_holder(void); static void wd_resign_lock_holder(void); static void wd_lock_all(void); static void wd_confirm_contactable(void); static void sleep_in_waiting(void); #define WD_INTERLOCK_WAIT_MSEC 500 #define WD_INTERLOCK_TIMEOUT_SEC 10 #define WD_INTERLOCK_WAIT_COUNT ((int) ((WD_INTERLOCK_TIMEOUT_SEC * 1000)/WD_INTERLOCK_WAIT_MSEC)) /* initialize interlock */ int wd_init_interlock(void) { int alloc_size; /* allocate WD_lock_holder */ if (WD_Locks == NULL) { alloc_size = sizeof(bool) * WD_MAX_LOCK_NUM; WD_Locks = pool_shared_memory_create(alloc_size); if (WD_Locks == NULL) { pool_error("wd_init_interlock: failed to allocate WD_Locks"); return WD_NG; } memset((void *)WD_Locks, 0, alloc_size); } return WD_OK; } /* notify to start interlocking */ void wd_start_interlock(bool by_health_check) { int count; int node_id; pool_log("wd_start_interlock: start interlocking"); /* confirm other pgpools are contactable */ wd_confirm_contactable(); /* lock all the resource */ wd_lock_all(); wd_set_interlocking(WD_MYSELF, true); wd_send_packet_no(WD_START_INTERLOCK); /* try to assume lock holder */ wd_assume_lock_holder(); /* * If it is due to DB down detection by healthcheck, send failover request * to other pgpools because detection of DB down on the others may be late. */ if (by_health_check && wd_am_I_lock_holder()) { node_id = Req_info->node_id[0]; wd_degenerate_backend_set(&node_id, 1); } /* wait for all pgpools starting interlock */ count = WD_INTERLOCK_WAIT_COUNT; while (wd_is_locked(WD_FAILOVER_START_LOCK)) { if (WD_MYSELF->status == WD_DOWN) { wd_set_lock_holder(WD_MYSELF, false); return; } if (wd_am_I_lock_holder() && wd_are_interlocking_all()) { wd_unlock(WD_FAILOVER_START_LOCK); } sleep_in_waiting(); if (--count < 0) { pool_error("wd_start_interlock: timed out"); break; } } } /* notify to end interlocking */ void wd_end_interlock(void) { int count; pool_log("wd_end_interlock: end interlocking"); wd_set_interlocking(WD_MYSELF, false); wd_send_packet_no(WD_END_INTERLOCK); /* wait for all pgpools ending interlock */ count = WD_INTERLOCK_WAIT_COUNT; while (wd_is_locked(WD_FAILOVER_END_LOCK)) { if (WD_MYSELF->status == WD_DOWN) { wd_set_lock_holder(WD_MYSELF, false); break; } if (wd_am_I_lock_holder() && !wd_get_interlocking()) { wd_unlock(WD_FAILOVER_END_LOCK); } sleep_in_waiting(); if (--count < 0) { pool_error("wd_end_interlock: timed out"); break; } } if (wd_am_I_lock_holder()) wd_resign_lock_holder(); wd_clear_interlocking_info(); } /* leave from interlocking by the wayside */ void wd_leave_interlock(void) { pool_log("wd_leave_interlock: leaving from interlocking"); if (wd_am_I_lock_holder()) wd_resign_lock_holder(); wd_end_interlock(); } /* if lock holder return true otherwise false */ bool wd_am_I_lock_holder(void) { wd_update_lock_holder(); return WD_MYSELF->is_lock_holder; } /* waiting for the lock or to be lock holder */ void wd_wait_for_lock(WD_LOCK_ID lock_id) { int count; count = WD_INTERLOCK_WAIT_COUNT; while (wd_is_locked(lock_id)) { if (WD_MYSELF->status == WD_DOWN) { wd_set_lock_holder(WD_MYSELF, false); return; } if (wd_am_I_lock_holder()) break; sleep_in_waiting(); if (--count < 0) { pool_error("wd_wait_for_lock: timed out"); break; } } } /* * assume lock holder * return WD_OK if success. */ static int wd_assume_lock_holder(void) { int rtn = WD_NG; wd_set_lock_holder(WD_MYSELF, false); if (WD_MYSELF->status == WD_DOWN) return WD_NG; /* * confirm contatable master exists; * If contactable master doesn't exists, WD_STAND_FOR_LOCK_HOLDER always * returns WD_OK, eventually multiple pgpools can become lock_holder. * Down of the host on which master pgpool was working is the case. */ while (!wd_is_contactable_master()) { if (WD_MYSELF->status == WD_DOWN) return WD_NG; } /* I'm master and not lock holder, or I succeeded to become lock holder */ if ((WD_MYSELF->status == WD_MASTER && wd_get_lock_holder() == NULL) || (wd_send_packet_no(WD_STAND_FOR_LOCK_HOLDER) == WD_OK)) { if (wd_send_packet_no(WD_DECLARE_LOCK_HOLDER) == WD_OK) { wd_set_lock_holder(WD_MYSELF, true); pool_log("wd_assume_lock_holder: become a new lock holder"); rtn = WD_OK; } } return rtn; } /* * update information of who's lock holder * Note that a lock holder pgpool may go down accidentally during interlocking. */ static void wd_update_lock_holder(void) { /* assume lock holder if not exist */ while (wd_get_lock_holder() == NULL) { if (WD_MYSELF->status == WD_DOWN) return; wd_assume_lock_holder(); } } /* resign lock holder */ static void wd_resign_lock_holder(void) { wd_set_lock_holder(WD_MYSELF, false); wd_send_packet_no(WD_RESIGN_LOCK_HOLDER); } /* returns true if lock_id is locked */ bool wd_is_locked(WD_LOCK_ID lock_id) { return WD_Locks[lock_id]; } /* lock of unlock a resource */ void wd_set_lock(WD_LOCK_ID lock_id, bool value) { WD_Locks[lock_id] = value; } /* lock all the resource */ static void wd_lock_all(void) { int i; for (i = 0; i < WD_MAX_LOCK_NUM; i++) wd_set_lock(i, true); } /* unlock a resource */ int wd_unlock(WD_LOCK_ID lock_id) { int rtn; wd_set_lock(lock_id, false); rtn = wd_send_lock_packet(WD_UNLOCK_REQUEST, lock_id); pool_debug("wd_unlock: send unlock request: %d", lock_id); return rtn; } /* confirm other pgpools are contactable */ static void wd_confirm_contactable(void) { int count; count = WD_INTERLOCK_WAIT_COUNT; while (!wd_are_contactable_all()) { if (WD_MYSELF->status == WD_DOWN) return; sleep_in_waiting(); if (--count < 0) { pool_error("wd_confirm_contactable: timed out"); break; } } } static void sleep_in_waiting(void) { struct timeval t = {0, WD_INTERLOCK_WAIT_MSEC * 1000}; select(0, NULL, NULL, NULL, &t); } pgpool-II-3.3.2/watchdog/Makefile.am0000664000076400007640000000044312245576267014126 00000000000000noinst_LIBRARIES = lib-watchdog.a lib_watchdog_a_SOURCES = \ watchdog.c \ watchdog.h \ wd_child.c \ wd_ext.h \ wd_if.c \ wd_init.c \ wd_lifecheck.c \ wd_list.c \ wd_packet.c \ wd_ping.c \ wd_heartbeat.c \ wd_interlock.c AM_CPPFLAGS = -D_GNU_SOURCE -I .. -I @PGSQL_INCLUDE_DIR@ pgpool-II-3.3.2/watchdog/wd_lifecheck.c0000664000076400007640000002546512245576267014660 00000000000000/* * $Header$ * * Handles watchdog connection, and protocol communication with pgpool-II * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include #include #include #include #include #include #include #include "pool.h" #include "pool_config.h" #include "watchdog.h" #include "wd_ext.h" #include "libpq-fe.h" int is_wd_lifecheck_ready(void); int wd_lifecheck(void); int wd_ping_pgpool(WdInfo * pgpool); static void * thread_ping_pgpool(void * arg); static PGconn * create_conn(char * hostname, int port); static int pgpool_down(WdInfo * pool); static void check_pgpool_status(void); static void check_pgpool_status_by_query(void); static void check_pgpool_status_by_hb(void); static int ping_pgpool(PGconn * conn); static int is_parent_alive(void); int is_wd_lifecheck_ready(void) { int rtn = WD_OK; WdInfo * p = WD_List; int i = 0; while (p->status != WD_END) { /* query mode */ if (!strcmp(pool_config->wd_lifecheck_method, MODE_QUERY)) { if (wd_ping_pgpool(p) == WD_NG) { pool_debug("is_wd_lifecheck_ready: pgpool %d (%s:%d) has not started yet", i, p->hostname, p->pgpool_port); rtn = WD_NG; } } /* heartbeat mode */ else if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT)) { if (p == WD_List) { p++; i++; continue; } if (!WD_TIME_ISSET(p->hb_last_recv_time) || !WD_TIME_ISSET(p->hb_send_time)) { pool_debug("is_wd_lifecheck_ready: pgpool %d (%s:%d) has not send the heartbeat signal yet", i, p->hostname, p->pgpool_port); rtn = WD_NG; } } /* otherwise */ else { pool_error("is_wd_lifecheck_ready: unkown watchdog mode %s", pool_config->wd_lifecheck_method); return WD_NG; } p ++; i ++; } return rtn; } /* * Check if pgpool is living */ int wd_lifecheck(void) { struct timeval tv; /* I'm in down.... */ if (WD_MYSELF->status == WD_DOWN) { pool_error("wd_lifecheck: watchdog status is DOWN. You need to restart pgpool"); return WD_NG; } /* set startup time */ gettimeofday(&tv, NULL); /* check upper connection */ if (strlen(pool_config->trusted_servers) && wd_is_upper_ok(pool_config->trusted_servers) != WD_OK) { pool_error("wd_lifecheck: failed to connect to any trusted servers"); if (WD_MYSELF->status == WD_MASTER && strlen(pool_config->delegate_IP) != 0) { wd_IP_down(); } wd_set_myself(&tv, WD_DOWN); wd_notice_server_down(); return WD_NG; } /* skip lifecheck during recovery execution */ if (*InRecovery != RECOVERY_INIT) { return WD_OK; } /* check and update pgpool status */ check_pgpool_status(); return WD_OK; } /* * check and update pgpool status */ static void check_pgpool_status() { /* query mode */ if (!strcmp(pool_config->wd_lifecheck_method, MODE_QUERY)) { check_pgpool_status_by_query(); } /* heartbeat mode */ else if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT)) { check_pgpool_status_by_hb(); } } static void check_pgpool_status_by_hb(void) { int cnt; WdInfo * p = WD_List; struct timeval tv; gettimeofday(&tv, NULL); cnt = 0; while (p->status != WD_END) { pool_debug("check_pgpool_status_by_hb: checking pgpool %d (%s:%d)", cnt, p->hostname, p->pgpool_port); /* about myself */ if (p == WD_MYSELF) { /* parent is dead so it's orphan.... */ if (is_parent_alive() == WD_NG && WD_MYSELF->status != WD_DOWN) { pool_debug("check_pgpool_status_by_hb: NG; the main pgpool process does't exist."); pool_log("check_pgpool_status_by_hb: lifecheck failed. pgpool %d (%s:%d) seems not to be working", cnt, p->hostname, p->pgpool_port); wd_set_myself(&tv, WD_DOWN); wd_notice_server_down(); } /* otherwise, the parent would take care of children. */ else { pool_debug("check_pgpool_status_by_hb: OK; status %d", p->status); } } /* about other pgpools, check the latest heartbeat. */ else { if (p->status == WD_DOWN) { pool_log("check_pgpool_status_by_hb: pgpool %d (%s:%d) is in down status", cnt, p->hostname, p->pgpool_port); } else if (wd_check_heartbeat(p) == WD_NG) { pool_debug("check_pgpool_status_by_hb: NG; status %d", p->status); pool_log("check_pgpool_status_by_hb: lifecheck failed. pgpool %d (%s:%d) seems not to be working", cnt, p->hostname, p->pgpool_port); if (p->status != WD_DOWN) pgpool_down(p); } else { pool_debug("check_pgpool_status_by_hb: OK; status %d", p->status); } } p++; cnt++; if (cnt >= MAX_WATCHDOG_NUM) { pool_error("check_pgpool_status_by_hb: pgpool num is out of range(%d)",cnt); break; } } } static void check_pgpool_status_by_query(void) { WdInfo * p = WD_List; struct timeval tv; pthread_attr_t attr; pthread_t thread[MAX_WATCHDOG_NUM]; WdPgpoolThreadArg thread_arg[MAX_WATCHDOG_NUM]; int rc; int i,cnt; /* set startup time */ gettimeofday(&tv, NULL); /* thread init */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); /* send queries to all pgpools using threads */ cnt = 0; while (p->status != WD_END) { if (p->status != WD_DOWN) { thread_arg[cnt].conn = create_conn(p->hostname, p->pgpool_port); rc = pthread_create(&thread[cnt], &attr, thread_ping_pgpool, (void*)&thread_arg[cnt]); } p ++; cnt ++; if (cnt >= MAX_WATCHDOG_NUM) { pool_error("check_pgpool_status_by_query: pgpool num is out of range(%d)",cnt); break; } } pthread_attr_destroy(&attr); /* check results of queries */ p = WD_List; for (i = 0; i < cnt; ) { int result; pool_debug("check_pgpool_status_by_query: checking pgpool %d (%s:%d)", i, p->hostname, p->pgpool_port); if (p->status == WD_DOWN) { pool_log("check_pgpool_status_by_query: pgpool %d (%s:%d) is in down status", i, p->hostname, p->pgpool_port); i++; p++; continue; } else { rc = pthread_join(thread[i], (void **)&result); if ((rc != 0) && (errno == EINTR)) { usleep(100); continue; } } if (result == WD_OK) { pool_debug("check_pgpool_status_by_query: OK; status: %d", p->status); /* life point init */ p->life = pool_config->wd_life_point; } else { pool_debug("check_pgpool_status_by_query: NG; status: %d life:%d", p->status, p->life); if (p->life > 0) { p->life --; } /* pgpool goes down */ if (p->life <= 0) { pool_log("check_pgpool_status_by_query: lifecheck failed %d times. pgpool %d (%s:%d) seems not to be working", pool_config->wd_life_point, i, p->hostname, p->pgpool_port); /* It's me! */ if ((i == 0) && (WD_MYSELF->status != WD_DOWN)) { wd_set_myself(&tv, WD_DOWN); wd_notice_server_down(); } /* It's other pgpool */ else if (p->status != WD_DOWN) pgpool_down(p); } } i++; p++; } } /* * Thread function to send lifecheck query to pgpool * Used in wd_lifecheck. */ static void * thread_ping_pgpool(void * arg) { uintptr_t rtn; WdPgpoolThreadArg * thread_arg; PGconn * conn; thread_arg = (WdPgpoolThreadArg *)arg; conn = thread_arg->conn; rtn = (uintptr_t)ping_pgpool(conn); pthread_exit((void *)rtn); } /* * Create connection to pgpool */ static PGconn * create_conn(char * hostname, int port) { static char conninfo[1024]; PGconn *conn; if (strlen(pool_config->wd_lifecheck_dbname) == 0) { pool_error("create_conn: wd_lifecheck_dbname is empty"); return NULL; } if (strlen(pool_config->wd_lifecheck_user) == 0) { pool_error("create_conn: wd_lifecheck_user is empty"); return NULL; } snprintf(conninfo,sizeof(conninfo), "host='%s' port='%d' dbname='%s' user='%s' password='%s' connect_timeout='%d'", hostname, port, pool_config->wd_lifecheck_dbname, pool_config->wd_lifecheck_user, pool_config->wd_lifecheck_password, pool_config->wd_interval / 2 + 1); conn = PQconnectdb(conninfo); if (PQstatus(conn) != CONNECTION_OK) { pool_debug("create_conn: Connection to database failed: %s", PQerrorMessage(conn)); PQfinish(conn); return NULL; } return conn; } /* handle other pgpool's down */ static int pgpool_down(WdInfo * pool) { int rtn = WD_OK; WD_STATUS prev_status; pool_log("pgpool_down: %s:%d is going down", pool->hostname, pool->pgpool_port); prev_status = pool->status; pool->status = WD_DOWN; /* the active pgpool goes down and I'm sandby pgpool */ if (prev_status == WD_MASTER && WD_MYSELF->status == WD_NORMAL) { if (wd_am_I_oldest() == WD_OK) { pool_log("pgpool_down: I'm oldest so standing for master"); /* stand for master */ rtn = wd_stand_for_master(); if (rtn == WD_OK) { /* win */ wd_escalation(); } else { /* rejected by others */ pool->status = prev_status; } } } return rtn; } /* * Check if pgpool is alive using heartbeat signal. */ int wd_check_heartbeat(WdInfo * pgpool) { int interval; struct timeval tv; gettimeofday(&tv, NULL); interval = WD_TIME_DIFF_SEC(tv, pgpool->hb_last_recv_time); pool_debug("wd_check_heartbeat: the latest heartbeat from %s:%d received %d seconds ago", pgpool->hostname, pgpool->pgpool_port, interval); if (interval > pool_config->wd_heartbeat_deadtime) return WD_NG; else return WD_OK; } /* * Check if pgpool can accept the lifecheck query. */ int wd_ping_pgpool(WdInfo * pgpool) { int rtn; PGconn * conn; conn = create_conn(pgpool->hostname, pgpool->pgpool_port); rtn = ping_pgpool(conn); return rtn; } /* inner function for issueing lifecheck query */ static int ping_pgpool(PGconn * conn) { int rtn = WD_NG; int status = PGRES_FATAL_ERROR; PGresult * res = (PGresult *)NULL; if (!conn) { return WD_NG; } res = PQexec(conn, pool_config->wd_lifecheck_query ); status = PQresultStatus(res); if (res != NULL) { PQclear(res); } if ((status != PGRES_NONFATAL_ERROR ) && (status != PGRES_FATAL_ERROR )) { rtn = WD_OK; } PQfinish(conn); return rtn; } static int is_parent_alive() { if (mypid == getppid()) return WD_OK; else return WD_NG; } pgpool-II-3.3.2/watchdog/wd_child.c0000664000076400007640000002772412245576267014026 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * child.c: child process main * */ #include #include #include #include #include #include #include #include #include #include "pool.h" #include "watchdog.h" #include "pool_config.h" #include "wd_ext.h" pid_t wd_child(int fork_wait_time); static void wd_child_exit(int exit_signo); static int wd_send_response(int sock, WdPacket * recv_pack); static void wd_node_request_signal(WD_PACKET_NO packet_no, WdNodeInfo *node); pid_t wd_child(int fork_wait_time) { int sock; int fd; int rtn; pid_t pid = 0; pid = fork(); if (pid != 0) { if (pid == -1) pool_error("wd_child: fork() failed."); return pid; } if (fork_wait_time > 0) { sleep(fork_wait_time); } myargv = save_ps_display_args(myargc, myargv); POOL_SETMASK(&UnBlockSig); signal(SIGTERM, wd_child_exit); signal(SIGINT, wd_child_exit); signal(SIGQUIT, wd_child_exit); signal(SIGCHLD, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGALRM, SIG_IGN); init_ps_display("", "", "", ""); if (WD_List == NULL) { /* memory allocate is not ready */ wd_child_exit(15); } sock = wd_create_recv_socket(WD_MYSELF->wd_port); if (sock < 0) { /* socket create failed */ wd_child_exit(15); } set_ps_display("watchdog", false); /* child loop */ for(;;) { WdPacket buf; fd = wd_accept(sock); if (fd < 0) { continue; } rtn = wd_recv_packet(fd, &buf); if (rtn == WD_OK) { wd_send_response(fd, &buf); } close(fd); } return pid; } static void wd_child_exit(int exit_signo) { sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGQUIT); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, NULL); exit(0); } static int wd_send_response(int sock, WdPacket * recv_pack) { int rtn = WD_NG; WdInfo * p, *q; WdNodeInfo * node; WdLockInfo * lock; WdPacket send_packet; struct timeval tv; char pack_str[WD_MAX_PACKET_STRING]; int pack_str_len; char hash[(MD5_PASSWD_LEN+1)*2]; bool is_node_packet = false; if (recv_pack == NULL) { return rtn; } memset(&send_packet, 0, sizeof(WdPacket)); p = &(recv_pack->wd_body.wd_info); /* authentication */ if (strlen(pool_config->wd_authkey)) { /* calculate hash from packet */ pack_str_len = wd_packet_to_string(recv_pack, pack_str, sizeof(pack_str)); wd_calc_hash(pack_str, pack_str_len, hash); if (strcmp(recv_pack->hash, hash)) { pool_log("wd_send_response: watchdog authentication failed"); rtn = wd_authentication_failed(sock); return rtn; } } /* set response packet no */ switch (recv_pack->packet_no) { /* information request */ case WD_INFO_REQ: p = &(recv_pack->wd_body.wd_info); wd_set_wd_list(p->hostname, p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status); send_packet.packet_no = WD_READY; memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); break; /* add request into the watchdog list */ case WD_ADD_REQ: p = &(recv_pack->wd_body.wd_info); if (wd_set_wd_list(p->hostname, p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status) > 0) { pool_log("wd_send_response: receive add request from %s:%d and accept it", p->hostname, p->pgpool_port); send_packet.packet_no = WD_ADD_ACCEPT; } else { pool_log("wd_send_response: receive add request from %s:%d and reject it", p->hostname, p->pgpool_port); send_packet.packet_no = WD_ADD_REJECT; } memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); break; /* announce candidacy to be the new master */ case WD_STAND_FOR_MASTER: p = &(recv_pack->wd_body.wd_info); wd_set_wd_list(p->hostname, p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status); /* check exist master */ if ((q = wd_is_alive_master()) != NULL) { /* vote against the candidate */ send_packet.packet_no = WD_MASTER_EXIST; memcpy(&(send_packet.wd_body.wd_info), q, sizeof(WdInfo)); pool_log("wd_send_response: WD_STAND_FOR_MASTER received, and voting against %s:%d", p->hostname, p->pgpool_port); } else { if (WD_MYSELF->tv.tv_sec <= p->tv.tv_sec ) { memcpy(&tv,&(p->tv),sizeof(struct timeval)); tv.tv_sec += 1; wd_set_myself(&tv, WD_NORMAL); } /* vote for the candidate */ send_packet.packet_no = WD_VOTE_YOU; memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); pool_log("wd_send_response: WD_STAND_FOR_MASTER received, and voting for %s:%d", p->hostname, p->pgpool_port); } break; /* announce assumption to be the new master */ case WD_DECLARE_NEW_MASTER: p = &(recv_pack->wd_body.wd_info); wd_set_wd_list(p->hostname, p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status); if (WD_MYSELF->status == WD_MASTER) { /* resign master server */ pool_log("wd_send_response: WD_DECLARE_NEW_MASTER received and resign master server"); if (strlen(pool_config->delegate_IP) != 0) wd_IP_down(); wd_set_myself(NULL, WD_NORMAL); } send_packet.packet_no = WD_READY; memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); break; /* announce to assume lock holder */ case WD_STAND_FOR_LOCK_HOLDER: p = &(recv_pack->wd_body.wd_info); wd_set_wd_list(p->hostname, p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status); /* only master handles lock holder assignment */ if (WD_MYSELF->status == WD_MASTER) { /* if lock holder exists yet */ if (wd_get_lock_holder() != NULL) { pool_log("wd_send_response: WD_STAND_FOR_LOCK_HOLDER received but lock holder exists already"); send_packet.packet_no = WD_LOCK_HOLDER_EXIST; } else { pool_log("wd_send_response: WD_STAND_FOR_LOCK_HOLDER received it"); wd_set_lock_holder(p, true); send_packet.packet_no = WD_READY; } } else { send_packet.packet_no = WD_READY; } memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); break; /* announce to assume lock holder */ case WD_DECLARE_LOCK_HOLDER: p = &(recv_pack->wd_body.wd_info); wd_set_wd_list(p->hostname, p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status); if (WD_MYSELF->is_lock_holder) { pool_log("wd_send_response: WD_DECLARE_LOCK_HOLDER received but lock holder exists already"); send_packet.packet_no = WD_LOCK_HOLDER_EXIST; } else { wd_set_lock_holder(p, true); send_packet.packet_no = WD_READY; } memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); break; /* announce to resign lock holder */ case WD_RESIGN_LOCK_HOLDER: p = &(recv_pack->wd_body.wd_info); wd_set_wd_list(p->hostname, p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status); wd_set_lock_holder(p, false); send_packet.packet_no = WD_READY; memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); break; /* announce to start interlocking */ case WD_START_INTERLOCK: p = &(recv_pack->wd_body.wd_info); wd_set_wd_list(p->hostname, p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status); wd_set_interlocking(p, true); send_packet.packet_no = WD_READY; memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); break; /* announce to end interlocking */ case WD_END_INTERLOCK: p = &(recv_pack->wd_body.wd_info); wd_set_wd_list(p->hostname, p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status); wd_set_interlocking(p, false); send_packet.packet_no = WD_READY; memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); break; /* announce that server is down */ case WD_SERVER_DOWN: p = &(recv_pack->wd_body.wd_info); wd_set_wd_list(p->hostname, p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), WD_DOWN); send_packet.packet_no = WD_READY; memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); if (wd_am_I_oldest() == WD_OK && WD_MYSELF->status != WD_MASTER) { wd_escalation(); } break; /* announce start online recovery */ case WD_START_RECOVERY: if (*InRecovery != RECOVERY_INIT) { send_packet.packet_no = WD_NODE_FAILED; } else { send_packet.packet_no = WD_NODE_READY; *InRecovery = RECOVERY_ONLINE; if (wait_connection_closed() != 0) { send_packet.packet_no = WD_NODE_FAILED; } } break; /* announce end online recovery */ case WD_END_RECOVERY: send_packet.packet_no = WD_NODE_READY; *InRecovery = RECOVERY_INIT; kill(wd_ppid, SIGUSR2); break; /* announce failback request */ case WD_FAILBACK_REQUEST: if (Req_info->switching) { pool_log("wd_send_response: failback request from other pgpool is canceled because it's while switching"); send_packet.packet_no = WD_NODE_FAILED; } else { node = &(recv_pack->wd_body.wd_node_info); wd_set_node_mask(WD_FAILBACK_REQUEST,node->node_id_set,node->node_num); is_node_packet = true; send_packet.packet_no = WD_NODE_READY; } break; /* announce degenerate backend */ case WD_DEGENERATE_BACKEND: if (Req_info->switching) { pool_log("wd_send_response: failover request from other pgpool is canceled because it's while switching"); send_packet.packet_no = WD_NODE_FAILED; } else { node = &(recv_pack->wd_body.wd_node_info); wd_set_node_mask(WD_DEGENERATE_BACKEND,node->node_id_set, node->node_num); is_node_packet = true; send_packet.packet_no = WD_NODE_READY; } break; /* announce promote backend */ case WD_PROMOTE_BACKEND: if (Req_info->switching) { pool_log("wd_send_response: promote request from other pgpool is canceled because it's while switching"); send_packet.packet_no = WD_NODE_FAILED; } else { node = &(recv_pack->wd_body.wd_node_info); wd_set_node_mask(WD_PROMOTE_BACKEND,node->node_id_set, node->node_num); is_node_packet = true; send_packet.packet_no = WD_NODE_READY; } break; /* announce to unlock command */ case WD_UNLOCK_REQUEST: lock = &(recv_pack->wd_body.wd_lock_info); wd_set_lock(lock->lock_id, false); send_packet.packet_no = WD_LOCK_READY; break; default: send_packet.packet_no = WD_INVALID; memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo)); break; } /* send response packet */ rtn = wd_send_packet(sock, &send_packet); /* send node request signal. * wd_node_request_signal() uses a semaphore lock internally, so should be * called after sending a response packet to prevent dead lock. */ if (is_node_packet) wd_node_request_signal(recv_pack->packet_no, node); return rtn; } /* send node request signal for other pgpool*/ static void wd_node_request_signal(WD_PACKET_NO packet_no, WdNodeInfo *node) { switch (packet_no) { case WD_FAILBACK_REQUEST: send_failback_request(node->node_id_set[0]); break; case WD_DEGENERATE_BACKEND: degenerate_backend_set(node->node_id_set, node->node_num); break; case WD_PROMOTE_BACKEND: promote_backend(node->node_id_set[0]); break; default: pool_error("wd_node_request_signal: unknown packet number"); break; } } pgpool-II-3.3.2/watchdog/wd_ping.c0000664000076400007640000001440612245576267013671 00000000000000/* * $Header$ * * Handles watchdog connection, and protocol communication with pgpool-II * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2013 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include #include #include #include #include #include #include #include "pool.h" #include "pool_config.h" #include "watchdog.h" #define WD_MAX_PING_RESULT 256 int wd_is_upper_ok(char * server_list); int wd_is_unused_ip(char * ip); static void * exec_ping(void * arg); static double get_result (char * ping_data); /** * Try to connect to trusted servers. */ int wd_is_upper_ok(char * server_list) { pthread_attr_t attr; char * buf; int rc = 0; int i,cnt; int len; pthread_t thread[MAX_WATCHDOG_NUM]; WdInfo thread_arg[MAX_WATCHDOG_NUM]; char * bp, *ep; int rtn = WD_NG; if (server_list == NULL) { pool_error("wd_is_upper_ok: server_list is NULL"); return WD_NG; } len = strlen(server_list)+2; buf = malloc(len); if (buf == NULL) { pool_error("wd_is_upper_ok: malloc failed"); return WD_NG; } memset(buf,0,len); strlcpy(buf,server_list,len); /* thread init */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); /* set hostname as a thread_arg */ bp = buf; cnt = 0; while (*bp != '\0') { ep = strchr(bp,','); if (ep != NULL) { *ep = '\0'; } strlcpy(thread_arg[cnt].hostname,bp,sizeof(thread_arg[cnt].hostname)); rc = pthread_create(&thread[cnt], &attr, exec_ping, (void*)&thread_arg[cnt]); cnt ++; if (ep != NULL) { bp = ep + 1; } else { break; } if (cnt >= MAX_WATCHDOG_NUM) { pool_debug("wd_is_upper_ok: trusted server num is out of range(%d)",cnt); break; } } pthread_attr_destroy(&attr); for (i=0; i ping_path); thread_arg = (WdInfo *)arg; memset(result,0,sizeof(result)); if (pipe(pfd) == -1) { pool_error("exec_ping: pipe open error:%s", strerror(errno)); return WD_NG; } args[i++] = "ping"; args[i++] = "-q"; args[i++] = "-c3"; args[i++] = thread_arg->hostname; args[i++] = NULL; pid = fork(); if (pid == -1) { pool_error("exec_ping: fork() failed. reason: %s", strerror(errno)); exit(1); } if (pid == 0) { close(STDOUT_FILENO); dup2(pfd[1], STDOUT_FILENO); close(pfd[0]); status = execv(ping_path,args); if (status == -1) { pool_error("exec_ping: execv(%s) failed. reason: %s", ping_path, strerror(errno)); exit(1); } exit(0); } else { close(pfd[1]); for (;;) { int r; r = wait(&status); if (r < 0) { if (errno == EINTR) continue; pool_error("exec_ping: wait() failed. reason: %s", strerror(errno)); close(pfd[0]); return WD_NG; } if (WIFEXITED(status) == 0) { pool_error("exec_ping: %s exited abnormally", ping_path); close(pfd[0]); return WD_NG; } else if (WEXITSTATUS(status) != 0) { pool_debug("exec_ping: failed to ping %s", thread_arg->hostname); return WD_NG; } else { pool_debug("exec_ping: succeed to ping %s", thread_arg->hostname); break; } } i = 0; while (( (r_size = read (pfd[0], &result[i], sizeof(result)-i-1)) > 0) && (errno == EINTR)) { i += r_size; } result[sizeof(result)-1] = '\0'; close(pfd[0]); } /* Check whether average RTT >= 0 */ rtn = (get_result (result) >= 0) ? WD_OK : WD_NG; pthread_exit((void *)rtn); } /** * Get average round-trip time of ping result. */ static double get_result (char * ping_data) { char * sp = NULL; char * ep = NULL; int i; double msec = 0; if (ping_data == NULL) { pool_error("get_result: no ping data"); return -1; } pool_debug("get_result: ping data: %s", ping_data); /* skip result until average data typical result of ping is as follows, "rtt min/avg/max/mdev = 0.045/0.045/0.046/0.006 ms" we can find the average data beyond the 4th '/'. */ sp = ping_data; for ( i = 0 ; i < 4 ; i ++) { sp = strchr(sp,'/'); if (sp == NULL) { return -1; } sp ++; } ep = strchr (sp,'/'); if (ep == NULL) { return -1; } *ep = '\0'; errno = 0; /* convert to numeric data from text */ msec = strtod(sp,(char **)NULL); if (errno != 0) { pool_error("get_result: strtod() failed. reason: %s", strerror(errno)); return -1; } return msec; } pgpool-II-3.3.2/watchdog/Makefile.in0000664000076400007640000003652412245776600014141 00000000000000# Makefile.in generated by automake 1.11.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = watchdog DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/c-compiler.m4 $(top_srcdir)/c-library.m4 \ $(top_srcdir)/general.m4 \ $(top_srcdir)/ac_func_accept_argtypes.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru lib_watchdog_a_AR = $(AR) $(ARFLAGS) lib_watchdog_a_LIBADD = am_lib_watchdog_a_OBJECTS = watchdog.$(OBJEXT) wd_child.$(OBJEXT) \ wd_if.$(OBJEXT) wd_init.$(OBJEXT) wd_lifecheck.$(OBJEXT) \ wd_list.$(OBJEXT) wd_packet.$(OBJEXT) wd_ping.$(OBJEXT) \ wd_heartbeat.$(OBJEXT) wd_interlock.$(OBJEXT) lib_watchdog_a_OBJECTS = $(am_lib_watchdog_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(lib_watchdog_a_SOURCES) DIST_SOURCES = $(lib_watchdog_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MEMCACHED_DIR = @MEMCACHED_DIR@ MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PGCONFIG = @PGCONFIG@ PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LIBRARIES = lib-watchdog.a lib_watchdog_a_SOURCES = \ watchdog.c \ watchdog.h \ wd_child.c \ wd_ext.h \ wd_if.c \ wd_init.c \ wd_lifecheck.c \ wd_list.c \ wd_packet.c \ wd_ping.c \ wd_heartbeat.c \ wd_interlock.c AM_CPPFLAGS = -D_GNU_SOURCE -I .. -I @PGSQL_INCLUDE_DIR@ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu watchdog/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu watchdog/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) lib-watchdog.a: $(lib_watchdog_a_OBJECTS) $(lib_watchdog_a_DEPENDENCIES) -rm -f lib-watchdog.a $(lib_watchdog_a_AR) lib-watchdog.a $(lib_watchdog_a_OBJECTS) $(lib_watchdog_a_LIBADD) $(RANLIB) lib-watchdog.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/watchdog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wd_child.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wd_heartbeat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wd_if.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wd_init.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wd_interlock.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wd_lifecheck.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wd_list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wd_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wd_ping.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: pgpool-II-3.3.2/watchdog/watchdog.h0000664000076400007640000001341612245576267014047 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * watchdog.h.: watchdog definition header file * */ #ifndef WATCHDOG_H #define WATCHDOG_H #include #include "libpq-fe.h" #include "md5.h" #define WD_MAX_HOST_NAMELEN (128) #define WD_MAX_PATH_LEN (128) #define MAX_WATCHDOG_NUM (128) #define WD_SEND_TIMEOUT (1) #define WD_MAX_IF_NUM (256) #define WD_MAX_IF_NAME_LEN (16) #define WD_INFO(wd_id) (pool_config->other_wd->wd_info[(wd_id)]) #define WD_HB_IF(if_id) (pool_config->hb_if[(if_id)]) #define WD_MYSELF (WD_List) #define WD_NG (0) #define WD_OK (1) #define WD_MAX_PACKET_STRING (256) #define WD_TIME_INIT(tv) ((tv).tv_sec = (tv).tv_usec = 0) #define WD_TIME_ISSET(tv) ((tv).tv_sec || (tv).tv_usec) #define WD_TIME_BEFORE(a,b) (((a).tv_sec == (b).tv_sec) ? \ ((a).tv_usec < (b).tv_usec) : \ ((a).tv_sec < (b).tv_sec)) #define WD_TIME_DIFF_SEC(a,b) (int)(((a).tv_sec - (b).tv_sec) + \ ((a).tv_usec - (b).tv_usec) / 1000000.0) /* * packet number of watchdog negotiation */ typedef enum { /* normal packet */ WD_INVALID = 0, /* invalid packet no */ WD_INFO_REQ, /* information request */ WD_ADD_REQ, /* add request into the watchdog list */ WD_ADD_ACCEPT, /* accept the add request */ WD_ADD_REJECT, /* reject the add request */ WD_STAND_FOR_MASTER, /* announce candidacy */ WD_VOTE_YOU, /* agree to the candidacy */ WD_MASTER_EXIST, /* disagree to the candidacy */ WD_DECLARE_NEW_MASTER, /* announce assumption */ WD_STAND_FOR_LOCK_HOLDER, /* announce candidacy for lock holder */ WD_LOCK_HOLDER_EXIST, /* reject the assumption for lock holder */ WD_DECLARE_LOCK_HOLDER, /* announce to assume lock holder */ WD_RESIGN_LOCK_HOLDER, /* announce to resign lock holder */ WD_START_INTERLOCK, /* announce to start interlocking */ WD_END_INTERLOCK, /* announce to end interlocking */ WD_SERVER_DOWN, /* announce server down */ WD_AUTH_FAILED, /* fail answer to authentication */ WD_READY, /* answer to the announce */ /* node packet */ WD_START_RECOVERY, /* announce start online recovery */ WD_END_RECOVERY, /* announce end online recovery */ WD_FAILBACK_REQUEST, /* announce failback request */ WD_DEGENERATE_BACKEND, /* announce degenerate backend */ WD_PROMOTE_BACKEND, /* announce promote backend */ WD_NODE_READY, /* answer to the node announce */ WD_NODE_FAILED, /* fail answer to the node announce */ /* lock packet */ WD_UNLOCK_REQUEST, /* announce to unlock command */ WD_LOCK_READY, /* answer to the lock announce */ WD_LOCK_FAILED /* fail answer to the lock announce */ } WD_PACKET_NO; /* * watchdog status */ typedef enum { WD_END = 0, WD_INIT, WD_NORMAL, WD_MASTER, WD_DOWN } WD_STATUS; /* * watchdog locks */ typedef enum { WD_FAILOVER_START_LOCK = 0, WD_FAILOVER_END_LOCK, WD_FAILOVER_COMMAND_LOCK, WD_FAILBACK_COMMAND_LOCK, WD_FOLLOW_MASTER_COMMAND_LOCK, WD_MAX_LOCK_NUM } WD_LOCK_ID; /* * watchdog list */ typedef struct WdInfo { WD_STATUS status; /* status */ struct timeval tv; /* startup time value */ char hostname[WD_MAX_HOST_NAMELEN]; /* host name */ int pgpool_port; /* pgpool port */ int wd_port; /* watchdog port */ int life; /* life point */ char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ int delegate_ip_flag; /* delegate IP flag */ struct timeval hb_send_time; /* send time */ struct timeval hb_last_recv_time; /* recv time */ bool is_lock_holder; /* lock holder flag */ bool in_interlocking; /* interlocking is in progress */ bool is_contactable; /* able to create socket and connection */ } WdInfo; typedef struct { int node_id_set[MAX_NUM_BACKENDS]; /* node sets */ int node_num; /* node number */ } WdNodeInfo; typedef struct { WD_LOCK_ID lock_id; } WdLockInfo; typedef union { WdInfo wd_info; WdNodeInfo wd_node_info; WdLockInfo wd_lock_info; } WD_PACKET_BODY; typedef struct { char addr[WD_MAX_HOST_NAMELEN]; char if_name[WD_MAX_IF_NAME_LEN]; int dest_port; } WdHbIf; typedef struct { int num_wd; /* number of watchdogs */ WdInfo wd_info[MAX_WATCHDOG_NUM]; } WdDesc; /* * negotiation packet */ typedef struct { WD_PACKET_NO packet_no; /* packet number */ WD_PACKET_BODY wd_body; /* watchdog information */ struct timeval send_time; char hash[(MD5_PASSWD_LEN+1)*2]; } WdPacket; /* * thread argument for watchdog negotiation */ typedef struct { int sock; /* socket */ WdInfo * target; /* target watchdog information */ WdPacket * packet; /* packet data */ } WdPacketThreadArg; /* * heartbeat packet */ typedef struct { char from[WD_MAX_HOST_NAMELEN]; int from_pgpool_port; struct timeval send_time; WD_STATUS status; char hash[(MD5_PASSWD_LEN+1)*2]; } WdHbPacket; /* * thread argument for lifecheck of pgpool */ typedef struct { PGconn * conn; /* PGconn */ int retry; /* retry times (not used?)*/ } WdPgpoolThreadArg; extern WdInfo * WD_List; extern unsigned char * WD_Node_List; #endif /* WATCHDOG_H */ pgpool-II-3.3.2/watchdog/watchdog.c0000664000076400007640000002171312245576267014041 00000000000000/* * $Header$ * * Handles watchdog connection, and protocol communication with pgpool-II * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include #include #include #include #include #include #include #include #include "pool.h" #include "pool_config.h" #include "watchdog.h" #include "wd_ext.h" WdInfo * WD_List = NULL; /* watchdog server list */ unsigned char * WD_Node_List = NULL; /* node list */ pid_t wd_ppid = 0; static pid_t lifecheck_pid; static pid_t child_pid; static pid_t hb_receiver_pid[WD_MAX_IF_NUM]; static pid_t hb_sender_pid[WD_MAX_IF_NUM]; pid_t wd_main(int fork_wait_time); void wd_kill_watchdog(int sig); int wd_reaper_watchdog(pid_t pid, int status); int wd_chk_setuid(void); static pid_t fork_a_lifecheck(int fork_wait_time); static void wd_exit(int exit_status); static int wd_check_config(void); static int has_setuid_bit(char * path); static void wd_exit(int exit_signo) { sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGQUIT); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, NULL); wd_notice_server_down(); exit(0); } /* send signal specified by sig to watchdog processes */ void wd_kill_watchdog(int sig) { int i; kill (lifecheck_pid, sig); kill (child_pid, sig); if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT)) { for (i = 0; i < pool_config->num_hb_if; i++) { kill (hb_receiver_pid[i], sig); kill (hb_sender_pid[i], sig); } } } static int wd_check_config(void) { int status = WD_OK; if (pool_config->other_wd->num_wd == 0) { pool_error("wd_check_config: there is no other pgpools setting."); status = WD_NG; } if (strlen(pool_config->wd_authkey) > MAX_PASSWORD_SIZE) { pool_error("wd_check_config: wd_authkey length can't be larger than %d", MAX_PASSWORD_SIZE); status = WD_NG; } return status; } pid_t wd_main(int fork_wait_time) { int status = WD_INIT; int i; if (!pool_config->use_watchdog) { return 0; } /* check pool_config data */ status = wd_check_config(); if (status != WD_OK) { pool_error("watchdog: wd_check_config failed"); return 0; } /* initialize */ status = wd_init(); if (status != WD_OK) { pool_error("watchdog: wd_init failed"); return 0; } wd_ppid = getpid(); /* launch child process */ child_pid = wd_child(1); if (child_pid < 0 ) { pool_error("launch wd_child failed"); return 0; } if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT)) { for (i = 0; i < pool_config->num_hb_if; i++) { /* heartbeat receiver process */ hb_receiver_pid[i] = wd_hb_receiver(1, &(pool_config->hb_if[i])); if (hb_receiver_pid[i] < 0 ) { pool_error("launch wd_hb_receiver failed"); return hb_receiver_pid[i]; } /* heartbeat sender process */ hb_sender_pid[i] = wd_hb_sender(1, &(pool_config->hb_if[i])); if (hb_sender_pid[i] < 0 ) { pool_error("launch wd_hb_sender failed"); return hb_sender_pid[i]; } } } /* fork lifecheck process*/ lifecheck_pid = fork_a_lifecheck(fork_wait_time); if (lifecheck_pid < 0 ) { pool_error("launch lifecheck process failed"); return 0; } return lifecheck_pid; } /* fork lifecheck process*/ static pid_t fork_a_lifecheck(int fork_wait_time) { pid_t pid; pid = fork(); if (pid != 0) { if (pid == -1) pool_error("fork_a_lifecheck: fork() failed."); return pid; } if (fork_wait_time > 0) { sleep(fork_wait_time); } myargv = save_ps_display_args(myargc, myargv); POOL_SETMASK(&UnBlockSig); init_ps_display("", "", "", ""); signal(SIGTERM, wd_exit); signal(SIGINT, wd_exit); signal(SIGQUIT, wd_exit); signal(SIGCHLD, SIG_DFL); signal(SIGHUP, SIG_IGN); signal(SIGPIPE, SIG_IGN); set_ps_display("lifecheck",false); /* wait until ready to go */ while (WD_OK != is_wd_lifecheck_ready()) { sleep(pool_config->wd_interval * 10); } pool_log("watchdog: lifecheck started"); /* watchdog loop */ for (;;) { /* pgpool life check */ wd_lifecheck(); sleep(pool_config->wd_interval); } return pid; } /* if pid is for one of watchdog processes return 1, othewize return 0 */ int wd_is_watchdog_pid(pid_t pid) { int i; if (pid == lifecheck_pid || pid == child_pid) { return 1; } for (i = 0; i < pool_config->num_hb_if; i++) { if (pid == hb_receiver_pid[i] || pid == hb_sender_pid[i]) { return 1; } } return 0; } /* restart watchdog process specified by pid */ int wd_reaper_watchdog(pid_t pid, int status) { int i; /* watchdog lifecheck process exits */ if (pid == lifecheck_pid) { if (WIFSIGNALED(status)) pool_debug("watchdog lifecheck process %d exits with status %d by signal %d", pid, status, WTERMSIG(status)); else pool_debug("watchdog lifecheck process %d exits with status %d", pid, status); lifecheck_pid = fork_a_lifecheck(1); if (lifecheck_pid < 0) { pool_error("wd_reaper: fork a watchdog lifecheck process failed"); return 0; } pool_log("fork a new watchdog lifecheck pid %d", lifecheck_pid); } /* watchdog child process exits */ else if (pid == child_pid) { if (WIFSIGNALED(status)) pool_debug("watchdog child process %d exits with status %d by signal %d", pid, status, WTERMSIG(status)); else pool_debug("watchdog child process %d exits with status %d", pid, status); child_pid = wd_child(1); if (child_pid < 0) { pool_error("wd_reaper: fork a watchdog child process failed"); return 0; } pool_log("fork a new watchdog child pid %d", child_pid); } /* receiver/sender process exits */ else { for (i = 0; i < pool_config->num_hb_if; i++) { if (pid == hb_receiver_pid[i]) { if (WIFSIGNALED(status)) pool_debug("watchdog heartbeat receiver process %d exits with status %d by signal %d", pid, status, WTERMSIG(status)); else pool_debug("watchdog heartbeat receiver process %d exits with status %d", pid, status); hb_receiver_pid[i] = wd_hb_receiver(1, &(pool_config->hb_if[i])); if (hb_receiver_pid[i] < 0) { pool_error("wd_reaper: fork a watchdog heartbeat receiver process failed"); return 0; } pool_log("fork a new watchdog heartbeat receiver: pid %d", hb_receiver_pid[i]); break; } else if (pid == hb_sender_pid[i]) { if (WIFSIGNALED(status)) pool_debug("watchdog heartbeat sender process %d exits with status %d by signal %d", pid, status, WTERMSIG(status)); else pool_debug("watchdog heartbeat sender process %d exits with status %d", pid, status); hb_sender_pid[i] = wd_hb_sender(1, &(pool_config->hb_if[i])); if (hb_sender_pid[i] < 0) { pool_error("wd_reaper: fork a watchdog heartbeat sender process failed"); return 0; } pool_log("fork a new watchdog heartbeat sender: pid %d", hb_sender_pid[i]); break; } } } return 1; } int wd_chk_setuid(void) { char path[128]; char cmd[128]; /* check setuid bit of ifup command */ wd_get_cmd(cmd, pool_config->if_up_cmd); snprintf(path, sizeof(path), "%s/%s", pool_config->ifconfig_path, cmd); if (! has_setuid_bit(path)) { pool_log("wd_chk_setuid: ifup[%s] doesn't have setuid bit", path); return 0; } /* check setuid bit of ifdown command */ wd_get_cmd(cmd, pool_config->if_down_cmd); snprintf(path, sizeof(path), "%s/%s", pool_config->ifconfig_path, cmd); if (! has_setuid_bit(path)) { pool_log("wd_chk_setuid: ifdown[%s] doesn't have setuid bit", path); return 0; } /* check setuid bit of arping command */ wd_get_cmd(cmd, pool_config->arping_cmd); snprintf(path, sizeof(path), "%s/%s", pool_config->arping_path, cmd); if (! has_setuid_bit(path)) { pool_log("wd_chk_setuid: arping[%s] doesn't have setuid bit", path); return 0; } pool_log("wd_chk_setuid all commands have setuid bit"); return 1; } /* if the file has setuid bit and the owner is root, it returns 1, otherwise returns 0 */ static int has_setuid_bit(char * path) { struct stat buf; if (stat(path,&buf) < 0) { pool_error("has_setuid_bit: %s: no such a command", path); pool_shmem_exit(1); exit(1); } return ((buf.st_uid == 0) && (S_ISREG(buf.st_mode)) && (buf.st_mode & S_ISUID))?1:0; } pgpool-II-3.3.2/watchdog/wd_init.c0000664000076400007640000000610712245576267013676 00000000000000/* * $Header$ * * Handles watchdog connection, and protocol communication with pgpool-II * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include #include #include "pool.h" #include "pool_config.h" #include "watchdog.h" #include "wd_ext.h" int wd_init(void); int wd_init(void) { struct timeval tv; WdInfo * p; /* set startup time */ gettimeofday(&tv, NULL); /* allocate watchdog list */ if (WD_List == NULL) { WD_List = pool_shared_memory_create(sizeof(WdInfo) * MAX_WATCHDOG_NUM); if (WD_List == NULL) { pool_error("wd_init: failed to allocate watchdog list"); return WD_NG; } memset(WD_List, 0, sizeof(WdInfo) * MAX_WATCHDOG_NUM); } /* allocate node list */ if (WD_Node_List == NULL) { WD_Node_List = pool_shared_memory_create(sizeof(unsigned char) * MAX_NUM_BACKENDS); if (WD_Node_List == NULL) { pool_error("wd_init: failed to allocate node list"); return WD_NG; } memset(WD_Node_List, 0, sizeof(unsigned char) * MAX_NUM_BACKENDS); } /* initialize interlock */ if (wd_init_interlock() != WD_OK) { pool_error("wd_init: wd_init_interlock failed"); return WD_NG; } /* set myself to watchdog list */ wd_set_wd_list(pool_config->wd_hostname, pool_config->port, pool_config->wd_port, pool_config->delegate_IP, &tv, WD_NORMAL); /* set other pgpools to watchdog list */ wd_add_wd_list(pool_config->other_wd); /* reset time value */ p = WD_List; while (p->status != WD_END) { WD_TIME_INIT(p->hb_send_time); WD_TIME_INIT(p->hb_last_recv_time); p++; } /* check upper connection */ if (strlen(pool_config->trusted_servers) && wd_is_upper_ok(pool_config->trusted_servers) != WD_OK) { pool_error("wd_init: failed to connect trusted server"); return WD_NG; } /* send startup packet */ if (wd_startup() == WD_NG) { pool_error("wd_init: failed to start watchdog"); return WD_NG; } /* check existence of master pgpool */ if (wd_is_exist_master() == NULL) { if (strlen(pool_config->delegate_IP) != 0 && !wd_is_unused_ip(pool_config->delegate_IP)) { pool_error("wd_init: delegate_IP %s already exists", pool_config->delegate_IP); return WD_NG; } /* escalate to delegate_IP holder */ wd_escalation(); } pool_log("wd_init: start watchdog"); return WD_OK; } pgpool-II-3.3.2/watchdog/wd_list.c0000664000076400007640000001776112245576267013716 00000000000000/* * $Header$ * * Handles watchdog connection, and protocol communication with pgpool-II * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * */ #include #include #include #include #include "pool.h" #include "pool_config.h" #include "watchdog.h" #include "wd_ext.h" int wd_add_wd_list(WdDesc * other_wd); int wd_set_wd_info(WdInfo * info); WdInfo * wd_is_exist_master(void); WdInfo * wd_get_lock_holder(void); WdInfo * wd_get_interlocking(void); bool wd_are_interlocking_all(void); void wd_set_lock_holder(WdInfo *info, bool value); void wd_set_interlocking(WdInfo *info, bool value); void wd_clear_interlocking_info(void); int wd_am_I_oldest(void); int wd_set_myself(struct timeval * tv, int status); WdInfo * wd_is_alive_master(void); bool wd_is_contactable_master(void); bool wd_are_contactable_all(void); /* add or modify watchdog information list */ int wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, char * delegate_ip, struct timeval * tv, int status) { int i = 0; WdInfo * p = NULL; if ((WD_List == NULL) || (hostname == NULL)) { pool_error("wd_set_wd_list: memory allocate error"); return -1; } if (strcmp(pool_config->delegate_IP, delegate_ip)) { pool_error("wd_set_wd_list: delegate IP mismatch error"); return -1; } for ( i = 0 ; i < MAX_WATCHDOG_NUM ; i ++) { p = (WD_List+i); if( p->status != WD_END) { /* found; modify the pgpool. */ if ((!strncmp(p->hostname, hostname, sizeof(p->hostname))) && (p->pgpool_port == pgpool_port) && (p->wd_port == wd_port)) { p->status = status; if (tv != NULL) { memcpy(&(p->tv), tv, sizeof(struct timeval)); } return i; } } /* not found; add as a new pgpool */ else { p->status = status; p->pgpool_port = pgpool_port; p->wd_port = wd_port; p->in_interlocking = false; p->is_lock_holder = false; strlcpy(p->hostname, hostname, sizeof(p->hostname)); strlcpy(p->delegate_ip, delegate_ip, sizeof(p->delegate_ip)); if (tv != NULL) { memcpy(&(p->tv), tv, sizeof(struct timeval)); } return i; } } pool_error("wd_set_wd_list: Can not add new watchdog information cause the WD_List is full."); return -1; } /* add watchdog information to list using config description */ int wd_add_wd_list(WdDesc * other_wd) { WdInfo * p = NULL; int i = 0; if (other_wd == NULL) { pool_error("wd_add_wd_list: memory allocate error"); return -1; } for ( i = 0 ; i < other_wd->num_wd ; i ++) { p = &(other_wd->wd_info[i]); strlcpy(p->delegate_ip, pool_config->delegate_IP, sizeof(p->delegate_ip)); wd_set_wd_info(p); } return i; } /* set watchdog information to list */ int wd_set_wd_info(WdInfo * info) { int rtn; rtn = wd_set_wd_list(info->hostname, info->pgpool_port, info->wd_port, info->delegate_ip, &(info->tv), info->status); return rtn; } /* return master if exist, NULL if not found */ WdInfo * wd_is_exist_master(void) { WdInfo * p = WD_List; while (p->status != WD_END) { /* find master pgpool in the other servers */ if (p->status == WD_MASTER) { /* master found */ return p; } p++; } /* not found */ return NULL; } /* set or unset in_interlocking flag */ void wd_set_interlocking(WdInfo *info, bool value) { WdInfo * p = WD_List; while (p->status != WD_END) { if ((!strncmp(p->hostname, info->hostname, sizeof(p->hostname))) && (p->pgpool_port == info->pgpool_port) && (p->wd_port == info->wd_port)) { p->in_interlocking = value; return; } p++; } } /* set or unset lock holder flag */ void wd_set_lock_holder(WdInfo *info, bool value) { WdInfo * p = WD_List; while (p->status != WD_END) { if ((!strncmp(p->hostname, info->hostname, sizeof(p->hostname))) && (p->pgpool_port == info->pgpool_port) && (p->wd_port == info->wd_port)) { p->is_lock_holder = value; return; } p++; } } /* return the lock holder if exist, NULL if not found */ WdInfo * wd_get_lock_holder(void) { WdInfo * p = WD_List; while (p->status != WD_END) { /* find failover lock holder */ if ((p->status == WD_NORMAL || p->status == WD_MASTER) && p->is_lock_holder) { /* found */ return p; } p++; } /* not found */ return NULL; } /* return the pgpool in interlocking found in first, NULL if not found */ WdInfo * wd_get_interlocking(void) { WdInfo * p = WD_List; /* for updating contactable flag */ wd_update_info(); while (p->status != WD_END) { /* skip if not contactable */ if (!p->is_contactable) { p++; continue; } /* find pgpool in interlocking */ if ((p->status == WD_NORMAL || p->status == WD_MASTER) && p->in_interlocking) { /* found */ return p; } p++; } /* not found */ return NULL; } /* if all pgpool are in interlocking return true, otherwise false */ bool wd_are_interlocking_all(void) { WdInfo * p = WD_List; bool rtn = true; /* for updating contactable flag */ wd_update_info(); while (p->status != WD_END) { /* skip if not contactable */ if (!p->is_contactable) { p++; continue; } /* find pgpool not in interlocking */ if ((p->status == WD_NORMAL || p->status == WD_MASTER) && !p->in_interlocking) { rtn = false; } p++; } return rtn; } /* clear flags for interlocking */ void wd_clear_interlocking_info(void) { WdInfo * p = WD_List; while (p->status != WD_END) { wd_set_lock_holder(p, false); wd_set_interlocking(p, false); p++; } } int wd_am_I_oldest(void) { WdInfo * p = WD_List; p++; while (p->status != WD_END) { if ((p->status == WD_NORMAL) || (p->status == WD_MASTER)) { if (WD_TIME_BEFORE(p->tv, WD_MYSELF->tv)) { return WD_NG; } } p++; } return WD_OK; } int wd_set_myself(struct timeval * tv, int status) { if (WD_MYSELF == NULL) { return WD_NG; } if (tv != NULL) { memcpy(&(WD_MYSELF->tv),tv,sizeof(struct timeval)); } WD_MYSELF->status = status; return WD_OK; } /* * if master exists and it is alive actually return the master, * otherwise return NULL */ WdInfo * wd_is_alive_master(void) { WdInfo * master = NULL; if (WD_MYSELF->status == WD_MASTER) return WD_MYSELF; master = wd_is_exist_master(); if (master != NULL) { if ((!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT)) || (!strcmp(pool_config->wd_lifecheck_method, MODE_QUERY) && wd_ping_pgpool(master) == WD_OK)) { return master; } } pool_debug("wd_is_alive_master: alive master not found"); return NULL; } /* * if master exists and it is contactable return true, * otherwise return false */ bool wd_is_contactable_master(void) { WdInfo * master = NULL; if (WD_MYSELF->status == WD_MASTER) return true; /* for updating contactable flag */ wd_update_info(); master = wd_is_exist_master(); if (master != NULL) { return master->is_contactable; } return false; } bool wd_are_contactable_all(void) { WdInfo * p = WD_List; /* for updating contactable flag */ wd_update_info(); while (p->status != WD_END) { if ((p->status == WD_NORMAL || p->status == WD_MASTER) && !p->is_contactable) { return false; } p++; } return true; } /* * get watchdog information of specified index */ WdInfo * wd_get_watchdog_info(int wd_index) { if (wd_index < 0 || wd_index > pool_config->other_wd->num_wd) return NULL; return &WD_List[wd_index]; } pgpool-II-3.3.2/watchdog/wd_ext.h0000664000076400007640000001071312245576267013536 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * wd_ext.h.: watchdog extern definition header file * */ #ifndef WD_EXT_H #define WD_EXT_H /* watchdog.c */ extern pid_t wd_ppid; extern pid_t wd_main(int fork_wait_time); extern int wd_chk_sticky(void); extern int wd_is_watchdog_pid(pid_t pid); extern int wd_reaper_watchdog(pid_t pid, int status); extern int wd_chk_setuid(void); extern void wd_kill_watchdog(int sig); /* wd_child.c */ extern pid_t wd_child(int fork_wait_time); /* wd_init.c */ extern int wd_init(void); /* wd_list.c */ extern int wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, char * delegate_ip, struct timeval * tv, int status); extern int wd_add_wd_list(WdDesc * other_wd); extern int wd_set_wd_info(WdInfo * info); extern WdInfo * wd_is_exist_master(void); extern int wd_am_I_oldest(void); extern int wd_set_myself(struct timeval * tv, int status); extern WdInfo * wd_is_alive_master(void); extern WdInfo * wd_get_lock_holder(void); extern WdInfo * wd_get_interlocking(void); extern bool wd_are_interlocking_all(void); extern void wd_set_lock_holder(WdInfo *p, bool value); extern void wd_set_interlocking(WdInfo *info, bool value); extern void wd_clear_interlocking_info(void); extern bool wd_is_contactable_master(void); extern bool wd_are_contactable_all(void); extern WdInfo * wd_get_watchdog_info(int num); /* wd_packet.c */ extern int wd_startup(void); extern int wd_declare(void); extern int wd_stand_for_master(void); extern int wd_notice_server_down(void); extern int wd_update_info(void); extern int wd_authentication_failed(int sock); extern int wd_create_send_socket(char * hostname, int port); extern int wd_create_recv_socket(int port); extern int wd_accept(int sock); extern int wd_send_packet(int sock, WdPacket * snd_pack); extern int wd_recv_packet(int sock, WdPacket * buf); extern int wd_escalation(void); extern int wd_start_recovery(void); extern int wd_end_recovery(void); extern int wd_send_failback_request(int node_id); extern int wd_degenerate_backend_set(int *node_id_set, int count); extern int wd_promote_backend(int node_id); extern int wd_set_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count); extern int wd_send_packet_no(WD_PACKET_NO packet_no ); extern int wd_send_lock_packet(WD_PACKET_NO packet_no, WD_LOCK_ID lock_id); extern void wd_calc_hash(const char *str, int len, char *buf); int wd_packet_to_string(WdPacket *pkt, char *str, int maxlen); /* wd_ping.c */ extern int wd_is_upper_ok(char * server_list); extern int wd_is_unused_ip(char * ip); /* wd_if.c */ extern int wd_IP_up(void); extern int wd_IP_down(void); extern int wd_get_cmd(char * buf, char * cmd); /* wd_lifecheck.c */ extern int is_wd_lifecheck_ready(void); extern int wd_lifecheck(void); extern int wd_check_heartbeat(WdInfo * pgpool); extern int wd_ping_pgpool(WdInfo * pgpool); /* wd_hearbeat.c */ extern int wd_create_hb_send_socket(WdHbIf * hb_if); extern int wd_create_hb_recv_socket(WdHbIf * hb_if); extern int wd_hb_send(int sock, WdHbPacket * pkt, int len, const char * destination, const int dest_port); extern int wd_hb_recv(int sock, WdHbPacket * pkt); extern pid_t wd_hb_receiver(int fork_wait_time, WdHbIf * hb_if); extern pid_t wd_hb_sender(int fork_wait_time, WdHbIf * hb_if); /* wd_interlock.c */ extern int wd_init_interlock(void); extern void wd_start_interlock(bool by_health_check); extern void wd_end_interlock(void); extern void wd_leave_interlock(void); extern void wd_wait_for_lock(WD_LOCK_ID lock_id); extern bool wd_am_I_lock_holder(void); extern bool wd_is_locked(WD_LOCK_ID lock_id); extern void wd_set_lock(WD_LOCK_ID lock_id, bool value); extern int wd_unlock(WD_LOCK_ID lock); /* main.c */ extern int myargc; extern char **myargv; #endif /* WD_EXT_H */ pgpool-II-3.3.2/ChangeLog0000664000076400007640000000001212063517557012027 00000000000000See NEWS. pgpool-II-3.3.2/pool_memqcache.h0000664000076400007640000002123112245576266013414 00000000000000/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_memqcache.h: on memory query cache related definitions * */ #ifndef POOL_MEMQCACHE_H #define POOL_MEMQCACHE_H #include "pool.h" #include #define NO_QUERY_CACHE "/*NO QUERY CACHE*/" #define NO_QUERY_CACHE_COMMENT_SZ (sizeof(NO_QUERY_CACHE)-1) #define POOL_MD5_HASHKEYLEN 32 /* MD5 hash key length */ /* * On memory query cache on shmem is divided into fixed length "cache * block". Each block is assigned a "cache block id", which is * starting with 0. */ typedef char *POOL_CACH_BLOCK; /* pointer to cache block */ typedef unsigned int POOL_CACHE_BLOCKID; /* cache block id */ typedef unsigned int POOL_CACHE_ITEMID; /* cache item id */ /* * "Cache id" represents "absolute address" of a cache item. */ typedef struct { POOL_CACHE_BLOCKID blockid; POOL_CACHE_ITEMID itemid; } POOL_CACHEID; /* cache id */ /* * Each block has management space called "cache block header" at the * very beginning of the cache block. */ #define POOL_BLOCK_USED 0x0001 /* is this block used? */ typedef struct { unsigned char flags; /* flags. see above */ unsigned int num_items; /* number of items */ unsigned int free_bytes; /* total free space in bytes */ } POOL_CACHE_BLOCK_HEADER; typedef struct { char query_hash[POOL_MD5_HASHKEYLEN]; } POOL_QUERY_HASH; #define POOL_ITEM_USED 0x0001 /* is this item used? */ #define POOL_ITEM_HAS_NEXT 0x0002 /* is this item has "next" item? */ #define POOL_ITEM_DELETED 0x0004 /* is this item deleted? */ typedef struct { POOL_QUERY_HASH query_hash; /* md5 hashed query signature */ POOL_CACHEID next; /* next cache item if any */ unsigned int offset; /* item offset in this block */ unsigned char flags; /* flags. see above */ } POOL_CACHE_ITEM_POINTER; /* * Each block holds several "cache item", which consists of variable * length of Data(header plus RowDescription packet and DataRow * packet). Each cache item is assigned "cache item id", which * represents the cache item order in a block. */ /* * "Cache Item" structure holds a SELECT result having several row * data in memory cache. Cache item can be used with either shmem or * memcached. */ /* * "Cache Item header" structure is used to manage each cache item. */ typedef struct { unsigned int total_length; /* total length in bytes including myself */ time_t timestamp; /* cache creation time */ } POOL_CACHE_ITEM_HEADER; typedef struct { POOL_CACHE_ITEM_HEADER header; /* cache item header */ char data[1]; /* variable length data follows */ } POOL_CACHE_ITEM; /* * Possible the largest free space size in bytes */ #define POOL_MAX_FREE_SPACE (pool_config->memqcache_cache_block_size - sizeof(POOL_CACHE_BLOCK_HEADER)) #define POOL_FSMM_RATIO (pool_config->memqcache_cache_block_size/256) #define MAX_VALUE 8192 #define MAX_KEY 256 extern int memcached_connect(void); extern void memcached_disconnect(void); extern void memqcache_register(char kind, POOL_CONNECTION *frontend, char *data, int data_len); /* * Cache key */ typedef union { POOL_CACHEID cacheid; /* cache key (shmem configuration) */ char hashkey[POOL_MD5_HASHKEYLEN]; /* cache key (memcached configuration) */ } POOL_CACHEKEY; /* * Internal buffer structure */ typedef struct { size_t bufsize; /* buffer size */ size_t buflen; /* used length */ char *buf; /* buffer */ } POOL_INTERNAL_BUFFER; /* * Temporary query cache buffer */ typedef struct { bool is_exceeded; /* true if data size exceeds memqcache_maxcache */ bool is_discarded; /* true if this cache entry is discarded */ char *query; /* SELECT query */ POOL_INTERNAL_BUFFER *buffer; int num_oids; POOL_INTERNAL_BUFFER *oids; } POOL_TEMP_QUERY_CACHE; /* * Temporary query cache buffer array */ typedef struct { int num_caches; int array_size; POOL_TEMP_QUERY_CACHE *caches[1]; /* actual data continues... */ } POOL_QUERY_CACHE_ARRAY; /* * Query cache statistics structure. This area must be placed on shared * memory and protected by QUERY_CACHE_STATS_SEM. */ typedef struct { time_t start_time; /* start time when the statistics begins */ long long int num_selects; /* number of successful SELECTs */ long long int num_cache_hits; /* number of SELECTs extracted from cache */ } POOL_QUERY_CACHE_STATS; /* * Shared memory cache stats interface. */ typedef struct { int num_hash_entries; /* number of total hash entries */ int used_hash_entries; /* number of used hash entries */ int num_cache_entries; /* number of used cache entries */ long used_cache_entries_size; /* total size of used cache entries */ long free_cache_entries_size; /* total size of free(usable) cache entries */ long fragment_cache_entries_size; /* total size of fragment(unusable) cache entries */ POOL_QUERY_CACHE_STATS cache_stats; } POOL_SHMEM_STATS; /*-------------------------------------------------------------------------------- * On shared memory hash table implementation *-------------------------------------------------------------------------------- */ /* Hash element */ typedef struct POOL_HASH_ELEMENT { struct POOL_HASH_ELEMENT *next; /* link to next entry */ POOL_QUERY_HASH hashkey; /* MD5 hash key */ POOL_CACHEID cacheid; /* logical location of this cache element */ } POOL_HASH_ELEMENT; typedef uint32 POOL_HASH_KEY; /* Hash header element */ typedef struct { POOL_HASH_KEY hashkey; /* hash key */ POOL_HASH_ELEMENT *element; /* hash element */ } POOL_HEADER_ELEMENT; /* Hash header */ typedef struct { long nhash; /* number of hash keys (power of 2) */ uint32 mask; /* mask for hash function */ POOL_HEADER_ELEMENT elements[1]; /* actual hash elements follows */ } POOL_HASH_HEADER; extern int pool_hash_init(int nelements); extern POOL_CACHEID *pool_hash_search(POOL_QUERY_HASH *key); extern int pool_hash_delete(POOL_QUERY_HASH *key); extern uint32 hash_any(unsigned char *k, int keylen); extern POOL_STATUS pool_fetch_from_memory_cache(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *contents, bool *foundp); extern bool pool_is_likely_select(char *query); extern bool pool_is_table_in_black_list(const char *table_name); extern bool pool_is_table_in_white_list(const char *table_name); extern bool pool_is_allow_to_cache(Node *node, char *query); extern int pool_extract_table_oids(Node *node, int **oidsp); extern void pool_add_dml_table_oid(int oid); extern void pool_discard_oid_maps(void); extern int pool_get_database_oid_from_dbname(char *dbname); extern void pool_discard_oid_maps_by_db(int dboid); extern bool pool_is_shmem_cache(void); extern size_t pool_shared_memory_cache_size(void); extern int pool_init_memory_cache(size_t size); extern void pool_clear_memory_cache(void); extern size_t pool_shared_memory_fsmm_size(void); extern int pool_init_fsmm(size_t size); extern void pool_allocate_fsmm_clock_hand(void); extern POOL_QUERY_CACHE_ARRAY *pool_create_query_cache_array(void); extern void pool_discard_query_cache_array(POOL_QUERY_CACHE_ARRAY *cache_array); extern POOL_TEMP_QUERY_CACHE *pool_create_temp_query_cache(char *query); extern void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *node, char state); extern int pool_init_memqcache_stats(void); extern POOL_QUERY_CACHE_STATS *pool_get_memqcache_stats(void); extern void pool_reset_memqcache_stats(void); extern long long int pool_stats_count_up_num_selects(long long int num); extern long long int pool_stats_count_up_num_cache_hits(void); extern long long int pool_tmp_stats_count_up_num_selects(void); extern long long int pool_tmp_stats_get_num_selects(void); extern void pool_tmp_stats_reset_num_selects(void); extern POOL_SHMEM_STATS *pool_get_shmem_storage_stats(void); extern POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void); extern POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void); extern void pool_discard_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache); extern void pool_shmem_lock(void); extern void pool_shmem_unlock(void); #endif /* POOL_MEMQCACHE_H */ pgpool-II-3.3.2/parser/0000775000076400007640000000000012245776616011645 500000000000000pgpool-II-3.3.2/parser/gram.h0000664000076400007640000004616112245576266012673 00000000000000/* A Bison parser, made by GNU Bison 2.4.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 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 . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { IDENT = 258, FCONST = 259, SCONST = 260, BCONST = 261, XCONST = 262, Op = 263, ICONST = 264, PARAM = 265, TYPECAST = 266, DOT_DOT = 267, COLON_EQUALS = 268, ABORT_P = 269, ABSOLUTE_P = 270, ACCESS = 271, ACTION = 272, ADD_P = 273, ADMIN = 274, AFTER = 275, AGGREGATE = 276, ALL = 277, ALSO = 278, ALTER = 279, ALWAYS = 280, ANALYSE = 281, ANALYZE = 282, AND = 283, ANY = 284, ARRAY = 285, AS = 286, ASC = 287, ASSERTION = 288, ASSIGNMENT = 289, ASYMMETRIC = 290, AT = 291, ATTRIBUTE = 292, AUTHORIZATION = 293, BACKWARD = 294, BEFORE = 295, BEGIN_P = 296, BETWEEN = 297, BIGINT = 298, BINARY = 299, BIT = 300, BOOLEAN_P = 301, BOTH = 302, BY = 303, CACHE = 304, CALLED = 305, CASCADE = 306, CASCADED = 307, CASE = 308, CAST = 309, CATALOG_P = 310, CHAIN = 311, CHAR_P = 312, CHARACTER = 313, CHARACTERISTICS = 314, CHECK = 315, CHECKPOINT = 316, CLASS = 317, CLOSE = 318, CLUSTER = 319, COALESCE = 320, COLLATE = 321, COLLATION = 322, COLUMN = 323, COMMENT = 324, COMMENTS = 325, COMMIT = 326, COMMITTED = 327, CONCURRENTLY = 328, CONFIGURATION = 329, CONNECTION = 330, CONSTRAINT = 331, CONSTRAINTS = 332, CONTENT_P = 333, CONTINUE_P = 334, CONVERSION_P = 335, COPY = 336, COST = 337, CREATE = 338, CROSS = 339, CSV = 340, CURRENT_P = 341, CURRENT_CATALOG = 342, CURRENT_DATE = 343, CURRENT_ROLE = 344, CURRENT_SCHEMA = 345, CURRENT_TIME = 346, CURRENT_TIMESTAMP = 347, CURRENT_USER = 348, CURSOR = 349, CYCLE = 350, DATA_P = 351, DATABASE = 352, DAY_P = 353, DEALLOCATE = 354, DEC = 355, DECIMAL_P = 356, DECLARE = 357, DEFAULT = 358, DEFAULTS = 359, DEFERRABLE = 360, DEFERRED = 361, DEFINER = 362, DELETE_P = 363, DELIMITER = 364, DELIMITERS = 365, DESC = 366, DICTIONARY = 367, DISABLE_P = 368, DISCARD = 369, DISTINCT = 370, DO = 371, DOCUMENT_P = 372, DOMAIN_P = 373, DOUBLE_P = 374, DROP = 375, EACH = 376, ELSE = 377, ENABLE_P = 378, ENCODING = 379, ENCRYPTED = 380, END_P = 381, ENUM_P = 382, ESCAPE = 383, EXCEPT = 384, EXCLUDE = 385, EXCLUDING = 386, EXCLUSIVE = 387, EXECUTE = 388, EXISTS = 389, EXPLAIN = 390, EXTENSION = 391, EXTERNAL = 392, EXTRACT = 393, FALSE_P = 394, FAMILY = 395, FETCH = 396, FIRST_P = 397, FLOAT_P = 398, FOLLOWING = 399, FOR = 400, FORCE = 401, FOREIGN = 402, FORWARD = 403, FREEZE = 404, FROM = 405, FULL = 406, FUNCTION = 407, FUNCTIONS = 408, GLOBAL = 409, GRANT = 410, GRANTED = 411, GREATEST = 412, GROUP_P = 413, HANDLER = 414, HAVING = 415, HEADER_P = 416, HOLD = 417, HOUR_P = 418, IDENTITY_P = 419, IF_P = 420, ILIKE = 421, IMMEDIATE = 422, IMMUTABLE = 423, IMPLICIT_P = 424, IN_P = 425, INCLUDING = 426, INCREMENT = 427, INDEX = 428, INDEXES = 429, INHERIT = 430, INHERITS = 431, INITIALLY = 432, INLINE_P = 433, INNER_P = 434, INOUT = 435, INPUT_P = 436, INSENSITIVE = 437, INSERT = 438, INSTEAD = 439, INT_P = 440, INTEGER = 441, INTERSECT = 442, INTERVAL = 443, INTO = 444, INVOKER = 445, IS = 446, ISNULL = 447, ISOLATION = 448, JOIN = 449, KEY = 450, LABEL = 451, LANGUAGE = 452, LARGE_P = 453, LAST_P = 454, LC_COLLATE_P = 455, LC_CTYPE_P = 456, LEADING = 457, LEAKPROOF = 458, LEAST = 459, LEFT = 460, LEVEL = 461, LIKE = 462, LIMIT = 463, LISTEN = 464, LOAD = 465, LOCAL = 466, LOCALTIME = 467, LOCALTIMESTAMP = 468, LOCATION = 469, LOCK_P = 470, MAPPING = 471, MATCH = 472, MAXVALUE = 473, MINUTE_P = 474, MINVALUE = 475, MODE = 476, MONTH_P = 477, MOVE = 478, NAME_P = 479, NAMES = 480, NATIONAL = 481, NATURAL = 482, NCHAR = 483, NEXT = 484, NO = 485, NONE = 486, NOT = 487, NOTHING = 488, NOTIFY = 489, NOTNULL = 490, NOWAIT = 491, NULL_P = 492, NULLIF = 493, NULLS_P = 494, NUMERIC = 495, OBJECT_P = 496, OF = 497, OFF = 498, OFFSET = 499, OIDS = 500, ON = 501, ONLY = 502, OPERATOR = 503, OPTION = 504, OPTIONS = 505, OR = 506, ORDER = 507, OUT_P = 508, OUTER_P = 509, OVER = 510, OVERLAPS = 511, OVERLAY = 512, OWNED = 513, OWNER = 514, PARSER = 515, PARTIAL = 516, PARTITION = 517, PASSING = 518, PASSWORD = 519, PLACING = 520, PLANS = 521, POSITION = 522, PRECEDING = 523, PRECISION = 524, PRESERVE = 525, PREPARE = 526, PREPARED = 527, PRIMARY = 528, PRIOR = 529, PRIVILEGES = 530, PROCEDURAL = 531, PROCEDURE = 532, QUOTE = 533, RANGE = 534, READ = 535, REAL = 536, REASSIGN = 537, RECHECK = 538, RECURSIVE = 539, REF = 540, REFERENCES = 541, REINDEX = 542, RELATIVE_P = 543, RELEASE = 544, RENAME = 545, REPEATABLE = 546, REPLACE = 547, REPLICA = 548, RESET = 549, RESTART = 550, RESTRICT = 551, RETURNING = 552, RETURNS = 553, REVOKE = 554, RIGHT = 555, ROLE = 556, ROLLBACK = 557, ROW = 558, ROWS = 559, RULE = 560, SAVEPOINT = 561, SCHEMA = 562, SCROLL = 563, SEARCH = 564, SECOND_P = 565, SECURITY = 566, SELECT = 567, SEQUENCE = 568, SEQUENCES = 569, SERIALIZABLE = 570, SERVER = 571, SESSION = 572, SESSION_USER = 573, SET = 574, SETOF = 575, SHARE = 576, SHOW = 577, SIMILAR = 578, SIMPLE = 579, SMALLINT = 580, SNAPSHOT = 581, SOME = 582, STABLE = 583, STANDALONE_P = 584, START = 585, STATEMENT = 586, STATISTICS = 587, STDIN = 588, STDOUT = 589, STORAGE = 590, STRICT_P = 591, STRIP_P = 592, SUBSTRING = 593, SYMMETRIC = 594, SYSID = 595, SYSTEM_P = 596, TABLE = 597, TABLES = 598, TABLESPACE = 599, TEMP = 600, TEMPLATE = 601, TEMPORARY = 602, TEXT_P = 603, THEN = 604, TIME = 605, TIMESTAMP = 606, TO = 607, TRAILING = 608, TRANSACTION = 609, TREAT = 610, TRIGGER = 611, TRIM = 612, TRUE_P = 613, TRUNCATE = 614, TRUSTED = 615, TYPE_P = 616, TYPES_P = 617, UNBOUNDED = 618, UNCOMMITTED = 619, UNENCRYPTED = 620, UNION = 621, UNIQUE = 622, UNKNOWN = 623, UNLISTEN = 624, UNLOGGED = 625, UNTIL = 626, UPDATE = 627, USER = 628, USING = 629, VACUUM = 630, VALID = 631, VALIDATE = 632, VALIDATOR = 633, VALUE_P = 634, VALUES = 635, VARCHAR = 636, VARIADIC = 637, VARYING = 638, VERBOSE = 639, VERSION_P = 640, VIEW = 641, VOLATILE = 642, WHEN = 643, WHERE = 644, WHITESPACE_P = 645, WINDOW = 646, WITH = 647, WITHOUT = 648, WORK = 649, WRAPPER = 650, WRITE = 651, XML_P = 652, XMLATTRIBUTES = 653, XMLCONCAT = 654, XMLELEMENT = 655, XMLEXISTS = 656, XMLFOREST = 657, XMLPARSE = 658, XMLPI = 659, XMLROOT = 660, XMLSERIALIZE = 661, YEAR_P = 662, YES_P = 663, ZONE = 664, NULLS_FIRST = 665, NULLS_LAST = 666, WITH_TIME = 667, POSTFIXOP = 668, UMINUS = 669 }; #endif /* Tokens. */ #define IDENT 258 #define FCONST 259 #define SCONST 260 #define BCONST 261 #define XCONST 262 #define Op 263 #define ICONST 264 #define PARAM 265 #define TYPECAST 266 #define DOT_DOT 267 #define COLON_EQUALS 268 #define ABORT_P 269 #define ABSOLUTE_P 270 #define ACCESS 271 #define ACTION 272 #define ADD_P 273 #define ADMIN 274 #define AFTER 275 #define AGGREGATE 276 #define ALL 277 #define ALSO 278 #define ALTER 279 #define ALWAYS 280 #define ANALYSE 281 #define ANALYZE 282 #define AND 283 #define ANY 284 #define ARRAY 285 #define AS 286 #define ASC 287 #define ASSERTION 288 #define ASSIGNMENT 289 #define ASYMMETRIC 290 #define AT 291 #define ATTRIBUTE 292 #define AUTHORIZATION 293 #define BACKWARD 294 #define BEFORE 295 #define BEGIN_P 296 #define BETWEEN 297 #define BIGINT 298 #define BINARY 299 #define BIT 300 #define BOOLEAN_P 301 #define BOTH 302 #define BY 303 #define CACHE 304 #define CALLED 305 #define CASCADE 306 #define CASCADED 307 #define CASE 308 #define CAST 309 #define CATALOG_P 310 #define CHAIN 311 #define CHAR_P 312 #define CHARACTER 313 #define CHARACTERISTICS 314 #define CHECK 315 #define CHECKPOINT 316 #define CLASS 317 #define CLOSE 318 #define CLUSTER 319 #define COALESCE 320 #define COLLATE 321 #define COLLATION 322 #define COLUMN 323 #define COMMENT 324 #define COMMENTS 325 #define COMMIT 326 #define COMMITTED 327 #define CONCURRENTLY 328 #define CONFIGURATION 329 #define CONNECTION 330 #define CONSTRAINT 331 #define CONSTRAINTS 332 #define CONTENT_P 333 #define CONTINUE_P 334 #define CONVERSION_P 335 #define COPY 336 #define COST 337 #define CREATE 338 #define CROSS 339 #define CSV 340 #define CURRENT_P 341 #define CURRENT_CATALOG 342 #define CURRENT_DATE 343 #define CURRENT_ROLE 344 #define CURRENT_SCHEMA 345 #define CURRENT_TIME 346 #define CURRENT_TIMESTAMP 347 #define CURRENT_USER 348 #define CURSOR 349 #define CYCLE 350 #define DATA_P 351 #define DATABASE 352 #define DAY_P 353 #define DEALLOCATE 354 #define DEC 355 #define DECIMAL_P 356 #define DECLARE 357 #define DEFAULT 358 #define DEFAULTS 359 #define DEFERRABLE 360 #define DEFERRED 361 #define DEFINER 362 #define DELETE_P 363 #define DELIMITER 364 #define DELIMITERS 365 #define DESC 366 #define DICTIONARY 367 #define DISABLE_P 368 #define DISCARD 369 #define DISTINCT 370 #define DO 371 #define DOCUMENT_P 372 #define DOMAIN_P 373 #define DOUBLE_P 374 #define DROP 375 #define EACH 376 #define ELSE 377 #define ENABLE_P 378 #define ENCODING 379 #define ENCRYPTED 380 #define END_P 381 #define ENUM_P 382 #define ESCAPE 383 #define EXCEPT 384 #define EXCLUDE 385 #define EXCLUDING 386 #define EXCLUSIVE 387 #define EXECUTE 388 #define EXISTS 389 #define EXPLAIN 390 #define EXTENSION 391 #define EXTERNAL 392 #define EXTRACT 393 #define FALSE_P 394 #define FAMILY 395 #define FETCH 396 #define FIRST_P 397 #define FLOAT_P 398 #define FOLLOWING 399 #define FOR 400 #define FORCE 401 #define FOREIGN 402 #define FORWARD 403 #define FREEZE 404 #define FROM 405 #define FULL 406 #define FUNCTION 407 #define FUNCTIONS 408 #define GLOBAL 409 #define GRANT 410 #define GRANTED 411 #define GREATEST 412 #define GROUP_P 413 #define HANDLER 414 #define HAVING 415 #define HEADER_P 416 #define HOLD 417 #define HOUR_P 418 #define IDENTITY_P 419 #define IF_P 420 #define ILIKE 421 #define IMMEDIATE 422 #define IMMUTABLE 423 #define IMPLICIT_P 424 #define IN_P 425 #define INCLUDING 426 #define INCREMENT 427 #define INDEX 428 #define INDEXES 429 #define INHERIT 430 #define INHERITS 431 #define INITIALLY 432 #define INLINE_P 433 #define INNER_P 434 #define INOUT 435 #define INPUT_P 436 #define INSENSITIVE 437 #define INSERT 438 #define INSTEAD 439 #define INT_P 440 #define INTEGER 441 #define INTERSECT 442 #define INTERVAL 443 #define INTO 444 #define INVOKER 445 #define IS 446 #define ISNULL 447 #define ISOLATION 448 #define JOIN 449 #define KEY 450 #define LABEL 451 #define LANGUAGE 452 #define LARGE_P 453 #define LAST_P 454 #define LC_COLLATE_P 455 #define LC_CTYPE_P 456 #define LEADING 457 #define LEAKPROOF 458 #define LEAST 459 #define LEFT 460 #define LEVEL 461 #define LIKE 462 #define LIMIT 463 #define LISTEN 464 #define LOAD 465 #define LOCAL 466 #define LOCALTIME 467 #define LOCALTIMESTAMP 468 #define LOCATION 469 #define LOCK_P 470 #define MAPPING 471 #define MATCH 472 #define MAXVALUE 473 #define MINUTE_P 474 #define MINVALUE 475 #define MODE 476 #define MONTH_P 477 #define MOVE 478 #define NAME_P 479 #define NAMES 480 #define NATIONAL 481 #define NATURAL 482 #define NCHAR 483 #define NEXT 484 #define NO 485 #define NONE 486 #define NOT 487 #define NOTHING 488 #define NOTIFY 489 #define NOTNULL 490 #define NOWAIT 491 #define NULL_P 492 #define NULLIF 493 #define NULLS_P 494 #define NUMERIC 495 #define OBJECT_P 496 #define OF 497 #define OFF 498 #define OFFSET 499 #define OIDS 500 #define ON 501 #define ONLY 502 #define OPERATOR 503 #define OPTION 504 #define OPTIONS 505 #define OR 506 #define ORDER 507 #define OUT_P 508 #define OUTER_P 509 #define OVER 510 #define OVERLAPS 511 #define OVERLAY 512 #define OWNED 513 #define OWNER 514 #define PARSER 515 #define PARTIAL 516 #define PARTITION 517 #define PASSING 518 #define PASSWORD 519 #define PLACING 520 #define PLANS 521 #define POSITION 522 #define PRECEDING 523 #define PRECISION 524 #define PRESERVE 525 #define PREPARE 526 #define PREPARED 527 #define PRIMARY 528 #define PRIOR 529 #define PRIVILEGES 530 #define PROCEDURAL 531 #define PROCEDURE 532 #define QUOTE 533 #define RANGE 534 #define READ 535 #define REAL 536 #define REASSIGN 537 #define RECHECK 538 #define RECURSIVE 539 #define REF 540 #define REFERENCES 541 #define REINDEX 542 #define RELATIVE_P 543 #define RELEASE 544 #define RENAME 545 #define REPEATABLE 546 #define REPLACE 547 #define REPLICA 548 #define RESET 549 #define RESTART 550 #define RESTRICT 551 #define RETURNING 552 #define RETURNS 553 #define REVOKE 554 #define RIGHT 555 #define ROLE 556 #define ROLLBACK 557 #define ROW 558 #define ROWS 559 #define RULE 560 #define SAVEPOINT 561 #define SCHEMA 562 #define SCROLL 563 #define SEARCH 564 #define SECOND_P 565 #define SECURITY 566 #define SELECT 567 #define SEQUENCE 568 #define SEQUENCES 569 #define SERIALIZABLE 570 #define SERVER 571 #define SESSION 572 #define SESSION_USER 573 #define SET 574 #define SETOF 575 #define SHARE 576 #define SHOW 577 #define SIMILAR 578 #define SIMPLE 579 #define SMALLINT 580 #define SNAPSHOT 581 #define SOME 582 #define STABLE 583 #define STANDALONE_P 584 #define START 585 #define STATEMENT 586 #define STATISTICS 587 #define STDIN 588 #define STDOUT 589 #define STORAGE 590 #define STRICT_P 591 #define STRIP_P 592 #define SUBSTRING 593 #define SYMMETRIC 594 #define SYSID 595 #define SYSTEM_P 596 #define TABLE 597 #define TABLES 598 #define TABLESPACE 599 #define TEMP 600 #define TEMPLATE 601 #define TEMPORARY 602 #define TEXT_P 603 #define THEN 604 #define TIME 605 #define TIMESTAMP 606 #define TO 607 #define TRAILING 608 #define TRANSACTION 609 #define TREAT 610 #define TRIGGER 611 #define TRIM 612 #define TRUE_P 613 #define TRUNCATE 614 #define TRUSTED 615 #define TYPE_P 616 #define TYPES_P 617 #define UNBOUNDED 618 #define UNCOMMITTED 619 #define UNENCRYPTED 620 #define UNION 621 #define UNIQUE 622 #define UNKNOWN 623 #define UNLISTEN 624 #define UNLOGGED 625 #define UNTIL 626 #define UPDATE 627 #define USER 628 #define USING 629 #define VACUUM 630 #define VALID 631 #define VALIDATE 632 #define VALIDATOR 633 #define VALUE_P 634 #define VALUES 635 #define VARCHAR 636 #define VARIADIC 637 #define VARYING 638 #define VERBOSE 639 #define VERSION_P 640 #define VIEW 641 #define VOLATILE 642 #define WHEN 643 #define WHERE 644 #define WHITESPACE_P 645 #define WINDOW 646 #define WITH 647 #define WITHOUT 648 #define WORK 649 #define WRAPPER 650 #define WRITE 651 #define XML_P 652 #define XMLATTRIBUTES 653 #define XMLCONCAT 654 #define XMLELEMENT 655 #define XMLEXISTS 656 #define XMLFOREST 657 #define XMLPARSE 658 #define XMLPI 659 #define XMLROOT 660 #define XMLSERIALIZE 661 #define YEAR_P 662 #define YES_P 663 #define ZONE 664 #define NULLS_FIRST 665 #define NULLS_LAST 666 #define WITH_TIME 667 #define POSTFIXOP 668 #define UMINUS 669 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE { /* Line 1685 of yacc.c */ #line 171 "gram.y" core_YYSTYPE core_yystype; /* these fields must match core_YYSTYPE: */ int ival; char *str; const char *keyword; char chr; bool boolean; JoinType jtype; DropBehavior dbehavior; OnCommitAction oncommit; List *list; Node *node; Value *value; ObjectType objtype; TypeName *typnam; FunctionParameter *fun_param; FunctionParameterMode fun_param_mode; FuncWithArgs *funwithargs; DefElem *defelt; SortBy *sortby; WindowDef *windef; JoinExpr *jexpr; IndexElem *ielem; Alias *alias; RangeVar *range; IntoClause *into; WithClause *with; A_Indices *aind; ResTarget *target; struct PrivTarget *privtarget; AccessPriv *accesspriv; InsertStmt *istmt; VariableSetStmt *vsetstmt; /* Line 1685 of yacc.c */ #line 918 "gram.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED typedef struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; } YYLTYPE; # define yyltype YYLTYPE /* obsolescent; will be withdrawn */ # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif pgpool-II-3.3.2/parser/makefuncs.h0000664000076400007640000000461612245576266013720 00000000000000/*------------------------------------------------------------------------- * * makefuncs.h * prototypes for the creator functions (for primitive nodes) * * * Portions Copyright (c) 2003-2013, PgPool Global Development Group * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/makefuncs.h * *------------------------------------------------------------------------- */ #ifndef MAKEFUNC_H #define MAKEFUNC_H #include "parsenodes.h" extern A_Expr *makeA_Expr(A_Expr_Kind kind, List *name, Node *lexpr, Node *rexpr, int location); extern A_Expr *makeSimpleA_Expr(A_Expr_Kind kind, char *name, Node *lexpr, Node *rexpr, int location); extern Var *makeVar(Index varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup); extern Var *makeVarFromTargetEntry(Index varno, TargetEntry *tle); extern Var *makeWholeRowVar(RangeTblEntry *rte, Index varno, Index varlevelsup, bool allowScalar); extern TargetEntry *makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk); extern TargetEntry *flatCopyTargetEntry(TargetEntry *src_tle); extern FromExpr *makeFromExpr(List *fromlist, Node *quals); extern Const *makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval); extern Const *makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid); extern Node *makeBoolConst(bool value, bool isnull); extern Expr *makeBoolExpr(BoolExprType boolop, List *args, int location); extern Alias *makeAlias(const char *aliasname, List *colnames); extern RelabelType *makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat); extern RangeVar *makeRangeVar(char *schemaname, char *relname, int location); extern TypeName *makeTypeName(char *typnam); extern TypeName *makeTypeNameFromNameList(List *names); extern TypeName *makeTypeNameFromOid(Oid typeid, int32 typmod); extern FuncExpr *makeFuncExpr(Oid funcid, Oid rettype, List *args, Oid funccollid, Oid inputcollid, CoercionForm fformat); extern DefElem *makeDefElem(char *name, Node *arg); extern DefElem *makeDefElemExtended(char *namespace, char *name, Node *arg, DefElemAction defaction); #endif /* MAKEFUNC_H */ pgpool-II-3.3.2/parser/memnodes.h0000664000076400007640000000514212245576266013546 00000000000000/*------------------------------------------------------------------------- * * memnodes.h * POSTGRES memory context node definitions. * * * Portions Copyright (c) 2003-2013, PgPool Global Development Group * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/memnodes.h * *------------------------------------------------------------------------- */ #ifndef MEMNODES_H #define MEMNODES_H #include "nodes.h" /* * MemoryContext * A logical context in which memory allocations occur. * * MemoryContext itself is an abstract type that can have multiple * implementations, though for now we have only AllocSetContext. * The function pointers in MemoryContextMethods define one specific * implementation of MemoryContext --- they are a virtual function table * in C++ terms. * * Node types that are actual implementations of memory contexts must * begin with the same fields as MemoryContext. * * Note: for largely historical reasons, typedef MemoryContext is a pointer * to the context struct rather than the struct type itself. */ typedef struct MemoryContextMethods { void *(*alloc) (MemoryContext context, Size size); /* call this free_p in case someone #define's free() */ void (*free_p) (MemoryContext context, void *pointer); void *(*realloc) (MemoryContext context, void *pointer, Size size); void (*init) (MemoryContext context); void (*reset) (MemoryContext context); void (*delete) (MemoryContext context); Size (*get_chunk_space) (MemoryContext context, void *pointer); bool (*is_empty) (MemoryContext context); void (*stats) (MemoryContext context); #ifdef MEMORY_CONTEXT_CHECKING void (*check) (MemoryContext context); #endif } MemoryContextMethods; typedef struct MemoryContextData { NodeTag type; /* identifies exact kind of context */ MemoryContextMethods *methods; /* virtual function table */ MemoryContext parent; /* NULL if no parent (toplevel context) */ MemoryContext firstchild; /* head of linked list of children */ MemoryContext nextchild; /* next child of same parent */ char *name; /* context name (just for debugging) */ bool isReset; /* T = no space alloced since last reset */ } MemoryContextData; /* utils/palloc.h contains typedef struct MemoryContextData *MemoryContext */ /* * MemoryContextIsValid * True iff memory context is valid. * * Add new context types to the set accepted by this macro. */ #define MemoryContextIsValid(context) \ ((context) != NULL && \ (IsA((context), AllocSetContext))) #endif /* MEMNODES_H */ pgpool-II-3.3.2/parser/pg_class.h0000664000076400007640000001400712245576266013532 00000000000000/*------------------------------------------------------------------------- * * pg_class.h * definition of the system "relation" relation (pg_class) * along with the relation's initial contents. * * * Portions Copyright (c) 2003-2013, PgPool Global Development Group * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_class.h * * NOTES * the genbki.pl script reads this file and generates .bki * information from the DATA() statements. * *------------------------------------------------------------------------- */ #ifndef PG_CLASS_H #define PG_CLASS_H #if 0 #include "catalog/genbki.h" /* ---------------- * pg_class definition. cpp turns this into * typedef struct FormData_pg_class * ---------------- */ #define RelationRelationId 1259 #define RelationRelation_Rowtype_Id 83 CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO { NameData relname; /* class name */ Oid relnamespace; /* OID of namespace containing this class */ Oid reltype; /* OID of entry in pg_type for table's * implicit row type */ Oid reloftype; /* OID of entry in pg_type for underlying * composite type */ Oid relowner; /* class owner */ Oid relam; /* index access method; 0 if not an index */ Oid relfilenode; /* identifier of physical storage file */ /* relfilenode == 0 means it is a "mapped" relation, see relmapper.c */ Oid reltablespace; /* identifier of table space for relation */ int4 relpages; /* # of blocks (not always up-to-date) */ float4 reltuples; /* # of tuples (not always up-to-date) */ int4 relallvisible; /* # of all-visible blocks (not always * up-to-date) */ Oid reltoastrelid; /* OID of toast table; 0 if none */ Oid reltoastidxid; /* if toast table, OID of chunk_id index */ bool relhasindex; /* T if has (or has had) any indexes */ bool relisshared; /* T if shared across databases */ char relpersistence; /* see RELPERSISTENCE_xxx constants below */ char relkind; /* see RELKIND_xxx constants below */ int2 relnatts; /* number of user attributes */ /* * Class pg_attribute must contain exactly "relnatts" user attributes * (with attnums ranging from 1 to relnatts) for this class. It may also * contain entries with negative attnums for system attributes. */ int2 relchecks; /* # of CHECK constraints for class */ bool relhasoids; /* T if we generate OIDs for rows of rel */ bool relhaspkey; /* has (or has had) PRIMARY KEY index */ bool relhasrules; /* has (or has had) any rules */ bool relhastriggers; /* has (or has had) any TRIGGERs */ bool relhassubclass; /* has (or has had) derived classes */ TransactionId relfrozenxid; /* all Xids < this are frozen in this rel */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ /* NOTE: These fields are not present in a relcache entry's rd_rel field. */ aclitem relacl[1]; /* access permissions */ text reloptions[1]; /* access-method-specific options */ #endif } FormData_pg_class; /* Size of fixed part of pg_class tuples, not counting var-length fields */ #define CLASS_TUPLE_SIZE \ (offsetof(FormData_pg_class,relfrozenxid) + sizeof(TransactionId)) /* ---------------- * Form_pg_class corresponds to a pointer to a tuple with * the format of pg_class relation. * ---------------- */ typedef FormData_pg_class *Form_pg_class; /* ---------------- * compiler constants for pg_class * ---------------- */ #define Natts_pg_class 27 #define Anum_pg_class_relname 1 #define Anum_pg_class_relnamespace 2 #define Anum_pg_class_reltype 3 #define Anum_pg_class_reloftype 4 #define Anum_pg_class_relowner 5 #define Anum_pg_class_relam 6 #define Anum_pg_class_relfilenode 7 #define Anum_pg_class_reltablespace 8 #define Anum_pg_class_relpages 9 #define Anum_pg_class_reltuples 10 #define Anum_pg_class_relallvisible 11 #define Anum_pg_class_reltoastrelid 12 #define Anum_pg_class_reltoastidxid 13 #define Anum_pg_class_relhasindex 14 #define Anum_pg_class_relisshared 15 #define Anum_pg_class_relpersistence 16 #define Anum_pg_class_relkind 17 #define Anum_pg_class_relnatts 18 #define Anum_pg_class_relchecks 19 #define Anum_pg_class_relhasoids 20 #define Anum_pg_class_relhaspkey 21 #define Anum_pg_class_relhasrules 22 #define Anum_pg_class_relhastriggers 23 #define Anum_pg_class_relhassubclass 24 #define Anum_pg_class_relfrozenxid 25 #define Anum_pg_class_relacl 26 #define Anum_pg_class_reloptions 27 /* ---------------- * initial contents of pg_class * * NOTE: only "bootstrapped" relations need to be declared here. Be sure that * the OIDs listed here match those given in their CATALOG macros, and that * the relnatts values are correct. * ---------------- */ /* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */ DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 0 f f p r 30 0 t f f f f 3 _null_ _null_ )); DESCR(""); DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 0 f f p r 21 0 f f f f f 3 _null_ _null_ )); DESCR(""); DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 0 f f p r 27 0 t f f f f 3 _null_ _null_ )); DESCR(""); DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 0 f f p r 27 0 t f f f f 3 _null_ _null_ )); DESCR(""); #endif #define RELKIND_RELATION 'r' /* ordinary table */ #define RELKIND_INDEX 'i' /* secondary index */ #define RELKIND_SEQUENCE 'S' /* sequence object */ #define RELKIND_TOASTVALUE 't' /* for out-of-line values */ #define RELKIND_VIEW 'v' /* view */ #define RELKIND_COMPOSITE_TYPE 'c' /* composite type */ #define RELKIND_FOREIGN_TABLE 'f' /* foreign table */ #define RELKIND_UNCATALOGED 'u' /* not yet cataloged */ #define RELPERSISTENCE_PERMANENT 'p' /* regular table */ #define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent table */ #define RELPERSISTENCE_TEMP 't' /* temporary table */ #endif /* PG_CLASS_H */ pgpool-II-3.3.2/parser/scansup.h0000664000076400007640000000146512245576266013417 00000000000000/*------------------------------------------------------------------------- * * scansup.h * scanner support routines. used by both the bootstrap lexer * as well as the normal lexer * * Portions Copyright (c) 2003-2013, PgPool Global Development Group * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/scansup.h * *------------------------------------------------------------------------- */ #ifndef SCANSUP_H #define SCANSUP_H extern char *scanstr(const char *s); extern char *downcase_truncate_identifier(const char *ident, int len, bool warn); extern void truncate_identifier(char *ident, int len, bool warn); extern bool scanner_isspace(char ch); #endif /* SCANSUP_H */ pgpool-II-3.3.2/parser/pool_string.h0000664000076400007640000000221612245576256014274 00000000000000/* -*-pgsql-c-*- */ /* * $Header$ * * Copyright (c) 2006-2008, pgpool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. */ #ifndef POOL_STRING_H #define POOL_STRING_H #define STRING_SIZE 128 typedef struct { int size; int len; char *data; } String; extern String *init_string(char *str); extern void string_append_string(String *string, String *append_data); extern void string_append_char(String *string, char *append_data); extern void free_string(String *string); extern String *copy_string(String *string); #endif /* POOL_STRING_H */ pgpool-II-3.3.2/parser/parsenodes.h0000664000076400007640000025553212245576266014114 00000000000000/*------------------------------------------------------------------------- * * parsenodes.h * definitions for parse tree nodes * * Many of the node types used in parsetrees include a "location" field. * This is a byte (not character) offset in the original source text, to be * used for positioning an error cursor when there is an error related to * the node. Access to the original source text is needed to make use of * the location. * * * Portions Copyright (c) 2003-2013, PgPool Global Development Group * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/parsenodes.h * *------------------------------------------------------------------------- */ #ifndef PARSENODES_H #define PARSENODES_H #include "../pool_type.h" #include "primnodes.h" #include "value.h" /* include/nodes/bitmapset.h start */ typedef uint32 bitmapword; /* must be an unsigned type */ typedef struct Bitmapset { int nwords; /* number of words in array */ bitmapword words[1]; /* really [nwords] */ } Bitmapset; /* VARIABLE LENGTH STRUCT */ extern Bitmapset *bms_copy(const Bitmapset *a); /* include/nodes/bitmapset.h end */ /* Possible sources of a Query */ typedef enum QuerySource { QSRC_ORIGINAL, /* original parsetree (explicit query) */ QSRC_PARSER, /* added by parse analysis (now unused) */ QSRC_INSTEAD_RULE, /* added by unconditional INSTEAD rule */ QSRC_QUAL_INSTEAD_RULE, /* added by conditional INSTEAD rule */ QSRC_NON_INSTEAD_RULE /* added by non-INSTEAD rule */ } QuerySource; /* Sort ordering options for ORDER BY and CREATE INDEX */ typedef enum SortByDir { SORTBY_DEFAULT, SORTBY_ASC, SORTBY_DESC, SORTBY_USING /* not allowed in CREATE INDEX ... */ } SortByDir; typedef enum SortByNulls { SORTBY_NULLS_DEFAULT, SORTBY_NULLS_FIRST, SORTBY_NULLS_LAST } SortByNulls; /* * Grantable rights are encoded so that we can OR them together in a bitmask. * The present representation of AclItem limits us to 16 distinct rights, * even though AclMode is defined as uint32. See utils/acl.h. * * Caution: changing these codes breaks stored ACLs, hence forces initdb. */ typedef uint32 AclMode; /* a bitmask of privilege bits */ #define ACL_INSERT (1<<0) /* for relations */ #define ACL_SELECT (1<<1) #define ACL_UPDATE (1<<2) #define ACL_DELETE (1<<3) #define ACL_TRUNCATE (1<<4) #define ACL_REFERENCES (1<<5) #define ACL_TRIGGER (1<<6) #define ACL_EXECUTE (1<<7) /* for functions */ #define ACL_USAGE (1<<8) /* for languages, namespaces, FDWs, and * servers */ #define ACL_CREATE (1<<9) /* for namespaces and databases */ #define ACL_CREATE_TEMP (1<<10) /* for databases */ #define ACL_CONNECT (1<<11) /* for databases */ #define N_ACL_RIGHTS 12 /* 1 plus the last 1<" */ AEXPR_IN /* [NOT] IN - name must be "=" or "<>" */ } A_Expr_Kind; typedef struct A_Expr { NodeTag type; A_Expr_Kind kind; /* see above */ List *name; /* possibly-qualified name of operator */ Node *lexpr; /* left argument, or NULL if none */ Node *rexpr; /* right argument, or NULL if none */ int location; /* token location, or -1 if unknown */ } A_Expr; /* * A_Const - a literal constant */ typedef struct A_Const { NodeTag type; Value val; /* value (includes type info, see value.h) */ int location; /* token location, or -1 if unknown */ } A_Const; /* * TypeCast - a CAST expression */ typedef struct TypeCast { NodeTag type; Node *arg; /* the expression being casted */ TypeName *typeName; /* the target type */ int location; /* token location, or -1 if unknown */ } TypeCast; /* * CollateClause - a COLLATE expression */ typedef struct CollateClause { NodeTag type; Node *arg; /* input expression */ List *collname; /* possibly-qualified collation name */ int location; /* token location, or -1 if unknown */ } CollateClause; /* * FuncCall - a function or aggregate invocation * * agg_order (if not NIL) indicates we saw 'foo(... ORDER BY ...)'. * agg_star indicates we saw a 'foo(*)' construct, while agg_distinct * indicates we saw 'foo(DISTINCT ...)'. In any of these cases, the * construct *must* be an aggregate call. Otherwise, it might be either an * aggregate or some other kind of function. However, if OVER is present * it had better be an aggregate or window function. */ typedef struct FuncCall { NodeTag type; List *funcname; /* qualified name of function */ List *args; /* the arguments (list of exprs) */ List *agg_order; /* ORDER BY (list of SortBy) */ bool agg_star; /* argument was really '*' */ bool agg_distinct; /* arguments were labeled DISTINCT */ bool func_variadic; /* last argument was labeled VARIADIC */ struct WindowDef *over; /* OVER clause, if any */ int location; /* token location, or -1 if unknown */ } FuncCall; /* * A_Star - '*' representing all columns of a table or compound field * * This can appear within ColumnRef.fields, A_Indirection.indirection, and * ResTarget.indirection lists. */ typedef struct A_Star { NodeTag type; } A_Star; /* * A_Indices - array subscript or slice bounds ([lidx:uidx] or [uidx]) */ typedef struct A_Indices { NodeTag type; Node *lidx; /* NULL if it's a single subscript */ Node *uidx; } A_Indices; /* * A_Indirection - select a field and/or array element from an expression * * The indirection list can contain A_Indices nodes (representing * subscripting), string Value nodes (representing field selection --- the * string value is the name of the field to select), and A_Star nodes * (representing selection of all fields of a composite type). * For example, a complex selection operation like * (foo).field1[42][7].field2 * would be represented with a single A_Indirection node having a 4-element * indirection list. * * Currently, A_Star must appear only as the last list element --- the grammar * is responsible for enforcing this! */ typedef struct A_Indirection { NodeTag type; Node *arg; /* the thing being selected from */ List *indirection; /* subscripts and/or field names and/or * */ } A_Indirection; /* * A_ArrayExpr - an ARRAY[] construct */ typedef struct A_ArrayExpr { NodeTag type; List *elements; /* array element expressions */ int location; /* token location, or -1 if unknown */ } A_ArrayExpr; /* * ResTarget - * result target (used in target list of pre-transformed parse trees) * * In a SELECT target list, 'name' is the column label from an * 'AS ColumnLabel' clause, or NULL if there was none, and 'val' is the * value expression itself. The 'indirection' field is not used. * * INSERT uses ResTarget in its target-column-names list. Here, 'name' is * the name of the destination column, 'indirection' stores any subscripts * attached to the destination, and 'val' is not used. * * In an UPDATE target list, 'name' is the name of the destination column, * 'indirection' stores any subscripts attached to the destination, and * 'val' is the expression to assign. * * See A_Indirection for more info about what can appear in 'indirection'. */ typedef struct ResTarget { NodeTag type; char *name; /* column name or NULL */ List *indirection; /* subscripts, field names, and '*', or NIL */ Node *val; /* the value expression to compute or assign */ int location; /* token location, or -1 if unknown */ } ResTarget; /* * SortBy - for ORDER BY clause */ typedef struct SortBy { NodeTag type; Node *node; /* expression to sort on */ SortByDir sortby_dir; /* ASC/DESC/USING/default */ SortByNulls sortby_nulls; /* NULLS FIRST/LAST */ List *useOp; /* name of op to use, if SORTBY_USING */ int location; /* operator location, or -1 if none/unknown */ } SortBy; /* * WindowDef - raw representation of WINDOW and OVER clauses * * For entries in a WINDOW list, "name" is the window name being defined. * For OVER clauses, we use "name" for the "OVER window" syntax, or "refname" * for the "OVER (window)" syntax, which is subtly different --- the latter * implies overriding the window frame clause. */ typedef struct WindowDef { NodeTag type; char *name; /* window's own name */ char *refname; /* referenced window name, if any */ List *partitionClause; /* PARTITION BY expression list */ List *orderClause; /* ORDER BY (list of SortBy) */ int frameOptions; /* frame_clause options, see below */ Node *startOffset; /* expression for starting bound, if any */ Node *endOffset; /* expression for ending bound, if any */ int location; /* parse location, or -1 if none/unknown */ } WindowDef; /* * frameOptions is an OR of these bits. The NONDEFAULT and BETWEEN bits are * used so that ruleutils.c can tell which properties were specified and * which were defaulted; the correct behavioral bits must be set either way. * The START_foo and END_foo options must come in pairs of adjacent bits for * the convenience of gram.y, even though some of them are useless/invalid. * We will need more bits (and fields) to cover the full SQL:2008 option set. */ #define FRAMEOPTION_NONDEFAULT 0x00001 /* any specified? */ #define FRAMEOPTION_RANGE 0x00002 /* RANGE behavior */ #define FRAMEOPTION_ROWS 0x00004 /* ROWS behavior */ #define FRAMEOPTION_BETWEEN 0x00008 /* BETWEEN given? */ #define FRAMEOPTION_START_UNBOUNDED_PRECEDING 0x00010 /* start is U. P. */ #define FRAMEOPTION_END_UNBOUNDED_PRECEDING 0x00020 /* (disallowed) */ #define FRAMEOPTION_START_UNBOUNDED_FOLLOWING 0x00040 /* (disallowed) */ #define FRAMEOPTION_END_UNBOUNDED_FOLLOWING 0x00080 /* end is U. F. */ #define FRAMEOPTION_START_CURRENT_ROW 0x00100 /* start is C. R. */ #define FRAMEOPTION_END_CURRENT_ROW 0x00200 /* end is C. R. */ #define FRAMEOPTION_START_VALUE_PRECEDING 0x00400 /* start is V. P. */ #define FRAMEOPTION_END_VALUE_PRECEDING 0x00800 /* end is V. P. */ #define FRAMEOPTION_START_VALUE_FOLLOWING 0x01000 /* start is V. F. */ #define FRAMEOPTION_END_VALUE_FOLLOWING 0x02000 /* end is V. F. */ #define FRAMEOPTION_START_VALUE \ (FRAMEOPTION_START_VALUE_PRECEDING | FRAMEOPTION_START_VALUE_FOLLOWING) #define FRAMEOPTION_END_VALUE \ (FRAMEOPTION_END_VALUE_PRECEDING | FRAMEOPTION_END_VALUE_FOLLOWING) #define FRAMEOPTION_DEFAULTS \ (FRAMEOPTION_RANGE | FRAMEOPTION_START_UNBOUNDED_PRECEDING | \ FRAMEOPTION_END_CURRENT_ROW) /* * RangeSubselect - subquery appearing in a FROM clause */ typedef struct RangeSubselect { NodeTag type; Node *subquery; /* the untransformed sub-select clause */ Alias *alias; /* table alias & optional column aliases */ } RangeSubselect; /* * RangeFunction - function call appearing in a FROM clause */ typedef struct RangeFunction { NodeTag type; Node *funccallnode; /* untransformed function call tree */ Alias *alias; /* table alias & optional column aliases */ List *coldeflist; /* list of ColumnDef nodes to describe result * of function returning RECORD */ } RangeFunction; /* * ColumnDef - column definition (used in various creates) * * If the column has a default value, we may have the value expression * in either "raw" form (an untransformed parse tree) or "cooked" form * (a post-parse-analysis, executable expression tree), depending on * how this ColumnDef node was created (by parsing, or by inheritance * from an existing relation). We should never have both in the same node! * * Similarly, we may have a COLLATE specification in either raw form * (represented as a CollateClause with arg==NULL) or cooked form * (the collation's OID). * * The constraints list may contain a CONSTR_DEFAULT item in a raw * parsetree produced by gram.y, but transformCreateStmt will remove * the item and set raw_default instead. CONSTR_DEFAULT items * should not appear in any subsequent processing. */ typedef struct ColumnDef { NodeTag type; char *colname; /* name of column */ TypeName *typeName; /* type of column */ int inhcount; /* number of times column is inherited */ bool is_local; /* column has local (non-inherited) def'n */ bool is_not_null; /* NOT NULL constraint specified? */ bool is_from_type; /* column definition came from table type */ char storage; /* attstorage setting, or 0 for default */ Node *raw_default; /* default value (untransformed parse tree) */ Node *cooked_default; /* default value (transformed expr tree) */ CollateClause *collClause; /* untransformed COLLATE spec, if any */ Oid collOid; /* collation OID (InvalidOid if not set) */ List *constraints; /* other constraints on column */ List *fdwoptions; /* per-column FDW options */ } ColumnDef; /* * TableLikeClause - CREATE TABLE ( ... LIKE ... ) clause */ typedef struct TableLikeClause { NodeTag type; RangeVar *relation; bits32 options; /* OR of TableLikeOption flags */ } TableLikeClause; typedef enum TableLikeOption { CREATE_TABLE_LIKE_DEFAULTS = 1 << 0, CREATE_TABLE_LIKE_CONSTRAINTS = 1 << 1, CREATE_TABLE_LIKE_INDEXES = 1 << 2, CREATE_TABLE_LIKE_STORAGE = 1 << 3, CREATE_TABLE_LIKE_COMMENTS = 1 << 4, CREATE_TABLE_LIKE_ALL = 0x7FFFFFFF } TableLikeOption; /* * IndexElem - index parameters (used in CREATE INDEX) * * For a plain index attribute, 'name' is the name of the table column to * index, and 'expr' is NULL. For an index expression, 'name' is NULL and * 'expr' is the expression tree. */ typedef struct IndexElem { NodeTag type; char *name; /* name of attribute to index, or NULL */ Node *expr; /* expression to index, or NULL */ char *indexcolname; /* name for index column; NULL = default */ List *collation; /* name of collation; NIL = default */ List *opclass; /* name of desired opclass; NIL = default */ SortByDir ordering; /* ASC/DESC/default */ SortByNulls nulls_ordering; /* FIRST/LAST/default */ } IndexElem; /* * DefElem - a generic "name = value" option definition * * In some contexts the name can be qualified. Also, certain SQL commands * allow a SET/ADD/DROP action to be attached to option settings, so it's * convenient to carry a field for that too. (Note: currently, it is our * practice that the grammar allows namespace and action only in statements * where they are relevant; C code can just ignore those fields in other * statements.) */ typedef enum DefElemAction { DEFELEM_UNSPEC, /* no action given */ DEFELEM_SET, DEFELEM_ADD, DEFELEM_DROP } DefElemAction; typedef struct DefElem { NodeTag type; char *defnamespace; /* NULL if unqualified name */ char *defname; Node *arg; /* a (Value *) or a (TypeName *) */ DefElemAction defaction; /* unspecified action, or SET/ADD/DROP */ } DefElem; /* * LockingClause - raw representation of FOR UPDATE/SHARE options * * Note: lockedRels == NIL means "all relations in query". Otherwise it * is a list of RangeVar nodes. (We use RangeVar mainly because it carries * a location field --- currently, parse analysis insists on unqualified * names in LockingClause.) */ typedef struct LockingClause { NodeTag type; List *lockedRels; /* FOR UPDATE or FOR SHARE relations */ bool forUpdate; /* true = FOR UPDATE, false = FOR SHARE */ bool noWait; /* NOWAIT option */ } LockingClause; /* * XMLSERIALIZE (in raw parse tree only) */ typedef struct XmlSerialize { NodeTag type; XmlOptionType xmloption; /* DOCUMENT or CONTENT */ Node *expr; TypeName *typeName; int location; /* token location, or -1 if unknown */ } XmlSerialize; /**************************************************************************** * Nodes for a Query tree ****************************************************************************/ /*-------------------- * RangeTblEntry - * A range table is a List of RangeTblEntry nodes. * * A range table entry may represent a plain relation, a sub-select in * FROM, or the result of a JOIN clause. (Only explicit JOIN syntax * produces an RTE, not the implicit join resulting from multiple FROM * items. This is because we only need the RTE to deal with SQL features * like outer joins and join-output-column aliasing.) Other special * RTE types also exist, as indicated by RTEKind. * * Note that we consider RTE_RELATION to cover anything that has a pg_class * entry. relkind distinguishes the sub-cases. * * alias is an Alias node representing the AS alias-clause attached to the * FROM expression, or NULL if no clause. * * eref is the table reference name and column reference names (either * real or aliases). Note that system columns (OID etc) are not included * in the column list. * eref->aliasname is required to be present, and should generally be used * to identify the RTE for error messages etc. * * In RELATION RTEs, the colnames in both alias and eref are indexed by * physical attribute number; this means there must be colname entries for * dropped columns. When building an RTE we insert empty strings ("") for * dropped columns. Note however that a stored rule may have nonempty * colnames for columns dropped since the rule was created (and for that * matter the colnames might be out of date due to column renamings). * The same comments apply to FUNCTION RTEs when the function's return type * is a named composite type. * * In JOIN RTEs, the colnames in both alias and eref are one-to-one with * joinaliasvars entries. A JOIN RTE will omit columns of its inputs when * those columns are known to be dropped at parse time. Again, however, * a stored rule might contain entries for columns dropped since the rule * was created. (This is only possible for columns not actually referenced * in the rule.) When loading a stored rule, we replace the joinaliasvars * items for any such columns with NULL Consts. (We can't simply delete * them from the joinaliasvars list, because that would affect the attnums * of Vars referencing the rest of the list.) * * inh is TRUE for relation references that should be expanded to include * inheritance children, if the rel has any. This *must* be FALSE for * RTEs other than RTE_RELATION entries. * * inFromCl marks those range variables that are listed in the FROM clause. * It's false for RTEs that are added to a query behind the scenes, such * as the NEW and OLD variables for a rule, or the subqueries of a UNION. * This flag is not used anymore during parsing, since the parser now uses * a separate "namespace" data structure to control visibility, but it is * needed by ruleutils.c to determine whether RTEs should be shown in * decompiled queries. * * requiredPerms and checkAsUser specify run-time access permissions * checks to be performed at query startup. The user must have *all* * of the permissions that are OR'd together in requiredPerms (zero * indicates no permissions checking). If checkAsUser is not zero, * then do the permissions checks using the access rights of that user, * not the current effective user ID. (This allows rules to act as * setuid gateways.) Permissions checks only apply to RELATION RTEs. * * For SELECT/INSERT/UPDATE permissions, if the user doesn't have * table-wide permissions then it is sufficient to have the permissions * on all columns identified in selectedCols (for SELECT) and/or * modifiedCols (for INSERT/UPDATE; we can tell which from the query type). * selectedCols and modifiedCols are bitmapsets, which cannot have negative * integer members, so we subtract FirstLowInvalidHeapAttributeNumber from * column numbers before storing them in these fields. A whole-row Var * reference is represented by setting the bit for InvalidAttrNumber. *-------------------- */ typedef enum RTEKind { RTE_RELATION, /* ordinary relation reference */ RTE_SUBQUERY, /* subquery in FROM */ RTE_JOIN, /* join */ RTE_FUNCTION, /* function in FROM */ RTE_VALUES, /* VALUES (), (), ... */ RTE_CTE /* common table expr (WITH list element) */ } RTEKind; typedef struct RangeTblEntry { NodeTag type; RTEKind rtekind; /* see above */ /* * XXX the fields applicable to only some rte kinds should be merged into * a union. I didn't do this yet because the diffs would impact a lot of * code that is being actively worked on. FIXME someday. */ /* * Fields valid for a plain relation RTE (else zero): */ Oid relid; /* OID of the relation */ char relkind; /* relation kind (see pg_class.relkind) */ /* * Fields valid for a subquery RTE (else NULL): */ Query *subquery; /* the sub-query */ bool security_barrier; /* subquery from security_barrier view */ /* * Fields valid for a join RTE (else NULL/zero): * * joinaliasvars is a list of Vars or COALESCE expressions corresponding * to the columns of the join result. An alias Var referencing column K * of the join result can be replaced by the K'th element of joinaliasvars * --- but to simplify the task of reverse-listing aliases correctly, we * do not do that until planning time. In a Query loaded from a stored * rule, it is also possible for joinaliasvars items to be NULL Consts, * denoting columns dropped since the rule was made. */ JoinType jointype; /* type of join */ List *joinaliasvars; /* list of alias-var expansions */ /* * Fields valid for a function RTE (else NULL): * * If the function returns RECORD, funccoltypes lists the column types * declared in the RTE's column type specification, funccoltypmods lists * their declared typmods, funccolcollations their collations. Otherwise, * those fields are NIL. */ Node *funcexpr; /* expression tree for func call */ List *funccoltypes; /* OID list of column type OIDs */ List *funccoltypmods; /* integer list of column typmods */ List *funccolcollations; /* OID list of column collation OIDs */ /* * Fields valid for a values RTE (else NIL): */ List *values_lists; /* list of expression lists */ List *values_collations; /* OID list of column collation OIDs */ /* * Fields valid for a CTE RTE (else NULL/zero): */ char *ctename; /* name of the WITH list item */ Index ctelevelsup; /* number of query levels up */ bool self_reference; /* is this a recursive self-reference? */ List *ctecoltypes; /* OID list of column type OIDs */ List *ctecoltypmods; /* integer list of column typmods */ List *ctecolcollations; /* OID list of column collation OIDs */ /* * Fields valid in all RTEs: */ Alias *alias; /* user-written alias clause, if any */ Alias *eref; /* expanded reference names */ bool inh; /* inheritance requested? */ bool inFromCl; /* present in FROM clause? */ AclMode requiredPerms; /* bitmask of required access permissions */ Oid checkAsUser; /* if valid, check access as this role */ Bitmapset *selectedCols; /* columns needing SELECT permission */ Bitmapset *modifiedCols; /* columns needing INSERT/UPDATE permission */ } RangeTblEntry; /* * SortGroupClause - * representation of ORDER BY, GROUP BY, PARTITION BY, * DISTINCT, DISTINCT ON items * * You might think that ORDER BY is only interested in defining ordering, * and GROUP/DISTINCT are only interested in defining equality. However, * one way to implement grouping is to sort and then apply a "uniq"-like * filter. So it's also interesting to keep track of possible sort operators * for GROUP/DISTINCT, and in particular to try to sort for the grouping * in a way that will also yield a requested ORDER BY ordering. So we need * to be able to compare ORDER BY and GROUP/DISTINCT lists, which motivates * the decision to give them the same representation. * * tleSortGroupRef must match ressortgroupref of exactly one entry of the * query's targetlist; that is the expression to be sorted or grouped by. * eqop is the OID of the equality operator. * sortop is the OID of the ordering operator (a "<" or ">" operator), * or InvalidOid if not available. * nulls_first means about what you'd expect. If sortop is InvalidOid * then nulls_first is meaningless and should be set to false. * hashable is TRUE if eqop is hashable (note this condition also depends * on the datatype of the input expression). * * In an ORDER BY item, all fields must be valid. (The eqop isn't essential * here, but it's cheap to get it along with the sortop, and requiring it * to be valid eases comparisons to grouping items.) Note that this isn't * actually enough information to determine an ordering: if the sortop is * collation-sensitive, a collation OID is needed too. We don't store the * collation in SortGroupClause because it's not available at the time the * parser builds the SortGroupClause; instead, consult the exposed collation * of the referenced targetlist expression to find out what it is. * * In a grouping item, eqop must be valid. If the eqop is a btree equality * operator, then sortop should be set to a compatible ordering operator. * We prefer to set eqop/sortop/nulls_first to match any ORDER BY item that * the query presents for the same tlist item. If there is none, we just * use the default ordering op for the datatype. * * If the tlist item's type has a hash opclass but no btree opclass, then * we will set eqop to the hash equality operator, sortop to InvalidOid, * and nulls_first to false. A grouping item of this kind can only be * implemented by hashing, and of course it'll never match an ORDER BY item. * * The hashable flag is provided since we generally have the requisite * information readily available when the SortGroupClause is constructed, * and it's relatively expensive to get it again later. Note there is no * need for a "sortable" flag since OidIsValid(sortop) serves the purpose. * * A query might have both ORDER BY and DISTINCT (or DISTINCT ON) clauses. * In SELECT DISTINCT, the distinctClause list is as long or longer than the * sortClause list, while in SELECT DISTINCT ON it's typically shorter. * The two lists must match up to the end of the shorter one --- the parser * rearranges the distinctClause if necessary to make this true. (This * restriction ensures that only one sort step is needed to both satisfy the * ORDER BY and set up for the Unique step. This is semantically necessary * for DISTINCT ON, and presents no real drawback for DISTINCT.) */ typedef struct SortGroupClause { NodeTag type; Index tleSortGroupRef; /* reference into targetlist */ Oid eqop; /* the equality operator ('=' op) */ Oid sortop; /* the ordering operator ('<' op), or 0 */ bool nulls_first; /* do NULLs come before normal values? */ bool hashable; /* can eqop be implemented by hashing? */ } SortGroupClause; /* * WindowClause - * transformed representation of WINDOW and OVER clauses * * A parsed Query's windowClause list contains these structs. "name" is set * if the clause originally came from WINDOW, and is NULL if it originally * was an OVER clause (but note that we collapse out duplicate OVERs). * partitionClause and orderClause are lists of SortGroupClause structs. * winref is an ID number referenced by WindowFunc nodes; it must be unique * among the members of a Query's windowClause list. * When refname isn't null, the partitionClause is always copied from there; * the orderClause might or might not be copied (see copiedOrder); the framing * options are never copied, per spec. */ typedef struct WindowClause { NodeTag type; char *name; /* window name (NULL in an OVER clause) */ char *refname; /* referenced window name, if any */ List *partitionClause; /* PARTITION BY list */ List *orderClause; /* ORDER BY list */ int frameOptions; /* frame_clause options, see WindowDef */ Node *startOffset; /* expression for starting bound, if any */ Node *endOffset; /* expression for ending bound, if any */ Index winref; /* ID referenced by window functions */ bool copiedOrder; /* did we copy orderClause from refname? */ } WindowClause; /* * RowMarkClause - * parser output representation of FOR UPDATE/SHARE clauses * * Query.rowMarks contains a separate RowMarkClause node for each relation * identified as a FOR UPDATE/SHARE target. If FOR UPDATE/SHARE is applied * to a subquery, we generate RowMarkClauses for all normal and subquery rels * in the subquery, but they are marked pushedDown = true to distinguish them * from clauses that were explicitly written at this query level. Also, * Query.hasForUpdate tells whether there were explicit FOR UPDATE/SHARE * clauses in the current query level. */ typedef struct RowMarkClause { NodeTag type; Index rti; /* range table index of target relation */ bool forUpdate; /* true = FOR UPDATE, false = FOR SHARE */ bool noWait; /* NOWAIT option */ bool pushedDown; /* pushed down from higher query level? */ } RowMarkClause; /* * WithClause - * representation of WITH clause * * Note: WithClause does not propagate into the Query representation; * but CommonTableExpr does. */ typedef struct WithClause { NodeTag type; List *ctes; /* list of CommonTableExprs */ bool recursive; /* true = WITH RECURSIVE */ int location; /* token location, or -1 if unknown */ } WithClause; /* * CommonTableExpr - * representation of WITH list element * * We don't currently support the SEARCH or CYCLE clause. */ typedef struct CommonTableExpr { NodeTag type; char *ctename; /* query name (never qualified) */ List *aliascolnames; /* optional list of column names */ /* SelectStmt/InsertStmt/etc before parse analysis, Query afterwards: */ Node *ctequery; /* the CTE's subquery */ int location; /* token location, or -1 if unknown */ /* These fields are set during parse analysis: */ bool cterecursive; /* is this CTE actually recursive? */ int cterefcount; /* number of RTEs referencing this CTE * (excluding internal self-references) */ List *ctecolnames; /* list of output column names */ List *ctecoltypes; /* OID list of output column type OIDs */ List *ctecoltypmods; /* integer list of output column typmods */ List *ctecolcollations; /* OID list of column collation OIDs */ } CommonTableExpr; /* Convenience macro to get the output tlist of a CTE's query */ #define GetCTETargetList(cte) \ (AssertMacro(IsA((cte)->ctequery, Query)), \ ((Query *) (cte)->ctequery)->commandType == CMD_SELECT ? \ ((Query *) (cte)->ctequery)->targetList : \ ((Query *) (cte)->ctequery)->returningList) /***************************************************************************** * Optimizable Statements *****************************************************************************/ /* ---------------------- * Insert Statement * * The source expression is represented by SelectStmt for both the * SELECT and VALUES cases. If selectStmt is NULL, then the query * is INSERT ... DEFAULT VALUES. * ---------------------- */ typedef struct InsertStmt { NodeTag type; RangeVar *relation; /* relation to insert into */ List *cols; /* optional: names of the target columns */ Node *selectStmt; /* the source SELECT/VALUES, or NULL */ List *returningList; /* list of expressions to return */ WithClause *withClause; /* WITH clause */ } InsertStmt; /* ---------------------- * Delete Statement * ---------------------- */ typedef struct DeleteStmt { NodeTag type; RangeVar *relation; /* relation to delete from */ List *usingClause; /* optional using clause for more tables */ Node *whereClause; /* qualifications */ List *returningList; /* list of expressions to return */ WithClause *withClause; /* WITH clause */ } DeleteStmt; /* ---------------------- * Update Statement * ---------------------- */ typedef struct UpdateStmt { NodeTag type; RangeVar *relation; /* relation to update */ List *targetList; /* the target list (of ResTarget) */ Node *whereClause; /* qualifications */ List *fromClause; /* optional from clause for more tables */ List *returningList; /* list of expressions to return */ WithClause *withClause; /* WITH clause */ } UpdateStmt; /* ---------------------- * Select Statement * * A "simple" SELECT is represented in the output of gram.y by a single * SelectStmt node; so is a VALUES construct. A query containing set * operators (UNION, INTERSECT, EXCEPT) is represented by a tree of SelectStmt * nodes, in which the leaf nodes are component SELECTs and the internal nodes * represent UNION, INTERSECT, or EXCEPT operators. Using the same node * type for both leaf and internal nodes allows gram.y to stick ORDER BY, * LIMIT, etc, clause values into a SELECT statement without worrying * whether it is a simple or compound SELECT. * ---------------------- */ typedef enum SetOperation { SETOP_NONE = 0, SETOP_UNION, SETOP_INTERSECT, SETOP_EXCEPT } SetOperation; typedef struct SelectStmt { NodeTag type; /* * These fields are used only in "leaf" SelectStmts. */ List *distinctClause; /* NULL, list of DISTINCT ON exprs, or * lcons(NIL,NIL) for all (SELECT DISTINCT) */ IntoClause *intoClause; /* target for SELECT INTO */ List *targetList; /* the target list (of ResTarget) */ List *fromClause; /* the FROM clause */ Node *whereClause; /* WHERE qualification */ List *groupClause; /* GROUP BY clauses */ Node *havingClause; /* HAVING conditional-expression */ List *windowClause; /* WINDOW window_name AS (...), ... */ WithClause *withClause; /* WITH clause */ /* * In a "leaf" node representing a VALUES list, the above fields are all * null, and instead this field is set. Note that the elements of the * sublists are just expressions, without ResTarget decoration. Also note * that a list element can be DEFAULT (represented as a SetToDefault * node), regardless of the context of the VALUES list. It's up to parse * analysis to reject that where not valid. */ List *valuesLists; /* untransformed list of expression lists */ /* * These fields are used in both "leaf" SelectStmts and upper-level * SelectStmts. */ List *sortClause; /* sort clause (a list of SortBy's) */ Node *limitOffset; /* # of result tuples to skip */ Node *limitCount; /* # of result tuples to return */ List *lockingClause; /* FOR UPDATE (list of LockingClause's) */ /* * These fields are used only in upper-level SelectStmts. */ SetOperation op; /* type of set op */ bool all; /* ALL specified? */ struct SelectStmt *larg; /* left child */ struct SelectStmt *rarg; /* right child */ /* Eventually add fields for CORRESPONDING spec here */ } SelectStmt; /* ---------------------- * Set Operation node for post-analysis query trees * * After parse analysis, a SELECT with set operations is represented by a * top-level Query node containing the leaf SELECTs as subqueries in its * range table. Its setOperations field shows the tree of set operations, * with leaf SelectStmt nodes replaced by RangeTblRef nodes, and internal * nodes replaced by SetOperationStmt nodes. Information about the output * column types is added, too. (Note that the child nodes do not necessarily * produce these types directly, but we've checked that their output types * can be coerced to the output column type.) Also, if it's not UNION ALL, * information about the types' sort/group semantics is provided in the form * of a SortGroupClause list (same representation as, eg, DISTINCT). * The resolved common column collations are provided too; but note that if * it's not UNION ALL, it's okay for a column to not have a common collation, * so a member of the colCollations list could be InvalidOid even though the * column has a collatable type. * ---------------------- */ typedef struct SetOperationStmt { NodeTag type; SetOperation op; /* type of set op */ bool all; /* ALL specified? */ Node *larg; /* left child */ Node *rarg; /* right child */ /* Eventually add fields for CORRESPONDING spec here */ /* Fields derived during parse analysis: */ List *colTypes; /* OID list of output column type OIDs */ List *colTypmods; /* integer list of output column typmods */ List *colCollations; /* OID list of output column collation OIDs */ List *groupClauses; /* a list of SortGroupClause's */ /* groupClauses is NIL if UNION ALL, but must be set otherwise */ } SetOperationStmt; /***************************************************************************** * Other Statements (no optimizations required) * * These are not touched by parser/analyze.c except to put them into * the utilityStmt field of a Query. This is eventually passed to * ProcessUtility (by-passing rewriting and planning). Some of the * statements do need attention from parse analysis, and this is * done by routines in parser/parse_utilcmd.c after ProcessUtility * receives the command for execution. *****************************************************************************/ /* * When a command can act on several kinds of objects with only one * parse structure required, use these constants to designate the * object type. Note that commands typically don't support all the types. */ typedef enum ObjectType { OBJECT_AGGREGATE, OBJECT_ATTRIBUTE, /* type's attribute, when distinct from column */ OBJECT_CAST, OBJECT_COLUMN, OBJECT_CONSTRAINT, OBJECT_COLLATION, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, OBJECT_ROLE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_VIEW } ObjectType; /* ---------------------- * Create Schema Statement * * NOTE: the schemaElts list contains raw parsetrees for component statements * of the schema, such as CREATE TABLE, GRANT, etc. These are analyzed and * executed after the schema itself is created. * ---------------------- */ typedef struct CreateSchemaStmt { NodeTag type; char *schemaname; /* the name of the schema to create */ char *authid; /* the owner of the created schema */ List *schemaElts; /* schema components (list of parsenodes) */ } CreateSchemaStmt; typedef enum DropBehavior { DROP_RESTRICT, /* drop fails if any dependent objects */ DROP_CASCADE /* remove dependent objects too */ } DropBehavior; /* ---------------------- * Alter Table * ---------------------- */ typedef struct AlterTableStmt { NodeTag type; RangeVar *relation; /* table to work on */ List *cmds; /* list of subcommands */ ObjectType relkind; /* type of object */ bool missing_ok; /* skip error if table missing */ } AlterTableStmt; typedef enum AlterTableType { AT_AddColumn, /* add column */ AT_AddColumnRecurse, /* internal to commands/tablecmds.c */ AT_AddColumnToView, /* implicitly via CREATE OR REPLACE VIEW */ AT_ColumnDefault, /* alter column default */ AT_DropNotNull, /* alter column drop not null */ AT_SetNotNull, /* alter column set not null */ AT_SetStatistics, /* alter column set statistics */ AT_SetOptions, /* alter column set ( options ) */ AT_ResetOptions, /* alter column reset ( options ) */ AT_SetStorage, /* alter column set storage */ AT_DropColumn, /* drop column */ AT_DropColumnRecurse, /* internal to commands/tablecmds.c */ AT_AddIndex, /* add index */ AT_ReAddIndex, /* internal to commands/tablecmds.c */ AT_AddConstraint, /* add constraint */ AT_AddConstraintRecurse, /* internal to commands/tablecmds.c */ AT_ValidateConstraint, /* validate constraint */ AT_ValidateConstraintRecurse, /* internal to commands/tablecmds.c */ AT_ProcessedConstraint, /* pre-processed add constraint (local in * parser/parse_utilcmd.c) */ AT_AddIndexConstraint, /* add constraint using existing index */ AT_DropConstraint, /* drop constraint */ AT_DropConstraintRecurse, /* internal to commands/tablecmds.c */ AT_AlterColumnType, /* alter column type */ AT_AlterColumnGenericOptions, /* alter column OPTIONS (...) */ AT_ChangeOwner, /* change owner */ AT_ClusterOn, /* CLUSTER ON */ AT_DropCluster, /* SET WITHOUT CLUSTER */ AT_AddOids, /* SET WITH OIDS */ AT_AddOidsRecurse, /* internal to commands/tablecmds.c */ AT_DropOids, /* SET WITHOUT OIDS */ AT_SetTableSpace, /* SET TABLESPACE */ AT_SetRelOptions, /* SET (...) -- AM specific parameters */ AT_ResetRelOptions, /* RESET (...) -- AM specific parameters */ AT_ReplaceRelOptions, /* replace reloption list in its entirety */ AT_EnableTrig, /* ENABLE TRIGGER name */ AT_EnableAlwaysTrig, /* ENABLE ALWAYS TRIGGER name */ AT_EnableReplicaTrig, /* ENABLE REPLICA TRIGGER name */ AT_DisableTrig, /* DISABLE TRIGGER name */ AT_EnableTrigAll, /* ENABLE TRIGGER ALL */ AT_DisableTrigAll, /* DISABLE TRIGGER ALL */ AT_EnableTrigUser, /* ENABLE TRIGGER USER */ AT_DisableTrigUser, /* DISABLE TRIGGER USER */ AT_EnableRule, /* ENABLE RULE name */ AT_EnableAlwaysRule, /* ENABLE ALWAYS RULE name */ AT_EnableReplicaRule, /* ENABLE REPLICA RULE name */ AT_DisableRule, /* DISABLE RULE name */ AT_AddInherit, /* INHERIT parent */ AT_DropInherit, /* NO INHERIT parent */ AT_AddOf, /* OF */ AT_DropOf, /* NOT OF */ AT_GenericOptions, /* OPTIONS (...) */ /* this will be in a more natural position in 9.3: */ AT_ReAddConstraint /* internal to commands/tablecmds.c */ } AlterTableType; typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ { NodeTag type; AlterTableType subtype; /* Type of table alteration to apply */ char *name; /* column, constraint, or trigger to act on, * or new owner or tablespace */ Node *def; /* definition of new column, index, * constraint, or parent table */ DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ bool missing_ok; /* skip error if missing? */ } AlterTableCmd; /* ---------------------- * Alter Domain * * The fields are used in different ways by the different variants of * this command. * ---------------------- */ typedef struct AlterDomainStmt { NodeTag type; char subtype; /*------------ * T = alter column default * N = alter column drop not null * O = alter column set not null * C = add constraint * X = drop constraint *------------ */ List *typeName; /* domain to work on */ char *name; /* column or constraint name to act on */ Node *def; /* definition of default or constraint */ DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ bool missing_ok; /* skip error if missing? */ } AlterDomainStmt; /* ---------------------- * Grant|Revoke Statement * ---------------------- */ typedef enum GrantTargetType { ACL_TARGET_OBJECT, /* grant on specific named object(s) */ ACL_TARGET_ALL_IN_SCHEMA, /* grant on all objects in given schema(s) */ ACL_TARGET_DEFAULTS /* ALTER DEFAULT PRIVILEGES */ } GrantTargetType; typedef enum GrantObjectType { ACL_OBJECT_COLUMN, /* column */ ACL_OBJECT_RELATION, /* table, view */ ACL_OBJECT_SEQUENCE, /* sequence */ ACL_OBJECT_DATABASE, /* database */ ACL_OBJECT_DOMAIN, /* domain */ ACL_OBJECT_FDW, /* foreign-data wrapper */ ACL_OBJECT_FOREIGN_SERVER, /* foreign server */ ACL_OBJECT_FUNCTION, /* function */ ACL_OBJECT_LANGUAGE, /* procedural language */ ACL_OBJECT_LARGEOBJECT, /* largeobject */ ACL_OBJECT_NAMESPACE, /* namespace */ ACL_OBJECT_TABLESPACE, /* tablespace */ ACL_OBJECT_TYPE /* type */ } GrantObjectType; typedef struct GrantStmt { NodeTag type; bool is_grant; /* true = GRANT, false = REVOKE */ GrantTargetType targtype; /* type of the grant target */ GrantObjectType objtype; /* kind of object being operated on */ List *objects; /* list of RangeVar nodes, FuncWithArgs nodes, * or plain names (as Value strings) */ List *privileges; /* list of AccessPriv nodes */ /* privileges == NIL denotes ALL PRIVILEGES */ List *grantees; /* list of PrivGrantee nodes */ bool grant_option; /* grant or revoke grant option */ DropBehavior behavior; /* drop behavior (for REVOKE) */ } GrantStmt; typedef struct PrivGrantee { NodeTag type; char *rolname; /* if NULL then PUBLIC */ } PrivGrantee; /* * Note: FuncWithArgs carries only the types of the input parameters of the * function. So it is sufficient to identify an existing function, but it * is not enough info to define a function nor to call it. */ typedef struct FuncWithArgs { NodeTag type; List *funcname; /* qualified name of function */ List *funcargs; /* list of Typename nodes */ } FuncWithArgs; /* * An access privilege, with optional list of column names * priv_name == NULL denotes ALL PRIVILEGES (only used with a column list) * cols == NIL denotes "all columns" * Note that simple "ALL PRIVILEGES" is represented as a NIL list, not * an AccessPriv with both fields null. */ typedef struct AccessPriv { NodeTag type; char *priv_name; /* string name of privilege */ List *cols; /* list of Value strings */ } AccessPriv; /* ---------------------- * Grant/Revoke Role Statement * * Note: because of the parsing ambiguity with the GRANT * statement, granted_roles is a list of AccessPriv; the execution code * should complain if any column lists appear. grantee_roles is a list * of role names, as Value strings. * ---------------------- */ typedef struct GrantRoleStmt { NodeTag type; List *granted_roles; /* list of roles to be granted/revoked */ List *grantee_roles; /* list of member roles to add/delete */ bool is_grant; /* true = GRANT, false = REVOKE */ bool admin_opt; /* with admin option */ char *grantor; /* set grantor to other than current role */ DropBehavior behavior; /* drop behavior (for REVOKE) */ } GrantRoleStmt; /* ---------------------- * Alter Default Privileges Statement * ---------------------- */ typedef struct AlterDefaultPrivilegesStmt { NodeTag type; List *options; /* list of DefElem */ GrantStmt *action; /* GRANT/REVOKE action (with objects=NIL) */ } AlterDefaultPrivilegesStmt; /* ---------------------- * Copy Statement * * We support "COPY relation FROM file", "COPY relation TO file", and * "COPY (query) TO file". In any given CopyStmt, exactly one of "relation" * and "query" must be non-NULL. * ---------------------- */ typedef struct CopyStmt { NodeTag type; RangeVar *relation; /* the relation to copy */ Node *query; /* the SELECT query to copy */ List *attlist; /* List of column names (as Strings), or NIL * for all columns */ bool is_from; /* TO or FROM */ char *filename; /* filename, or NULL for STDIN/STDOUT */ List *options; /* List of DefElem nodes */ } CopyStmt; /* ---------------------- * SET Statement (includes RESET) * * "SET var TO DEFAULT" and "RESET var" are semantically equivalent, but we * preserve the distinction in VariableSetKind for CreateCommandTag(). * ---------------------- */ typedef enum { VAR_SET_VALUE, /* SET var = value */ VAR_SET_DEFAULT, /* SET var TO DEFAULT */ VAR_SET_CURRENT, /* SET var FROM CURRENT */ VAR_SET_MULTI, /* special case for SET TRANSACTION ... */ VAR_RESET, /* RESET var */ VAR_RESET_ALL /* RESET ALL */ } VariableSetKind; typedef struct VariableSetStmt { NodeTag type; VariableSetKind kind; char *name; /* variable to be set */ List *args; /* List of A_Const nodes */ bool is_local; /* SET LOCAL? */ } VariableSetStmt; /* ---------------------- * Show Statement * ---------------------- */ typedef struct VariableShowStmt { NodeTag type; char *name; } VariableShowStmt; /* ---------------------- * Create Table Statement * * NOTE: in the raw gram.y output, ColumnDef and Constraint nodes are * intermixed in tableElts, and constraints is NIL. After parse analysis, * tableElts contains just ColumnDefs, and constraints contains just * Constraint nodes (in fact, only CONSTR_CHECK nodes, in the present * implementation). * ---------------------- */ typedef struct CreateStmt { NodeTag type; RangeVar *relation; /* relation to create */ List *tableElts; /* column definitions (list of ColumnDef) */ List *inhRelations; /* relations to inherit from (list of * inhRelation) */ TypeName *ofTypename; /* OF typename */ List *constraints; /* constraints (list of Constraint nodes) */ List *options; /* options from WITH clause */ OnCommitAction oncommit; /* what do we do at COMMIT? */ char *tablespacename; /* table space to use, or NULL */ bool if_not_exists; /* just do nothing if it already exists? */ } CreateStmt; /* ---------- * Definitions for constraints in CreateStmt * * Note that column defaults are treated as a type of constraint, * even though that's a bit odd semantically. * * For constraints that use expressions (CONSTR_CHECK, CONSTR_DEFAULT) * we may have the expression in either "raw" form (an untransformed * parse tree) or "cooked" form (the nodeToString representation of * an executable expression tree), depending on how this Constraint * node was created (by parsing, or by inheritance from an existing * relation). We should never have both in the same node! * * FKCONSTR_ACTION_xxx values are stored into pg_constraint.confupdtype * and pg_constraint.confdeltype columns; FKCONSTR_MATCH_xxx values are * stored into pg_constraint.confmatchtype. Changing the code values may * require an initdb! * * If skip_validation is true then we skip checking that the existing rows * in the table satisfy the constraint, and just install the catalog entries * for the constraint. A new FK constraint is marked as valid iff * initially_valid is true. (Usually skip_validation and initially_valid * are inverses, but we can set both true if the table is known empty.) * * Constraint attributes (DEFERRABLE etc) are initially represented as * separate Constraint nodes for simplicity of parsing. parse_utilcmd.c makes * a pass through the constraints list to insert the info into the appropriate * Constraint node. * ---------- */ typedef enum ConstrType /* types of constraints */ { CONSTR_NULL, /* not SQL92, but a lot of people expect it */ CONSTR_NOTNULL, CONSTR_DEFAULT, CONSTR_CHECK, CONSTR_PRIMARY, CONSTR_UNIQUE, CONSTR_EXCLUSION, CONSTR_FOREIGN, CONSTR_ATTR_DEFERRABLE, /* attributes for previous constraint node */ CONSTR_ATTR_NOT_DEFERRABLE, CONSTR_ATTR_DEFERRED, CONSTR_ATTR_IMMEDIATE } ConstrType; /* Foreign key action codes */ #define FKCONSTR_ACTION_NOACTION 'a' #define FKCONSTR_ACTION_RESTRICT 'r' #define FKCONSTR_ACTION_CASCADE 'c' #define FKCONSTR_ACTION_SETNULL 'n' #define FKCONSTR_ACTION_SETDEFAULT 'd' /* Foreign key matchtype codes */ #define FKCONSTR_MATCH_FULL 'f' #define FKCONSTR_MATCH_PARTIAL 'p' #define FKCONSTR_MATCH_UNSPECIFIED 'u' typedef struct Constraint { NodeTag type; ConstrType contype; /* see above */ /* Fields used for most/all constraint types: */ char *conname; /* Constraint name, or NULL if unnamed */ bool deferrable; /* DEFERRABLE? */ bool initdeferred; /* INITIALLY DEFERRED? */ int location; /* token location, or -1 if unknown */ /* Fields used for constraints with expressions (CHECK and DEFAULT): */ bool is_no_inherit; /* is constraint non-inheritable? */ Node *raw_expr; /* expr, as untransformed parse tree */ char *cooked_expr; /* expr, as nodeToString representation */ /* Fields used for unique constraints (UNIQUE and PRIMARY KEY): */ List *keys; /* String nodes naming referenced column(s) */ /* Fields used for EXCLUSION constraints: */ List *exclusions; /* list of (IndexElem, operator name) pairs */ /* Fields used for index constraints (UNIQUE, PRIMARY KEY, EXCLUSION): */ List *options; /* options from WITH clause */ char *indexname; /* existing index to use; otherwise NULL */ char *indexspace; /* index tablespace; NULL for default */ /* These could be, but currently are not, used for UNIQUE/PKEY: */ char *access_method; /* index access method; NULL for default */ Node *where_clause; /* partial index predicate */ /* Fields used for FOREIGN KEY constraints: */ RangeVar *pktable; /* Primary key table */ List *fk_attrs; /* Attributes of foreign key */ List *pk_attrs; /* Corresponding attrs in PK table */ char fk_matchtype; /* FULL, PARTIAL, UNSPECIFIED */ char fk_upd_action; /* ON UPDATE action */ char fk_del_action; /* ON DELETE action */ List *old_conpfeqop; /* pg_constraint.conpfeqop of my former self */ /* Fields used for constraints that allow a NOT VALID specification */ bool skip_validation; /* skip validation of existing rows? */ bool initially_valid; /* mark the new constraint as valid? */ } Constraint; /* ---------------------- * Create/Drop Table Space Statements * ---------------------- */ typedef struct CreateTableSpaceStmt { NodeTag type; char *tablespacename; char *owner; char *location; } CreateTableSpaceStmt; typedef struct DropTableSpaceStmt { NodeTag type; char *tablespacename; bool missing_ok; /* skip error if missing? */ } DropTableSpaceStmt; typedef struct AlterTableSpaceOptionsStmt { NodeTag type; char *tablespacename; List *options; bool isReset; } AlterTableSpaceOptionsStmt; /* ---------------------- * Create/Alter Extension Statements * ---------------------- */ typedef struct CreateExtensionStmt { NodeTag type; char *extname; bool if_not_exists; /* just do nothing if it already exists? */ List *options; /* List of DefElem nodes */ } CreateExtensionStmt; /* Only used for ALTER EXTENSION UPDATE; later might need an action field */ typedef struct AlterExtensionStmt { NodeTag type; char *extname; List *options; /* List of DefElem nodes */ } AlterExtensionStmt; typedef struct AlterExtensionContentsStmt { NodeTag type; char *extname; /* Extension's name */ int action; /* +1 = add object, -1 = drop object */ ObjectType objtype; /* Object's type */ List *objname; /* Qualified name of the object */ List *objargs; /* Arguments if needed (eg, for functions) */ } AlterExtensionContentsStmt; /* ---------------------- * Create/Alter FOREIGN DATA WRAPPER Statements * ---------------------- */ typedef struct CreateFdwStmt { NodeTag type; char *fdwname; /* foreign-data wrapper name */ List *func_options; /* HANDLER/VALIDATOR options */ List *options; /* generic options to FDW */ } CreateFdwStmt; typedef struct AlterFdwStmt { NodeTag type; char *fdwname; /* foreign-data wrapper name */ List *func_options; /* HANDLER/VALIDATOR options */ List *options; /* generic options to FDW */ } AlterFdwStmt; /* ---------------------- * Create/Alter FOREIGN SERVER Statements * ---------------------- */ typedef struct CreateForeignServerStmt { NodeTag type; char *servername; /* server name */ char *servertype; /* optional server type */ char *version; /* optional server version */ char *fdwname; /* FDW name */ List *options; /* generic options to server */ } CreateForeignServerStmt; typedef struct AlterForeignServerStmt { NodeTag type; char *servername; /* server name */ char *version; /* optional server version */ List *options; /* generic options to server */ bool has_version; /* version specified */ } AlterForeignServerStmt; /* ---------------------- * Create FOREIGN TABLE Statements * ---------------------- */ typedef struct CreateForeignTableStmt { CreateStmt base; char *servername; List *options; } CreateForeignTableStmt; /* ---------------------- * Create/Drop USER MAPPING Statements * ---------------------- */ typedef struct CreateUserMappingStmt { NodeTag type; char *username; /* username or PUBLIC/CURRENT_USER */ char *servername; /* server name */ List *options; /* generic options to server */ } CreateUserMappingStmt; typedef struct AlterUserMappingStmt { NodeTag type; char *username; /* username or PUBLIC/CURRENT_USER */ char *servername; /* server name */ List *options; /* generic options to server */ } AlterUserMappingStmt; typedef struct DropUserMappingStmt { NodeTag type; char *username; /* username or PUBLIC/CURRENT_USER */ char *servername; /* server name */ bool missing_ok; /* ignore missing mappings */ } DropUserMappingStmt; /* ---------------------- * Create TRIGGER Statement * ---------------------- */ typedef struct CreateTrigStmt { NodeTag type; char *trigname; /* TRIGGER's name */ RangeVar *relation; /* relation trigger is on */ List *funcname; /* qual. name of function to call */ List *args; /* list of (T_String) Values or NIL */ bool row; /* ROW/STATEMENT */ /* timing uses the TRIGGER_TYPE bits defined in catalog/pg_trigger.h */ int16 timing; /* BEFORE, AFTER, or INSTEAD */ /* events uses the TRIGGER_TYPE bits defined in catalog/pg_trigger.h */ int16 events; /* "OR" of INSERT/UPDATE/DELETE/TRUNCATE */ List *columns; /* column names, or NIL for all columns */ Node *whenClause; /* qual expression, or NULL if none */ bool isconstraint; /* This is a constraint trigger */ /* The remaining fields are only used for constraint triggers */ bool deferrable; /* [NOT] DEFERRABLE */ bool initdeferred; /* INITIALLY {DEFERRED|IMMEDIATE} */ RangeVar *constrrel; /* opposite relation, if RI trigger */ } CreateTrigStmt; /* ---------------------- * Create PROCEDURAL LANGUAGE Statements * ---------------------- */ typedef struct CreatePLangStmt { NodeTag type; bool replace; /* T => replace if already exists */ char *plname; /* PL name */ List *plhandler; /* PL call handler function (qual. name) */ List *plinline; /* optional inline function (qual. name) */ List *plvalidator; /* optional validator function (qual. name) */ bool pltrusted; /* PL is trusted */ } CreatePLangStmt; /* ---------------------- * Create/Alter/Drop Role Statements * * Note: these node types are also used for the backwards-compatible * Create/Alter/Drop User/Group statements. In the ALTER and DROP cases * there's really no need to distinguish what the original spelling was, * but for CREATE we mark the type because the defaults vary. * ---------------------- */ typedef enum RoleStmtType { ROLESTMT_ROLE, ROLESTMT_USER, ROLESTMT_GROUP } RoleStmtType; typedef struct CreateRoleStmt { NodeTag type; RoleStmtType stmt_type; /* ROLE/USER/GROUP */ char *role; /* role name */ List *options; /* List of DefElem nodes */ } CreateRoleStmt; typedef struct AlterRoleStmt { NodeTag type; char *role; /* role name */ List *options; /* List of DefElem nodes */ int action; /* +1 = add members, -1 = drop members */ } AlterRoleStmt; typedef struct AlterRoleSetStmt { NodeTag type; char *role; /* role name */ char *database; /* database name, or NULL */ VariableSetStmt *setstmt; /* SET or RESET subcommand */ } AlterRoleSetStmt; typedef struct DropRoleStmt { NodeTag type; List *roles; /* List of roles to remove */ bool missing_ok; /* skip error if a role is missing? */ } DropRoleStmt; /* ---------------------- * {Create|Alter} SEQUENCE Statement * ---------------------- */ typedef struct CreateSeqStmt { NodeTag type; RangeVar *sequence; /* the sequence to create */ List *options; Oid ownerId; /* ID of owner, or InvalidOid for default */ } CreateSeqStmt; typedef struct AlterSeqStmt { NodeTag type; RangeVar *sequence; /* the sequence to alter */ List *options; bool missing_ok; /* skip error if a role is missing? */ } AlterSeqStmt; /* ---------------------- * Create {Aggregate|Operator|Type} Statement * ---------------------- */ typedef struct DefineStmt { NodeTag type; ObjectType kind; /* aggregate, operator, type */ bool oldstyle; /* hack to signal old CREATE AGG syntax */ List *defnames; /* qualified name (list of Value strings) */ List *args; /* a list of TypeName (if needed) */ List *definition; /* a list of DefElem */ } DefineStmt; /* ---------------------- * Create Domain Statement * ---------------------- */ typedef struct CreateDomainStmt { NodeTag type; List *domainname; /* qualified name (list of Value strings) */ TypeName *typeName; /* the base type */ CollateClause *collClause; /* untransformed COLLATE spec, if any */ List *constraints; /* constraints (list of Constraint nodes) */ } CreateDomainStmt; /* ---------------------- * Create Operator Class Statement * ---------------------- */ typedef struct CreateOpClassStmt { NodeTag type; List *opclassname; /* qualified name (list of Value strings) */ List *opfamilyname; /* qualified name (ditto); NIL if omitted */ char *amname; /* name of index AM opclass is for */ TypeName *datatype; /* datatype of indexed column */ List *items; /* List of CreateOpClassItem nodes */ bool isDefault; /* Should be marked as default for type? */ } CreateOpClassStmt; #define OPCLASS_ITEM_OPERATOR 1 #define OPCLASS_ITEM_FUNCTION 2 #define OPCLASS_ITEM_STORAGETYPE 3 typedef struct CreateOpClassItem { NodeTag type; int itemtype; /* see codes above */ /* fields used for an operator or function item: */ List *name; /* operator or function name */ List *args; /* argument types */ int number; /* strategy num or support proc num */ List *order_family; /* only used for ordering operators */ List *class_args; /* only used for functions */ /* fields used for a storagetype item: */ TypeName *storedtype; /* datatype stored in index */ } CreateOpClassItem; /* ---------------------- * Create Operator Family Statement * ---------------------- */ typedef struct CreateOpFamilyStmt { NodeTag type; List *opfamilyname; /* qualified name (list of Value strings) */ char *amname; /* name of index AM opfamily is for */ } CreateOpFamilyStmt; /* ---------------------- * Alter Operator Family Statement * ---------------------- */ typedef struct AlterOpFamilyStmt { NodeTag type; List *opfamilyname; /* qualified name (list of Value strings) */ char *amname; /* name of index AM opfamily is for */ bool isDrop; /* ADD or DROP the items? */ List *items; /* List of CreateOpClassItem nodes */ } AlterOpFamilyStmt; /* ---------------------- * Drop Table|Sequence|View|Index|Type|Domain|Conversion|Schema Statement * ---------------------- */ typedef struct DropStmt { NodeTag type; List *objects; /* list of sublists of names (as Values) */ List *arguments; /* list of sublists of arguments (as Values) */ ObjectType removeType; /* object type */ DropBehavior behavior; /* RESTRICT or CASCADE behavior */ bool missing_ok; /* skip error if object is missing? */ bool concurrent; /* drop index concurrently? */ } DropStmt; /* ---------------------- * Truncate Table Statement * ---------------------- */ typedef struct TruncateStmt { NodeTag type; List *relations; /* relations (RangeVars) to be truncated */ bool restart_seqs; /* restart owned sequences? */ DropBehavior behavior; /* RESTRICT or CASCADE behavior */ } TruncateStmt; /* ---------------------- * Comment On Statement * ---------------------- */ typedef struct CommentStmt { NodeTag type; ObjectType objtype; /* Object's type */ List *objname; /* Qualified name of the object */ List *objargs; /* Arguments if needed (eg, for functions) */ char *comment; /* Comment to insert, or NULL to remove */ } CommentStmt; /* ---------------------- * SECURITY LABEL Statement * ---------------------- */ typedef struct SecLabelStmt { NodeTag type; ObjectType objtype; /* Object's type */ List *objname; /* Qualified name of the object */ List *objargs; /* Arguments if needed (eg, for functions) */ char *provider; /* Label provider (or NULL) */ char *label; /* New security label to be assigned */ } SecLabelStmt; /* ---------------------- * Declare Cursor Statement * * Note: the "query" field of DeclareCursorStmt is only used in the raw grammar * output. After parse analysis it's set to null, and the Query points to the * DeclareCursorStmt, not vice versa. * ---------------------- */ #define CURSOR_OPT_BINARY 0x0001 /* BINARY */ #define CURSOR_OPT_SCROLL 0x0002 /* SCROLL explicitly given */ #define CURSOR_OPT_NO_SCROLL 0x0004 /* NO SCROLL explicitly given */ #define CURSOR_OPT_INSENSITIVE 0x0008 /* INSENSITIVE */ #define CURSOR_OPT_HOLD 0x0010 /* WITH HOLD */ /* these planner-control flags do not correspond to any SQL grammar: */ #define CURSOR_OPT_FAST_PLAN 0x0020 /* prefer fast-start plan */ #define CURSOR_OPT_GENERIC_PLAN 0x0040 /* force use of generic plan */ #define CURSOR_OPT_CUSTOM_PLAN 0x0080 /* force use of custom plan */ typedef struct DeclareCursorStmt { NodeTag type; char *portalname; /* name of the portal (cursor) */ int options; /* bitmask of options (see above) */ Node *query; /* the raw SELECT query */ } DeclareCursorStmt; /* ---------------------- * Close Portal Statement * ---------------------- */ typedef struct ClosePortalStmt { NodeTag type; char *portalname; /* name of the portal (cursor) */ /* NULL means CLOSE ALL */ } ClosePortalStmt; /* ---------------------- * Fetch Statement (also Move) * ---------------------- */ typedef enum FetchDirection { /* for these, howMany is how many rows to fetch; FETCH_ALL means ALL */ FETCH_FORWARD, FETCH_BACKWARD, /* for these, howMany indicates a position; only one row is fetched */ FETCH_ABSOLUTE, FETCH_RELATIVE } FetchDirection; #define FETCH_ALL LONG_MAX typedef struct FetchStmt { NodeTag type; FetchDirection direction; /* see above */ long howMany; /* number of rows, or position argument */ char *portalname; /* name of portal (cursor) */ bool ismove; /* TRUE if MOVE */ } FetchStmt; /* ---------------------- * Create Index Statement * * This represents creation of an index and/or an associated constraint. * If isconstraint is true, we should create a pg_constraint entry along * with the index. But if indexOid isn't InvalidOid, we are not creating an * index, just a UNIQUE/PKEY constraint using an existing index. isconstraint * must always be true in this case, and the fields describing the index * properties are empty. * ---------------------- */ typedef struct IndexStmt { NodeTag type; char *idxname; /* name of new index, or NULL for default */ RangeVar *relation; /* relation to build index on */ char *accessMethod; /* name of access method (eg. btree) */ char *tableSpace; /* tablespace, or NULL for default */ List *indexParams; /* columns to index: a list of IndexElem */ List *options; /* WITH clause options: a list of DefElem */ Node *whereClause; /* qualification (partial-index predicate) */ List *excludeOpNames; /* exclusion operator names, or NIL if none */ char *idxcomment; /* comment to apply to index, or NULL */ Oid indexOid; /* OID of an existing index, if any */ Oid oldNode; /* relfilenode of existing storage, if any */ bool unique; /* is index unique? */ bool primary; /* is index a primary key? */ bool isconstraint; /* is it for a pkey/unique constraint? */ bool deferrable; /* is the constraint DEFERRABLE? */ bool initdeferred; /* is the constraint INITIALLY DEFERRED? */ bool concurrent; /* should this be a concurrent index build? */ } IndexStmt; /* ---------------------- * Create Function Statement * ---------------------- */ typedef struct CreateFunctionStmt { NodeTag type; bool replace; /* T => replace if already exists */ List *funcname; /* qualified name of function to create */ List *parameters; /* a list of FunctionParameter */ TypeName *returnType; /* the return type */ List *options; /* a list of DefElem */ List *withClause; /* a list of DefElem */ } CreateFunctionStmt; typedef enum FunctionParameterMode { /* the assigned enum values appear in pg_proc, don't change 'em! */ FUNC_PARAM_IN = 'i', /* input only */ FUNC_PARAM_OUT = 'o', /* output only */ FUNC_PARAM_INOUT = 'b', /* both */ FUNC_PARAM_VARIADIC = 'v', /* variadic (always input) */ FUNC_PARAM_TABLE = 't' /* table function output column */ } FunctionParameterMode; typedef struct FunctionParameter { NodeTag type; char *name; /* parameter name, or NULL if not given */ TypeName *argType; /* TypeName for parameter type */ FunctionParameterMode mode; /* IN/OUT/etc */ Node *defexpr; /* raw default expr, or NULL if not given */ } FunctionParameter; typedef struct AlterFunctionStmt { NodeTag type; FuncWithArgs *func; /* name and args of function */ List *actions; /* list of DefElem */ } AlterFunctionStmt; /* ---------------------- * DO Statement * * DoStmt is the raw parser output, InlineCodeBlock is the execution-time API * ---------------------- */ typedef struct DoStmt { NodeTag type; List *args; /* List of DefElem nodes */ } DoStmt; typedef struct InlineCodeBlock { NodeTag type; char *source_text; /* source text of anonymous code block */ Oid langOid; /* OID of selected language */ bool langIsTrusted; /* trusted property of the language */ } InlineCodeBlock; /* ---------------------- * Alter Object Rename Statement * ---------------------- */ typedef struct RenameStmt { NodeTag type; ObjectType renameType; /* OBJECT_TABLE, OBJECT_COLUMN, etc */ ObjectType relationType; /* if column name, associated relation type */ RangeVar *relation; /* in case it's a table */ List *object; /* in case it's some other object */ List *objarg; /* argument types, if applicable */ char *subname; /* name of contained object (column, rule, * trigger, etc) */ char *newname; /* the new name */ DropBehavior behavior; /* RESTRICT or CASCADE behavior */ bool missing_ok; /* skip error if missing? */ } RenameStmt; /* ---------------------- * ALTER object SET SCHEMA Statement * ---------------------- */ typedef struct AlterObjectSchemaStmt { NodeTag type; ObjectType objectType; /* OBJECT_TABLE, OBJECT_TYPE, etc */ RangeVar *relation; /* in case it's a table */ List *object; /* in case it's some other object */ List *objarg; /* argument types, if applicable */ char *addname; /* additional name if needed */ char *newschema; /* the new schema */ bool missing_ok; /* skip error if missing? */ } AlterObjectSchemaStmt; /* ---------------------- * Alter Object Owner Statement * ---------------------- */ typedef struct AlterOwnerStmt { NodeTag type; ObjectType objectType; /* OBJECT_TABLE, OBJECT_TYPE, etc */ RangeVar *relation; /* in case it's a table */ List *object; /* in case it's some other object */ List *objarg; /* argument types, if applicable */ char *addname; /* additional name if needed */ char *newowner; /* the new owner */ } AlterOwnerStmt; /* ---------------------- * Create Rule Statement * ---------------------- */ typedef struct RuleStmt { NodeTag type; RangeVar *relation; /* relation the rule is for */ char *rulename; /* name of the rule */ Node *whereClause; /* qualifications */ CmdType event; /* SELECT, INSERT, etc */ bool instead; /* is a 'do instead'? */ List *actions; /* the action statements */ bool replace; /* OR REPLACE */ } RuleStmt; /* ---------------------- * Notify Statement * ---------------------- */ typedef struct NotifyStmt { NodeTag type; char *conditionname; /* condition name to notify */ char *payload; /* the payload string, or NULL if none */ } NotifyStmt; /* ---------------------- * Listen Statement * ---------------------- */ typedef struct ListenStmt { NodeTag type; char *conditionname; /* condition name to listen on */ } ListenStmt; /* ---------------------- * Unlisten Statement * ---------------------- */ typedef struct UnlistenStmt { NodeTag type; char *conditionname; /* name to unlisten on, or NULL for all */ } UnlistenStmt; /* ---------------------- * {Begin|Commit|Rollback} Transaction Statement * ---------------------- */ typedef enum TransactionStmtKind { TRANS_STMT_BEGIN, TRANS_STMT_START, /* semantically identical to BEGIN */ TRANS_STMT_COMMIT, TRANS_STMT_ROLLBACK, TRANS_STMT_SAVEPOINT, TRANS_STMT_RELEASE, TRANS_STMT_ROLLBACK_TO, TRANS_STMT_PREPARE, TRANS_STMT_COMMIT_PREPARED, TRANS_STMT_ROLLBACK_PREPARED } TransactionStmtKind; typedef struct TransactionStmt { NodeTag type; TransactionStmtKind kind; /* see above */ List *options; /* for BEGIN/START and savepoint commands */ char *gid; /* for two-phase-commit related commands */ } TransactionStmt; /* ---------------------- * Create Type Statement, composite types * ---------------------- */ typedef struct CompositeTypeStmt { NodeTag type; RangeVar *typevar; /* the composite type to be created */ List *coldeflist; /* list of ColumnDef nodes */ } CompositeTypeStmt; /* ---------------------- * Create Type Statement, enum types * ---------------------- */ typedef struct CreateEnumStmt { NodeTag type; List *typeName; /* qualified name (list of Value strings) */ List *vals; /* enum values (list of Value strings) */ } CreateEnumStmt; /* ---------------------- * Create Type Statement, range types * ---------------------- */ typedef struct CreateRangeStmt { NodeTag type; List *typeName; /* qualified name (list of Value strings) */ List *params; /* range parameters (list of DefElem) */ } CreateRangeStmt; /* ---------------------- * Alter Type Statement, enum types * ---------------------- */ typedef struct AlterEnumStmt { NodeTag type; List *typeName; /* qualified name (list of Value strings) */ char *newVal; /* new enum value's name */ char *newValNeighbor; /* neighboring enum value, if specified */ bool newValIsAfter; /* place new enum value after neighbor? */ } AlterEnumStmt; /* ---------------------- * Create View Statement * ---------------------- */ typedef struct ViewStmt { NodeTag type; RangeVar *view; /* the view to be created */ List *aliases; /* target column names */ Node *query; /* the SELECT query */ bool replace; /* replace an existing view? */ List *options; /* options from WITH clause */ } ViewStmt; /* ---------------------- * Load Statement * ---------------------- */ typedef struct LoadStmt { NodeTag type; char *filename; /* file to load */ } LoadStmt; /* ---------------------- * Createdb Statement * ---------------------- */ typedef struct CreatedbStmt { NodeTag type; char *dbname; /* name of database to create */ List *options; /* List of DefElem nodes */ } CreatedbStmt; /* ---------------------- * Alter Database * ---------------------- */ typedef struct AlterDatabaseStmt { NodeTag type; char *dbname; /* name of database to alter */ List *options; /* List of DefElem nodes */ } AlterDatabaseStmt; typedef struct AlterDatabaseSetStmt { NodeTag type; char *dbname; /* database name */ VariableSetStmt *setstmt; /* SET or RESET subcommand */ } AlterDatabaseSetStmt; /* ---------------------- * Dropdb Statement * ---------------------- */ typedef struct DropdbStmt { NodeTag type; char *dbname; /* database to drop */ bool missing_ok; /* skip error if db is missing? */ } DropdbStmt; /* ---------------------- * Cluster Statement (support pbrown's cluster index implementation) * ---------------------- */ typedef struct ClusterStmt { NodeTag type; RangeVar *relation; /* relation being indexed, or NULL if all */ char *indexname; /* original index defined */ bool verbose; /* print progress info */ } ClusterStmt; /* ---------------------- * Vacuum and Analyze Statements * * Even though these are nominally two statements, it's convenient to use * just one node type for both. Note that at least one of VACOPT_VACUUM * and VACOPT_ANALYZE must be set in options. VACOPT_FREEZE is an internal * convenience for the grammar and is not examined at runtime --- the * freeze_min_age and freeze_table_age fields are what matter. * ---------------------- */ typedef enum VacuumOption { VACOPT_VACUUM = 1 << 0, /* do VACUUM */ VACOPT_ANALYZE = 1 << 1, /* do ANALYZE */ VACOPT_VERBOSE = 1 << 2, /* print progress info */ VACOPT_FREEZE = 1 << 3, /* FREEZE option */ VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */ VACOPT_NOWAIT = 1 << 5 /* don't wait to get lock (autovacuum only) */ } VacuumOption; typedef struct VacuumStmt { NodeTag type; int options; /* OR of VacuumOption flags */ int freeze_min_age; /* min freeze age, or -1 to use default */ int freeze_table_age; /* age at which to scan whole table */ RangeVar *relation; /* single table to process, or NULL */ List *va_cols; /* list of column names, or NIL for all */ } VacuumStmt; /* ---------------------- * Explain Statement * * The "query" field is either a raw parse tree (SelectStmt, InsertStmt, etc) * or a Query node if parse analysis has been done. Note that rewriting and * planning of the query are always postponed until execution of EXPLAIN. * ---------------------- */ typedef struct ExplainStmt { NodeTag type; Node *query; /* the query (see comments above) */ List *options; /* list of DefElem nodes */ } ExplainStmt; /* ---------------------- * CREATE TABLE AS Statement (a/k/a SELECT INTO) * * A query written as CREATE TABLE AS will produce this node type natively. * A query written as SELECT ... INTO will be transformed to this form during * parse analysis. * * The "query" field is handled similarly to EXPLAIN, though note that it * can be a SELECT or an EXECUTE, but not other DML statements. * ---------------------- */ typedef struct CreateTableAsStmt { NodeTag type; Node *query; /* the query (see comments above) */ IntoClause *into; /* destination table */ bool is_select_into; /* it was written as SELECT INTO */ } CreateTableAsStmt; /* ---------------------- * Checkpoint Statement * ---------------------- */ typedef struct CheckPointStmt { NodeTag type; } CheckPointStmt; /* ---------------------- * Discard Statement * ---------------------- */ typedef enum DiscardMode { DISCARD_ALL, DISCARD_PLANS, DISCARD_TEMP } DiscardMode; typedef struct DiscardStmt { NodeTag type; DiscardMode target; } DiscardStmt; /* ---------------------- * LOCK Statement * ---------------------- */ typedef struct LockStmt { NodeTag type; List *relations; /* relations to lock */ int mode; /* lock mode */ bool nowait; /* no wait mode */ } LockStmt; /* ---------------------- * SET CONSTRAINTS Statement * ---------------------- */ typedef struct ConstraintsSetStmt { NodeTag type; List *constraints; /* List of names as RangeVars */ bool deferred; } ConstraintsSetStmt; /* ---------------------- * REINDEX Statement * ---------------------- */ typedef struct ReindexStmt { NodeTag type; ObjectType kind; /* OBJECT_INDEX, OBJECT_TABLE, OBJECT_DATABASE */ RangeVar *relation; /* Table or index to reindex */ const char *name; /* name of database to reindex */ bool do_system; /* include system tables in database case */ bool do_user; /* include user tables in database case */ } ReindexStmt; /* ---------------------- * CREATE CONVERSION Statement * ---------------------- */ typedef struct CreateConversionStmt { NodeTag type; List *conversion_name; /* Name of the conversion */ char *for_encoding_name; /* source encoding name */ char *to_encoding_name; /* destination encoding name */ List *func_name; /* qualified conversion function name */ bool def; /* is this a default conversion? */ } CreateConversionStmt; /* ---------------------- * CREATE CAST Statement * ---------------------- */ typedef struct CreateCastStmt { NodeTag type; TypeName *sourcetype; TypeName *targettype; FuncWithArgs *func; CoercionContext context; bool inout; } CreateCastStmt; /* ---------------------- * PREPARE Statement * ---------------------- */ typedef struct PrepareStmt { NodeTag type; char *name; /* Name of plan, arbitrary */ List *argtypes; /* Types of parameters (List of TypeName) */ Node *query; /* The query itself (as a raw parsetree) */ } PrepareStmt; /* ---------------------- * EXECUTE Statement * ---------------------- */ typedef struct ExecuteStmt { NodeTag type; char *name; /* The name of the plan to execute */ List *params; /* Values to assign to parameters */ } ExecuteStmt; /* ---------------------- * DEALLOCATE Statement * ---------------------- */ typedef struct DeallocateStmt { NodeTag type; char *name; /* The name of the plan to remove */ /* NULL means DEALLOCATE ALL */ } DeallocateStmt; /* * DROP OWNED statement */ typedef struct DropOwnedStmt { NodeTag type; List *roles; DropBehavior behavior; } DropOwnedStmt; /* * REASSIGN OWNED statement */ typedef struct ReassignOwnedStmt { NodeTag type; List *roles; char *newrole; } ReassignOwnedStmt; /* * TS Dictionary stmts: DefineStmt, RenameStmt and DropStmt are default */ typedef struct AlterTSDictionaryStmt { NodeTag type; List *dictname; /* qualified name (list of Value strings) */ List *options; /* List of DefElem nodes */ } AlterTSDictionaryStmt; /* * TS Configuration stmts: DefineStmt, RenameStmt and DropStmt are default */ typedef struct AlterTSConfigurationStmt { NodeTag type; List *cfgname; /* qualified name (list of Value strings) */ /* * dicts will be non-NIL if ADD/ALTER MAPPING was specified. If dicts is * NIL, but tokentype isn't, DROP MAPPING was specified. */ List *tokentype; /* list of Value strings */ List *dicts; /* list of list of Value strings */ bool override; /* if true - remove old variant */ bool replace; /* if true - replace dictionary by another */ bool missing_ok; /* for DROP - skip error if missing? */ } AlterTSConfigurationStmt; #endif /* PARSENODES_H */ pgpool-II-3.3.2/parser/gram.y0000664000076400007640000126424612245576266012723 00000000000000%{ /*#define YYDEBUG 1*/ /*------------------------------------------------------------------------- * * gram.y * POSTGRESQL BISON rules/actions * * Portions Copyright (c) 2003-2013, PgPool Global Development Group * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * src/backend/parser/gram.y * * HISTORY * AUTHOR DATE MAJOR EVENT * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion * Andrew Yu Oct, 1994 lispy code conversion * * NOTES * CAPITALS are used to represent terminal symbols. * non-capitals are used to represent non-terminals. * SQL92-specific syntax is separated from plain SQL/Postgres syntax * to help isolate the non-extensible portions of the parser. * * In general, nothing in this file should initiate database accesses * nor depend on changeable state (such as SET variables). If you do * database accesses, your code will fail when we have aborted the * current transaction and are just parsing commands to find the next * ROLLBACK or COMMIT. If you make use of SET variables, then you * will do the wrong thing in multi-query strings like this: * SET SQL_inheritance TO off; SELECT * FROM foo; * because the entire string is parsed by gram.y before the SET gets * executed. Anything that depends on the database or changeable state * should be handled during parse analysis so that it happens at the * right time not the wrong time. The handling of SQL_inheritance is * a good example. * * WARNINGS * If you use a list, make sure the datum is a node so that the printing * routines work. * * Sometimes we assign constants to makeStrings. Make sure we don't free * those. * *------------------------------------------------------------------------- */ #include "pool_parser.h" #include #include #include #include #include #include "nodes.h" #include "keywords.h" #include "pool_memory.h" #include "gramparse.h" #include "makefuncs.h" #include "pool_string.h" #include "parser.h" #include "pg_class.h" #include "pg_trigger.h" /* for XML data type */ typedef enum { XML_STANDALONE_YES, XML_STANDALONE_NO, XML_STANDALONE_NO_VALUE, XML_STANDALONE_OMITTED } XmlStandaloneType; static DefElem *defWithOids(bool value); /* Location tracking support --- simpler than bison's default */ #define YYLLOC_DEFAULT(Current, Rhs, N) \ do { \ if (N) \ (Current) = (Rhs)[1]; \ else \ (Current) = (Rhs)[0]; \ } while (0) /* * Bison doesn't allocate anything that needs to live across parser calls, * so we can easily have it use palloc instead of malloc. This prevents * memory leaks if we error out during parsing. Note this only works with * bison >= 2.0. However, in bison 1.875 the default is to use alloca() * if possible, so there's not really much problem anyhow, at least if * you're building with gcc. */ #define YYMALLOC palloc #define YYFREE pfree /* Private struct for the result of privilege_target production */ typedef struct PrivTarget { GrantTargetType targtype; GrantObjectType objtype; List *objs; } PrivTarget; /* ConstraintAttributeSpec yields an integer bitmask of these flags: */ #define CAS_NOT_DEFERRABLE 0x01 #define CAS_DEFERRABLE 0x02 #define CAS_INITIALLY_IMMEDIATE 0x04 #define CAS_INITIALLY_DEFERRED 0x08 #define CAS_NOT_VALID 0x10 #define CAS_NO_INHERIT 0x20 #define parser_yyerror(msg) scanner_yyerror(msg, yyscanner) #define parser_errposition(pos) scanner_errposition(pos, yyscanner) static void base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner, const char *msg); static Node *makeColumnRef(char *colname, List *indirection, int location, core_yyscan_t yyscanner); static Node *makeTypeCast(Node *arg, TypeName *typename, int location); static Node *makeStringConst(char *str, int location); static Node *makeStringConstCast(char *str, int location, TypeName *typename); static Node *makeIntConst(int val, int location); static Node *makeFloatConst(char *str, int location); static Node *makeBitStringConst(char *str, int location); static Node *makeNullAConst(int location); static Node *makeAConst(Value *v, int location); static Node *makeBoolAConst(bool state, int location); static FuncCall *makeOverlaps(List *largs, List *rargs, int location, core_yyscan_t yyscanner); static void check_qualified_name(List *names, core_yyscan_t yyscanner); static List *check_func_name(List *names, core_yyscan_t yyscanner); static List *check_indirection(List *indirection, core_yyscan_t yyscanner); static List *extractArgTypes(List *parameters); static void insertSelectOptions(SelectStmt *stmt, List *sortClause, List *lockingClause, Node *limitOffset, Node *limitCount, WithClause *withClause, core_yyscan_t yyscanner); static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg); static Node *doNegate(Node *n, int location); static void doNegateFloat(Value *v); static Node *makeAArrayExpr(List *elements, int location); static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args, int location); static List *mergeTableFuncParameters(List *func_args, List *columns); static TypeName *TableFuncTypeName(List *columns); static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner); static void SplitColQualList(List *qualList, List **constraintList, CollateClause **collClause, core_yyscan_t yyscanner); static void processCASbits(int cas_bits, int location, const char *constrType, bool *deferrable, bool *initdeferred, bool *not_valid, bool *no_inherit, core_yyscan_t yyscanner); %} %pure-parser %expect 0 %name-prefix="base_yy" %locations %parse-param {core_yyscan_t yyscanner} %lex-param {core_yyscan_t yyscanner} %union { core_YYSTYPE core_yystype; /* these fields must match core_YYSTYPE: */ int ival; char *str; const char *keyword; char chr; bool boolean; JoinType jtype; DropBehavior dbehavior; OnCommitAction oncommit; List *list; Node *node; Value *value; ObjectType objtype; TypeName *typnam; FunctionParameter *fun_param; FunctionParameterMode fun_param_mode; FuncWithArgs *funwithargs; DefElem *defelt; SortBy *sortby; WindowDef *windef; JoinExpr *jexpr; IndexElem *ielem; Alias *alias; RangeVar *range; IntoClause *into; WithClause *with; A_Indices *aind; ResTarget *target; struct PrivTarget *privtarget; AccessPriv *accesspriv; InsertStmt *istmt; VariableSetStmt *vsetstmt; } %type stmt schema_stmt AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterEnumStmt AlterFdwStmt AlterForeignServerStmt AlterGroupStmt AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt AlterExtensionStmt AlterExtensionContentsStmt AlterForeignTableStmt AlterCompositeTypeStmt AlterUserStmt AlterUserMappingStmt AlterUserSetStmt AlterRoleStmt AlterRoleSetStmt AlterDefaultPrivilegesStmt DefACLAction AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt CreateDomainStmt CreateExtensionStmt CreateGroupStmt CreateOpClassStmt CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt CreateFdwStmt CreateForeignServerStmt CreateForeignTableStmt CreateAssertStmt CreateTrigStmt CreateUserStmt CreateUserMappingStmt CreateRoleStmt CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt DoStmt DropGroupStmt DropOpClassStmt DropOpFamilyStmt DropPLangStmt DropStmt DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt DropUserStmt DropdbStmt DropTableSpaceStmt DropFdwStmt DropForeignServerStmt DropUserMappingStmt ExplainStmt FetchStmt GrantStmt GrantRoleStmt IndexStmt InsertStmt ListenStmt LoadStmt LockStmt NotifyStmt ExplainableStmt PreparableStmt CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt RevokeRoleStmt RuleActionStmt RuleActionStmtOrEmpty RuleStmt SecLabelStmt SelectStmt TransactionStmt TruncateStmt UnlistenStmt UpdateStmt VacuumStmt VariableResetStmt VariableSetStmt VariableShowStmt ViewStmt CheckPointStmt CreateConversionStmt DeallocateStmt PrepareStmt ExecuteStmt DropOwnedStmt ReassignOwnedStmt AlterTSConfigurationStmt AlterTSDictionaryStmt %type select_no_parens select_with_parens select_clause simple_select values_clause %type alter_column_default opclass_item opclass_drop alter_using %type add_drop opt_asc_desc opt_nulls_order %type alter_table_cmd alter_type_cmd opt_collate_clause %type alter_table_cmds alter_type_cmds %type opt_drop_behavior %type createdb_opt_list alterdb_opt_list copy_opt_list transaction_mode_list create_extension_opt_list alter_extension_opt_list %type createdb_opt_item alterdb_opt_item copy_opt_item transaction_mode_item create_extension_opt_item alter_extension_opt_item %type opt_lock lock_type cast_context %type vacuum_option_list vacuum_option_elem %type opt_force opt_or_replace opt_grant_grant_option opt_grant_admin_option opt_nowait opt_if_exists opt_with_data %type OptRoleList AlterOptRoleList %type CreateOptRoleElem AlterOptRoleElem %type opt_type %type foreign_server_version opt_foreign_server_version %type auth_ident %type opt_in_database %type OptSchemaName %type OptSchemaEltList %type TriggerForSpec TriggerForType %type TriggerActionTime %type TriggerEvents TriggerOneEvent %type TriggerFuncArg %type TriggerWhen %type copy_file_name database_name access_method_clause access_method attr_name name cursor_name file_name index_name opt_index_name cluster_index_specification %type func_name handler_name qual_Op qual_all_Op subquery_Op opt_class opt_inline_handler opt_validator validator_clause opt_collate %type qualified_name OptConstrFromTable %type all_Op MathOp %type iso_level opt_encoding %type grantee %type grantee_list %type privilege %type privileges privilege_list %type privilege_target %type function_with_argtypes %type function_with_argtypes_list %type defacl_privilege_target %type DefACLOption %type DefACLOptionList %type stmtblock stmtmulti OptTableElementList TableElementList OptInherit definition OptTypedTableElementList TypedTableElementList OptForeignTableElementList ForeignTableElementList reloptions opt_reloptions OptWith opt_distinct opt_definition func_args func_args_list func_args_with_defaults func_args_with_defaults_list func_as createfunc_opt_list alterfunc_opt_list aggr_args old_aggr_definition old_aggr_list oper_argtypes RuleActionList RuleActionMulti opt_column_list columnList opt_name_list sort_clause opt_sort_clause sortby_list index_params name_list from_clause from_list opt_array_bounds qualified_name_list any_name any_name_list any_operator expr_list attrs target_list insert_column_list set_target_list set_clause_list set_clause multiple_set_clause ctext_expr_list ctext_row def_list indirection opt_indirection reloption_list group_clause TriggerFuncArgs select_limit opt_select_limit opclass_item_list opclass_drop_list opclass_purpose opt_opfamily transaction_mode_list_or_empty OptTableFuncElementList TableFuncElementList opt_type_modifiers prep_type_clause execute_param_clause using_clause returning_clause opt_enum_val_list enum_val_list table_func_column_list create_generic_options alter_generic_options relation_expr_list dostmt_opt_list %type opt_fdw_options fdw_options %type fdw_option %type OptTempTableName %type into_clause create_as_target %type createfunc_opt_item common_func_opt_item dostmt_opt_item %type func_arg func_arg_with_default table_func_column %type arg_class %type func_return func_type %type opt_trusted opt_restart_seqs %type OptTemp %type OnCommitOption %type for_locking_item %type for_locking_clause opt_for_locking_clause for_locking_items %type locked_rels_list %type opt_all %type join_outer join_qual %type join_type %type extract_list overlay_list position_list %type substr_list trim_list %type opt_interval interval_second %type overlay_placing substr_from substr_for %type opt_instead %type opt_unique opt_concurrently opt_verbose opt_full %type opt_freeze opt_default opt_recheck %type opt_binary opt_oids copy_delimiter %type copy_from %type opt_column event cursor_options opt_hold opt_set_data %type reindex_type drop_type comment_type security_label_type %type fetch_args limit_clause select_limit_value offset_clause select_offset_value select_offset_value2 opt_select_fetch_first_value %type row_or_rows first_or_next %type OptSeqOptList SeqOptList %type SeqOptElem %type insert_rest %type set_rest set_rest_more SetResetClause FunctionSetResetClause %type TableElement TypedTableElement ConstraintElem TableFuncElement ForeignTableElement %type columnDef columnOptions %type def_elem reloption_elem old_aggr_elem %type def_arg columnElem where_clause where_or_current_clause a_expr b_expr c_expr func_expr AexprConst indirection_el columnref in_expr having_clause func_table array_expr ExclusionWhereClause %type ExclusionConstraintList ExclusionConstraintElem %type func_arg_list %type func_arg_expr %type row type_list array_expr_list %type case_expr case_arg when_clause case_default %type when_clause_list %type sub_type %type ctext_expr %type NumericOnly %type NumericOnly_list %type alias_clause %type sortby %type index_elem %type table_ref %type joined_table %type relation_expr %type relation_expr_opt_alias %type target_el single_set_clause set_target insert_column_item %type generic_option_name %type generic_option_arg %type generic_option_elem alter_generic_option_elem %type generic_option_list alter_generic_option_list %type explain_option_name %type explain_option_arg %type explain_option_elem %type explain_option_list %type copy_generic_opt_arg copy_generic_opt_arg_list_item %type copy_generic_opt_elem %type copy_generic_opt_list copy_generic_opt_arg_list %type copy_options %type Typename SimpleTypename ConstTypename GenericType Numeric opt_float Character ConstCharacter CharacterWithLength CharacterWithoutLength ConstDatetime ConstInterval Bit ConstBit BitWithLength BitWithoutLength %type character %type extract_arg %type opt_charset %type opt_varying opt_timezone opt_no_inherit %type Iconst SignedIconst %type Sconst comment_text notify_payload %type RoleId opt_granted_by opt_boolean_or_string ColId_or_Sconst %type var_list %type ColId ColLabel var_name type_function_name param_name %type var_value zone_value %type unreserved_keyword type_func_name_keyword %type col_name_keyword reserved_keyword %type TableConstraint TableLikeClause %type TableLikeOptionList TableLikeOption %type ColQualList %type ColConstraint ColConstraintElem ConstraintAttr %type key_actions key_delete key_match key_update key_action %type ConstraintAttributeSpec ConstraintAttributeElem %type ExistingIndex %type constraints_set_list %type constraints_set_mode %type OptTableSpace OptConsTableSpace OptTableSpaceOwner %type opt_check_option %type opt_provider security_label %type xml_attribute_el %type xml_attribute_list xml_attributes %type xml_root_version opt_xml_root_standalone %type xmlexists_argument %type document_or_content %type xml_whitespace_option %type common_table_expr %type with_clause opt_with_clause %type cte_list %type window_clause window_definition_list opt_partition_clause %type window_definition over_clause window_specification opt_frame_clause frame_extent frame_bound %type opt_existing_window_name /* * Non-keyword token types. These are hard-wired into the "flex" lexer. * They must be listed first so that their numeric codes do not depend on * the set of keywords. PL/pgsql depends on this so that it can share the * same lexer. If you add/change tokens here, fix PL/pgsql to match! * * DOT_DOT is unused in the core SQL grammar, and so will always provoke * parse errors. It is needed by PL/pgsql. */ %token IDENT FCONST SCONST BCONST XCONST Op %token ICONST PARAM %token TYPECAST DOT_DOT COLON_EQUALS /* * If you want to make any keyword changes, update the keyword table in * src/include/parser/kwlist.h and add new keywords to the appropriate one * of the reserved-or-not-so-reserved keyword lists, below; search * this file for "Keyword category lists". */ /* ordinary key words in alphabetical order */ %token ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC ASSERTION ASSIGNMENT ASYMMETRIC AT ATTRIBUTE AUTHORIZATION BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT BOOLEAN_P BOTH BY CACHE CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE CLUSTER COALESCE COLLATE COLLATION COLUMN COMMENT COMMENTS COMMIT COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CROSS CSV CURRENT_P CURRENT_CATALOG CURRENT_DATE CURRENT_ROLE CURRENT_SCHEMA CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DESC DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTENSION EXTERNAL EXTRACT FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS GLOBAL GRANT GRANTED GREATEST GROUP_P HANDLER HAVING HEADER_P HOLD HOUR_P IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION JOIN KEY LABEL LANGUAGE LARGE_P LAST_P LC_COLLATE_P LC_CTYPE_P LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE NAME_P NAMES NATIONAL NATURAL NCHAR NEXT NO NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC OBJECT_P OF OFF OFFSET OIDS ON ONLY OPERATOR OPTION OPTIONS OR ORDER OUT_P OUTER_P OVER OVERLAPS OVERLAY OWNED OWNER PARSER PARTIAL PARTITION PASSING PASSWORD PLACING PLANS POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE QUOTE RANGE READ REAL REASSIGN RECHECK RECURSIVE REF REFERENCES REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROW ROWS RULE SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES SERIALIZABLE SERVER SESSION SESSION_USER SET SETOF SHARE SHOW SIMILAR SIMPLE SMALLINT SNAPSHOT SOME STABLE STANDALONE_P START STATEMENT STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SYMMETRIC SYSID SYSTEM_P TABLE TABLES TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P TYPES_P UNBOUNDED UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNLOGGED UNTIL UPDATE USER USING VACUUM VALID VALIDATE VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING VERBOSE VERSION_P VIEW VOLATILE WHEN WHERE WHITESPACE_P WINDOW WITH WITHOUT WORK WRAPPER WRITE XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLPARSE XMLPI XMLROOT XMLSERIALIZE YEAR_P YES_P ZONE /* * The grammar thinks these are keywords, but they are not in the kwlist.h * list and so can never be entered directly. The filter in parser.c * creates these tokens when required. */ %token NULLS_FIRST NULLS_LAST WITH_TIME /* Precedence: lowest to highest */ %nonassoc SET /* see relation_expr_opt_alias */ %left UNION EXCEPT %left INTERSECT %left OR %left AND %right NOT %right '=' %nonassoc '<' '>' %nonassoc LIKE ILIKE SIMILAR %nonassoc ESCAPE %nonassoc OVERLAPS %nonassoc BETWEEN %nonassoc IN_P %left POSTFIXOP /* dummy for postfix Op rules */ /* * To support target_el without AS, we must give IDENT an explicit priority * between POSTFIXOP and Op. We can safely assign the same priority to * various unreserved keywords as needed to resolve ambiguities (this can't * have any bad effects since obviously the keywords will still behave the * same as if they weren't keywords). We need to do this for PARTITION, * RANGE, ROWS to support opt_existing_window_name; and for RANGE, ROWS * so that they can follow a_expr without creating postfix-operator problems; * and for NULL so that it can follow b_expr in ColQualList without creating * postfix-operator problems. * * The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING * are even messier: since UNBOUNDED is an unreserved keyword (per spec!), * there is no principled way to distinguish these from the productions * a_expr PRECEDING/FOLLOWING. We hack this up by giving UNBOUNDED slightly * lower precedence than PRECEDING and FOLLOWING. At present this doesn't * appear to cause UNBOUNDED to be treated differently from other unreserved * keywords anywhere else in the grammar, but it's definitely risky. We can * blame any funny behavior of UNBOUNDED on the SQL standard, though. */ %nonassoc UNBOUNDED /* ideally should have same precedence as IDENT */ %nonassoc IDENT NULL_P PARTITION RANGE ROWS PRECEDING FOLLOWING %left Op OPERATOR /* multi-character ops and user-defined operators */ %nonassoc NOTNULL %nonassoc ISNULL %nonassoc IS /* sets precedence for IS NULL, etc */ %left '+' '-' %left '*' '/' '%' %left '^' /* Unary Operators */ %left AT /* sets precedence for AT TIME ZONE */ %left COLLATE %right UMINUS %left '[' ']' %left '(' ')' %left TYPECAST %left '.' /* * These might seem to be low-precedence, but actually they are not part * of the arithmetic hierarchy at all in their use as JOIN operators. * We make them high-precedence to support their use as function names. * They wouldn't be given a precedence at all, were it not that we need * left-associativity among the JOIN rules themselves. */ %left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL /* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */ %right PRESERVE STRIP_P %% /* * The target production for the whole parse. */ stmtblock: stmtmulti { pg_yyget_extra(yyscanner)->parsetree = $1; } ; /* the thrashing around here is to discard "empty" statements... */ stmtmulti: stmtmulti ';' stmt { if ($3 != NULL) $$ = lappend($1, $3); else $$ = $1; } | stmt { if ($1 != NULL) $$ = list_make1($1); else $$ = NIL; } ; stmt : AlterDatabaseStmt | AlterDatabaseSetStmt | AlterDefaultPrivilegesStmt | AlterDomainStmt | AlterEnumStmt | AlterExtensionStmt | AlterExtensionContentsStmt | AlterFdwStmt | AlterForeignServerStmt | AlterForeignTableStmt | AlterFunctionStmt | AlterGroupStmt | AlterObjectSchemaStmt | AlterOwnerStmt | AlterSeqStmt | AlterTableStmt | AlterCompositeTypeStmt | AlterRoleSetStmt | AlterRoleStmt | AlterTSConfigurationStmt | AlterTSDictionaryStmt | AlterUserMappingStmt | AlterUserSetStmt | AlterUserStmt | AnalyzeStmt | CheckPointStmt | ClosePortalStmt | ClusterStmt | CommentStmt | ConstraintsSetStmt | CopyStmt | CreateAsStmt | CreateAssertStmt | CreateCastStmt | CreateConversionStmt | CreateDomainStmt | CreateExtensionStmt | CreateFdwStmt | CreateForeignServerStmt | CreateForeignTableStmt | CreateFunctionStmt | CreateGroupStmt | CreateOpClassStmt | CreateOpFamilyStmt | AlterOpFamilyStmt | CreatePLangStmt | CreateSchemaStmt | CreateSeqStmt | CreateStmt | CreateTableSpaceStmt | CreateTrigStmt | CreateRoleStmt | CreateUserStmt | CreateUserMappingStmt | CreatedbStmt | DeallocateStmt | DeclareCursorStmt | DefineStmt | DeleteStmt | DiscardStmt | DoStmt | DropAssertStmt | DropCastStmt | DropFdwStmt | DropForeignServerStmt | DropGroupStmt | DropOpClassStmt | DropOpFamilyStmt | DropOwnedStmt | DropPLangStmt | DropRuleStmt | DropStmt | DropTableSpaceStmt | DropTrigStmt | DropRoleStmt | DropUserStmt | DropUserMappingStmt | DropdbStmt | ExecuteStmt | ExplainStmt | FetchStmt | GrantStmt | GrantRoleStmt | IndexStmt | InsertStmt | ListenStmt | LoadStmt | LockStmt | NotifyStmt | PrepareStmt | ReassignOwnedStmt | ReindexStmt | RemoveAggrStmt | RemoveFuncStmt | RemoveOperStmt | RenameStmt | RevokeStmt | RevokeRoleStmt | RuleStmt | SecLabelStmt | SelectStmt | TransactionStmt | TruncateStmt | UnlistenStmt | UpdateStmt | VacuumStmt | VariableResetStmt | VariableSetStmt | VariableShowStmt | ViewStmt | /*EMPTY*/ { $$ = NULL; } ; /***************************************************************************** * * Create a new Postgres DBMS role * *****************************************************************************/ CreateRoleStmt: CREATE ROLE RoleId opt_with OptRoleList { CreateRoleStmt *n = makeNode(CreateRoleStmt); n->stmt_type = ROLESTMT_ROLE; n->role = $3; n->options = $5; $$ = (Node *)n; } ; opt_with: WITH {} | /*EMPTY*/ {} ; /* * Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER * for backwards compatibility). Note: the only option required by SQL99 * is "WITH ADMIN name". */ OptRoleList: OptRoleList CreateOptRoleElem { $$ = lappend($1, $2); } | /* EMPTY */ { $$ = NIL; } ; AlterOptRoleList: AlterOptRoleList AlterOptRoleElem { $$ = lappend($1, $2); } | /* EMPTY */ { $$ = NIL; } ; AlterOptRoleElem: PASSWORD Sconst { $$ = makeDefElem("password", (Node *)makeString($2)); } | PASSWORD NULL_P { $$ = makeDefElem("password", NULL); } | ENCRYPTED PASSWORD Sconst { $$ = makeDefElem("encryptedPassword", (Node *)makeString($3)); } | UNENCRYPTED PASSWORD Sconst { $$ = makeDefElem("unencryptedPassword", (Node *)makeString($3)); } | INHERIT { $$ = makeDefElem("inherit", (Node *)makeInteger(TRUE)); } | CONNECTION LIMIT SignedIconst { $$ = makeDefElem("connectionlimit", (Node *)makeInteger($3)); } | VALID UNTIL Sconst { $$ = makeDefElem("validUntil", (Node *)makeString($3)); } /* Supported but not documented for roles, for use by ALTER GROUP. */ | USER name_list { $$ = makeDefElem("rolemembers", (Node *)$2); } | IDENT { /* * We handle identifiers that aren't parser keywords with * the following special-case codes, to avoid bloating the * size of the main parser. */ if (strcmp($1, "superuser") == 0) $$ = makeDefElem("superuser", (Node *)makeInteger(TRUE)); else if (strcmp($1, "nosuperuser") == 0) $$ = makeDefElem("superuser", (Node *)makeInteger(FALSE)); else if (strcmp($1, "createuser") == 0) { /* For backwards compatibility, synonym for SUPERUSER */ $$ = makeDefElem("superuser", (Node *)makeInteger(TRUE)); } else if (strcmp($1, "nocreateuser") == 0) { /* For backwards compatibility, synonym for SUPERUSER */ $$ = makeDefElem("superuser", (Node *)makeInteger(FALSE)); } else if (strcmp($1, "createrole") == 0) $$ = makeDefElem("createrole", (Node *)makeInteger(TRUE)); else if (strcmp($1, "nocreaterole") == 0) $$ = makeDefElem("createrole", (Node *)makeInteger(FALSE)); else if (strcmp($1, "replication") == 0) $$ = makeDefElem("isreplication", (Node *)makeInteger(TRUE)); else if (strcmp($1, "noreplication") == 0) $$ = makeDefElem("isreplication", (Node *)makeInteger(FALSE)); else if (strcmp($1, "createdb") == 0) $$ = makeDefElem("createdb", (Node *)makeInteger(TRUE)); else if (strcmp($1, "nocreatedb") == 0) $$ = makeDefElem("createdb", (Node *)makeInteger(FALSE)); else if (strcmp($1, "login") == 0) $$ = makeDefElem("canlogin", (Node *)makeInteger(TRUE)); else if (strcmp($1, "nologin") == 0) $$ = makeDefElem("canlogin", (Node *)makeInteger(FALSE)); else if (strcmp($1, "noinherit") == 0) { /* * Note that INHERIT is a keyword, so it's handled by main parser, but * NOINHERIT is handled here. */ $$ = makeDefElem("inherit", (Node *)makeInteger(FALSE)); } else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("unrecognized role option \"%s\"", $1), parser_errposition(@1))); } ; CreateOptRoleElem: AlterOptRoleElem { $$ = $1; } /* The following are not supported by ALTER ROLE/USER/GROUP */ | SYSID Iconst { $$ = makeDefElem("sysid", (Node *)makeInteger($2)); } | ADMIN name_list { $$ = makeDefElem("adminmembers", (Node *)$2); } | ROLE name_list { $$ = makeDefElem("rolemembers", (Node *)$2); } | IN_P ROLE name_list { $$ = makeDefElem("addroleto", (Node *)$3); } | IN_P GROUP_P name_list { $$ = makeDefElem("addroleto", (Node *)$3); } ; /***************************************************************************** * * Create a new Postgres DBMS user (role with implied login ability) * *****************************************************************************/ CreateUserStmt: CREATE USER RoleId opt_with OptRoleList { CreateRoleStmt *n = makeNode(CreateRoleStmt); n->stmt_type = ROLESTMT_USER; n->role = $3; n->options = $5; $$ = (Node *)n; } ; /***************************************************************************** * * Alter a postgresql DBMS role * *****************************************************************************/ AlterRoleStmt: ALTER ROLE RoleId opt_with AlterOptRoleList { AlterRoleStmt *n = makeNode(AlterRoleStmt); n->role = $3; n->action = +1; /* add, if there are members */ n->options = $5; $$ = (Node *)n; } ; opt_in_database: /* EMPTY */ { $$ = NULL; } | IN_P DATABASE database_name { $$ = $3; } ; AlterRoleSetStmt: ALTER ROLE RoleId opt_in_database SetResetClause { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); n->role = $3; n->database = $4; n->setstmt = $5; $$ = (Node *)n; } ; /***************************************************************************** * * Alter a postgresql DBMS user * *****************************************************************************/ AlterUserStmt: ALTER USER RoleId opt_with AlterOptRoleList { AlterRoleStmt *n = makeNode(AlterRoleStmt); n->role = $3; n->action = +1; /* add, if there are members */ n->options = $5; $$ = (Node *)n; } ; AlterUserSetStmt: ALTER USER RoleId SetResetClause { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); n->role = $3; n->database = NULL; n->setstmt = $4; $$ = (Node *)n; } ; /***************************************************************************** * * Drop a postgresql DBMS role * * XXX Ideally this would have CASCADE/RESTRICT options, but since a role * might own objects in multiple databases, there is presently no way to * implement either cascading or restricting. Caveat DBA. *****************************************************************************/ DropRoleStmt: DROP ROLE name_list { DropRoleStmt *n = makeNode(DropRoleStmt); n->missing_ok = FALSE; n->roles = $3; $$ = (Node *)n; } | DROP ROLE IF_P EXISTS name_list { DropRoleStmt *n = makeNode(DropRoleStmt); n->missing_ok = TRUE; n->roles = $5; $$ = (Node *)n; } ; /***************************************************************************** * * Drop a postgresql DBMS user * * XXX Ideally this would have CASCADE/RESTRICT options, but since a user * might own objects in multiple databases, there is presently no way to * implement either cascading or restricting. Caveat DBA. *****************************************************************************/ DropUserStmt: DROP USER name_list { DropRoleStmt *n = makeNode(DropRoleStmt); n->missing_ok = FALSE; n->roles = $3; $$ = (Node *)n; } | DROP USER IF_P EXISTS name_list { DropRoleStmt *n = makeNode(DropRoleStmt); n->roles = $5; n->missing_ok = TRUE; $$ = (Node *)n; } ; /***************************************************************************** * * Create a postgresql group (role without login ability) * *****************************************************************************/ CreateGroupStmt: CREATE GROUP_P RoleId opt_with OptRoleList { CreateRoleStmt *n = makeNode(CreateRoleStmt); n->stmt_type = ROLESTMT_GROUP; n->role = $3; n->options = $5; $$ = (Node *)n; } ; /***************************************************************************** * * Alter a postgresql group * *****************************************************************************/ AlterGroupStmt: ALTER GROUP_P RoleId add_drop USER name_list { AlterRoleStmt *n = makeNode(AlterRoleStmt); n->role = $3; n->action = $4; n->options = list_make1(makeDefElem("rolemembers", (Node *)$6)); $$ = (Node *)n; } ; add_drop: ADD_P { $$ = +1; } | DROP { $$ = -1; } ; /***************************************************************************** * * Drop a postgresql group * * XXX see above notes about cascading DROP USER; groups have same problem. *****************************************************************************/ DropGroupStmt: DROP GROUP_P name_list { DropRoleStmt *n = makeNode(DropRoleStmt); n->missing_ok = FALSE; n->roles = $3; $$ = (Node *)n; } | DROP GROUP_P IF_P EXISTS name_list { DropRoleStmt *n = makeNode(DropRoleStmt); n->missing_ok = TRUE; n->roles = $5; $$ = (Node *)n; } ; /***************************************************************************** * * Manipulate a schema * *****************************************************************************/ CreateSchemaStmt: CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); /* One can omit the schema name or the authorization id. */ if ($3 != NULL) n->schemaname = $3; else n->schemaname = $5; n->authid = $5; n->schemaElts = $6; $$ = (Node *)n; } | CREATE SCHEMA ColId OptSchemaEltList { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); /* ...but not both */ n->schemaname = $3; n->authid = NULL; n->schemaElts = $4; $$ = (Node *)n; } ; OptSchemaName: ColId { $$ = $1; } | /* EMPTY */ { $$ = NULL; } ; OptSchemaEltList: OptSchemaEltList schema_stmt { $$ = lappend($1, $2); } | /* EMPTY */ { $$ = NIL; } ; /* * schema_stmt are the ones that can show up inside a CREATE SCHEMA * statement (in addition to by themselves). */ schema_stmt: CreateStmt | IndexStmt | CreateSeqStmt | CreateTrigStmt | GrantStmt | ViewStmt ; /***************************************************************************** * * Set PG internal variable * SET name TO 'var_value' * Include SQL92 syntax (thomas 1997-10-22): * SET TIME ZONE 'var_value' * *****************************************************************************/ VariableSetStmt: SET set_rest { VariableSetStmt *n = $2; n->is_local = false; $$ = (Node *) n; } | SET LOCAL set_rest { VariableSetStmt *n = $3; n->is_local = true; $$ = (Node *) n; } | SET SESSION set_rest { VariableSetStmt *n = $3; n->is_local = false; $$ = (Node *) n; } ; set_rest: TRANSACTION transaction_mode_list { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_MULTI; n->name = "TRANSACTION"; n->args = $2; $$ = n; } | SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_MULTI; n->name = "SESSION CHARACTERISTICS"; n->args = $5; $$ = n; } | set_rest_more ; set_rest_more: /* Generic SET syntaxes: */ var_name TO var_list { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_VALUE; n->name = $1; n->args = $3; $$ = n; } | var_name '=' var_list { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_VALUE; n->name = $1; n->args = $3; $$ = n; } | var_name TO DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_DEFAULT; n->name = $1; $$ = n; } | var_name '=' DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_DEFAULT; n->name = $1; $$ = n; } | var_name FROM CURRENT_P { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_CURRENT; n->name = $1; $$ = n; } /* Special syntaxes mandated by SQL standard: */ | TIME ZONE zone_value { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_VALUE; n->name = "timezone"; if ($3 != NULL) n->args = list_make1($3); else n->kind = VAR_SET_DEFAULT; $$ = n; } | CATALOG_P Sconst { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("current database cannot be changed"), parser_errposition(@2))); $$ = NULL; /*not reached*/ } | SCHEMA Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_VALUE; n->name = "search_path"; n->args = list_make1(makeStringConst($2, @2)); $$ = n; } | NAMES opt_encoding { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_VALUE; n->name = "client_encoding"; if ($2 != NULL) n->args = list_make1(makeStringConst($2, @2)); else n->kind = VAR_SET_DEFAULT; $$ = n; } | ROLE ColId_or_Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_VALUE; n->name = "role"; n->args = list_make1(makeStringConst($2, @2)); $$ = n; } | SESSION AUTHORIZATION ColId_or_Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_VALUE; n->name = "session_authorization"; n->args = list_make1(makeStringConst($3, @3)); $$ = n; } | SESSION AUTHORIZATION DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_DEFAULT; n->name = "session_authorization"; $$ = n; } | XML_P OPTION document_or_content { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_VALUE; n->name = "xmloption"; n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", @3)); $$ = n; } /* Special syntaxes invented by PostgreSQL: */ | TRANSACTION SNAPSHOT Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_MULTI; n->name = "TRANSACTION SNAPSHOT"; n->args = list_make1(makeStringConst($3, @3)); $$ = n; } ; var_name: ColId { $$ = $1; } | var_name '.' ColId { $$ = palloc(strlen($1) + strlen($3) + 2); sprintf($$, "%s.%s", $1, $3); } ; var_list: var_value { $$ = list_make1($1); } | var_list ',' var_value { $$ = lappend($1, $3); } ; var_value: opt_boolean_or_string { $$ = makeStringConst($1, @1); } | NumericOnly { $$ = makeAConst($1, @1); } ; iso_level: READ UNCOMMITTED { $$ = "read uncommitted"; } | READ COMMITTED { $$ = "read committed"; } | REPEATABLE READ { $$ = "repeatable read"; } | SERIALIZABLE { $$ = "serializable"; } ; opt_boolean_or_string: TRUE_P { $$ = "true"; } | FALSE_P { $$ = "false"; } | ON { $$ = "on"; } /* * OFF is also accepted as a boolean value, but is handled * by the ColId rule below. The action for booleans and strings * is the same, so we don't need to distinguish them here. */ | ColId_or_Sconst { $$ = $1; } ; /* Timezone values can be: * - a string such as 'pst8pdt' * - an identifier such as "pst8pdt" * - an integer or floating point number * - a time interval per SQL99 * ColId gives reduce/reduce errors against ConstInterval and LOCAL, * so use IDENT (meaning we reject anything that is a key word). */ zone_value: Sconst { $$ = makeStringConst($1, @1); } | IDENT { $$ = makeStringConst($1, @1); } | ConstInterval Sconst opt_interval { TypeName *t = $1; if ($3 != NIL) { A_Const *n = (A_Const *) linitial($3); if ((n->val.val.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("time zone interval must be HOUR or HOUR TO MINUTE"), parser_errposition(@3))); } t->typmods = $3; $$ = makeStringConstCast($2, @2, t); } | ConstInterval '(' Iconst ')' Sconst opt_interval { TypeName *t = $1; if ($6 != NIL) { A_Const *n = (A_Const *) linitial($6); if ((n->val.val.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("time zone interval must be HOUR or HOUR TO MINUTE"), parser_errposition(@6))); if (list_length($6) != 1) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("interval precision specified twice"), parser_errposition(@1))); t->typmods = lappend($6, makeIntConst($3, @3)); } else t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), makeIntConst($3, @3)); $$ = makeStringConstCast($5, @5, t); } | NumericOnly { $$ = makeAConst($1, @1); } | DEFAULT { $$ = NULL; } | LOCAL { $$ = NULL; } ; opt_encoding: Sconst { $$ = $1; } | DEFAULT { $$ = NULL; } | /*EMPTY*/ { $$ = NULL; } ; ColId_or_Sconst: ColId { $$ = $1; } | Sconst { $$ = $1; } ; VariableResetStmt: RESET var_name { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_RESET; n->name = $2; $$ = (Node *) n; } | RESET TIME ZONE { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_RESET; n->name = "timezone"; $$ = (Node *) n; } | RESET TRANSACTION ISOLATION LEVEL { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_RESET; n->name = "transaction_isolation"; $$ = (Node *) n; } | RESET SESSION AUTHORIZATION { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_RESET; n->name = "session_authorization"; $$ = (Node *) n; } | RESET ALL { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_RESET_ALL; $$ = (Node *) n; } ; /* SetResetClause allows SET or RESET without LOCAL */ SetResetClause: SET set_rest { $$ = $2; } | VariableResetStmt { $$ = (VariableSetStmt *) $1; } ; /* SetResetClause allows SET or RESET without LOCAL */ FunctionSetResetClause: SET set_rest_more { $$ = $2; } | VariableResetStmt { $$ = (VariableSetStmt *) $1; } ; VariableShowStmt: SHOW var_name { VariableShowStmt *n = makeNode(VariableShowStmt); n->name = $2; $$ = (Node *) n; } | SHOW TIME ZONE { VariableShowStmt *n = makeNode(VariableShowStmt); n->name = "timezone"; $$ = (Node *) n; } | SHOW TRANSACTION ISOLATION LEVEL { VariableShowStmt *n = makeNode(VariableShowStmt); n->name = "transaction_isolation"; $$ = (Node *) n; } | SHOW SESSION AUTHORIZATION { VariableShowStmt *n = makeNode(VariableShowStmt); n->name = "session_authorization"; $$ = (Node *) n; } | SHOW ALL { VariableShowStmt *n = makeNode(VariableShowStmt); n->name = "all"; $$ = (Node *) n; } ; ConstraintsSetStmt: SET CONSTRAINTS constraints_set_list constraints_set_mode { ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt); n->constraints = $3; n->deferred = $4; $$ = (Node *) n; } ; constraints_set_list: ALL { $$ = NIL; } | qualified_name_list { $$ = $1; } ; constraints_set_mode: DEFERRED { $$ = TRUE; } | IMMEDIATE { $$ = FALSE; } ; /* * Checkpoint statement */ CheckPointStmt: CHECKPOINT { CheckPointStmt *n = makeNode(CheckPointStmt); $$ = (Node *)n; } ; /***************************************************************************** * * DISCARD { ALL | TEMP | PLANS } * *****************************************************************************/ DiscardStmt: DISCARD ALL { DiscardStmt *n = makeNode(DiscardStmt); n->target = DISCARD_ALL; $$ = (Node *) n; } | DISCARD TEMP { DiscardStmt *n = makeNode(DiscardStmt); n->target = DISCARD_TEMP; $$ = (Node *) n; } | DISCARD TEMPORARY { DiscardStmt *n = makeNode(DiscardStmt); n->target = DISCARD_TEMP; $$ = (Node *) n; } | DISCARD PLANS { DiscardStmt *n = makeNode(DiscardStmt); n->target = DISCARD_PLANS; $$ = (Node *) n; } ; /***************************************************************************** * * ALTER [ TABLE | INDEX | SEQUENCE | VIEW ] variations * * Note: we accept all subcommands for each of the four variants, and sort * out what's really legal at execution time. *****************************************************************************/ AlterTableStmt: ALTER TABLE relation_expr alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); n->relation = $3; n->cmds = $4; n->relkind = OBJECT_TABLE; n->missing_ok = false; $$ = (Node *)n; } | ALTER TABLE IF_P EXISTS relation_expr alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); n->relation = $5; n->cmds = $6; n->relkind = OBJECT_TABLE; n->missing_ok = true; $$ = (Node *)n; } | ALTER INDEX qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); n->relation = $3; n->cmds = $4; n->relkind = OBJECT_INDEX; n->missing_ok = false; $$ = (Node *)n; } | ALTER INDEX IF_P EXISTS qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); n->relation = $5; n->cmds = $6; n->relkind = OBJECT_INDEX; n->missing_ok = true; $$ = (Node *)n; } | ALTER SEQUENCE qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); n->relation = $3; n->cmds = $4; n->relkind = OBJECT_SEQUENCE; n->missing_ok = false; $$ = (Node *)n; } | ALTER SEQUENCE IF_P EXISTS qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); n->relation = $5; n->cmds = $6; n->relkind = OBJECT_SEQUENCE; n->missing_ok = true; $$ = (Node *)n; } | ALTER VIEW qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); n->relation = $3; n->cmds = $4; n->relkind = OBJECT_VIEW; n->missing_ok = false; $$ = (Node *)n; } | ALTER VIEW IF_P EXISTS qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); n->relation = $5; n->cmds = $6; n->relkind = OBJECT_VIEW; n->missing_ok = true; $$ = (Node *)n; } ; alter_table_cmds: alter_table_cmd { $$ = list_make1($1); } | alter_table_cmds ',' alter_table_cmd { $$ = lappend($1, $3); } ; alter_table_cmd: /* ALTER TABLE ADD */ ADD_P columnDef { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_AddColumn; n->def = $2; $$ = (Node *)n; } /* ALTER TABLE ADD COLUMN */ | ADD_P COLUMN columnDef { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_AddColumn; n->def = $3; $$ = (Node *)n; } /* ALTER TABLE ALTER [COLUMN] {SET DEFAULT |DROP DEFAULT} */ | ALTER opt_column ColId alter_column_default { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_ColumnDefault; n->name = $3; n->def = $4; $$ = (Node *)n; } /* ALTER TABLE ALTER [COLUMN] DROP NOT NULL */ | ALTER opt_column ColId DROP NOT NULL_P { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropNotNull; n->name = $3; $$ = (Node *)n; } /* ALTER TABLE ALTER [COLUMN] SET NOT NULL */ | ALTER opt_column ColId SET NOT NULL_P { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_SetNotNull; n->name = $3; $$ = (Node *)n; } /* ALTER TABLE ALTER [COLUMN] SET STATISTICS */ | ALTER opt_column ColId SET STATISTICS SignedIconst { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_SetStatistics; n->name = $3; n->def = (Node *) makeInteger($6); $$ = (Node *)n; } /* ALTER TABLE ALTER [COLUMN] SET ( column_parameter = value [, ... ] ) */ | ALTER opt_column ColId SET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_SetOptions; n->name = $3; n->def = (Node *) $5; $$ = (Node *)n; } /* ALTER TABLE ALTER [COLUMN] SET ( column_parameter = value [, ... ] ) */ | ALTER opt_column ColId RESET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_ResetOptions; n->name = $3; n->def = (Node *) $5; $$ = (Node *)n; } /* ALTER TABLE ALTER [COLUMN] SET STORAGE */ | ALTER opt_column ColId SET STORAGE ColId { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_SetStorage; n->name = $3; n->def = (Node *) makeString($6); $$ = (Node *)n; } /* ALTER TABLE DROP [COLUMN] IF EXISTS [RESTRICT|CASCADE] */ | DROP opt_column IF_P EXISTS ColId opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropColumn; n->name = $5; n->behavior = $6; n->missing_ok = TRUE; $$ = (Node *)n; } /* ALTER TABLE DROP [COLUMN] [RESTRICT|CASCADE] */ | DROP opt_column ColId opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropColumn; n->name = $3; n->behavior = $4; n->missing_ok = FALSE; $$ = (Node *)n; } /* * ALTER TABLE ALTER [COLUMN] [SET DATA] TYPE * [ USING ] */ | ALTER opt_column ColId opt_set_data TYPE_P Typename opt_collate_clause alter_using { AlterTableCmd *n = makeNode(AlterTableCmd); ColumnDef *def = makeNode(ColumnDef); n->subtype = AT_AlterColumnType; n->name = $3; n->def = (Node *) def; /* We only use these three fields of the ColumnDef node */ def->typeName = $6; def->collClause = (CollateClause *) $7; def->raw_default = $8; $$ = (Node *)n; } /* ALTER FOREIGN TABLE ALTER [COLUMN] OPTIONS */ | ALTER opt_column ColId alter_generic_options { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_AlterColumnGenericOptions; n->name = $3; n->def = (Node *) $4; $$ = (Node *)n; } /* ALTER TABLE ADD CONSTRAINT ... */ | ADD_P TableConstraint { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_AddConstraint; n->def = $2; $$ = (Node *)n; } /* ALTER TABLE VALIDATE CONSTRAINT ... */ | VALIDATE CONSTRAINT name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_ValidateConstraint; n->name = $3; $$ = (Node *)n; } /* ALTER TABLE DROP CONSTRAINT IF EXISTS [RESTRICT|CASCADE] */ | DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropConstraint; n->name = $5; n->behavior = $6; n->missing_ok = TRUE; $$ = (Node *)n; } /* ALTER TABLE DROP CONSTRAINT [RESTRICT|CASCADE] */ | DROP CONSTRAINT name opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropConstraint; n->name = $3; n->behavior = $4; n->missing_ok = FALSE; $$ = (Node *)n; } /* ALTER TABLE SET WITH OIDS */ | SET WITH OIDS { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_AddOids; $$ = (Node *)n; } /* ALTER TABLE SET WITHOUT OIDS */ | SET WITHOUT OIDS { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropOids; $$ = (Node *)n; } /* ALTER TABLE CLUSTER ON */ | CLUSTER ON name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_ClusterOn; n->name = $3; $$ = (Node *)n; } /* ALTER TABLE SET WITHOUT CLUSTER */ | SET WITHOUT CLUSTER { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropCluster; n->name = NULL; $$ = (Node *)n; } /* ALTER TABLE ENABLE TRIGGER */ | ENABLE_P TRIGGER name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_EnableTrig; n->name = $3; $$ = (Node *)n; } /* ALTER TABLE ENABLE ALWAYS TRIGGER */ | ENABLE_P ALWAYS TRIGGER name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_EnableAlwaysTrig; n->name = $4; $$ = (Node *)n; } /* ALTER TABLE ENABLE REPLICA TRIGGER */ | ENABLE_P REPLICA TRIGGER name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_EnableReplicaTrig; n->name = $4; $$ = (Node *)n; } /* ALTER TABLE ENABLE TRIGGER ALL */ | ENABLE_P TRIGGER ALL { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_EnableTrigAll; $$ = (Node *)n; } /* ALTER TABLE ENABLE TRIGGER USER */ | ENABLE_P TRIGGER USER { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_EnableTrigUser; $$ = (Node *)n; } /* ALTER TABLE DISABLE TRIGGER */ | DISABLE_P TRIGGER name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DisableTrig; n->name = $3; $$ = (Node *)n; } /* ALTER TABLE DISABLE TRIGGER ALL */ | DISABLE_P TRIGGER ALL { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DisableTrigAll; $$ = (Node *)n; } /* ALTER TABLE DISABLE TRIGGER USER */ | DISABLE_P TRIGGER USER { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DisableTrigUser; $$ = (Node *)n; } /* ALTER TABLE ENABLE RULE */ | ENABLE_P RULE name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_EnableRule; n->name = $3; $$ = (Node *)n; } /* ALTER TABLE ENABLE ALWAYS RULE */ | ENABLE_P ALWAYS RULE name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_EnableAlwaysRule; n->name = $4; $$ = (Node *)n; } /* ALTER TABLE ENABLE REPLICA RULE */ | ENABLE_P REPLICA RULE name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_EnableReplicaRule; n->name = $4; $$ = (Node *)n; } /* ALTER TABLE DISABLE RULE */ | DISABLE_P RULE name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DisableRule; n->name = $3; $$ = (Node *)n; } /* ALTER TABLE INHERIT */ | INHERIT qualified_name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_AddInherit; n->def = (Node *) $2; $$ = (Node *)n; } /* ALTER TABLE NO INHERIT */ | NO INHERIT qualified_name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropInherit; n->def = (Node *) $3; $$ = (Node *)n; } /* ALTER TABLE OF */ | OF any_name { AlterTableCmd *n = makeNode(AlterTableCmd); TypeName *def = makeTypeNameFromNameList($2); def->location = @2; n->subtype = AT_AddOf; n->def = (Node *) def; $$ = (Node *)n; } /* ALTER TABLE NOT OF */ | NOT OF { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropOf; $$ = (Node *)n; } /* ALTER TABLE OWNER TO RoleId */ | OWNER TO RoleId { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_ChangeOwner; n->name = $3; $$ = (Node *)n; } /* ALTER TABLE SET TABLESPACE */ | SET TABLESPACE name { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_SetTableSpace; n->name = $3; $$ = (Node *)n; } /* ALTER TABLE SET (...) */ | SET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_SetRelOptions; n->def = (Node *)$2; $$ = (Node *)n; } /* ALTER TABLE RESET (...) */ | RESET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_ResetRelOptions; n->def = (Node *)$2; $$ = (Node *)n; } | alter_generic_options { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_GenericOptions; n->def = (Node *)$1; $$ = (Node *) n; } ; alter_column_default: SET DEFAULT a_expr { $$ = $3; } | DROP DEFAULT { $$ = NULL; } ; opt_drop_behavior: CASCADE { $$ = DROP_CASCADE; } | RESTRICT { $$ = DROP_RESTRICT; } | /* EMPTY */ { $$ = DROP_RESTRICT; /* default */ } ; opt_collate_clause: COLLATE any_name { CollateClause *n = makeNode(CollateClause); n->arg = NULL; n->collname = $2; n->location = @1; $$ = (Node *) n; } | /* EMPTY */ { $$ = NULL; } ; alter_using: USING a_expr { $$ = $2; } | /* EMPTY */ { $$ = NULL; } ; reloptions: '(' reloption_list ')' { $$ = $2; } ; opt_reloptions: WITH reloptions { $$ = $2; } | /* EMPTY */ { $$ = NIL; } ; reloption_list: reloption_elem { $$ = list_make1($1); } | reloption_list ',' reloption_elem { $$ = lappend($1, $3); } ; /* This should match def_elem and also allow qualified names */ reloption_elem: ColLabel '=' def_arg { $$ = makeDefElem($1, (Node *) $3); } | ColLabel { $$ = makeDefElem($1, NULL); } | ColLabel '.' ColLabel '=' def_arg { $$ = makeDefElemExtended($1, $3, (Node *) $5, DEFELEM_UNSPEC); } | ColLabel '.' ColLabel { $$ = makeDefElemExtended($1, $3, NULL, DEFELEM_UNSPEC); } ; /***************************************************************************** * * ALTER TYPE * * really variants of the ALTER TABLE subcommands with different spellings *****************************************************************************/ AlterCompositeTypeStmt: ALTER TYPE_P any_name alter_type_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); /* can't use qualified_name, sigh */ n->relation = makeRangeVarFromAnyName($3, @3, yyscanner); n->cmds = $4; n->relkind = OBJECT_TYPE; $$ = (Node *)n; } ; alter_type_cmds: alter_type_cmd { $$ = list_make1($1); } | alter_type_cmds ',' alter_type_cmd { $$ = lappend($1, $3); } ; alter_type_cmd: /* ALTER TYPE ADD ATTRIBUTE [RESTRICT|CASCADE] */ ADD_P ATTRIBUTE TableFuncElement opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_AddColumn; n->def = $3; n->behavior = $4; $$ = (Node *)n; } /* ALTER TYPE DROP ATTRIBUTE IF EXISTS [RESTRICT|CASCADE] */ | DROP ATTRIBUTE IF_P EXISTS ColId opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropColumn; n->name = $5; n->behavior = $6; n->missing_ok = TRUE; $$ = (Node *)n; } /* ALTER TYPE DROP ATTRIBUTE [RESTRICT|CASCADE] */ | DROP ATTRIBUTE ColId opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_DropColumn; n->name = $3; n->behavior = $4; n->missing_ok = FALSE; $$ = (Node *)n; } /* ALTER TYPE ALTER ATTRIBUTE [SET DATA] TYPE [RESTRICT|CASCADE] */ | ALTER ATTRIBUTE ColId opt_set_data TYPE_P Typename opt_collate_clause opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); ColumnDef *def = makeNode(ColumnDef); n->subtype = AT_AlterColumnType; n->name = $3; n->def = (Node *) def; n->behavior = $8; /* We only use these three fields of the ColumnDef node */ def->typeName = $6; def->collClause = (CollateClause *) $7; def->raw_default = NULL; $$ = (Node *)n; } ; /***************************************************************************** * * QUERY : * close * *****************************************************************************/ ClosePortalStmt: CLOSE cursor_name { ClosePortalStmt *n = makeNode(ClosePortalStmt); n->portalname = $2; $$ = (Node *)n; } | CLOSE ALL { ClosePortalStmt *n = makeNode(ClosePortalStmt); n->portalname = NULL; $$ = (Node *)n; } ; /***************************************************************************** * * QUERY : * COPY relname [(columnList)] FROM/TO file [WITH] [(options)] * COPY ( SELECT ... ) TO file [WITH] [(options)] * * In the preferred syntax the options are comma-separated * and use generic identifiers instead of keywords. The pre-9.0 * syntax had a hard-wired, space-separated set of options. * * Really old syntax, from versions 7.2 and prior: * COPY [ BINARY ] table [ WITH OIDS ] FROM/TO file * [ [ USING ] DELIMITERS 'delimiter' ] ] * [ WITH NULL AS 'null string' ] * This option placement is not supported with COPY (SELECT...). * *****************************************************************************/ CopyStmt: COPY opt_binary qualified_name opt_column_list opt_oids copy_from copy_file_name copy_delimiter opt_with copy_options { CopyStmt *n = makeNode(CopyStmt); n->relation = $3; n->query = NULL; n->attlist = $4; n->is_from = $6; n->filename = $7; n->options = NIL; /* Concatenate user-supplied flags */ if ($2) n->options = lappend(n->options, $2); if ($5) n->options = lappend(n->options, $5); if ($8) n->options = lappend(n->options, $8); if ($10) n->options = list_concat(n->options, $10); $$ = (Node *)n; } | COPY select_with_parens TO copy_file_name opt_with copy_options { CopyStmt *n = makeNode(CopyStmt); n->relation = NULL; n->query = $2; n->attlist = NIL; n->is_from = false; n->filename = $4; n->options = $6; $$ = (Node *)n; } ; copy_from: FROM { $$ = TRUE; } | TO { $$ = FALSE; } ; /* * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is * used depends on the direction. (It really doesn't make sense to copy from * stdout. We silently correct the "typo".) - AY 9/94 */ copy_file_name: Sconst { $$ = $1; } | STDIN { $$ = NULL; } | STDOUT { $$ = NULL; } ; copy_options: copy_opt_list { $$ = $1; } | '(' copy_generic_opt_list ')' { $$ = $2; } ; /* old COPY option syntax */ copy_opt_list: copy_opt_list copy_opt_item { $$ = lappend($1, $2); } | /* EMPTY */ { $$ = NIL; } ; copy_opt_item: BINARY { $$ = makeDefElem("format", (Node *)makeString("binary")); } | OIDS { $$ = makeDefElem("oids", (Node *)makeInteger(TRUE)); } | DELIMITER opt_as Sconst { $$ = makeDefElem("delimiter", (Node *)makeString($3)); } | NULL_P opt_as Sconst { $$ = makeDefElem("null", (Node *)makeString($3)); } | CSV { $$ = makeDefElem("format", (Node *)makeString("csv")); } | HEADER_P { $$ = makeDefElem("header", (Node *)makeInteger(TRUE)); } | QUOTE opt_as Sconst { $$ = makeDefElem("quote", (Node *)makeString($3)); } | ESCAPE opt_as Sconst { $$ = makeDefElem("escape", (Node *)makeString($3)); } | FORCE QUOTE columnList { $$ = makeDefElem("force_quote", (Node *)$3); } | FORCE QUOTE '*' { $$ = makeDefElem("force_quote", (Node *)makeNode(A_Star)); } | FORCE NOT NULL_P columnList { $$ = makeDefElem("force_not_null", (Node *)$4); } | ENCODING Sconst { $$ = makeDefElem("encoding", (Node *)makeString($2)); } ; /* The following exist for backward compatibility with very old versions */ opt_binary: BINARY { $$ = makeDefElem("format", (Node *)makeString("binary")); } | /*EMPTY*/ { $$ = NULL; } ; opt_oids: WITH OIDS { $$ = makeDefElem("oids", (Node *)makeInteger(TRUE)); } | /*EMPTY*/ { $$ = NULL; } ; copy_delimiter: opt_using DELIMITERS Sconst { $$ = makeDefElem("delimiter", (Node *)makeString($3)); } | /*EMPTY*/ { $$ = NULL; } ; opt_using: USING {} | /*EMPTY*/ {} ; /* new COPY option syntax */ copy_generic_opt_list: copy_generic_opt_elem { $$ = list_make1($1); } | copy_generic_opt_list ',' copy_generic_opt_elem { $$ = lappend($1, $3); } ; copy_generic_opt_elem: ColLabel copy_generic_opt_arg { $$ = makeDefElem($1, $2); } ; copy_generic_opt_arg: opt_boolean_or_string { $$ = (Node *) makeString($1); } | NumericOnly { $$ = (Node *) $1; } | '*' { $$ = (Node *) makeNode(A_Star); } | '(' copy_generic_opt_arg_list ')' { $$ = (Node *) $2; } | /* EMPTY */ { $$ = NULL; } ; copy_generic_opt_arg_list: copy_generic_opt_arg_list_item { $$ = list_make1($1); } | copy_generic_opt_arg_list ',' copy_generic_opt_arg_list_item { $$ = lappend($1, $3); } ; /* beware of emitting non-string list elements here; see commands/define.c */ copy_generic_opt_arg_list_item: opt_boolean_or_string { $$ = (Node *) makeString($1); } ; /***************************************************************************** * * QUERY : * CREATE TABLE relname * *****************************************************************************/ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' OptInherit OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); $4->relpersistence = $2; n->relation = $4; n->tableElts = $6; n->inhRelations = $8; n->constraints = NIL; n->options = $9; n->oncommit = $10; n->tablespacename = $11; n->if_not_exists = false; $$ = (Node *)n; } | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name '(' OptTableElementList ')' OptInherit OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); $7->relpersistence = $2; n->relation = $7; n->tableElts = $9; n->inhRelations = $11; n->constraints = NIL; n->options = $12; n->oncommit = $13; n->tablespacename = $14; n->if_not_exists = true; $$ = (Node *)n; } | CREATE OptTemp TABLE qualified_name OF any_name OptTypedTableElementList OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); $4->relpersistence = $2; n->relation = $4; n->tableElts = $7; n->ofTypename = makeTypeNameFromNameList($6); n->ofTypename->location = @6; n->constraints = NIL; n->options = $8; n->oncommit = $9; n->tablespacename = $10; n->if_not_exists = false; $$ = (Node *)n; } | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name OF any_name OptTypedTableElementList OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); $7->relpersistence = $2; n->relation = $7; n->tableElts = $10; n->ofTypename = makeTypeNameFromNameList($9); n->ofTypename->location = @9; n->constraints = NIL; n->options = $11; n->oncommit = $12; n->tablespacename = $13; n->if_not_exists = true; $$ = (Node *)n; } ; /* * Redundancy here is needed to avoid shift/reduce conflicts, * since TEMP is not a reserved word. See also OptTempTableName. * * NOTE: we accept both GLOBAL and LOCAL options. They currently do nothing, * but future versions might consider GLOBAL to request SQL-spec-compliant * temp table behavior, so warn about that. Since we have no modules the * LOCAL keyword is really meaningless; furthermore, some other products * implement LOCAL as meaning the same as our default temp table behavior, * so we'll probably continue to treat LOCAL as a noise word. */ OptTemp: TEMPORARY { $$ = RELPERSISTENCE_TEMP; } | TEMP { $$ = RELPERSISTENCE_TEMP; } | LOCAL TEMPORARY { $$ = RELPERSISTENCE_TEMP; } | LOCAL TEMP { $$ = RELPERSISTENCE_TEMP; } | GLOBAL TEMPORARY { ereport(WARNING, (errmsg("GLOBAL is deprecated in temporary table creation"), parser_errposition(@1))); $$ = RELPERSISTENCE_TEMP; } | GLOBAL TEMP { ereport(WARNING, (errmsg("GLOBAL is deprecated in temporary table creation"), parser_errposition(@1))); $$ = RELPERSISTENCE_TEMP; } | UNLOGGED { $$ = RELPERSISTENCE_UNLOGGED; } | /*EMPTY*/ { $$ = RELPERSISTENCE_PERMANENT; } ; OptTableElementList: TableElementList { $$ = $1; } | /*EMPTY*/ { $$ = NIL; } ; OptTypedTableElementList: '(' TypedTableElementList ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ; TableElementList: TableElement { $$ = list_make1($1); } | TableElementList ',' TableElement { $$ = lappend($1, $3); } ; TypedTableElementList: TypedTableElement { $$ = list_make1($1); } | TypedTableElementList ',' TypedTableElement { $$ = lappend($1, $3); } ; TableElement: columnDef { $$ = $1; } | TableLikeClause { $$ = $1; } | TableConstraint { $$ = $1; } ; TypedTableElement: columnOptions { $$ = $1; } | TableConstraint { $$ = $1; } ; columnDef: ColId Typename create_generic_options ColQualList { ColumnDef *n = makeNode(ColumnDef); n->colname = $1; n->typeName = $2; n->inhcount = 0; n->is_local = true; n->is_not_null = false; n->is_from_type = false; n->storage = 0; n->raw_default = NULL; n->cooked_default = NULL; n->collOid = InvalidOid; n->fdwoptions = $3; SplitColQualList($4, &n->constraints, &n->collClause, yyscanner); $$ = (Node *)n; } ; columnOptions: ColId WITH OPTIONS ColQualList { ColumnDef *n = makeNode(ColumnDef); n->colname = $1; n->typeName = NULL; n->inhcount = 0; n->is_local = true; n->is_not_null = false; n->is_from_type = false; n->storage = 0; n->raw_default = NULL; n->cooked_default = NULL; n->collOid = InvalidOid; SplitColQualList($4, &n->constraints, &n->collClause, yyscanner); $$ = (Node *)n; } ; ColQualList: ColQualList ColConstraint { $$ = lappend($1, $2); } | /*EMPTY*/ { $$ = NIL; } ; ColConstraint: CONSTRAINT name ColConstraintElem { Constraint *n = (Constraint *) $3; Assert(IsA(n, Constraint)); n->conname = $2; n->location = @1; $$ = (Node *) n; } | ColConstraintElem { $$ = $1; } | ConstraintAttr { $$ = $1; } | COLLATE any_name { /* * Note: the CollateClause is momentarily included in * the list built by ColQualList, but we split it out * again in SplitColQualList. */ CollateClause *n = makeNode(CollateClause); n->arg = NULL; n->collname = $2; n->location = @1; $$ = (Node *) n; } ; /* DEFAULT NULL is already the default for Postgres. * But define it here and carry it forward into the system * to make it explicit. * - thomas 1998-09-13 * * WITH NULL and NULL are not SQL92-standard syntax elements, * so leave them out. Use DEFAULT NULL to explicitly indicate * that a column may have that value. WITH NULL leads to * shift/reduce conflicts with WITH TIME ZONE anyway. * - thomas 1999-01-08 * * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce * conflict on NOT (since NOT might start a subsequent NOT NULL constraint, * or be part of a_expr NOT LIKE or similar constructs). */ ColConstraintElem: NOT NULL_P { Constraint *n = makeNode(Constraint); n->contype = CONSTR_NOTNULL; n->location = @1; $$ = (Node *)n; } | NULL_P { Constraint *n = makeNode(Constraint); n->contype = CONSTR_NULL; n->location = @1; $$ = (Node *)n; } | UNIQUE opt_definition OptConsTableSpace { Constraint *n = makeNode(Constraint); n->contype = CONSTR_UNIQUE; n->location = @1; n->keys = NULL; n->options = $2; n->indexname = NULL; n->indexspace = $3; $$ = (Node *)n; } | PRIMARY KEY opt_definition OptConsTableSpace { Constraint *n = makeNode(Constraint); n->contype = CONSTR_PRIMARY; n->location = @1; n->keys = NULL; n->options = $3; n->indexname = NULL; n->indexspace = $4; $$ = (Node *)n; } | CHECK '(' a_expr ')' opt_no_inherit { Constraint *n = makeNode(Constraint); n->contype = CONSTR_CHECK; n->location = @1; n->is_no_inherit = $5; n->raw_expr = $3; n->cooked_expr = NULL; $$ = (Node *)n; } | DEFAULT b_expr { Constraint *n = makeNode(Constraint); n->contype = CONSTR_DEFAULT; n->location = @1; n->raw_expr = $2; n->cooked_expr = NULL; $$ = (Node *)n; } | REFERENCES qualified_name opt_column_list key_match key_actions { Constraint *n = makeNode(Constraint); n->contype = CONSTR_FOREIGN; n->location = @1; n->pktable = $2; n->fk_attrs = NIL; n->pk_attrs = $3; n->fk_matchtype = $4; n->fk_upd_action = (char) ($5 >> 8); n->fk_del_action = (char) ($5 & 0xFF); n->skip_validation = false; n->initially_valid = true; $$ = (Node *)n; } ; /* * ConstraintAttr represents constraint attributes, which we parse as if * they were independent constraint clauses, in order to avoid shift/reduce * conflicts (since NOT might start either an independent NOT NULL clause * or an attribute). parse_utilcmd.c is responsible for attaching the * attribute information to the preceding "real" constraint node, and for * complaining if attribute clauses appear in the wrong place or wrong * combinations. * * See also ConstraintAttributeSpec, which can be used in places where * there is no parsing conflict. (Note: currently, NOT VALID and NO INHERIT * are allowed clauses in ConstraintAttributeSpec, but not here. Someday we * might need to allow them here too, but for the moment it doesn't seem * useful in the statements that use ConstraintAttr.) */ ConstraintAttr: DEFERRABLE { Constraint *n = makeNode(Constraint); n->contype = CONSTR_ATTR_DEFERRABLE; n->location = @1; $$ = (Node *)n; } | NOT DEFERRABLE { Constraint *n = makeNode(Constraint); n->contype = CONSTR_ATTR_NOT_DEFERRABLE; n->location = @1; $$ = (Node *)n; } | INITIALLY DEFERRED { Constraint *n = makeNode(Constraint); n->contype = CONSTR_ATTR_DEFERRED; n->location = @1; $$ = (Node *)n; } | INITIALLY IMMEDIATE { Constraint *n = makeNode(Constraint); n->contype = CONSTR_ATTR_IMMEDIATE; n->location = @1; $$ = (Node *)n; } ; TableLikeClause: LIKE qualified_name TableLikeOptionList { TableLikeClause *n = makeNode(TableLikeClause); n->relation = $2; n->options = $3; $$ = (Node *)n; } ; TableLikeOptionList: TableLikeOptionList INCLUDING TableLikeOption { $$ = $1 | $3; } | TableLikeOptionList EXCLUDING TableLikeOption { $$ = $1 & ~$3; } | /* EMPTY */ { $$ = 0; } ; TableLikeOption: DEFAULTS { $$ = CREATE_TABLE_LIKE_DEFAULTS; } | CONSTRAINTS { $$ = CREATE_TABLE_LIKE_CONSTRAINTS; } | INDEXES { $$ = CREATE_TABLE_LIKE_INDEXES; } | STORAGE { $$ = CREATE_TABLE_LIKE_STORAGE; } | COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; } | ALL { $$ = CREATE_TABLE_LIKE_ALL; } ; /* ConstraintElem specifies constraint syntax which is not embedded into * a column definition. ColConstraintElem specifies the embedded form. * - thomas 1997-12-03 */ TableConstraint: CONSTRAINT name ConstraintElem { Constraint *n = (Constraint *) $3; Assert(IsA(n, Constraint)); n->conname = $2; n->location = @1; $$ = (Node *) n; } | ConstraintElem { $$ = $1; } ; ConstraintElem: CHECK '(' a_expr ')' ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); n->contype = CONSTR_CHECK; n->location = @1; n->raw_expr = $3; n->cooked_expr = NULL; processCASbits($5, @5, "CHECK", NULL, NULL, &n->skip_validation, &n->is_no_inherit, yyscanner); n->initially_valid = !n->skip_validation; $$ = (Node *)n; } | UNIQUE '(' columnList ')' opt_definition OptConsTableSpace ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); n->contype = CONSTR_UNIQUE; n->location = @1; n->keys = $3; n->options = $5; n->indexname = NULL; n->indexspace = $6; processCASbits($7, @7, "UNIQUE", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); $$ = (Node *)n; } | UNIQUE ExistingIndex ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); n->contype = CONSTR_UNIQUE; n->location = @1; n->keys = NIL; n->options = NIL; n->indexname = $2; n->indexspace = NULL; processCASbits($3, @3, "UNIQUE", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); $$ = (Node *)n; } | PRIMARY KEY '(' columnList ')' opt_definition OptConsTableSpace ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); n->contype = CONSTR_PRIMARY; n->location = @1; n->keys = $4; n->options = $6; n->indexname = NULL; n->indexspace = $7; processCASbits($8, @8, "PRIMARY KEY", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); $$ = (Node *)n; } | PRIMARY KEY ExistingIndex ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); n->contype = CONSTR_PRIMARY; n->location = @1; n->keys = NIL; n->options = NIL; n->indexname = $3; n->indexspace = NULL; processCASbits($4, @4, "PRIMARY KEY", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); $$ = (Node *)n; } | EXCLUDE access_method_clause '(' ExclusionConstraintList ')' opt_definition OptConsTableSpace ExclusionWhereClause ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); n->contype = CONSTR_EXCLUSION; n->location = @1; n->access_method = $2; n->exclusions = $4; n->options = $6; n->indexname = NULL; n->indexspace = $7; n->where_clause = $8; processCASbits($9, @9, "EXCLUDE", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); $$ = (Node *)n; } | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list key_match key_actions ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); n->contype = CONSTR_FOREIGN; n->location = @1; n->pktable = $7; n->fk_attrs = $4; n->pk_attrs = $8; n->fk_matchtype = $9; n->fk_upd_action = (char) ($10 >> 8); n->fk_del_action = (char) ($10 & 0xFF); processCASbits($11, @11, "FOREIGN KEY", &n->deferrable, &n->initdeferred, &n->skip_validation, NULL, yyscanner); n->initially_valid = !n->skip_validation; $$ = (Node *)n; } ; opt_no_inherit: NO INHERIT { $$ = TRUE; } | /* EMPTY */ { $$ = FALSE; } ; opt_column_list: '(' columnList ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ; columnList: columnElem { $$ = list_make1($1); } | columnList ',' columnElem { $$ = lappend($1, $3); } ; columnElem: ColId { $$ = (Node *) makeString($1); } ; key_match: MATCH FULL { $$ = FKCONSTR_MATCH_FULL; } | MATCH PARTIAL { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("MATCH PARTIAL not yet implemented"), parser_errposition(@1))); $$ = FKCONSTR_MATCH_PARTIAL; } | MATCH SIMPLE { $$ = FKCONSTR_MATCH_UNSPECIFIED; } | /*EMPTY*/ { $$ = FKCONSTR_MATCH_UNSPECIFIED; } ; ExclusionConstraintList: ExclusionConstraintElem { $$ = list_make1($1); } | ExclusionConstraintList ',' ExclusionConstraintElem { $$ = lappend($1, $3); } ; ExclusionConstraintElem: index_elem WITH any_operator { $$ = list_make2($1, $3); } /* allow OPERATOR() decoration for the benefit of ruleutils.c */ | index_elem WITH OPERATOR '(' any_operator ')' { $$ = list_make2($1, $5); } ; ExclusionWhereClause: WHERE '(' a_expr ')' { $$ = $3; } | /*EMPTY*/ { $$ = NULL; } ; /* * We combine the update and delete actions into one value temporarily * for simplicity of parsing, and then break them down again in the * calling production. update is in the left 8 bits, delete in the right. * Note that NOACTION is the default. */ key_actions: key_update { $$ = ($1 << 8) | (FKCONSTR_ACTION_NOACTION & 0xFF); } | key_delete { $$ = (FKCONSTR_ACTION_NOACTION << 8) | ($1 & 0xFF); } | key_update key_delete { $$ = ($1 << 8) | ($2 & 0xFF); } | key_delete key_update { $$ = ($2 << 8) | ($1 & 0xFF); } | /*EMPTY*/ { $$ = (FKCONSTR_ACTION_NOACTION << 8) | (FKCONSTR_ACTION_NOACTION & 0xFF); } ; key_update: ON UPDATE key_action { $$ = $3; } ; key_delete: ON DELETE_P key_action { $$ = $3; } ; key_action: NO ACTION { $$ = FKCONSTR_ACTION_NOACTION; } | RESTRICT { $$ = FKCONSTR_ACTION_RESTRICT; } | CASCADE { $$ = FKCONSTR_ACTION_CASCADE; } | SET NULL_P { $$ = FKCONSTR_ACTION_SETNULL; } | SET DEFAULT { $$ = FKCONSTR_ACTION_SETDEFAULT; } ; OptInherit: INHERITS '(' qualified_name_list ')' { $$ = $3; } | /*EMPTY*/ { $$ = NIL; } ; /* WITH (options) is preferred, WITH OIDS and WITHOUT OIDS are legacy forms */ OptWith: WITH reloptions { $$ = $2; } | WITH OIDS { $$ = list_make1(defWithOids(true)); } | WITHOUT OIDS { $$ = list_make1(defWithOids(false)); } | /*EMPTY*/ { $$ = NIL; } ; OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; } | ON COMMIT DELETE_P ROWS { $$ = ONCOMMIT_DELETE_ROWS; } | ON COMMIT PRESERVE ROWS { $$ = ONCOMMIT_PRESERVE_ROWS; } | /*EMPTY*/ { $$ = ONCOMMIT_NOOP; } ; OptTableSpace: TABLESPACE name { $$ = $2; } | /*EMPTY*/ { $$ = NULL; } ; OptConsTableSpace: USING INDEX TABLESPACE name { $$ = $4; } | /*EMPTY*/ { $$ = NULL; } ; ExistingIndex: USING INDEX index_name { $$ = $3; } ; /***************************************************************************** * * QUERY : * CREATE TABLE relname AS SelectStmt [ WITH [NO] DATA ] * * * Note: SELECT ... INTO is a now-deprecated alternative for this. * *****************************************************************************/ CreateAsStmt: CREATE OptTemp TABLE create_as_target AS SelectStmt opt_with_data { CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); ctas->query = $6; ctas->into = $4; ctas->is_select_into = false; /* cram additional flags into the IntoClause */ $4->rel->relpersistence = $2; $4->skipData = !($7); $$ = (Node *) ctas; } ; create_as_target: qualified_name opt_column_list OptWith OnCommitOption OptTableSpace { $$ = makeNode(IntoClause); $$->rel = $1; $$->colNames = $2; $$->options = $3; $$->onCommit = $4; $$->tableSpaceName = $5; $$->skipData = false; /* might get changed later */ } ; opt_with_data: WITH DATA_P { $$ = TRUE; } | WITH NO DATA_P { $$ = FALSE; } | /*EMPTY*/ { $$ = TRUE; } ; /***************************************************************************** * * QUERY : * CREATE SEQUENCE seqname * ALTER SEQUENCE seqname * *****************************************************************************/ CreateSeqStmt: CREATE OptTemp SEQUENCE qualified_name OptSeqOptList { CreateSeqStmt *n = makeNode(CreateSeqStmt); $4->relpersistence = $2; n->sequence = $4; n->options = $5; n->ownerId = InvalidOid; $$ = (Node *)n; } ; AlterSeqStmt: ALTER SEQUENCE qualified_name SeqOptList { AlterSeqStmt *n = makeNode(AlterSeqStmt); n->sequence = $3; n->options = $4; n->missing_ok = false; $$ = (Node *)n; } | ALTER SEQUENCE IF_P EXISTS qualified_name SeqOptList { AlterSeqStmt *n = makeNode(AlterSeqStmt); n->sequence = $5; n->options = $6; n->missing_ok = true; $$ = (Node *)n; } ; OptSeqOptList: SeqOptList { $$ = $1; } | /*EMPTY*/ { $$ = NIL; } ; SeqOptList: SeqOptElem { $$ = list_make1($1); } | SeqOptList SeqOptElem { $$ = lappend($1, $2); } ; SeqOptElem: CACHE NumericOnly { $$ = makeDefElem("cache", (Node *)$2); } | CYCLE { $$ = makeDefElem("cycle", (Node *)makeInteger(TRUE)); } | NO CYCLE { $$ = makeDefElem("cycle", (Node *)makeInteger(FALSE)); } | INCREMENT opt_by NumericOnly { $$ = makeDefElem("increment", (Node *)$3); } | MAXVALUE NumericOnly { $$ = makeDefElem("maxvalue", (Node *)$2); } | MINVALUE NumericOnly { $$ = makeDefElem("minvalue", (Node *)$2); } | NO MAXVALUE { $$ = makeDefElem("maxvalue", NULL); } | NO MINVALUE { $$ = makeDefElem("minvalue", NULL); } | OWNED BY any_name { $$ = makeDefElem("owned_by", (Node *)$3); } | START opt_with NumericOnly { $$ = makeDefElem("start", (Node *)$3); } | RESTART { $$ = makeDefElem("restart", NULL); } | RESTART opt_with NumericOnly { $$ = makeDefElem("restart", (Node *)$3); } ; opt_by: BY {} | /* empty */ {} ; NumericOnly: FCONST { $$ = makeFloat($1); } | '-' FCONST { $$ = makeFloat($2); doNegateFloat($$); } | SignedIconst { $$ = makeInteger($1); } ; NumericOnly_list: NumericOnly { $$ = list_make1($1); } | NumericOnly_list ',' NumericOnly { $$ = lappend($1, $3); } ; /***************************************************************************** * * QUERIES : * CREATE [OR REPLACE] [TRUSTED] [PROCEDURAL] LANGUAGE ... * DROP [PROCEDURAL] LANGUAGE ... * *****************************************************************************/ CreatePLangStmt: CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE ColId_or_Sconst { CreatePLangStmt *n = makeNode(CreatePLangStmt); n->replace = $2; n->plname = $6; /* parameters are all to be supplied by system */ n->plhandler = NIL; n->plinline = NIL; n->plvalidator = NIL; n->pltrusted = false; $$ = (Node *)n; } | CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE ColId_or_Sconst HANDLER handler_name opt_inline_handler opt_validator { CreatePLangStmt *n = makeNode(CreatePLangStmt); n->replace = $2; n->plname = $6; n->plhandler = $8; n->plinline = $9; n->plvalidator = $10; n->pltrusted = $3; $$ = (Node *)n; } ; opt_trusted: TRUSTED { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; /* This ought to be just func_name, but that causes reduce/reduce conflicts * (CREATE LANGUAGE is the only place where func_name isn't followed by '('). * Work around by using simple names, instead. */ handler_name: name { $$ = list_make1(makeString($1)); } | name attrs { $$ = lcons(makeString($1), $2); } ; opt_inline_handler: INLINE_P handler_name { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ; validator_clause: VALIDATOR handler_name { $$ = $2; } | NO VALIDATOR { $$ = NIL; } ; opt_validator: validator_clause { $$ = $1; } | /*EMPTY*/ { $$ = NIL; } ; DropPLangStmt: DROP opt_procedural LANGUAGE ColId_or_Sconst opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_LANGUAGE; n->objects = list_make1(list_make1(makeString($4))); n->arguments = NIL; n->behavior = $5; n->missing_ok = false; n->concurrent = false; $$ = (Node *)n; } | DROP opt_procedural LANGUAGE IF_P EXISTS ColId_or_Sconst opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_LANGUAGE; n->objects = list_make1(list_make1(makeString($6))); n->behavior = $7; n->missing_ok = true; n->concurrent = false; $$ = (Node *)n; } ; opt_procedural: PROCEDURAL {} | /*EMPTY*/ {} ; /***************************************************************************** * * QUERY: * CREATE TABLESPACE tablespace LOCATION '/path/to/tablespace/' * *****************************************************************************/ CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst { CreateTableSpaceStmt *n = makeNode(CreateTableSpaceStmt); n->tablespacename = $3; n->owner = $4; n->location = $6; $$ = (Node *) n; } ; OptTableSpaceOwner: OWNER name { $$ = $2; } | /*EMPTY */ { $$ = NULL; } ; /***************************************************************************** * * QUERY : * DROP TABLESPACE * * No need for drop behaviour as we cannot implement dependencies for * objects in other databases; we can only support RESTRICT. * ****************************************************************************/ DropTableSpaceStmt: DROP TABLESPACE name { DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt); n->tablespacename = $3; n->missing_ok = false; $$ = (Node *) n; } | DROP TABLESPACE IF_P EXISTS name { DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt); n->tablespacename = $5; n->missing_ok = true; $$ = (Node *) n; } ; /***************************************************************************** * * QUERY: * CREATE EXTENSION extension * [ WITH ] [ SCHEMA schema ] [ VERSION version ] [ FROM oldversion ] * *****************************************************************************/ CreateExtensionStmt: CREATE EXTENSION name opt_with create_extension_opt_list { CreateExtensionStmt *n = makeNode(CreateExtensionStmt); n->extname = $3; n->if_not_exists = false; n->options = $5; $$ = (Node *) n; } | CREATE EXTENSION IF_P NOT EXISTS name opt_with create_extension_opt_list { CreateExtensionStmt *n = makeNode(CreateExtensionStmt); n->extname = $6; n->if_not_exists = true; n->options = $8; $$ = (Node *) n; } ; create_extension_opt_list: create_extension_opt_list create_extension_opt_item { $$ = lappend($1, $2); } | /* EMPTY */ { $$ = NIL; } ; create_extension_opt_item: SCHEMA name { $$ = makeDefElem("schema", (Node *)makeString($2)); } | VERSION_P ColId_or_Sconst { $$ = makeDefElem("new_version", (Node *)makeString($2)); } | FROM ColId_or_Sconst { $$ = makeDefElem("old_version", (Node *)makeString($2)); } ; /***************************************************************************** * * ALTER EXTENSION name UPDATE [ TO version ] * *****************************************************************************/ AlterExtensionStmt: ALTER EXTENSION name UPDATE alter_extension_opt_list { AlterExtensionStmt *n = makeNode(AlterExtensionStmt); n->extname = $3; n->options = $5; $$ = (Node *) n; } ; alter_extension_opt_list: alter_extension_opt_list alter_extension_opt_item { $$ = lappend($1, $2); } | /* EMPTY */ { $$ = NIL; } ; alter_extension_opt_item: TO ColId_or_Sconst { $$ = makeDefElem("new_version", (Node *)makeString($2)); } ; /***************************************************************************** * * ALTER EXTENSION name ADD/DROP object-identifier * *****************************************************************************/ AlterExtensionContentsStmt: ALTER EXTENSION name add_drop AGGREGATE func_name aggr_args { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_AGGREGATE; n->objname = $6; n->objargs = $7; $$ = (Node *)n; } | ALTER EXTENSION name add_drop CAST '(' Typename AS Typename ')' { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_CAST; n->objname = list_make1($7); n->objargs = list_make1($9); $$ = (Node *) n; } | ALTER EXTENSION name add_drop COLLATION any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_COLLATION; n->objname = $6; $$ = (Node *)n; } | ALTER EXTENSION name add_drop CONVERSION_P any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_CONVERSION; n->objname = $6; $$ = (Node *)n; } | ALTER EXTENSION name add_drop DOMAIN_P any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_DOMAIN; n->objname = $6; $$ = (Node *)n; } | ALTER EXTENSION name add_drop FUNCTION function_with_argtypes { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_FUNCTION; n->objname = $6->funcname; n->objargs = $6->funcargs; $$ = (Node *)n; } | ALTER EXTENSION name add_drop opt_procedural LANGUAGE name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_LANGUAGE; n->objname = list_make1(makeString($7)); $$ = (Node *)n; } | ALTER EXTENSION name add_drop OPERATOR any_operator oper_argtypes { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_OPERATOR; n->objname = $6; n->objargs = $7; $$ = (Node *)n; } | ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING access_method { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_OPCLASS; n->objname = $7; n->objargs = list_make1(makeString($9)); $$ = (Node *)n; } | ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING access_method { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_OPFAMILY; n->objname = $7; n->objargs = list_make1(makeString($9)); $$ = (Node *)n; } | ALTER EXTENSION name add_drop SCHEMA name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_SCHEMA; n->objname = list_make1(makeString($6)); $$ = (Node *)n; } | ALTER EXTENSION name add_drop TABLE any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_TABLE; n->objname = $6; $$ = (Node *)n; } | ALTER EXTENSION name add_drop TEXT_P SEARCH PARSER any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_TSPARSER; n->objname = $8; $$ = (Node *)n; } | ALTER EXTENSION name add_drop TEXT_P SEARCH DICTIONARY any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_TSDICTIONARY; n->objname = $8; $$ = (Node *)n; } | ALTER EXTENSION name add_drop TEXT_P SEARCH TEMPLATE any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_TSTEMPLATE; n->objname = $8; $$ = (Node *)n; } | ALTER EXTENSION name add_drop TEXT_P SEARCH CONFIGURATION any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_TSCONFIGURATION; n->objname = $8; $$ = (Node *)n; } | ALTER EXTENSION name add_drop SEQUENCE any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_SEQUENCE; n->objname = $6; $$ = (Node *)n; } | ALTER EXTENSION name add_drop VIEW any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_VIEW; n->objname = $6; $$ = (Node *)n; } | ALTER EXTENSION name add_drop FOREIGN TABLE any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_FOREIGN_TABLE; n->objname = $7; $$ = (Node *)n; } | ALTER EXTENSION name add_drop FOREIGN DATA_P WRAPPER name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_FDW; n->objname = list_make1(makeString($8)); $$ = (Node *)n; } | ALTER EXTENSION name add_drop SERVER name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_FOREIGN_SERVER; n->objname = list_make1(makeString($6)); $$ = (Node *)n; } | ALTER EXTENSION name add_drop TYPE_P any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); n->extname = $3; n->action = $4; n->objtype = OBJECT_TYPE; n->objname = $6; $$ = (Node *)n; } ; /***************************************************************************** * * QUERY: * CREATE FOREIGN DATA WRAPPER name options * *****************************************************************************/ CreateFdwStmt: CREATE FOREIGN DATA_P WRAPPER name opt_fdw_options create_generic_options { CreateFdwStmt *n = makeNode(CreateFdwStmt); n->fdwname = $5; n->func_options = $6; n->options = $7; $$ = (Node *) n; } ; fdw_option: HANDLER handler_name { $$ = makeDefElem("handler", (Node *)$2); } | NO HANDLER { $$ = makeDefElem("handler", NULL); } | VALIDATOR handler_name { $$ = makeDefElem("validator", (Node *)$2); } | NO VALIDATOR { $$ = makeDefElem("validator", NULL); } ; fdw_options: fdw_option { $$ = list_make1($1); } | fdw_options fdw_option { $$ = lappend($1, $2); } ; opt_fdw_options: fdw_options { $$ = $1; } | /*EMPTY*/ { $$ = NIL; } ; /***************************************************************************** * * QUERY : * DROP FOREIGN DATA WRAPPER name * ****************************************************************************/ DropFdwStmt: DROP FOREIGN DATA_P WRAPPER name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_FDW; n->objects = list_make1(list_make1(makeString($5))); n->arguments = NIL; n->missing_ok = false; n->behavior = $6; n->concurrent = false; $$ = (Node *) n; } | DROP FOREIGN DATA_P WRAPPER IF_P EXISTS name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_FDW; n->objects = list_make1(list_make1(makeString($7))); n->arguments = NIL; n->missing_ok = true; n->behavior = $8; n->concurrent = false; $$ = (Node *) n; } ; /***************************************************************************** * * QUERY : * ALTER FOREIGN DATA WRAPPER name options * ****************************************************************************/ AlterFdwStmt: ALTER FOREIGN DATA_P WRAPPER name opt_fdw_options alter_generic_options { AlterFdwStmt *n = makeNode(AlterFdwStmt); n->fdwname = $5; n->func_options = $6; n->options = $7; $$ = (Node *) n; } | ALTER FOREIGN DATA_P WRAPPER name fdw_options { AlterFdwStmt *n = makeNode(AlterFdwStmt); n->fdwname = $5; n->func_options = $6; n->options = NIL; $$ = (Node *) n; } ; /* Options definition for CREATE FDW, SERVER and USER MAPPING */ create_generic_options: OPTIONS '(' generic_option_list ')' { $$ = $3; } | /*EMPTY*/ { $$ = NIL; } ; generic_option_list: generic_option_elem { $$ = list_make1($1); } | generic_option_list ',' generic_option_elem { $$ = lappend($1, $3); } ; /* Options definition for ALTER FDW, SERVER and USER MAPPING */ alter_generic_options: OPTIONS '(' alter_generic_option_list ')' { $$ = $3; } ; alter_generic_option_list: alter_generic_option_elem { $$ = list_make1($1); } | alter_generic_option_list ',' alter_generic_option_elem { $$ = lappend($1, $3); } ; alter_generic_option_elem: generic_option_elem { $$ = $1; } | SET generic_option_elem { $$ = $2; $$->defaction = DEFELEM_SET; } | ADD_P generic_option_elem { $$ = $2; $$->defaction = DEFELEM_ADD; } | DROP generic_option_name { $$ = makeDefElemExtended(NULL, $2, NULL, DEFELEM_DROP); } ; generic_option_elem: generic_option_name generic_option_arg { $$ = makeDefElem($1, $2); } ; generic_option_name: ColLabel { $$ = $1; } ; /* We could use def_arg here, but the spec only requires string literals */ generic_option_arg: Sconst { $$ = (Node *) makeString($1); } ; /***************************************************************************** * * QUERY: * CREATE SERVER name [TYPE] [VERSION] [OPTIONS] * *****************************************************************************/ CreateForeignServerStmt: CREATE SERVER name opt_type opt_foreign_server_version FOREIGN DATA_P WRAPPER name create_generic_options { CreateForeignServerStmt *n = makeNode(CreateForeignServerStmt); n->servername = $3; n->servertype = $4; n->version = $5; n->fdwname = $9; n->options = $10; $$ = (Node *) n; } ; opt_type: TYPE_P Sconst { $$ = $2; } | /*EMPTY*/ { $$ = NULL; } ; foreign_server_version: VERSION_P Sconst { $$ = $2; } | VERSION_P NULL_P { $$ = NULL; } ; opt_foreign_server_version: foreign_server_version { $$ = $1; } | /*EMPTY*/ { $$ = NULL; } ; /***************************************************************************** * * QUERY : * DROP SERVER name * ****************************************************************************/ DropForeignServerStmt: DROP SERVER name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_FOREIGN_SERVER; n->objects = list_make1(list_make1(makeString($3))); n->arguments = NIL; n->missing_ok = false; n->behavior = $4; n->concurrent = false; $$ = (Node *) n; } | DROP SERVER IF_P EXISTS name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_FOREIGN_SERVER; n->objects = list_make1(list_make1(makeString($5))); n->arguments = NIL; n->missing_ok = true; n->behavior = $6; n->concurrent = false; $$ = (Node *) n; } ; /***************************************************************************** * * QUERY : * ALTER SERVER name [VERSION] [OPTIONS] * ****************************************************************************/ AlterForeignServerStmt: ALTER SERVER name foreign_server_version alter_generic_options { AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); n->servername = $3; n->version = $4; n->options = $5; n->has_version = true; $$ = (Node *) n; } | ALTER SERVER name foreign_server_version { AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); n->servername = $3; n->version = $4; n->has_version = true; $$ = (Node *) n; } | ALTER SERVER name alter_generic_options { AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); n->servername = $3; n->options = $4; $$ = (Node *) n; } ; /***************************************************************************** * * QUERY: * CREATE FOREIGN TABLE relname (...) SERVER name (...) * *****************************************************************************/ CreateForeignTableStmt: CREATE FOREIGN TABLE qualified_name OptForeignTableElementList SERVER name create_generic_options { CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); $4->relpersistence = RELPERSISTENCE_PERMANENT; n->base.relation = $4; n->base.tableElts = $5; n->base.inhRelations = NIL; n->base.if_not_exists = false; /* FDW-specific data */ n->servername = $7; n->options = $8; $$ = (Node *) n; } | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name OptForeignTableElementList SERVER name create_generic_options { CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); $7->relpersistence = RELPERSISTENCE_PERMANENT; n->base.relation = $7; n->base.tableElts = $8; n->base.inhRelations = NIL; n->base.if_not_exists = true; /* FDW-specific data */ n->servername = $10; n->options = $11; $$ = (Node *) n; } ; OptForeignTableElementList: '(' ForeignTableElementList ')' { $$ = $2; } | '(' ')' { $$ = NIL; } ; ForeignTableElementList: ForeignTableElement { $$ = list_make1($1); } | ForeignTableElementList ',' ForeignTableElement { $$ = lappend($1, $3); } ; ForeignTableElement: columnDef { $$ = $1; } ; /***************************************************************************** * * QUERY: * ALTER FOREIGN TABLE relname [...] * *****************************************************************************/ AlterForeignTableStmt: ALTER FOREIGN TABLE relation_expr alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); n->relation = $4; n->cmds = $5; n->relkind = OBJECT_FOREIGN_TABLE; n->missing_ok = false; $$ = (Node *)n; } | ALTER FOREIGN TABLE IF_P EXISTS relation_expr alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); n->relation = $6; n->cmds = $7; n->relkind = OBJECT_FOREIGN_TABLE; n->missing_ok = true; $$ = (Node *)n; } ; /***************************************************************************** * * QUERY: * CREATE USER MAPPING FOR auth_ident SERVER name [OPTIONS] * *****************************************************************************/ CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_generic_options { CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt); n->username = $5; n->servername = $7; n->options = $8; $$ = (Node *) n; } ; /* User mapping authorization identifier */ auth_ident: CURRENT_USER { $$ = "current_user"; } | USER { $$ = "current_user"; } | RoleId { $$ = (strcmp($1, "public") == 0) ? NULL : $1; } ; /***************************************************************************** * * QUERY : * DROP USER MAPPING FOR auth_ident SERVER name * ****************************************************************************/ DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name { DropUserMappingStmt *n = makeNode(DropUserMappingStmt); n->username = $5; n->servername = $7; n->missing_ok = false; $$ = (Node *) n; } | DROP USER MAPPING IF_P EXISTS FOR auth_ident SERVER name { DropUserMappingStmt *n = makeNode(DropUserMappingStmt); n->username = $7; n->servername = $9; n->missing_ok = true; $$ = (Node *) n; } ; /***************************************************************************** * * QUERY : * ALTER USER MAPPING FOR auth_ident SERVER name OPTIONS * ****************************************************************************/ AlterUserMappingStmt: ALTER USER MAPPING FOR auth_ident SERVER name alter_generic_options { AlterUserMappingStmt *n = makeNode(AlterUserMappingStmt); n->username = $5; n->servername = $7; n->options = $8; $$ = (Node *) n; } ; /***************************************************************************** * * QUERIES : * CREATE TRIGGER ... * DROP TRIGGER ... * *****************************************************************************/ CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON qualified_name TriggerForSpec TriggerWhen EXECUTE PROCEDURE func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); n->trigname = $3; n->relation = $7; n->funcname = $12; n->args = $14; n->row = $8; n->timing = $4; n->events = intVal(linitial($5)); n->columns = (List *) lsecond($5); n->whenClause = $9; n->isconstraint = FALSE; n->deferrable = FALSE; n->initdeferred = FALSE; n->constrrel = NULL; $$ = (Node *)n; } | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON qualified_name OptConstrFromTable ConstraintAttributeSpec FOR EACH ROW TriggerWhen EXECUTE PROCEDURE func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); n->trigname = $4; n->relation = $8; n->funcname = $17; n->args = $19; n->row = TRUE; n->timing = TRIGGER_TYPE_AFTER; n->events = intVal(linitial($6)); n->columns = (List *) lsecond($6); n->whenClause = $14; n->isconstraint = TRUE; processCASbits($10, @10, "TRIGGER", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); n->constrrel = $9; $$ = (Node *)n; } ; TriggerActionTime: BEFORE { $$ = TRIGGER_TYPE_BEFORE; } | AFTER { $$ = TRIGGER_TYPE_AFTER; } | INSTEAD OF { $$ = TRIGGER_TYPE_INSTEAD; } ; TriggerEvents: TriggerOneEvent { $$ = $1; } | TriggerEvents OR TriggerOneEvent { int events1 = intVal(linitial($1)); int events2 = intVal(linitial($3)); List *columns1 = (List *) lsecond($1); List *columns2 = (List *) lsecond($3); if (events1 & events2) parser_yyerror("duplicate trigger events specified"); /* * concat'ing the columns lists loses information about * which columns went with which event, but so long as * only UPDATE carries columns and we disallow multiple * UPDATE items, it doesn't matter. Command execution * should just ignore the columns for non-UPDATE events. */ $$ = list_make2(makeInteger(events1 | events2), list_concat(columns1, columns2)); } ; TriggerOneEvent: INSERT { $$ = list_make2(makeInteger(TRIGGER_TYPE_INSERT), NIL); } | DELETE_P { $$ = list_make2(makeInteger(TRIGGER_TYPE_DELETE), NIL); } | UPDATE { $$ = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), NIL); } | UPDATE OF columnList { $$ = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), $3); } | TRUNCATE { $$ = list_make2(makeInteger(TRIGGER_TYPE_TRUNCATE), NIL); } ; TriggerForSpec: FOR TriggerForOptEach TriggerForType { $$ = $3; } | /* EMPTY */ { /* * If ROW/STATEMENT not specified, default to * STATEMENT, per SQL */ $$ = FALSE; } ; TriggerForOptEach: EACH {} | /*EMPTY*/ {} ; TriggerForType: ROW { $$ = TRUE; } | STATEMENT { $$ = FALSE; } ; TriggerWhen: WHEN '(' a_expr ')' { $$ = $3; } | /*EMPTY*/ { $$ = NULL; } ; TriggerFuncArgs: TriggerFuncArg { $$ = list_make1($1); } | TriggerFuncArgs ',' TriggerFuncArg { $$ = lappend($1, $3); } | /*EMPTY*/ { $$ = NIL; } ; TriggerFuncArg: Iconst { char buf[64]; snprintf(buf, sizeof(buf), "%d", $1); $$ = makeString(pstrdup(buf)); } | FCONST { $$ = makeString($1); } | Sconst { $$ = makeString($1); } | ColLabel { $$ = makeString($1); } ; OptConstrFromTable: FROM qualified_name { $$ = $2; } | /*EMPTY*/ { $$ = NULL; } ; ConstraintAttributeSpec: /*EMPTY*/ { $$ = 0; } | ConstraintAttributeSpec ConstraintAttributeElem { /* * We must complain about conflicting options. * We could, but choose not to, complain about redundant * options (ie, where $2's bit is already set in $1). */ int newspec = $1 | $2; /* special message for this case */ if ((newspec & (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED)) == (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED)) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"), parser_errposition(@2))); /* generic message for other conflicts */ if ((newspec & (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE)) == (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE) || (newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting constraint properties"), parser_errposition(@2))); $$ = newspec; } ; ConstraintAttributeElem: NOT DEFERRABLE { $$ = CAS_NOT_DEFERRABLE; } | DEFERRABLE { $$ = CAS_DEFERRABLE; } | INITIALLY IMMEDIATE { $$ = CAS_INITIALLY_IMMEDIATE; } | INITIALLY DEFERRED { $$ = CAS_INITIALLY_DEFERRED; } | NOT VALID { $$ = CAS_NOT_VALID; } | NO INHERIT { $$ = CAS_NO_INHERIT; } ; DropTrigStmt: DROP TRIGGER name ON any_name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_TRIGGER; n->objects = list_make1(lappend($5, makeString($3))); n->arguments = NIL; n->behavior = $6; n->missing_ok = false; n->concurrent = false; $$ = (Node *) n; } | DROP TRIGGER IF_P EXISTS name ON any_name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_TRIGGER; n->objects = list_make1(lappend($7, makeString($5))); n->arguments = NIL; n->behavior = $8; n->missing_ok = true; n->concurrent = false; $$ = (Node *) n; } ; /***************************************************************************** * * QUERIES : * CREATE ASSERTION ... * DROP ASSERTION ... * *****************************************************************************/ CreateAssertStmt: CREATE ASSERTION name CHECK '(' a_expr ')' ConstraintAttributeSpec { CreateTrigStmt *n = makeNode(CreateTrigStmt); n->trigname = $3; n->args = list_make1($6); n->isconstraint = TRUE; processCASbits($8, @8, "ASSERTION", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("CREATE ASSERTION is not yet implemented"))); $$ = (Node *)n; } ; DropAssertStmt: DROP ASSERTION name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->objects = NIL; n->arguments = NIL; n->behavior = $4; n->removeType = OBJECT_TRIGGER; /* XXX */ ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("DROP ASSERTION is not yet implemented"))); $$ = (Node *) n; } ; /***************************************************************************** * * QUERY : * define (aggregate,operator,type) * *****************************************************************************/ DefineStmt: CREATE AGGREGATE func_name aggr_args definition { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_AGGREGATE; n->oldstyle = false; n->defnames = $3; n->args = $4; n->definition = $5; $$ = (Node *)n; } | CREATE AGGREGATE func_name old_aggr_definition { /* old-style (pre-8.2) syntax for CREATE AGGREGATE */ DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_AGGREGATE; n->oldstyle = true; n->defnames = $3; n->args = NIL; n->definition = $4; $$ = (Node *)n; } | CREATE OPERATOR any_operator definition { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_OPERATOR; n->oldstyle = false; n->defnames = $3; n->args = NIL; n->definition = $4; $$ = (Node *)n; } | CREATE TYPE_P any_name definition { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_TYPE; n->oldstyle = false; n->defnames = $3; n->args = NIL; n->definition = $4; $$ = (Node *)n; } | CREATE TYPE_P any_name { /* Shell type (identified by lack of definition) */ DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_TYPE; n->oldstyle = false; n->defnames = $3; n->args = NIL; n->definition = NIL; $$ = (Node *)n; } | CREATE TYPE_P any_name AS '(' OptTableFuncElementList ')' { CompositeTypeStmt *n = makeNode(CompositeTypeStmt); /* can't use qualified_name, sigh */ n->typevar = makeRangeVarFromAnyName($3, @3, yyscanner); n->coldeflist = $6; $$ = (Node *)n; } | CREATE TYPE_P any_name AS ENUM_P '(' opt_enum_val_list ')' { CreateEnumStmt *n = makeNode(CreateEnumStmt); n->typeName = $3; n->vals = $7; $$ = (Node *)n; } | CREATE TYPE_P any_name AS RANGE definition { CreateRangeStmt *n = makeNode(CreateRangeStmt); n->typeName = $3; n->params = $6; $$ = (Node *)n; } | CREATE TEXT_P SEARCH PARSER any_name definition { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_TSPARSER; n->args = NIL; n->defnames = $5; n->definition = $6; $$ = (Node *)n; } | CREATE TEXT_P SEARCH DICTIONARY any_name definition { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_TSDICTIONARY; n->args = NIL; n->defnames = $5; n->definition = $6; $$ = (Node *)n; } | CREATE TEXT_P SEARCH TEMPLATE any_name definition { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_TSTEMPLATE; n->args = NIL; n->defnames = $5; n->definition = $6; $$ = (Node *)n; } | CREATE TEXT_P SEARCH CONFIGURATION any_name definition { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_TSCONFIGURATION; n->args = NIL; n->defnames = $5; n->definition = $6; $$ = (Node *)n; } | CREATE COLLATION any_name definition { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_COLLATION; n->args = NIL; n->defnames = $3; n->definition = $4; $$ = (Node *)n; } | CREATE COLLATION any_name FROM any_name { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_COLLATION; n->args = NIL; n->defnames = $3; n->definition = list_make1(makeDefElem("from", (Node *) $5)); $$ = (Node *)n; } ; definition: '(' def_list ')' { $$ = $2; } ; def_list: def_elem { $$ = list_make1($1); } | def_list ',' def_elem { $$ = lappend($1, $3); } ; def_elem: ColLabel '=' def_arg { $$ = makeDefElem($1, (Node *) $3); } | ColLabel { $$ = makeDefElem($1, NULL); } ; /* Note: any simple identifier will be returned as a type name! */ def_arg: func_type { $$ = (Node *)$1; } | reserved_keyword { $$ = (Node *)makeString(pstrdup($1)); } | qual_all_Op { $$ = (Node *)$1; } | NumericOnly { $$ = (Node *)$1; } | Sconst { $$ = (Node *)makeString($1); } ; aggr_args: '(' type_list ')' { $$ = $2; } | '(' '*' ')' { $$ = NIL; } ; old_aggr_definition: '(' old_aggr_list ')' { $$ = $2; } ; old_aggr_list: old_aggr_elem { $$ = list_make1($1); } | old_aggr_list ',' old_aggr_elem { $$ = lappend($1, $3); } ; /* * Must use IDENT here to avoid reduce/reduce conflicts; fortunately none of * the item names needed in old aggregate definitions are likely to become * SQL keywords. */ old_aggr_elem: IDENT '=' def_arg { $$ = makeDefElem($1, (Node *)$3); } ; opt_enum_val_list: enum_val_list { $$ = $1; } | /*EMPTY*/ { $$ = NIL; } ; enum_val_list: Sconst { $$ = list_make1(makeString($1)); } | enum_val_list ',' Sconst { $$ = lappend($1, makeString($3)); } ; /***************************************************************************** * * ALTER TYPE enumtype ADD ... * *****************************************************************************/ AlterEnumStmt: ALTER TYPE_P any_name ADD_P VALUE_P Sconst { AlterEnumStmt *n = makeNode(AlterEnumStmt); n->typeName = $3; n->newVal = $6; n->newValNeighbor = NULL; n->newValIsAfter = true; $$ = (Node *) n; } | ALTER TYPE_P any_name ADD_P VALUE_P Sconst BEFORE Sconst { AlterEnumStmt *n = makeNode(AlterEnumStmt); n->typeName = $3; n->newVal = $6; n->newValNeighbor = $8; n->newValIsAfter = false; $$ = (Node *) n; } | ALTER TYPE_P any_name ADD_P VALUE_P Sconst AFTER Sconst { AlterEnumStmt *n = makeNode(AlterEnumStmt); n->typeName = $3; n->newVal = $6; n->newValNeighbor = $8; n->newValIsAfter = true; $$ = (Node *) n; } ; /***************************************************************************** * * QUERIES : * CREATE OPERATOR CLASS ... * CREATE OPERATOR FAMILY ... * ALTER OPERATOR FAMILY ... * DROP OPERATOR CLASS ... * DROP OPERATOR FAMILY ... * *****************************************************************************/ CreateOpClassStmt: CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename USING access_method opt_opfamily AS opclass_item_list { CreateOpClassStmt *n = makeNode(CreateOpClassStmt); n->opclassname = $4; n->isDefault = $5; n->datatype = $8; n->amname = $10; n->opfamilyname = $11; n->items = $13; $$ = (Node *) n; } ; opclass_item_list: opclass_item { $$ = list_make1($1); } | opclass_item_list ',' opclass_item { $$ = lappend($1, $3); } ; opclass_item: OPERATOR Iconst any_operator opclass_purpose opt_recheck { CreateOpClassItem *n = makeNode(CreateOpClassItem); n->itemtype = OPCLASS_ITEM_OPERATOR; n->name = $3; n->args = NIL; n->number = $2; n->order_family = $4; $$ = (Node *) n; } | OPERATOR Iconst any_operator oper_argtypes opclass_purpose opt_recheck { CreateOpClassItem *n = makeNode(CreateOpClassItem); n->itemtype = OPCLASS_ITEM_OPERATOR; n->name = $3; n->args = $4; n->number = $2; n->order_family = $5; $$ = (Node *) n; } | FUNCTION Iconst func_name func_args { CreateOpClassItem *n = makeNode(CreateOpClassItem); n->itemtype = OPCLASS_ITEM_FUNCTION; n->name = $3; n->args = extractArgTypes($4); n->number = $2; $$ = (Node *) n; } | FUNCTION Iconst '(' type_list ')' func_name func_args { CreateOpClassItem *n = makeNode(CreateOpClassItem); n->itemtype = OPCLASS_ITEM_FUNCTION; n->name = $6; n->args = extractArgTypes($7); n->number = $2; n->class_args = $4; $$ = (Node *) n; } | STORAGE Typename { CreateOpClassItem *n = makeNode(CreateOpClassItem); n->itemtype = OPCLASS_ITEM_STORAGETYPE; n->storedtype = $2; $$ = (Node *) n; } ; opt_default: DEFAULT { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; opt_opfamily: FAMILY any_name { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ; opclass_purpose: FOR SEARCH { $$ = NIL; } | FOR ORDER BY any_name { $$ = $4; } | /*EMPTY*/ { $$ = NIL; } ; opt_recheck: RECHECK { /* * RECHECK no longer does anything in opclass definitions, * but we still accept it to ease porting of old database * dumps. */ ereport(NOTICE, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("RECHECK is no longer required"), errhint("Update your data type."), parser_errposition(@1))); $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; CreateOpFamilyStmt: CREATE OPERATOR FAMILY any_name USING access_method { CreateOpFamilyStmt *n = makeNode(CreateOpFamilyStmt); n->opfamilyname = $4; n->amname = $6; $$ = (Node *) n; } ; AlterOpFamilyStmt: ALTER OPERATOR FAMILY any_name USING access_method ADD_P opclass_item_list { AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt); n->opfamilyname = $4; n->amname = $6; n->isDrop = false; n->items = $8; $$ = (Node *) n; } | ALTER OPERATOR FAMILY any_name USING access_method DROP opclass_drop_list { AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt); n->opfamilyname = $4; n->amname = $6; n->isDrop = true; n->items = $8; $$ = (Node *) n; } ; opclass_drop_list: opclass_drop { $$ = list_make1($1); } | opclass_drop_list ',' opclass_drop { $$ = lappend($1, $3); } ; opclass_drop: OPERATOR Iconst '(' type_list ')' { CreateOpClassItem *n = makeNode(CreateOpClassItem); n->itemtype = OPCLASS_ITEM_OPERATOR; n->number = $2; n->args = $4; $$ = (Node *) n; } | FUNCTION Iconst '(' type_list ')' { CreateOpClassItem *n = makeNode(CreateOpClassItem); n->itemtype = OPCLASS_ITEM_FUNCTION; n->number = $2; n->args = $4; $$ = (Node *) n; } ; DropOpClassStmt: DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->objects = list_make1($4); n->arguments = list_make1(list_make1(makeString($6))); n->removeType = OBJECT_OPCLASS; n->behavior = $7; n->missing_ok = false; n->concurrent = false; $$ = (Node *) n; } | DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->objects = list_make1($6); n->arguments = list_make1(list_make1(makeString($8))); n->removeType = OBJECT_OPCLASS; n->behavior = $9; n->missing_ok = true; n->concurrent = false; $$ = (Node *) n; } ; DropOpFamilyStmt: DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->objects = list_make1($4); n->arguments = list_make1(list_make1(makeString($6))); n->removeType = OBJECT_OPFAMILY; n->behavior = $7; n->missing_ok = false; n->concurrent = false; $$ = (Node *) n; } | DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->objects = list_make1($6); n->arguments = list_make1(list_make1(makeString($8))); n->removeType = OBJECT_OPFAMILY; n->behavior = $9; n->missing_ok = true; n->concurrent = false; $$ = (Node *) n; } ; /***************************************************************************** * * QUERY: * * DROP OWNED BY username [, username ...] [ RESTRICT | CASCADE ] * REASSIGN OWNED BY username [, username ...] TO username * *****************************************************************************/ DropOwnedStmt: DROP OWNED BY name_list opt_drop_behavior { DropOwnedStmt *n = makeNode(DropOwnedStmt); n->roles = $4; n->behavior = $5; $$ = (Node *)n; } ; ReassignOwnedStmt: REASSIGN OWNED BY name_list TO name { ReassignOwnedStmt *n = makeNode(ReassignOwnedStmt); n->roles = $4; n->newrole = $6; $$ = (Node *)n; } ; /***************************************************************************** * * QUERY: * * DROP itemtype [ IF EXISTS ] itemname [, itemname ...] * [ RESTRICT | CASCADE ] * *****************************************************************************/ DropStmt: DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = $2; n->missing_ok = TRUE; n->objects = $5; n->arguments = NIL; n->behavior = $6; n->concurrent = false; $$ = (Node *)n; } | DROP drop_type any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = $2; n->missing_ok = FALSE; n->objects = $3; n->arguments = NIL; n->behavior = $4; n->concurrent = false; $$ = (Node *)n; } | DROP INDEX CONCURRENTLY any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_INDEX; n->missing_ok = FALSE; n->objects = $4; n->arguments = NIL; n->behavior = $5; n->concurrent = true; $$ = (Node *)n; } | DROP INDEX CONCURRENTLY IF_P EXISTS any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_INDEX; n->missing_ok = TRUE; n->objects = $6; n->arguments = NIL; n->behavior = $7; n->concurrent = true; $$ = (Node *)n; } ; drop_type: TABLE { $$ = OBJECT_TABLE; } | SEQUENCE { $$ = OBJECT_SEQUENCE; } | VIEW { $$ = OBJECT_VIEW; } | INDEX { $$ = OBJECT_INDEX; } | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } | TYPE_P { $$ = OBJECT_TYPE; } | DOMAIN_P { $$ = OBJECT_DOMAIN; } | COLLATION { $$ = OBJECT_COLLATION; } | CONVERSION_P { $$ = OBJECT_CONVERSION; } | SCHEMA { $$ = OBJECT_SCHEMA; } | EXTENSION { $$ = OBJECT_EXTENSION; } | TEXT_P SEARCH PARSER { $$ = OBJECT_TSPARSER; } | TEXT_P SEARCH DICTIONARY { $$ = OBJECT_TSDICTIONARY; } | TEXT_P SEARCH TEMPLATE { $$ = OBJECT_TSTEMPLATE; } | TEXT_P SEARCH CONFIGURATION { $$ = OBJECT_TSCONFIGURATION; } ; any_name_list: any_name { $$ = list_make1($1); } | any_name_list ',' any_name { $$ = lappend($1, $3); } ; any_name: ColId { $$ = list_make1(makeString($1)); } | ColId attrs { $$ = lcons(makeString($1), $2); } ; attrs: '.' attr_name { $$ = list_make1(makeString($2)); } | attrs '.' attr_name { $$ = lappend($1, makeString($3)); } ; /***************************************************************************** * * QUERY: * truncate table relname1, relname2, ... * *****************************************************************************/ TruncateStmt: TRUNCATE opt_table relation_expr_list opt_restart_seqs opt_drop_behavior { TruncateStmt *n = makeNode(TruncateStmt); n->relations = $3; n->restart_seqs = $4; n->behavior = $5; $$ = (Node *)n; } ; opt_restart_seqs: CONTINUE_P IDENTITY_P { $$ = false; } | RESTART IDENTITY_P { $$ = true; } | /* EMPTY */ { $$ = false; } ; /***************************************************************************** * * The COMMENT ON statement can take different forms based upon the type of * the object associated with the comment. The form of the statement is: * * COMMENT ON [ [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW | * COLLATION | CONVERSION | LANGUAGE | OPERATOR CLASS | * LARGE OBJECT | CAST | COLUMN | SCHEMA | TABLESPACE | * EXTENSION | ROLE | TEXT SEARCH PARSER | * TEXT SEARCH DICTIONARY | TEXT SEARCH TEMPLATE | * TEXT SEARCH CONFIGURATION | FOREIGN TABLE | * FOREIGN DATA WRAPPER | SERVER ] | * AGGREGATE (arg1, ...) | * FUNCTION (arg1, arg2, ...) | * OPERATOR (leftoperand_typ, rightoperand_typ) | * TRIGGER ON | * CONSTRAINT ON | * RULE ON ] * IS 'text' * *****************************************************************************/ CommentStmt: COMMENT ON comment_type any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = $3; n->objname = $4; n->objargs = NIL; n->comment = $6; $$ = (Node *) n; } | COMMENT ON AGGREGATE func_name aggr_args IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_AGGREGATE; n->objname = $4; n->objargs = $5; n->comment = $7; $$ = (Node *) n; } | COMMENT ON FUNCTION func_name func_args IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_FUNCTION; n->objname = $4; n->objargs = extractArgTypes($5); n->comment = $7; $$ = (Node *) n; } | COMMENT ON OPERATOR any_operator oper_argtypes IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_OPERATOR; n->objname = $4; n->objargs = $5; n->comment = $7; $$ = (Node *) n; } | COMMENT ON CONSTRAINT name ON any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_CONSTRAINT; n->objname = lappend($6, makeString($4)); n->objargs = NIL; n->comment = $8; $$ = (Node *) n; } | COMMENT ON RULE name ON any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_RULE; n->objname = lappend($6, makeString($4)); n->objargs = NIL; n->comment = $8; $$ = (Node *) n; } | COMMENT ON RULE name IS comment_text { /* Obsolete syntax supported for awhile for compatibility */ CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_RULE; n->objname = list_make1(makeString($4)); n->objargs = NIL; n->comment = $6; $$ = (Node *) n; } | COMMENT ON TRIGGER name ON any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_TRIGGER; n->objname = lappend($6, makeString($4)); n->objargs = NIL; n->comment = $8; $$ = (Node *) n; } | COMMENT ON OPERATOR CLASS any_name USING access_method IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_OPCLASS; n->objname = $5; n->objargs = list_make1(makeString($7)); n->comment = $9; $$ = (Node *) n; } | COMMENT ON OPERATOR FAMILY any_name USING access_method IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_OPFAMILY; n->objname = $5; n->objargs = list_make1(makeString($7)); n->comment = $9; $$ = (Node *) n; } | COMMENT ON LARGE_P OBJECT_P NumericOnly IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_LARGEOBJECT; n->objname = list_make1($5); n->objargs = NIL; n->comment = $7; $$ = (Node *) n; } | COMMENT ON CAST '(' Typename AS Typename ')' IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_CAST; n->objname = list_make1($5); n->objargs = list_make1($7); n->comment = $10; $$ = (Node *) n; } | COMMENT ON opt_procedural LANGUAGE any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_LANGUAGE; n->objname = $5; n->objargs = NIL; n->comment = $7; $$ = (Node *) n; } | COMMENT ON TEXT_P SEARCH PARSER any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_TSPARSER; n->objname = $6; n->comment = $8; $$ = (Node *) n; } | COMMENT ON TEXT_P SEARCH DICTIONARY any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_TSDICTIONARY; n->objname = $6; n->comment = $8; $$ = (Node *) n; } | COMMENT ON TEXT_P SEARCH TEMPLATE any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_TSTEMPLATE; n->objname = $6; n->comment = $8; $$ = (Node *) n; } | COMMENT ON TEXT_P SEARCH CONFIGURATION any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_TSCONFIGURATION; n->objname = $6; n->comment = $8; $$ = (Node *) n; } ; comment_type: COLUMN { $$ = OBJECT_COLUMN; } | DATABASE { $$ = OBJECT_DATABASE; } | SCHEMA { $$ = OBJECT_SCHEMA; } | INDEX { $$ = OBJECT_INDEX; } | SEQUENCE { $$ = OBJECT_SEQUENCE; } | TABLE { $$ = OBJECT_TABLE; } | DOMAIN_P { $$ = OBJECT_DOMAIN; } | TYPE_P { $$ = OBJECT_TYPE; } | VIEW { $$ = OBJECT_VIEW; } | COLLATION { $$ = OBJECT_COLLATION; } | CONVERSION_P { $$ = OBJECT_CONVERSION; } | TABLESPACE { $$ = OBJECT_TABLESPACE; } | EXTENSION { $$ = OBJECT_EXTENSION; } | ROLE { $$ = OBJECT_ROLE; } | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } | SERVER { $$ = OBJECT_FOREIGN_SERVER; } | FOREIGN DATA_P WRAPPER { $$ = OBJECT_FDW; } ; comment_text: Sconst { $$ = $1; } | NULL_P { $$ = NULL; } ; /***************************************************************************** * * SECURITY LABEL [FOR ] ON IS