Windows has different types of status codes, HRESULT and NTSTATUS for instance, that allow for representing both success and failure values. This allows for macros like FAILED and NT_SUCCESS. One example of a success status code is STATUS_PENDING that indicates an IO is not yet complete.
I'm trying to map similar style status codes in Linux. I have a (WIP) cross platform library that uses the above type of status codes on Windows (user mode and kernel mode). I have my own "FAILED" macro that wraps the above macros. I need an equivalent for Linux for it all.
I've looked around and haven't found anything interesting/helpful. For any system/platform function (sockets, thread, locks) that might return and error, I need to make sure it is converted to the appropriate status code type. Windows has lots of helpers for things like this, but I'm not sure about Linux.
Psuedocode example:
MY_STATUS SendAsync(...) {
ASYNC_OPERATION* Operation = MY_ALLOC(...)
if (Operation == NULL) {
return MY_OUT_OF_MEMORY_ERROR; // Error status
}
// Build the operation
MY_STATUS Status = QueueOperation(Operation);
if (MY_FAILED(Status)) {
return Status;
}
return MY_STATUS_PENDING; // Success status
}
The caller should then be able to have the following code:
MY_STATUS Status = SendAsync(...)
if (MY_FAILED(Status)) {
// Bail
}
// Handle success
I think the crux of the problem is that I don't know how to stuff status codes from system/platform function calls into a generic type that supports success/fail. Generally, it looks like all the status codes are positive, so I could just say my success error codes are <= 0. But I'm not sure that's a great solution.
To be clear, since it was proposed that this question might the answer, I'm not trying to force the Linux status/error codes into HRESULT format explicitly. I'm just trying to find some way to represent error codes as either success or failure. If I have to convert system error codes (negate them?) along the way, that's acceptable. If there is no real solution to this problem, then that would be an acceptable answer (though not desired), and I'll have to find some work around.
For error codes in linux there are the constants defined in errno.h header file. The error constants are available from man page man 3 errno. Also there is: What errno means
As for exit status codes, there is no standard set of codes. The value 0 has always denoting success, and non-zero value has denoted an error state. Bash, for example has this Bash exit status information.
All of the Bash builtins return an exit status of zero if they succeed
and a non-zero status on failure, so they may be used by the
conditional and list constructs. All builtins return an exit status of
2 to indicate incorrect usage, generally invalid options or missing
arguments.
There is sysexits which was an attempt to define a set of status codes, but it has been largely ignored in the field of linux software.
For more info: Exit Status codes in Linux
To get the error return code from a function in Linux, use the function's return value (usually nonzero on error) and the value of the errno variable, from errno.h.
Search for "linux errno codes" or run man errno on Linux to get more information.
errno (and return statuses) are usually represented as an int, so that's what I'd go with if you're looking for a type to use.
For example, checking to see if the return code of non-blocking connect is negative one and errno is EINPROGRESS is the same as checking for STATUS_PENDING in Windows.
Here's some pseudocode to respond to your pseudocode example:
#ifdef _WIN32
typedef /* Windows stuff */ MY_STATUS;
# define MY_FAILED(x) /* Windows stuff */
#else /* POSIX, other reasonable operating systems, etc. */
typedef int MY_STATUS;
# define MY_FAILED(x) ((x) == -1)
#endif
Of course, this assumes that your functions will return int or something similar, which may not be the case. But you get the idea.
Related
I've created a publisher-subscriber communication scheme with ZeroMQ and I noticed one small issue with my server and client programs.
I know there is no try catch in C (according to my brief research) however having the next two while(1) without an exception catching seems dangerous to me.
Taking into account the following code snippets, what would be the most correct way to handle an exception (inside the while)? With the structure I have right now (as you can see below), the zmq_close and zmq_ctx_destroy will never execute, but I want them to, in case of a program error/exception (whichever the origin).
Note: In this architecture I have one client listening to multiple publishers, thus the for cycles in the Client code.
Server
(...inside main)
while (1) {
char update[20];
sprintf(update, "%s", "new_update");
s_send(publisher, update);
sleep(1);
}
zmq_close(publisher);
zmq_ctx_destroy(context);
return 0;
Client
(...inside main)
while(1){
for (c = 1; c < server_num; c = c + 1){
char *msg = s_recv(subscribers[c]);
if (msg) {
printf("%s\n",msg);
free(msg);
}
sleep(1);
}
}
for (c = 0; c < server_num; c = c + 1)
zmq_close(subscribers[c]);
zmq_ctx_destroy(context);
return 0;
In case one has never worked with ZeroMQ,
or have never met the concept of the art of Zen-of-Zero,
one may here enjoy to first look at "ZeroMQ Principles in less than Five Seconds" before diving into further details
Being the tag error-handling present ... :
Q : what would be the most correct way to handle an exception (inside the while)?
The best strategy is an error-prevention rather than any kind of "reactive" ( ex-post Exception ) handling.
Always assume the things may and will turn wreck havoc and let them fail cheaply. The cheaper the costs of failings are, the better and sooner the system may turn back into its own, intended behaviour.
This said, in modern low-latency distributed-systems, the more in real-time-systems an exception is extremely expensive, disruptive element of the designed code-execution flow.
For these reasons, and for allowing sustained levels of the utmost performance too,
ZeroMQ has since ever a very different approach :
0)
better use zmq_poll() as a cheapest ever detection of a presence ( or not presence ) of any read-able message ( already delivered and being ready so as to be received ), before ever, if at all, calling an API function of a zmq_recv(), to fetch such data into your application-level code's hands, from inside the Context()-instance internal storage.
1)
depending on your language binding (wrapper), best enjoy the non-blocking forms of the .poll(), .send() and .recv() methods. The native API is the most straightforward in always going in this mode with retCode = zmq_recv( ..., ZMQ_NOBLOCK );
2)
Always analyse the retCode - be it in a silent or explanatory assert( retCode == 0 && zmq_errno() ) or otherwise.
3)
Best review and fine-tune all configuration attributes of the instantiated tools available from ZeroMQ framework and harness all their hidden strengths to best match your application domain's needs. Many native API-settings may help mitigate, if not principally avoid, lots of colliding requirements right inside the Context()-engine instance, so do not hesitate to learn all details of possible settings and use them to the best of their help for your code.
Without doing all of this above, your code is not making the best of the Zen-of-Zero
Q : With the structure I have right now (...), the zmq_close and zmq_ctx_destroy will never execute, but I want them to, in case of a program error/exception (whichever the origin).
it is fair enough to set an explicit flag:
bool DoNotExitSoFar = True;
while ( DoNotExitSoFar ){
// Do whatever you need
// Record return-codes, always
retCode = zmq_...(...);
// Test/Set the explicit flag upon a context of retCode and zmq_errno()
if ( retCode == EPROTONOTSUPPORTED ){
// take all due measures needed
...
// FINALLY: Set
DoNotExitSoFar = False;
}
}
// --------------------------------------------- GRACEFUL TERMINATION .close()
if ( ENOTSOCK == zmq_close(...) ) { ...; }
...
// --------------------------------------------- GRACEFUL TERMINATION .term()
retCode = zmq_ctx_term(...);
if ( EINTR == retCode ){ ...; }
if ( EFAULT == retCode ){ ...; }
...
Using other tooling, like int atexit(void (*func)(void)); may serve as the last resort for a ALAP calling zmq_close() or zmq_ctx_term()
You are correct, C has no concept of try/catch, but that shouldn't be an issue. It just means you need to handle exceptions in the s_send() and s_recv() routines (so, for example, if something unexpected happens (like malloc() returning NULL), you have to deal with it and continue processing or return).
I would also suggest you look at the poll() or select() system calls for your client instead of doing a looping poll. It's much more elegant to only service the file descriptors that have data waiting to be read.
The idiomatic way in C to check for error is to look the return value and then check errno if it's negative.
// ... Your previous code
int ret = zmq_ctx_destroy(context);
if(ret < 0) {
// Process your error here
printf("My error message is : %s\n", strerror(errno));
}
You may need to add #include <errno.h> and <string.h> if it's not already in your program.
You can also read strerror documentation.
Now to adress this part of the question :
Taking into account the following code snippets, what would be the most correct way to handle an exception (inside the while)? With the structure I have right now (as you can see below), the zmq_close and zmq_ctx_destroy will never execute, but I want them to, in case of a program error/exception (whichever the origin).
All zmq_* functions will return an error and set errno. Check every function and break when an error occur. In that scenario, polling on non-blocking function is best to break out of your whileloop when an error occurs.
On Linux, you can also set a signal handler and execute a clean up routine when a singal is raised (for example, it is very common to catch SIGINT to properly exit a program on UNIX on ctrl+C in the console). See this answer
Is this the correct way to do error handling in OpenSSL?
And what is the difference between SSL_get_error and ERR_get_error?
The docs are quite vague in this regard.
int ssl_shutdown(SSL *ssl_connection)
{
int rv, err;
ERR_clear_error();
rv = SSL_shutdown(ssl_connection);
if (rv == 0)
SSL_shutdown(ssl_connection);
if (rv < 0)
{
err = SSL_get_error(ssl_connection, rv);
if (err == SSL_ERROR_SSL)
fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
fprintf(stderr, "%s\n", SSL_state_string(ssl_connection));
return 1;
}
SSL_free(ssl_connection);
return 0;
}
SSL_get_error:
SSL_get_error() returns a result code (suitable for the C "switch"
statement) for a preceding call to SSL_connect(), SSL_accept(),
SSL_do_handshake(), SSL_read(), SSL_peek(), or SSL_write() on ssl. The
value returned by that TLS/SSL I/O function must be passed to
SSL_get_error() in parameter ret.
ERR_get_error:
ERR_get_error() returns the earliest error code from the thread's
error queue and removes the entry. This function can be called
repeatedly until there are no more error codes to return.
So the latter is for more general use and those shouldn't be used together, because:
The current thread's error queue must be empty before the TLS/SSL I/O operation is attempted, or SSL_get_error() will not work reliably.
So you have to read all of the errors using ERR_get_error and handle them (or ignore them by removal as you did in your code sample with ERR_clear_error) and then perform the IO operation. Your approach seems to be correct, although I can't check all aspects of it by myself at the moment.
Refer to this answer and this post for more information.
EDIT: according to this tutorial, BIO_ routines may generate an error and affect error queue:
The third field is the name of the package that generated the error,
such as "BIO routines" or "bignum routines".
And what is the difference between SSL_get_error and ERR_get_error?
There are two logical parts to OpenSSL. First is the SSL library, libssl.a (and libssl.so), and it includes the communication related stuff. Second is the cryptography library, libcrypto.a (and libcrypto.so), and it includes big numbers, configuration, input/output, etc.
libssl.a depends upon libcrypto.a, and its why the link command is ordered as -lssl -lcrypto.
You use SSL_get_error to retrieve most errors from the SSL portion library, and you use ERR_get_error to retrieve errors not in the SSL portion of the library.
Is this the correct way to do error handling in OpenSSL?
The code you showed is closer to "how do you shutdown a SSL socket". Ultimately, the gyrations control two cases. First is a half open connection, when the client shutdowns without sending the close notify message. The second is your program's behavior when sending the close notify message.
Its hard to answer "is it correct" because we don't know the behavior you want. If you don't care if the close notify is sent, then I believe you only need to call SSL_shutdown once, regardless of what the client does.
I've done the following code to test the use of ioctl and I'm pretty confused about the results.
int main(void)
{
int id;
dvd_struct s;
id=open("/dev/dvd",O_RDONLY);
ioctl(id,DVD_READ_STRUCT,&s);
printf("%d,%s,%s",s.bca.len,s.manufact.value,s.disckey.value);
close(id);
}
First of all in manufact and disckey value rare symbols appear, but that wouldn't be that important, if it weren't because any time I run the program a new value appears, despite always keeping the dvd in the dvd player. Even bca.len varies in each execution, although it's true that it alway gives a number above 32000 and lower than 33000.
Finally the results are given whether there's an inserted dvd or not, so I wonder where it's getting exactly those results from, even if it's reading the dvd.
The dvd is being recognized by the operating system, as a cat /dev/dvd displays it's content in a fine way.
Can someone explain why is it working that way and if I could make it work appropiately (I mean, getting the same results at least for manufact and disckey values and making sure the info is taken from the inserted dvd?
Thanks for your attention.
Check the return value of ioctl. If it fails s will not filled with infos.
if (ioctl(id, DVD_READ_STRUCT, &s) < 0)
{
perror("DVD_READ_STRUCT");
return -1;
}
Man
RETURN VALUE
Usually, on success zero is returned. A few ioctl() requests use the
return value as an output parameter and return a nonnegative value on
success. On error, -1 is returned, and errno is set appropriately.
ERRORS
EBADF fd is not a valid descriptor.
EFAULT argp references an inaccessible memory area.
EINVAL request or argp is not valid.
ENOTTY fd is not associated with a character special device.
ENOTTY The specified request does not apply to the kind of object
that the descriptor fd references.
BTW always check return values of non void function.
Thanks, for your tips, I got to solve it via a code similar to this one that is inserted before the ioctl call:
memset(&s, 0, sizeof(s));
s.type = DVD_STRUCT_MANUFACT;
You must set a type for s and you'll get the ones related to that type and do the same for every otrher type.
For example, if it failed to invoke msgsnd/msgrcv:
How to handle the errno – what is the best way?
What principle is applying to business product?
Shall I have to cover all of them?
What kinds of error must be handled? Do I have to write a signal handler for EINTR or something like this?
Here's my straw-man code:
RetVal = msgrcv(... );
if( RetVal == -1 )
{
switch (errno)
{
case E2BIG:
...
case EAGAIN:
...
case EFAULT:
...
case EIDRM:
...
case EINTR:
...
case EINVAL:
...
case ENOMEM:
...
default:
...
}
This depends on the coding standards you want to apply, and how you might reasonably respond to the failures.
You should always check errors, but you might commonly only handle one or two of them such as EINTR. I would at least try to print some kind of diagnostic last-gasp message before violently exiting in the case of unexpected errors.
The more critical the software, the more carefuly-designed it needs to be, and more comprehensive error handling is part of that.
Since your tags are "C" and "Linux" I assume you're using GCC, in which case have a look at the handy %m in printf.
Obviously this too simple for some cases, but until your program is finished something like this is a good stub to have.
if(RetVal == -1) {
perror("message receive");
exit(1);
}
Typically, one only looks at the exact error if a specific recovery is called for in that case. Until you have some code that you need to make conditional on exactly the type of error, you should simply decide between...
Silently ignore the error
Warn, and then continue
Complain, and then exit
See also...
the nonstandard-but-useful err(3).
setjmp, longjmp, sigsetjmp, et al
It depends on your code and what you can do (similar to exception) and what error you have received. For example EAGAIN is not a strictly an error (it denotes that you tried non-blocking operation and it would block).
If it is a quick program you may do nothing (say - you just playing with API). If it has GUI it might display a message (say "disk is full" or "cannot connect to network") etc.
If the question had an ultimate answer there would be no need for errno - system call could do it as well.
The basic Linux system calls almost universally return -1 on error, and 0 or positive value on success. Also, the errno is set to one of the predefined values. So, checking failure of system calls is pretty easy and should be done consistently. Checking the errno for what type of error occurs should be done for the errors you can handle in your program itself. For other errors, it is best to inform the user that he made an error and notify him with the error. The strerror() in the string.h takes erroro as the parameter and returns a pointer to string describing the error.
#include<string.h>
char* strerror(int errno);
After telling the error, it is on the severity of the error whether to continut running the program or exit the program by
exit(1);
I am using the library Function ConnectToTCPServer. This function times out when the host is not reachable. In that case the application crashes with the following error:
"NON-FATAL RUN-TIME ERROR: "MyClient.c", line 93, col 15, thread id 0x000017F0: Library function error (return value == -11 [0xfffffff5]). Timeout error"
The Errorcode 11 is a Timeout error, so this could happen quite often in my application - however the application crashes - i would like to catch this error rather than having my application crash.
How can i catch this runtime error in Ansi C90?
EDIT:
Here is a Codesnippet of the current use:
ConnectToTCPServer(&srvHandle, srvPort, srvName, HPMClientCb, answer, timeout);
with
int HPMClientCb(UINT handle, int xType, int errCode, void *transData){
printf("This was never printed\n");
return errCode;
}
The Callbackfunction is never called. My Server is not running, so ConnectToTCPServer will timeout. I would suspect that the callback is called - but it never is called.
EDIT 2: The Callback function is actually not called, the Returnvalue of ConnectToTCPServer contains the same error information. I think it might be a bug that ConnectToTCPServer throws this error. I just need to catch it and bin it in C90. Any Ideas?
EDIT 3: I tested the Callbackfunction, on the rare occaision that my server is online the callback function is actually called - this does not help though because the callback is not called when an error occurs.
Looking in NI documentation, I see this:
"Library error breakpoints -- You can set an option to break program execution whenever a LabWindows/CVI library function returns an error during run time. "
I would speculate they have a debug option to cause the program to stop on run-time errors, which you need to disable in configuration, in compile time or in run-time.
My first guess would have been configuration value or compilation flag, but this is the only option I found, which is a run-time option:
// If debugging is enabled, this function directs LabWindows/CVI not
// to display a run-time error dialog box when a National Instruments
// library function reports an error.
DisableBreakOnLibraryErrors();
Say if it helped.
Theres no such thing as a general case of "catching" an error (or an 'exception') in standard C. Thats up to your library to decide what to do with it. Likely its logging its state and then simply calling abort(). In Unix, that signals SIGABRT which can be handled and not just exit()ed. Or their library may just be logging and then calling exit().
You could run your application under a utility like strace to see what system calls are being performed and what signals are being asserted.
I'd work with your vendor if you can't make any headway otherwise.
From the documentation, it seems you should get a call to your clientCallbackFunction when an error occurs. If you don't, you should edit your question to clarify that.
I'm not sure I understand you.
I looked at the documentation for the library function ConnectToTCPServer(). It returns an int; 0 means success, negative numbers are the error codes.
EDIT: Here is a Codesnippet of the
current use:
ConnectToTCPServer(&srvHandle, srvPort, srvName, HPMClientCb, answer, timeout);
If that's really the current use, you don't seem to be trying to tell whether ConnectToTCPServer() succeeds. To do that, you'd need
int err_code;
...
err_code = ConnectToTCPServer(&srvHandle, srvPort, srvName, HPMClientCb, answer, timeout);
and then test err_code.
The documentation for ConnectToTCPServer()implies that your callback function won't be called unless there's a message from a TCP server. No server, no message. In that case,
ConnectToTCPServer() should return a negative number.
You should check the return value of ConnectToTCPServer().
Finding a negative number there, you should do something sensible.
Did I understand the documentation correctly?
Normally, you should be able to simply check the return value. The fact that your application exits implies that something is already catching the error and asserting (or something similar). Without seeing any context (i.e. code demonstrating how you're using this function), it's difficult to be any more precise.
The documentation states that ConnectToTCPServer will return the error code. The callback is only called if the connection is established, disconnected or when there is data ready to be read.
The message you get states that the error is NON-FATAL, hence it shouldn't abort. If you're sure the code doesn't abort later it seems indeed like a bug in the library.
I'm not familiar with CVI, but there might be a (compile-/runtime-) option to abort even on non-fatal errors (for debugging purposes). If you can reproduce this in a minimal example you should report it to NI.