[Haifux] OT: PROG question: regarding returning errors in libraries
hi, as part of writing various programming libraries, i keep stumbling on the issue of returning errors (this includes the issue of a function notifying its calling funciton that it had an error - and what that error was, in a way that will allow the calling funciton to both handle the error, and [optionally] report it to the user. right now, i'm not interested in how to actually report the error to the user or the programmer). the following 'discussion' focuses on programming in C, and is thus limited to features supported by the C language. i am aware of several 'error reporting' models: 1. C's errno - there is a global (or a global-per-thread, in multi threaded environments) variable in which an error code is returned, in case the function invoked failed. all error codes come form one pool of error types - and should be interpreted by the caller, in the context of the specific function invoked (i.e. ENOSPC for a semaphore creation is not the same as ENOSPC for writing into a file). this makes it easy for the programmer to remember the different error codes (cause they repeat all the time in all programs). on the other hand - if a function has some specific errors, adding them to the large pool of error codes seems irrelevant. there is a function that translates the error code into a human-readable string (strerror) - but there is no way to supply an error-specific error string - this is left for the caller to do. this is ok when the functions perform little tasks - but is insufficient when the function does a complex job (e.g. recursively delete a directory) - and we need to give some context in the errors. another advantage of this mechanism is that every C programmer is familiar with it, and thus will learn it easily, if it comes in a different library. in fact, libraries may even piggy-back on top of it, and return their own errors inside the global 'errno' variable. another problem with this mechanism - the error code must be checked/stored immediately after the call, since calling another function might change this global 'errno'. this is especially annoying (and prone to errors) if we need to make some cleanup if there was an error (e.g. a function that needs to check the 'magic number' of a file - it needs to open the file, read the magic number with a 'read' call. if the 'read' fails, we want to report its errno to the user - but we need to first close the file - and this close might change the value of errno - and thus we need to temporarily store errno's value before the clode, so as not to loose it. 2. specific error codes set per function - in this manner, each function defines its own set of error codes. it should also need to supply its own error string, since it can no longer be derived by a single global function. this makes the error reporting flexible, and somewhat 'type save' (one could define an enum for the error codes of a given function in the library, and then the user can make a 'switch' on the various error codes, with the compiler warning them if they forgot to check one of the possible values. the problem is this makes the programmer have to remember (or look-up often) the error codes for different functions. this is especially annoying when propagating errors back to the caller. 3. the function returns the error code by itself (with either a per-function errors enum, or a global list of error codes - with one value for 'success'). this puts consistency into the code (every function that might fail reports an error code) - while making the interface less convinient, when the funciton could sometimes have returned a pointer (e.g. the 'fopen' functoin returns a pointer to a FILE on success, or NULL on failure - and this works because it can report the error code in the global 'errno' variable). there could also be the model of 'only report success or failure - the error code itself does not matter' - which is valid for certain situations (e.g when there's nothing to do with the eror, except for freeing the resource for which it was done and aborting the operation, without reporting anything else to the user). i wonder what people here have to add regarding these models, or regarding other models (again - for the C language) they have used, or wanted to try to use. if you comment - please state if you're talking about somehting you used, something you've started using lately, or something you didn't yet use. or if its soemthing you've read about somewhere. and please be fair - i.e. when you describe your magnificent no-problem error reporting system, please also state what are the bad parts of it - where it was annoying, what in it would you improve if you had the time, or if you had an idea how to do, etc. thanks, -- guy For world domination - press 1, or dial 0,
[Haifux] Re: OT: PROG question: regarding returning errors in libraries
On Fri, Feb 07, 2003 at 03:18:41PM +0200, guy keren wrote: 3. the function returns the error code by itself (with either a per-function errors enum, or a global list of error codes - with one value for 'success'). this puts consistency into the code (every function that might fail reports an error code) - while making the interface less convinient, when the funciton could sometimes have returned a pointer (e.g. the 'fopen' functoin returns a pointer to a FILE on success, or NULL on failure - and this works because it can report the error code in the global 'errno' variable). I like this mode, and the single project every Linux user uses uses it. You return -ERRNO to signify error, and 0 on success. As for a less convenient, either you pass the 'errno' variable, or the pointer parameter by reference. Another alternative is use the ugly ERR_PTR and PTR_ERR macros, to return a small numeric value (errno) in the high bits of a pointer, when the function returns a pointer. i wonder what people here have to add regarding these models, or regarding other models (again - for the C language) they have used, or wanted to try to use. I've used all three, and the most important issues have been: 1. Always remain consistent. Make sure that all functions return error values in the same range, or use the same value(s) to return an error or success. 2. Global errno is bad, because you might inadvertently change its value by making a different call before checking it. 3. Each function having its own return codes is not consistent, and thus breaks point (1) above. For new code I write (and even old code I have occasion to modify), I always use the kernel's -ERRNO for failure, 0 for success mode. if you comment - please state if you're talking about somehting you used, something you've started using lately, or something you didn't yet use. or if its soemthing you've read about somewhere. and please be fair - i.e. when you describe your magnificent no-problem error reporting system, please also state what are the bad parts of it - where it was annoying, what in it would you improve if you had the time, or if you had an idea how to do, etc. I really dislike the ERR_PTR and PTR_ERR macros mentioned above. If I was rewriting the kernel, I would probably make all those places pass the pointer by reference and return an int. -- Muli Ben-Yehuda http://www.mulix.org http://syscalltrack.sf.net -- Haifa Linux Club Mailing List (http://www.haifux.org) To unsub send an empty message to [EMAIL PROTECTED]
[Haifux] Aviram Jenik on Network Security
On April 14, at 18:30, Aviram Jenik, CEO of Beyond Security, will give a talk at Haifux. Please let me know which of the following subject you'd prefer to hear: Network Security Basics This basic network security course gives network developers and administrators a quick primer in network security, by showing common attack methods that are used by attackers every day on the Internet, along with some of the common solutions (firewalls, proxies) that are commonly used. Understanding Network Security This course introduces network security and shows the reasons behind the current wave of security holes in the Internet, the ways and tools hackers employ when doing attacks, and the different types of attacks: network level, service level, and application level. The course will also cover Denial-of-Service attacks (DoS and DDoS) and some common solutions that exist to defend against every class of attack. Live demonstrations and examples will be shown during the day. Advanced Network Security - security auditing The course will cover practical ways to perform security auditing in the organization with specific focus on showing and demonstrating common tools, guidelines and so on. The course is intended for a technical audience and will include live demonstrations and in-depth explanations. Advanced Network Security - inside application level attacks Application level attacks are a hot buzzword, but unfortunately not many programmers and software developers are aware of the possible security holes in their applications. This course will show common attack methods such as buffer overflow, SQL injection, cross site scripting, race conditions, and other application-level attacks that are used widely by attackers and are exploitable on almost every known platform and OS. Advanced Network Security - wireless security Wireless communication is considered by security experts to be one of the largest security risks to organizations today. This course will explain and demonstrate the reasons for this inherent insecurity, and show practical ways to secure wireless networks. The course will also discuss the future of wireless security and the upcoming technologies in the field. -- Muli Ben-Yehuda http://www.mulix.org http://syscalltrack.sf.net -- Haifa Linux Club Mailing List (http://www.haifux.org) To unsub send an empty message to [EMAIL PROTECTED]
Re: [Haifux] OT: PROG question: regarding returning errors inlibraries
Hi, Another error handling model I encountered is using an error handler (a function which is called when something goes wrong). I have encountered this error handling model in two main libraries: 1) Xlib. The default handler displays an error message and calls exit(), but can be replaced by something more appropriate 2) IPL (Intel's performance library for image processing) uses a similar model, but it is slightly improved. Each function in IPL returns a status code, but it also uses an error handling function. The programmer has the possibility to specify the behavior of the library during error conditions: -fail at the leafs of the call tree (invoke the error handler from the deepest calling level inside the library) -fail at the parents of the call tree (invoke the error handler from most shallow calling level inside the library) -fail silently (i.e. do not call the error handler), just return the error code. The default error handling mode is set to leaf mode with the default error handler printing a stack trace. Looks like a nice and highly flexible model. 3) And there is OpenGL in which all functions fail silently (many of them return void). The programmer has to check whether an error occured (using something a'la errno, but the error code is not modified after the first error occurred). In OpenGL performance is the highest priority, so they somehow discourage code which checks whether an error occurred after each function. But debugging can be a nightmare ;-) In the few libraries I have written, I use style #3 from your list. Emil On Fri, 7 Feb 2003, guy keren wrote: hi, as part of writing various programming libraries, i keep stumbling on the issue of returning errors (this includes the issue of a function notifying its calling funciton that it had an error - and what that error was, in a way that will allow the calling funciton to both handle the error, and [optionally] report it to the user. right now, i'm not interested in how to actually report the error to the user or the programmer). the following 'discussion' focuses on programming in C, andis thus limited to features supported by the C language. i am aware of several 'error reporting' models: 1. C's errno - there is a global (or a global-per-thread, in multi threaded environments) variable in which an error code is returned, in case the function invoked failed. all error codes come form one pool of error types - and should be interpreted by the caller, in the context of the specific function invoked (i.e. ENOSPC for a semaphore creation is not the same as ENOSPC for writing into a file). this makes it easy for the programmer to remember the different error codes (cause they repeat all the time in all programs). on the other hand - if a function has some specific errors, adding them to the large pool of error codes seems irrelevant. there is a function that translates the error code into a human-readable string (strerror) - but there is no way to supply an error-specific error string - this is left for the caller to do. this is ok when the functions perform little tasks - but is insufficient when the function does a complex job (e.g. recursively delete a directory) - and we need to give some context in the errors. another advantage of this mechanism is that every C programmer is familiar with it, and thus will learn it easily, if it comes in a different library. in fact, libraries may even piggy-back on top of it, and return their own errors inside the global 'errno' variable. another problem with this mechanism - the error code must be checked/stored immediately after the call, since calling another function might change this global 'errno'. this is especially annoying (and prone to errors) if we need to make some cleanup if there was an error (e.g. a function that needs to check the 'magic number' of a file - it needs to open the file, read the magic number with a 'read' call. if the 'read' fails, we want to report its errno to the user - but we need to first close the file - and this close might change the value of errno - and thus we need to temporarily store errno's value before the clode, so as not to loose it. 2. specific error codes set per function - in this manner, each function defines its own set of error codes. it should also need to supply its own error string, since it can no longer be derived by a single global function. this makes the error reporting flexible, and somewhat 'type save' (one could define an enum for the error codes of a given function in the library, and then the user can make a 'switch' on the various error codes, with the compiler warning them if they forgot to check one of the possible values. the problem is this makes the programmer have to remember (or look-up often) the error codes for different