mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-10-28 23:34:53 +03:00 
			
		
		
		
	Update.
* misc/error.c (error): Handle wide oriented stderr stream correctly. * stdio-common/perror.c (perror): Implement according to standard. The stream orientation must not be changed if the stream was not oriented before the call. * stdio-common/Makefile (tests): Add tst-perror. * stdio-common/tst-perror.c: New file. See ChangeLog.12 for earlier changes.
This commit is contained in:
		
							
								
								
									
										153
									
								
								misc/error.c
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								misc/error.c
									
									
									
									
									
								
							| @@ -26,6 +26,9 @@ | |||||||
|  |  | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <libintl.h> | #include <libintl.h> | ||||||
|  | #ifdef _LIBC | ||||||
|  | # include <wchar.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC | #if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC | ||||||
| # if __STDC__ | # if __STDC__ | ||||||
| @@ -117,12 +120,94 @@ private_strerror (errnum) | |||||||
| # endif	/* HAVE_STRERROR_R */ | # endif	/* HAVE_STRERROR_R */ | ||||||
| #endif	/* not _LIBC */ | #endif	/* not _LIBC */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef VA_START | ||||||
|  | static void | ||||||
|  | error_tail (int status, int errnum, const char *message, va_list args) | ||||||
|  | { | ||||||
|  | # if HAVE_VPRINTF || _LIBC | ||||||
|  | #  ifdef _LIBC | ||||||
|  |   if (_IO_fwide (stderr, 0) > 0) | ||||||
|  |     { | ||||||
|  | #   define ALLOCA_LIMIT	2000 | ||||||
|  |       size_t len = strlen (message) + 1; | ||||||
|  |       wchar_t *wmessage = NULL; | ||||||
|  |       mbstate_t st; | ||||||
|  |       size_t res; | ||||||
|  |       const char *tmp; | ||||||
|  |  | ||||||
|  |       do | ||||||
|  | 	{ | ||||||
|  | 	  if (len < ALLOCA_LIMIT) | ||||||
|  | 	    wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); | ||||||
|  | 	  else | ||||||
|  | 	    { | ||||||
|  | 	      if (wmessage != NULL && len / 2 < ALLOCA_LIMIT) | ||||||
|  | 		wmessage = NULL; | ||||||
|  |  | ||||||
|  | 	      wmessage = (wchar_t *) realloc (wmessage, | ||||||
|  | 					      len * sizeof (wchar_t)); | ||||||
|  |  | ||||||
|  | 	      if (wmessage == NULL) | ||||||
|  | 		{ | ||||||
|  | 		  fputws (L"out of memory\n", stderr); | ||||||
|  | 		  return; | ||||||
|  | 		} | ||||||
|  | 	    } | ||||||
|  |  | ||||||
|  | 	  memset (&st, '\0', sizeof (st)); | ||||||
|  | 	  tmp =message; | ||||||
|  | 	} | ||||||
|  |       while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len); | ||||||
|  |  | ||||||
|  |       if (res == (size_t) -1) | ||||||
|  | 	/* The string cannot be converted.  */ | ||||||
|  | 	wmessage = (wchar_t *) L"???"; | ||||||
|  |  | ||||||
|  |       vfwprintf (stderr, wmessage, args); | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  | #  endif | ||||||
|  |     vfprintf (stderr, message, args); | ||||||
|  | # else | ||||||
|  |   _doprnt (message, args, stderr); | ||||||
|  | # endif | ||||||
|  |   va_end (args); | ||||||
|  |  | ||||||
|  |   ++error_message_count; | ||||||
|  |   if (errnum) | ||||||
|  |     { | ||||||
|  | #if defined HAVE_STRERROR_R || _LIBC | ||||||
|  |       char errbuf[1024]; | ||||||
|  |       char *s = __strerror_r (errnum, errbuf, sizeof errbuf); | ||||||
|  | # ifdef _LIBC | ||||||
|  |       if (_IO_fwide (stderr, 0) > 0) | ||||||
|  | 	fwprintf (stderr, L": %s", s); | ||||||
|  |       else | ||||||
|  | # endif | ||||||
|  | 	fprintf (stderr, ": %s", s); | ||||||
|  | #else | ||||||
|  |       fprintf (stderr, ": %s", strerror (errnum)); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  | #ifdef _LIBC | ||||||
|  |   if (_IO_fwide (stderr, 0) > 0) | ||||||
|  |     putwc (L'\n', stderr); | ||||||
|  |   else | ||||||
|  | #endif | ||||||
|  |     putc ('\n', stderr); | ||||||
|  |   fflush (stderr); | ||||||
|  |   if (status) | ||||||
|  |     exit (status); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| /* Print the program name and error message MESSAGE, which is a printf-style | /* Print the program name and error message MESSAGE, which is a printf-style | ||||||
|    format string with optional args. |    format string with optional args. | ||||||
|    If ERRNUM is nonzero, print its corresponding system error message. |    If ERRNUM is nonzero, print its corresponding system error message. | ||||||
|    Exit with status STATUS if it is nonzero.  */ |    Exit with status STATUS if it is nonzero.  */ | ||||||
| /* VARARGS */ | /* VARARGS */ | ||||||
|  |  | ||||||
| void | void | ||||||
| #if defined VA_START && __STDC__ | #if defined VA_START && __STDC__ | ||||||
| error (int status, int errnum, const char *message, ...) | error (int status, int errnum, const char *message, ...) | ||||||
| @@ -139,37 +224,38 @@ error (status, errnum, message, va_alist) | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   fflush (stdout); |   fflush (stdout); | ||||||
|  | #ifdef _LIBC | ||||||
|  |   flockfile (stderr); | ||||||
|  | #endif | ||||||
|   if (error_print_progname) |   if (error_print_progname) | ||||||
|     (*error_print_progname) (); |     (*error_print_progname) (); | ||||||
|   else |   else | ||||||
|  |     { | ||||||
|  | #ifdef _LIBC | ||||||
|  |       if (_IO_fwide (stderr, 0) > 0) | ||||||
|  | 	fwprintf (stderr, L"%s: ", program_name); | ||||||
|  |       else | ||||||
|  | #endif | ||||||
| 	fprintf (stderr, "%s: ", program_name); | 	fprintf (stderr, "%s: ", program_name); | ||||||
|  |     } | ||||||
|  |  | ||||||
| #ifdef VA_START | #ifdef VA_START | ||||||
|   VA_START (args, message); |   VA_START (args, message); | ||||||
| # if HAVE_VPRINTF || _LIBC |   error_tail (status, errnum, message, args); | ||||||
|   vfprintf (stderr, message, args); | # ifdef _LIBC | ||||||
| # else |   funlockfile (stderr); | ||||||
|   _doprnt (message, args, stderr); |  | ||||||
| # endif | # endif | ||||||
|   va_end (args); |  | ||||||
| #else | #else | ||||||
|   fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); |   fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   ++error_message_count; |   ++error_message_count; | ||||||
|   if (errnum) |   if (errnum) | ||||||
|     { |  | ||||||
| #if defined HAVE_STRERROR_R || _LIBC |  | ||||||
|       char errbuf[1024]; |  | ||||||
|       fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf)); |  | ||||||
| #else |  | ||||||
|     fprintf (stderr, ": %s", strerror (errnum)); |     fprintf (stderr, ": %s", strerror (errnum)); | ||||||
| #endif |  | ||||||
|     } |  | ||||||
|   putc ('\n', stderr); |   putc ('\n', stderr); | ||||||
|   fflush (stderr); |   fflush (stderr); | ||||||
|   if (status) |   if (status) | ||||||
|     exit (status); |     exit (status); | ||||||
|  | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Sometimes we want to have at most one error per line.  This | /* Sometimes we want to have at most one error per line.  This | ||||||
| @@ -199,8 +285,9 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist) | |||||||
|       static const char *old_file_name; |       static const char *old_file_name; | ||||||
|       static unsigned int old_line_number; |       static unsigned int old_line_number; | ||||||
|  |  | ||||||
|       if (old_line_number == line_number && |       if (old_line_number == line_number | ||||||
| 	  (file_name == old_file_name || !strcmp (old_file_name, file_name))) | 	  && (file_name == old_file_name | ||||||
|  | 	      || strcmp (old_file_name, file_name) == 0)) | ||||||
| 	/* Simply return and print nothing.  */ | 	/* Simply return and print nothing.  */ | ||||||
| 	return; | 	return; | ||||||
|  |  | ||||||
| @@ -209,40 +296,48 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   fflush (stdout); |   fflush (stdout); | ||||||
|  | #ifdef _LIBC | ||||||
|  |   flockfile (stderr); | ||||||
|  | #endif | ||||||
|   if (error_print_progname) |   if (error_print_progname) | ||||||
|     (*error_print_progname) (); |     (*error_print_progname) (); | ||||||
|   else |   else | ||||||
|  |     { | ||||||
|  | #ifdef _LIBC | ||||||
|  |       if (_IO_fwide (stderr, 0) > 0) | ||||||
|  | 	fwprintf (stderr, L"%s: ", program_name); | ||||||
|  |       else | ||||||
|  | #endif | ||||||
| 	fprintf (stderr, "%s:", program_name); | 	fprintf (stderr, "%s:", program_name); | ||||||
|  |     } | ||||||
|  |  | ||||||
|   if (file_name != NULL) |   if (file_name != NULL) | ||||||
|  |     { | ||||||
|  | #ifdef _LIBC | ||||||
|  |       if (_IO_fwide (stderr, 0) > 0) | ||||||
|  | 	fwprintf (stderr, L"%s:%d: ", file_name, line_number); | ||||||
|  |       else | ||||||
|  | #endif | ||||||
| 	fprintf (stderr, "%s:%d: ", file_name, line_number); | 	fprintf (stderr, "%s:%d: ", file_name, line_number); | ||||||
|  |     } | ||||||
|  |  | ||||||
| #ifdef VA_START | #ifdef VA_START | ||||||
|   VA_START (args, message); |   VA_START (args, message); | ||||||
| # if HAVE_VPRINTF || _LIBC |   error_tail (status, errnum, message, args); | ||||||
|   vfprintf (stderr, message, args); | # ifdef _LIBC | ||||||
| # else |   funlockfile (stderr); | ||||||
|   _doprnt (message, args, stderr); |  | ||||||
| # endif | # endif | ||||||
|   va_end (args); |  | ||||||
| #else | #else | ||||||
|   fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); |   fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   ++error_message_count; |   ++error_message_count; | ||||||
|   if (errnum) |   if (errnum) | ||||||
|     { |  | ||||||
| #if defined HAVE_STRERROR_R || _LIBC |  | ||||||
|       char errbuf[1024]; |  | ||||||
|       fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf)); |  | ||||||
| #else |  | ||||||
|     fprintf (stderr, ": %s", strerror (errnum)); |     fprintf (stderr, ": %s", strerror (errnum)); | ||||||
| #endif |  | ||||||
|     } |  | ||||||
|   putc ('\n', stderr); |   putc ('\n', stderr); | ||||||
|   fflush (stderr); |   fflush (stderr); | ||||||
|   if (status) |   if (status) | ||||||
|     exit (status); |     exit (status); | ||||||
|  | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| #ifdef _LIBC | #ifdef _LIBC | ||||||
|   | |||||||
| @@ -55,7 +55,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ | |||||||
| 	 tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \ | 	 tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \ | ||||||
| 	 scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \ | 	 scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \ | ||||||
| 	 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf tst-swprintf \ | 	 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf tst-swprintf \ | ||||||
| 	 tst-fseek tst-fmemopen test-vfprintf tst-gets | 	 tst-fseek tst-fmemopen test-vfprintf tst-gets tst-perror | ||||||
|  |  | ||||||
| test-srcs = tst-unbputc tst-printf | test-srcs = tst-unbputc tst-printf | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,13 +19,14 @@ | |||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <unistd.h> | ||||||
| #include <wchar.h> | #include <wchar.h> | ||||||
|  | #ifdef USE_IN_LIBIO | ||||||
|  | # include "libioP.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* Print a line on stderr consisting of the text in S, a colon, a space, | static void | ||||||
|    a message describing the meaning of the contents of `errno' and a newline. | perror_internal (FILE *fp, const char *s) | ||||||
|    If S is NULL or "", the colon and space are omitted.  */ |  | ||||||
| void |  | ||||||
| perror (const char *s) |  | ||||||
| { | { | ||||||
|   char buf[1024]; |   char buf[1024]; | ||||||
|   int errnum = errno; |   int errnum = errno; | ||||||
| @@ -40,9 +41,47 @@ perror (const char *s) | |||||||
|   errstring = __strerror_r (errnum, buf, sizeof buf); |   errstring = __strerror_r (errnum, buf, sizeof buf); | ||||||
|  |  | ||||||
| #ifdef USE_IN_LIBIO | #ifdef USE_IN_LIBIO | ||||||
|   if (_IO_fwide (stderr, 0) > 0) |   if (_IO_fwide (fp, 0) > 0) | ||||||
|     (void) fwprintf (stderr, L"%s%s%s\n", s, colon, errstring); |     (void) fwprintf (fp, L"%s%s%s\n", s, colon, errstring); | ||||||
|   else |   else | ||||||
| #endif | #endif | ||||||
|     (void) fprintf (stderr, "%s%s%s\n", s, colon, errstring); |     (void) fprintf (fp, "%s%s%s\n", s, colon, errstring); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* Print a line on stderr consisting of the text in S, a colon, a space, | ||||||
|  |    a message describing the meaning of the contents of `errno' and a newline. | ||||||
|  |    If S is NULL or "", the colon and space are omitted.  */ | ||||||
|  | void | ||||||
|  | perror (const char *s) | ||||||
|  | { | ||||||
|  |   FILE *fp; | ||||||
|  |   int fd = -1; | ||||||
|  |  | ||||||
|  |   /* The standard says that 'perror' must not change the orientation | ||||||
|  |      of the stream.  What is supposed to happen when the stream isn't | ||||||
|  |      oriented yet?  In this case we'll create a new stream which is | ||||||
|  |      using the same underlying file descriptor.  */ | ||||||
|  |   if (__builtin_expect (_IO_fwide (stderr, 0) != 0, 1) | ||||||
|  |       || fileno_unlocked (stderr) == -1 | ||||||
|  |       || (fd = dup (fileno_unlocked (stderr))) == -1 | ||||||
|  |       || (fp = fdopen (fd, "w+")) == NULL) | ||||||
|  |     { | ||||||
|  |       if (__builtin_expect (fd != -1, 0)) | ||||||
|  | 	close (fd); | ||||||
|  |  | ||||||
|  |       /* Use standard error as is.  */ | ||||||
|  |       perror_internal (stderr, s); | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       /* We don't have to do any special hacks regarding the file | ||||||
|  | 	 position.  Since the stderr stream wasn't used so far we just | ||||||
|  | 	 write to the descriptor.  */ | ||||||
|  |       perror_internal (fp, s); | ||||||
|  |       /* Close the stream.  */ | ||||||
|  |       fclose (fp); | ||||||
|  |  | ||||||
|  |       ((_IO_FILE *) stderr)->_offset = _IO_pos_BAD; | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										154
									
								
								stdio-common/tst-perror.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								stdio-common/tst-perror.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | |||||||
|  | /* Test of perror. | ||||||
|  |    Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. | ||||||
|  |    To be used only for testing glibc.  */ | ||||||
|  |  | ||||||
|  | #include <errno.h> | ||||||
|  | #include <error.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <wchar.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #define MB_EXP \ | ||||||
|  |   "null mode test 1: Invalid or incomplete multibyte or wide character\n" \ | ||||||
|  |   "multibyte string\n" \ | ||||||
|  |   "<0 mode test: Invalid argument\n" | ||||||
|  | #define MB_EXP_LEN (sizeof (MB_EXP) - 1) | ||||||
|  |  | ||||||
|  | #define WC_EXP \ | ||||||
|  |   "null mode test 2: Invalid or incomplete multibyte or wide character\n" \ | ||||||
|  |   "wide string\n" \ | ||||||
|  |   ">0 mode test: Invalid argument\n" | ||||||
|  | #define WC_EXP_LEN (sizeof (WC_EXP) - 1) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int | ||||||
|  | main (void) | ||||||
|  | { | ||||||
|  |   int fd; | ||||||
|  |   char fname[] = "/tmp/tst-perror.XXXXXX"; | ||||||
|  |   int result = 0; | ||||||
|  |   char buf[200]; | ||||||
|  |   ssize_t n; | ||||||
|  |  | ||||||
|  |   fd = mkstemp (fname); | ||||||
|  |   if (fd == -1) | ||||||
|  |     error (EXIT_FAILURE, errno, "cannot create temporary file"); | ||||||
|  |  | ||||||
|  |   /* Make sure the file gets removed.  */ | ||||||
|  |   unlink (fname); | ||||||
|  |  | ||||||
|  |   fclose (stderr); | ||||||
|  |  | ||||||
|  |   if (dup2 (fd, 2) == -1) | ||||||
|  |     { | ||||||
|  |       printf ("cannot create file descriptor 2: %m\n"); | ||||||
|  |       exit (EXIT_FAILURE); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   stderr = fdopen (2, "w"); | ||||||
|  |   if (stderr == NULL) | ||||||
|  |     { | ||||||
|  |       printf ("fdopen failed: %m\n"); | ||||||
|  |       exit (EXIT_FAILURE); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   if (fwide (stderr, 0) != 0) | ||||||
|  |     { | ||||||
|  |       printf ("stderr not initially in mode 0\n"); | ||||||
|  |       exit (EXIT_FAILURE); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   errno = EILSEQ; | ||||||
|  |   perror ("null mode test 1"); | ||||||
|  |  | ||||||
|  |   if (fwide (stderr, 0) != 0) | ||||||
|  |     { | ||||||
|  |       puts ("perror changed the mode from 0"); | ||||||
|  |       result = 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   fputs ("multibyte string\n", stderr); | ||||||
|  |  | ||||||
|  |   if (fwide (stderr, 0) >= 0) | ||||||
|  |     { | ||||||
|  |       puts ("fputs didn't set orientation to narrow"); | ||||||
|  |       result = 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   errno = EINVAL; | ||||||
|  |   perror ("<0 mode test"); | ||||||
|  |  | ||||||
|  |   fclose (stderr); | ||||||
|  |  | ||||||
|  |   lseek (fd, 0, SEEK_SET); | ||||||
|  |   n = read (fd, buf, sizeof (buf)); | ||||||
|  |   if (n != MB_EXP_LEN || memcmp (buf, MB_EXP, MB_EXP_LEN) != 0) | ||||||
|  |     { | ||||||
|  |       printf ("multibyte test failed.  Expected:\n%s\nGot:\n%.*s\n", | ||||||
|  | 	      MB_EXP, (int) n, buf); | ||||||
|  |       result = 1; | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     puts ("multibyte test succeeded"); | ||||||
|  |  | ||||||
|  |   lseek (fd, 0, SEEK_SET); | ||||||
|  |   ftruncate (fd, 0); | ||||||
|  |  | ||||||
|  |   if (dup2 (fd, 2) == -1) | ||||||
|  |     { | ||||||
|  |       printf ("cannot create file descriptor 2: %m\n"); | ||||||
|  |       exit (EXIT_FAILURE); | ||||||
|  |     } | ||||||
|  |   stderr = fdopen (2, "w"); | ||||||
|  |   if (stderr == NULL) | ||||||
|  |     { | ||||||
|  |       printf ("fdopen failed: %m\n"); | ||||||
|  |       exit (EXIT_FAILURE); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   if (fwide (stderr, 0) != 0) | ||||||
|  |     { | ||||||
|  |       printf ("stderr not initially in mode 0\n"); | ||||||
|  |       exit (EXIT_FAILURE); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   errno = EILSEQ; | ||||||
|  |   perror ("null mode test 2"); | ||||||
|  |  | ||||||
|  |   if (fwide (stderr, 0) != 0) | ||||||
|  |     { | ||||||
|  |       puts ("perror changed the mode from 0"); | ||||||
|  |       result = 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   fputws (L"wide string\n", stderr); | ||||||
|  |  | ||||||
|  |   if (fwide (stderr, 0) <= 0) | ||||||
|  |     { | ||||||
|  |       puts ("fputws didn't set orientation to wide"); | ||||||
|  |       result = 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   errno = EINVAL; | ||||||
|  |   perror (">0 mode test"); | ||||||
|  |  | ||||||
|  |   fclose (stderr); | ||||||
|  |  | ||||||
|  |   lseek (fd, 0, SEEK_SET); | ||||||
|  |   n = read (fd, buf, sizeof (buf)); | ||||||
|  |   if (n != WC_EXP_LEN || memcmp (buf, WC_EXP, WC_EXP_LEN) != 0) | ||||||
|  |     { | ||||||
|  |       printf ("wide test failed.  Expected:\n%s\nGot:\n%.*s\n", | ||||||
|  | 	      WC_EXP, (int) n, buf); | ||||||
|  |       result = 1; | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     puts ("wide test succeeded"); | ||||||
|  |  | ||||||
|  |   close (fd); | ||||||
|  |  | ||||||
|  |   return result; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user