2525#include <sys/wait.h>
2626#include <unistd.h>
2727
28+ /*
29+ * Hacky solution to allow expressing both frontend and backend error reports
30+ * in one macro call. First argument of log_error is an errcode() call of
31+ * some sort (ignored if FRONTEND); the rest are errmsg_internal() arguments,
32+ * i.e. message string and any parameters for it.
33+ *
34+ * Caller must provide the gettext wrapper around the message string, if
35+ * appropriate, so that it gets translated in the FRONTEND case; this
36+ * motivates using errmsg_internal() not errmsg(). We handle appending a
37+ * newline, if needed, inside the macro, so that there's only one translatable
38+ * string per call not two.
39+ */
2840#ifndef FRONTEND
29- /* We use only 3- and 4-parameter elog calls in this file, for simplicity */
30- /* NOTE: caller must provide gettext call around str! */
31- #define log_error (str ,param )elog(LOG, str, param)
32- #define log_error4 (str ,param ,arg1 )elog(LOG, str, param, arg1)
41+ #define log_error (errcodefn , ...) \
42+ ereport(LOG, (errcodefn, errmsg_internal(__VA_ARGS__)))
3343#else
34- #define log_error (str , param )(fprintf(stderr, str, param), fputc('\n', stderr))
35- #define log_error4 ( str , param , arg1 ) (fprintf(stderr,str, param, arg1 ), fputc('\n', stderr))
44+ #define log_error (errcodefn , ...) \
45+ (fprintf(stderr,__VA_ARGS__ ), fputc('\n', stderr))
3646#endif
3747
3848#ifdef _MSC_VER
@@ -124,10 +134,8 @@ find_my_exec(const char *argv0, char *retpath)
124134
125135if (!getcwd (cwd ,MAXPGPATH ))
126136{
127- int save_errno = errno ;
128-
129- log_error (_ ("could not identify current directory: %s" ),
130- strerror (save_errno ));
137+ log_error (errcode_for_file_access (),
138+ _ ("could not identify current directory: %m" ));
131139return -1 ;
132140}
133141
@@ -145,7 +153,8 @@ find_my_exec(const char *argv0, char *retpath)
145153if (validate_exec (retpath )== 0 )
146154return resolve_symlinks (retpath );
147155
148- log_error (_ ("invalid binary \"%s\"" ),retpath );
156+ log_error (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
157+ _ ("invalid binary \"%s\"" ),retpath );
149158return -1 ;
150159}
151160
@@ -194,14 +203,16 @@ find_my_exec(const char *argv0, char *retpath)
194203case -1 :/* wasn't even a candidate, keep looking */
195204break ;
196205case -2 :/* found but disqualified */
197- log_error (_ ("could not read binary \"%s\"" ),
206+ log_error (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
207+ _ ("could not read binary \"%s\"" ),
198208retpath );
199209break ;
200210}
201211}while (* endp );
202212}
203213
204- log_error (_ ("could not find a \"%s\" to execute" ),argv0 );
214+ log_error (errcode (ERRCODE_UNDEFINED_FILE ),
215+ _ ("could not find a \"%s\" to execute" ),argv0 );
205216return -1 ;
206217}
207218
@@ -240,10 +251,8 @@ resolve_symlinks(char *path)
240251 */
241252if (!getcwd (orig_wd ,MAXPGPATH ))
242253{
243- int save_errno = errno ;
244-
245- log_error (_ ("could not identify current directory: %s" ),
246- strerror (save_errno ));
254+ log_error (errcode_for_file_access (),
255+ _ ("could not identify current directory: %m" ));
247256return -1 ;
248257}
249258
@@ -258,10 +267,8 @@ resolve_symlinks(char *path)
258267* lsep = '\0' ;
259268if (chdir (path )== -1 )
260269{
261- int save_errno = errno ;
262-
263- log_error4 (_ ("could not change directory to \"%s\": %s" ),
264- path ,strerror (save_errno ));
270+ log_error (errcode_for_file_access (),
271+ _ ("could not change directory to \"%s\": %m" ),path );
265272return -1 ;
266273}
267274fname = lsep + 1 ;
@@ -273,10 +280,12 @@ resolve_symlinks(char *path)
273280!S_ISLNK (buf .st_mode ))
274281break ;
275282
283+ errno = 0 ;
276284rllen = readlink (fname ,link_buf ,sizeof (link_buf ));
277285if (rllen < 0 || rllen >=sizeof (link_buf ))
278286{
279- log_error (_ ("could not read symbolic link \"%s\"" ),fname );
287+ log_error (errcode_for_file_access (),
288+ _ ("could not read symbolic link \"%s\": %m" ),fname );
280289return -1 ;
281290}
282291link_buf [rllen ]= '\0' ;
@@ -288,21 +297,17 @@ resolve_symlinks(char *path)
288297
289298if (!getcwd (path ,MAXPGPATH ))
290299{
291- int save_errno = errno ;
292-
293- log_error (_ ("could not identify current directory: %s" ),
294- strerror (save_errno ));
300+ log_error (errcode_for_file_access (),
301+ _ ("could not identify current directory: %m" ));
295302return -1 ;
296303}
297304join_path_components (path ,path ,link_buf );
298305canonicalize_path (path );
299306
300307if (chdir (orig_wd )== -1 )
301308{
302- int save_errno = errno ;
303-
304- log_error4 (_ ("could not change directory to \"%s\": %s" ),
305- orig_wd ,strerror (save_errno ));
309+ log_error (errcode_for_file_access (),
310+ _ ("could not change directory to \"%s\": %m" ),orig_wd );
306311return -1 ;
307312}
308313#endif /* HAVE_READLINK */
@@ -532,20 +537,15 @@ pclose_check(FILE *stream)
532537if (exitstatus == -1 )
533538{
534539/* pclose() itself failed, and hopefully set errno */
535- int save_errno = errno ;
536-
537- log_error (_ ("pclose failed: %s" ),
538- strerror (save_errno ));
540+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
541+ _ ("pclose failed: %m" ));
539542}
540543else
541544{
542545reason = wait_result_to_str (exitstatus );
543- log_error ("%s" ,reason );
544- #ifdef FRONTEND
545- free (reason );
546- #else
546+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
547+ "%s" ,reason );
547548pfree (reason );
548- #endif
549549}
550550return exitstatus ;
551551}
@@ -666,19 +666,24 @@ AddUserToTokenDacl(HANDLE hToken)
666666ptdd = (TOKEN_DEFAULT_DACL * )LocalAlloc (LPTR ,dwSize );
667667if (ptdd == NULL )
668668{
669- log_error ("could not allocate %lu bytes of memory" ,dwSize );
669+ log_error (errcode (ERRCODE_OUT_OF_MEMORY ),
670+ _ ("out of memory" ));
670671gotocleanup ;
671672}
672673
673674if (!GetTokenInformation (hToken ,tic , (LPVOID )ptdd ,dwSize ,& dwSize ))
674675{
675- log_error ("could not get token information: error code %lu" ,GetLastError ());
676+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
677+ "could not get token information: error code %lu" ,
678+ GetLastError ());
676679gotocleanup ;
677680}
678681}
679682else
680683{
681- log_error ("could not get token information buffer size: error code %lu" ,GetLastError ());
684+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
685+ "could not get token information buffer size: error code %lu" ,
686+ GetLastError ());
682687gotocleanup ;
683688}
684689}
@@ -688,7 +693,9 @@ AddUserToTokenDacl(HANDLE hToken)
688693 (DWORD )sizeof (ACL_SIZE_INFORMATION ),
689694AclSizeInformation ))
690695{
691- log_error ("could not get ACL information: error code %lu" ,GetLastError ());
696+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
697+ "could not get ACL information: error code %lu" ,
698+ GetLastError ());
692699gotocleanup ;
693700}
694701
@@ -704,13 +711,15 @@ AddUserToTokenDacl(HANDLE hToken)
704711pacl = (PACL )LocalAlloc (LPTR ,dwNewAclSize );
705712if (pacl == NULL )
706713{
707- log_error ("could not allocate %lu bytes of memory" ,dwNewAclSize );
714+ log_error (errcode (ERRCODE_OUT_OF_MEMORY ),
715+ _ ("out of memory" ));
708716gotocleanup ;
709717}
710718
711719if (!InitializeAcl (pacl ,dwNewAclSize ,ACL_REVISION ))
712720{
713- log_error ("could not initialize ACL: error code %lu" ,GetLastError ());
721+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
722+ "could not initialize ACL: error code %lu" ,GetLastError ());
714723gotocleanup ;
715724}
716725
@@ -719,21 +728,25 @@ AddUserToTokenDacl(HANDLE hToken)
719728{
720729if (!GetAce (ptdd -> DefaultDacl ,i , (LPVOID * )& pace ))
721730{
722- log_error ("could not get ACE: error code %lu" ,GetLastError ());
731+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
732+ "could not get ACE: error code %lu" ,GetLastError ());
723733gotocleanup ;
724734}
725735
726736if (!AddAce (pacl ,ACL_REVISION ,MAXDWORD ,pace , ((PACE_HEADER )pace )-> AceSize ))
727737{
728- log_error ("could not add ACE: error code %lu" ,GetLastError ());
738+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
739+ "could not add ACE: error code %lu" ,GetLastError ());
729740gotocleanup ;
730741}
731742}
732743
733744/* Add the new ACE for the current user */
734745if (!AddAccessAllowedAceEx (pacl ,ACL_REVISION ,OBJECT_INHERIT_ACE ,GENERIC_ALL ,pTokenUser -> User .Sid ))
735746{
736- log_error ("could not add access allowed ACE: error code %lu" ,GetLastError ());
747+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
748+ "could not add access allowed ACE: error code %lu" ,
749+ GetLastError ());
737750gotocleanup ;
738751}
739752
@@ -742,7 +755,9 @@ AddUserToTokenDacl(HANDLE hToken)
742755
743756if (!SetTokenInformation (hToken ,tic , (LPVOID )& tddNew ,dwNewAclSize ))
744757{
745- log_error ("could not set token information: error code %lu" ,GetLastError ());
758+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
759+ "could not set token information: error code %lu" ,
760+ GetLastError ());
746761gotocleanup ;
747762}
748763
@@ -788,13 +803,16 @@ GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser)
788803
789804if (* ppTokenUser == NULL )
790805{
791- log_error ("could not allocate %lu bytes of memory" ,dwLength );
806+ log_error (errcode (ERRCODE_OUT_OF_MEMORY ),
807+ _ ("out of memory" ));
792808return FALSE;
793809}
794810}
795811else
796812{
797- log_error ("could not get token information buffer size: error code %lu" ,GetLastError ());
813+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
814+ "could not get token information buffer size: error code %lu" ,
815+ GetLastError ());
798816return FALSE;
799817}
800818}
@@ -808,7 +826,9 @@ GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser)
808826LocalFree (* ppTokenUser );
809827* ppTokenUser = NULL ;
810828
811- log_error ("could not get token information: error code %lu" ,GetLastError ());
829+ log_error (errcode (ERRCODE_SYSTEM_ERROR ),
830+ "could not get token information: error code %lu" ,
831+ GetLastError ());
812832return FALSE;
813833}
814834