This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] error.h


This patch series adds error.h and the error(3) functions, a GNU
extension:

http://www.kernel.org/doc/man-pages/online/pages/man3/error.3.html

I implemented this within Cygwin itself instead of newlib, because it is
a GNU extension which depends on program_invocation_name, another GNU
extension available only in Cygwin.

Patches for winsup/cygwin and winsup/doc, the new error.h header, and a
test application, attached.


Yaakov

http://www.kernel.org/doc/man-pages/online/pages/man3/error.3.html

2011-05-17  Yaakov Selkowitz  <yselkowitz@...>

	* cygwin.din (error): Export.
	(error_at_line): Export.
	(error_message_count): Export.
	(error_one_per_line): Export.
	(error_print_progname): Export.
	* errno.cc (error_message_count): Define.
	(error_one_per_line): Define.
	(error_print_progname): Define.
	(_verror): New static function.
	(error): New function.
	(error_at_line): New function.
	* posix.sgml (std-gnu): Add error, error_at_line.
	* include/error.h: New header.
	* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.

Index: cygwin.din
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/cygwin.din,v
retrieving revision 1.241
diff -u -r1.241 cygwin.din
--- cygwin.din	15 May 2011 18:49:39 -0000	1.241
+++ cygwin.din	16 May 2011 05:50:06 -0000
@@ -10,6 +10,9 @@
 __cygwin_environ DATA
 __cygwin_user_data DATA
 _daylight DATA
+error_message_count DATA
+error_one_per_line DATA
+error_print_progname DATA
 h_errno DATA
 _impure_ptr DATA
 in6addr_any DATA
@@ -389,6 +392,8 @@
 _erff = erff NOSIGFE
 err SIGFE
 __errno NOSIGFE
+error SIGFE
+error_at_line SIGFE
 errx SIGFE
 euidaccess SIGFE
 execl SIGFE
Index: errno.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/errno.cc,v
retrieving revision 1.81
diff -u -r1.81 errno.cc
--- errno.cc	29 Apr 2011 18:54:23 -0000	1.81
+++ errno.cc	16 May 2011 05:50:06 -0000
@@ -13,6 +13,13 @@
 #define sys_nerr FOOsys_nerr
 #define _sys_errlist FOO_sys_errlist
 #define strerror_r FOO_strerror_r
+#define __INSIDE_CYGWIN__
+#include <errno.h>
+#include <error.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include "winsup.h"
 #include "cygtls.h"
 #include "ntdll.h"
@@ -417,3 +424,67 @@
   strcpy (buf, error);
   return result;
 }
+
+unsigned int error_message_count = 0;
+int error_one_per_line = 0;
+void (*error_print_progname) (void) = NULL;
+
+static void
+_verror (int status, int errnum, const char *filename, unsigned int lineno, const char *fmt, va_list ap)
+{
+  error_message_count++;
+
+  fflush (stdout);
+
+  if (error_print_progname)
+    (*error_print_progname) ();
+  else
+    fprintf (stderr, "%s:%s", program_invocation_name, filename ? "" : " ");
+
+  if (filename)
+    fprintf (stderr, "%s:%d: ", filename, lineno);
+
+  vfprintf (stderr, fmt, ap);
+
+  if (errnum != 0)
+    fprintf (stderr, ": %s", strerror (errnum));
+
+  fprintf (stderr, "\n");
+
+  if (status != 0)
+    exit (status);
+}
+
+extern "C" void
+error (int status, int errnum, const char *fmt, ...)
+{
+  va_list ap;
+  va_start (ap, fmt);
+  _verror (status, errnum, NULL, 0, fmt, ap);
+  va_end (ap);
+}
+
+extern "C" void
+error_at_line (int status, int errnum, const char *filename, unsigned int lineno, const char *fmt, ...)
+{
+  va_list ap;
+
+  if (error_one_per_line != 0)
+    {
+      static const char *last_filename;
+      static unsigned int last_lineno;
+
+      /* strcmp(3) will SEGV if filename or last_filename are NULL */
+      if (lineno == last_lineno
+          && ((!filename && !last_filename)
+              || (filename && last_filename && strcmp (filename, last_filename) == 0)))
+        return;
+
+      last_filename = filename;
+      last_lineno = lineno;
+    }
+
+  va_start (ap, fmt);
+  _verror (status, errnum, filename, lineno, fmt, ap);
+  va_end (ap);
+}
Index: posix.sgml
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/posix.sgml,v
retrieving revision 1.63
diff -u -r1.63 posix.sgml
--- posix.sgml	15 May 2011 18:49:39 -0000	1.63
+++ posix.sgml	16 May 2011 05:50:06 -0000
@@ -1089,6 +1089,8 @@
     envz_merge
     envz_remove
     envz_strip
+    error
+    error_at_line
     euidaccess
     execvpe
     exp10
Index: include/cygwin/version.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/include/cygwin/version.h,v
retrieving revision 1.346
diff -u -r1.346 version.h
--- include/cygwin/version.h	15 May 2011 18:49:40 -0000	1.346
+++ include/cygwin/version.h	16 May 2011 05:50:07 -0000
@@ -414,12 +414,14 @@
 	   pthread_attr_setstack, pthread_attr_setstackaddr.
       246: Add CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID.
 	   Export clock_getcpuclockid, pthread_getcpuclockid.
+      247: Export error, error_at_line, error_message_count, error_one_per_line,
+	   error_print_progname.
      */
 
      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
 
 #define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 246
+#define CYGWIN_VERSION_API_MINOR 247
 
      /* There is also a compatibity version number associated with the
 	shared memory regions.  It is incremented when incompatible
2011-05-17  Yaakov Selkowitz  <yselkowitz@...>

	* new-features.sgml (ov-new1.7.10): Document error.h functions.

Index: new-features.sgml
===================================================================
RCS file: /cvs/src/src/winsup/doc/new-features.sgml,v
retrieving revision 1.82
diff -u -r1.82 new-features.sgml
--- new-features.sgml	17 May 2011 17:09:32 -0000	1.82
+++ new-features.sgml	17 May 2011 17:14:52 -0000
@@ -31,6 +31,11 @@
 </para></listitem>
 
 <listitem><para>
+GNU/glibc error.h error reporting functions.  New APIs: error, error_at_line.
+New exports: error_message_count, error_one_per_line, error_print_progname.
+</para></listitem>
+
+<listitem><para>
 /proc/loadavg now shows the number of currently running processes and the
 total number of processes.
 </para></listitem>
/* error.h: GNU error reporting functions

   Copyright 2011 Red Hat, Inc.

This file is part of Cygwin.

This software is a copyrighted work licensed under the terms of the
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
details. */

#ifndef _ERROR_H
#define _ERROR_H

#ifdef __cplusplus
extern "C"
{
#endif

void error (int, int, const char *, ...);
void error_at_line (int, int, const char *, unsigned int, const char *, ...);

extern unsigned int error_message_count;
extern int error_one_per_line;
extern void (*error_print_progname) (void);

#ifdef __cplusplus
}
#endif

#endif /* _ERROR_H */
#define _GNU_SOURCE
#include <errno.h>	/* for program_invocation_name */
#include <error.h>
#include <stdio.h>

void
mymsg (void)
{
	fprintf (stderr, "custom message:");
}

int
main (int argc, char **argv)
{
	error (0, 0, NULL);		/* error 1 */
	error (0, 0, "error 2");

	/* has effect */
	program_invocation_name = "foobar";

	error (0, 0, NULL);		/* error 3 */
	error (0, 0, "error 4");

	error (0, 1, NULL);		/* error 5 */
	error (0, 2, "%s", "error 6");

	/* same as error() if filename is NULL */
	error_at_line (0, 0, NULL, 32, "error 7");

	error_at_line (0, 0, __FILE__, 34, "%s", "error 8");

	error_one_per_line = -1;
	/* error_one_per_line only counts once set */
	error_at_line (0, 0, __FILE__, 34, "%s", "error 9");
	/* error_one_per_line causes this to be ignored */
	error_at_line (error_message_count, 0, __FILE__, 34, "%s", "OOPS! error 10");
	/* error_one_per_line tracks only the last lineno, none previous */
	error_at_line (0, 0, __FILE__, 32, "%s", "error 11");
	/* error_one_per_line requires both matching filename and lineno */
	error_at_line (0, 0, "myfilename", 32, "%s", "error 12");

	/* overrides the printing of program_invocation_name: */
	error_print_progname = &mymsg;

	error (0, 0, NULL); 	/* error 13 */
	error (0, 0, "error 14");
	error (0, 3, NULL); 	/* error 15 */
	error (0, 4, "%s", "error 16");

	error_at_line (0, 5, __FILE__, 53, "%s", "error 17");
#if !defined(__GLIBC__) || __GLIBC_MINOR__ >= 14
	/* SEGVs on glibc due to strcmp (NULL, __FILE__)
           http://sourceware.org/bugzilla/show_bug.cgi?id=12766
           Fixed upstream for upcoming 2.14:
           http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=15cc7dd */
	error_at_line (0, 6, NULL, 53, "%s", "error 18");
#endif
	/* non-zero status calls exit() */
	/* note that skipped error 8 does not increment count */
	error_at_line (error_message_count, 7, __FILE__, __LINE__, "%s", "error 19");

	/* not reached */
	fprintf (stderr, "Exiting normally\n");
	return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]