且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

更新已弃用的sys_errlist?简单的问题?

更新时间:2022-10-25 09:59:22

Brennan Young认为:
你好,

我一直在尝试编译我在网上找到的一些代码。

AFAICT它的意图是可移植的代码(它可以作为源和/或DOS二进制文件,但在自述文件中提到UNIX - 我正在Mac OS X下编译,fwiw)。
片段,因为如果没有一些更改它就无法编译。

搜索完网络后我设法得到编译的代码但它要求我简化一些错误处理,我认为应该更好地''更新''。

以下是相关位:

// #include< malloc.h> //由我评论
#include< stdlib.h> //由我添加


#include< errno.h>

#include< string.h>


下面你需要它...

//大量未经修改的代码剪掉

文件*
efopen(名称,模式)
char * name;
char * mode;


这是古老的风格。它更好:


FILE * efopen(char * name,char * mode)

{
FILE * f;
extern int errno;


现在你不需要上面的行(errno在errno.h中声明)。

// extern char * sys_errlist []; //由我评论
// extern int sys_nerr; //由我评论


这是一些古老的系统特定的映射错误消息系统

到错误代码。现在你应该使用`strerr()`。

char * errmess;


你可以把:


errno = 0;


因为标准只规定了在程序启动时它被设置为0,

和库函数/可能/设置为正值(NB,错误或没有

错误!),但从不为零。这里还有来自

标准的相关段落:


7.5p3

程序中errno的值为零启动,但任何库函数都不会将
设置为零。 errno的值可能是

由库函数调用设置为非零值是否存在

是错误,只要在

本国际标准中函数的描述。

if((f = fopen(name,mode))== NULL){
(void)fprintf(stderr) ,***错误***无法打开
''%s''!\ n",name);

/ * //这个chunk由我评论

if(errno< = sys_nerr)
errmess = sys_errlist [errno];

errmess ="未知错误!&quot ;;

* /


if(errno)

errmess = strerror(errno); //由我添加


这就是你想要的。

(void)fprintf(stderr," ********** ***原因:%s \ n",errmess);
退出(1);
}
返回(f);
}
>这段代码编译得很好,它也按预期工作,但我认为如果我向程序发送一个坏文件,它将失败得多。


可能,也可能不是,具体取决于实施情况。我认为

标准并不保证`strerror()`会返回任何内容

明智(它只是指向返回指向消息的指针)。 />
我假设我做了正确的事情,将#include指令从
malloc.h改为stdlib.h


是的。你还需要< errno.h>和< string.h>用于错误处理。

我意识到我需要找到一个更现代的sys_errlist
和sys_nerr, - 一个网络搜索让我发现sys_errlist已被弃用,并且把我添加的单行放在一起。

我还了解到stredror是由stdio.h提供的(已经#inc>已经#include)。


>
我认为它只在< string.h>中,但可能是错误的。


HTH


-

BR,弗拉基米尔


你将开创第一个火星殖民地。


Brennan Young写道:

你好,

首先我会为我的无知道歉!

我一直试图编译一些我在网上找到的代码。

AFAICT它的目的是成为可移植的代码(它作为源代码提供,并且作为DOS二进制文件提供,但是提到的是UNIX中的自述 - 我在Mac OS X下编译,fwiw )。

它可能曾经是便携式的,但显然使用了一些过时的
片段,因为它没有一些变化就不能编译。

搜索网络后我设法得到编译的代码,但它要求我简化一些错误处理,我觉得应该更好''更新''。

以下是相关的位:

// #include< malloc.h> //由我评论
#include< stdlib.h> //由我添加

//大量未经修改的代码剪掉

文件*
efopen(名称,模式)
char * name;
char * mode;
{
FILE * f;
extern int errno;

// extern char * sys_errlist []; //由我评论


这很可能包含错误编号到错误

文本的映射,但是没有看到实际的定义我可以做什么

猜。如果是这种情况,请查看strerror()。另外perror()

在这里工作得很好。

// extern int sys_nerr; //由我评论


errno.h提供的errno可用于此。

char * errmess;

if((f = fopen(name,mode))== NULL){
(void)fprintf(stderr," *** ERROR ***无法打开''%s''' !\\\
&QUOT;,姓名);


鉴于以上信息,这可以改为:


if((f = fopen(name,mode))== NULL ){

perror(fopen);

/ * //这个chunk由我评论

if(errno< = sys_nerr)
errmess = sys_errlist [errno];

errmess ="未知错误!&quot ;;

* /


您可以将其删除。我们已经使用perror()进行了上述操作。

errmess = strerror(errno); //由我添加

(void)fprintf(stderr," ************* Reason:%s \ n",errmess);


以上两行现在也是多余的。

退出(1);


马虎。你可能想在这里使用EXIT_FAILURE。

}
返回(f);
}
这个代码编译得很好,它也有效按照预期,但我认为如果我向
程序发送一个坏文件,它将会失败得多。


其实没有,它不会。它会像你之前那样优雅地失败。

你进行了更改,唯一的不同就是你的更改了它

不会在失败时打印出错误信息(这可能是一个坏的

Thing(tm))。

我认为我做了正确的事情,将#include指令从
malloc.h更改为stdlib。 h


是的。

我意识到我需要找到一个更现代的sys_errlist和
sys_nerr, - 一个网络搜索让我发现不推荐使用sys_errlist,并将我添加的单行放在一起。


你不需要其中任何一个。

我还了解到stredror是由stdio.h提供的(已经是
执行#included)。一切都很好,但我不知道如何恢复
''if''测试并使错误处理更加强大。


错误处理对我来说非常好。如果fopen()返回NULL

然后只需调用perror(fopen)来查看错误消息。

提前感谢您的帮助!




没问题,希望能让你指出正确的方向。


Joe


2006-03-19,Joe Estock< je ***** @ NOSPAMnutextonline.com>写道:

Brennan Young写道:
你好,

首先,我会为我的无知道歉!
>我一直在尝试编译我在网上找到的一些代码。

AFAICT它的目的是成为可移植代码(它作为源代码提供,并且作为DOS二进制文件提供,但是在自述文件中提到了UNIX - 我在Mac OS X下编译,fwiw)。

它可能曾经是可移植的,但显然使用了一些过时的
片段,因为如果没有一些更改,它就无法编译。

在搜索网络后,我设法获得编译的代码,但它要求我简化一些错误处理,我认为应该是
以下是相关内容:

// #include< malloc.h> //由我评论
#include< stdlib.h> //由我添加

//大量未经修改的代码剪掉

文件*
efopen(名称,模式)
char * name;
char * mode;
{
FILE * f;
extern int errno;

// extern char * sys_errlist []; //由我评论



这很可能包含错误编号到错误文本的映射,但是如果没有看到实际的定义我可以做的就是
猜。如果是这种情况,请查看strerror()。另外perror()
在这里工作得很好。

// extern int sys_nerr; //由我评论



errno.h提供了errno,你可以使用它。




sys_nerr是sys_errlist中的条目总数,而不是索引。


[嗯,它可以是实现想要的任何东西,但我的猜测

更可能比你的更好]

char * errmess;

if((f = fopen( name,mode))== NULL){
(void)fprintf(stderr," *** ERROR ***无法打开''%s''!\ n",名称);


鉴于以上信息,可将此更改为:

if((f = fopen(name,mode))== NULL){
perror (fopen);




我已经使用了perror(名字)。


Hi there,

First I''ll apologise for my ignorance!

I have been attempting to compile some code that I found on the net.

AFAICT it''s intended to be portable code (it was available as source and
as a DOS binary, but mention was made of UNIX in the readme - I am
compiling under Mac OS X, fwiw).

It probably once was portable, but apparently uses some obsolete
snippets because it wouldn''t compile without some changes.

After searching the web I managed to get the code to compile but it
required that I simplify some error handling which I feel ought to be
better ''updated''.

Here are the relevant bits:
//#include <malloc.h> // commented out by me
#include <stdlib.h> // added by me

//plenty of unaltered code snipped

FILE *
efopen(name,mode)
char *name;
char *mode;
{
FILE *f;
extern int errno;

// extern char *sys_errlist[]; // commented out by me
// extern int sys_nerr; // commented out by me

char *errmess;

if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open ''%s''!\n",name);

/* // this chunk commented out by me

if ( errno <= sys_nerr )
errmess = sys_errlist[errno];
else
errmess = "Unknown error!";

*/

errmess = strerror(errno); // added by me

(void) fprintf(stderr,"************* Reason: %s\n",errmess);
exit(1);
}
return(f);
}

This code compiles just fine, and it also works as intended, but I
assume it will fail much less gracefully if I send a ''bad'' file to the
program.

I assume I did the right thing changing the #include directive from
malloc.h to stdlib.h

I realised I needed to find a more modern equivalent of sys_errlist and
sys_nerr, - a web search led me to discover that sys_errlist is
deprecated, and to put together the single line I added.

I also learned that strerror is provided by stdio.h (which was already
#included). All well and good, but I have no clue how to reinstate the
''if'' test and make the error handling more robust.

Thanks in advance for any assistance!

Brennan Young opined:
Hi there,

First I''ll apologise for my ignorance!

I have been attempting to compile some code that I found on the net.

AFAICT it''s intended to be portable code (it was available as source
and as a DOS binary, but mention was made of UNIX in the readme - I
am compiling under Mac OS X, fwiw).

It probably once was portable, but apparently uses some obsolete
snippets because it wouldn''t compile without some changes.

After searching the web I managed to get the code to compile but it
required that I simplify some error handling which I feel ought to be
better ''updated''.

Here are the relevant bits:
//#include <malloc.h> // commented out by me
#include <stdlib.h> // added by me
#include <errno.h>
#include <string.h>

You''ll need it below...

//plenty of unaltered code snipped

FILE *
efopen(name,mode)
char *name;
char *mode;
This is ancient style. It''s better:

FILE *efopen(char *name, char *mode)
{
FILE *f;
extern int errno;
Now you don''t need the line above (errno is declared in errno.h).
// extern char *sys_errlist[]; // commented out by me
// extern int sys_nerr; // commented out by me
This is some ancient, system-specific system of mapping error messages
to error codes. Now you should use `strerr()`.
char *errmess;
You could put:

errno = 0;

as the Standard only specifies that it''s set to 0 at program startup,
and library function /may/ set it to positive value (NB, error or no
error!), but never to zero. Here''s also the relevant paragraph from
the Standard:

7.5p3
The value of errno is zero at program startup, but is never set
to zero by any library function. The value of errno may be
set to nonzero by a library function call whether or not there
is an error, provided the use of errno is not documented in the
description of the function in this International Standard.
if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open
''%s''!\n",name);

/* // this chunk commented out by me

if ( errno <= sys_nerr )
errmess = sys_errlist[errno];
else
errmess = "Unknown error!";

*/
if (errno)
errmess = strerror(errno); // added by me

Is what you want here.

(void) fprintf(stderr,"************* Reason: %s\n",errmess);
exit(1);
}
return(f);
}

This code compiles just fine, and it also works as intended, but I
assume it will fail much less gracefully if I send a ''bad'' file to
the program.
It may, or it may not, depending on the implementation. I think
Standard does not guarantee that `strerror()` will return anything
sensible (it just talks of returning a pointer to "a message").
I assume I did the right thing changing the #include directive from
malloc.h to stdlib.h
Yes. You also need <errno.h> and <string.h> for error handling.
I realised I needed to find a more modern equivalent of sys_errlist
and sys_nerr, - a web search led me to discover that sys_errlist is
deprecated, and to put together the single line I added.

I also learned that strerror is provided by stdio.h (which was
already #included).



I think it''s only in <string.h>, but may be wrong.

HTH

--
BR, Vladimir

You will pioneer the first Martian colony.


Brennan Young wrote:
Hi there,

First I''ll apologise for my ignorance!

I have been attempting to compile some code that I found on the net.

AFAICT it''s intended to be portable code (it was available as source and
as a DOS binary, but mention was made of UNIX in the readme - I am
compiling under Mac OS X, fwiw).

It probably once was portable, but apparently uses some obsolete
snippets because it wouldn''t compile without some changes.

After searching the web I managed to get the code to compile but it
required that I simplify some error handling which I feel ought to be
better ''updated''.

Here are the relevant bits:
//#include <malloc.h> // commented out by me
#include <stdlib.h> // added by me

//plenty of unaltered code snipped

FILE *
efopen(name,mode)
char *name;
char *mode;
{
FILE *f;
extern int errno;

// extern char *sys_errlist[]; // commented out by me
This most likely contains mappings for the error number to the error
text, however without seeing the actual definitions all I can do is
guess. If this is the case, take a look at strerror(). Also perror()
would work just fine here.
// extern int sys_nerr; // commented out by me
There is errno which is provided by errno.h that you can use for this.

char *errmess;

if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open ''%s''!\n",name);
Given the above information, this can be changed to:

if((f = fopen(name, mode)) == NULL) {
perror("fopen");

/* // this chunk commented out by me

if ( errno <= sys_nerr )
errmess = sys_errlist[errno];
else
errmess = "Unknown error!";

*/
You can leave this out. We are already doing this above with perror().

errmess = strerror(errno); // added by me

(void) fprintf(stderr,"************* Reason: %s\n",errmess);
The above two lines are redundant now as well.
exit(1);
Sloppy. You might want to use EXIT_FAILURE here instead.
}
return(f);
}

This code compiles just fine, and it also works as intended, but I
assume it will fail much less gracefully if I send a ''bad'' file to the
program.
Actually no, it won''t. It will fail just as gracefully as it did before
you made the changes, the only different is that with your changes it
will not print out an error message upon failure (which could be a Bad
Thing(tm)).

I assume I did the right thing changing the #include directive from
malloc.h to stdlib.h
Yes.

I realised I needed to find a more modern equivalent of sys_errlist and
sys_nerr, - a web search led me to discover that sys_errlist is
deprecated, and to put together the single line I added.
You don''t need either one of those.

I also learned that strerror is provided by stdio.h (which was already
#included). All well and good, but I have no clue how to reinstate the
''if'' test and make the error handling more robust.
The error handling looks perfectly fine to me. If fopen() returns NULL
then simply call perror("fopen") to see the error message.

Thanks in advance for any assistance!



No problem, hope that gets you pointed in the right direction.

Joe


On 2006-03-19, Joe Estock <je*****@NOSPAMnutextonline.com> wrote:
Brennan Young wrote:
Hi there,

First I''ll apologise for my ignorance!

I have been attempting to compile some code that I found on the net.

AFAICT it''s intended to be portable code (it was available as source and
as a DOS binary, but mention was made of UNIX in the readme - I am
compiling under Mac OS X, fwiw).

It probably once was portable, but apparently uses some obsolete
snippets because it wouldn''t compile without some changes.

After searching the web I managed to get the code to compile but it
required that I simplify some error handling which I feel ought to be
better ''updated''.

Here are the relevant bits:
//#include <malloc.h> // commented out by me
#include <stdlib.h> // added by me

//plenty of unaltered code snipped

FILE *
efopen(name,mode)
char *name;
char *mode;
{
FILE *f;
extern int errno;

// extern char *sys_errlist[]; // commented out by me



This most likely contains mappings for the error number to the error
text, however without seeing the actual definitions all I can do is
guess. If this is the case, take a look at strerror(). Also perror()
would work just fine here.

// extern int sys_nerr; // commented out by me



There is errno which is provided by errno.h that you can use for this.



sys_nerr is the total number of entries in sys_errlist, NOT an index.

[well, it can be whatever an implementation wants it to be, but my guess
is more likely to be right than yours]

char *errmess;

if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open ''%s''!\n",name);



Given the above information, this can be changed to:

if((f = fopen(name, mode)) == NULL) {
perror("fopen");



I''d have used perror(name) instead.