Skip to Content.
Sympa Menu

freetds - Re: [freetds] ENOMEM vs. errno

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: christos AT zoulas.com (Christos Zoulas)
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] ENOMEM vs. errno
  • Date: Thu, 6 Dec 2007 13:15:27 -0500

On Dec 6, 7:04pm, freddy77 AT gmail.com (Frediano Ziglio) wrote:
-- Subject: Re: [freetds] ENOMEM vs. errno

|
| Il giorno gio, 06/12/2007 alle 12.06 -0500, James K. Lowden ha scritto:
| > Hi Freddy,
| >
| > I'm surprised by
| >
| > $Id: dblib.c,v 1.312 2007/12/06 07:52:17 freddy77 Exp $
| >
| > which replaces all
| > dbperror(dbproc, SYBEMEM, errno);
| > with
| > dbperror(dbproc, SYBEMEM, ENOMEM);
| >
| > Was yesterday's discussion unclear?
| >
| > If malloc fails, it must set errno to ENOMEM.
| >
| > If malloc does not set errno to ENOMEM, the application should deal with
| > it.
| >
| > db-lib's job in this case is only to convey what malloc(3) said. If
| > malloc returned NULL and didn't set errno to ENOMEM, that's not db-lib's
| > problem. That's for the application to settle with malloc(3). If the
| > application cannot rely on malloc to set errno, it has enough information
| > from SYBEMEM.
| >
| > By hard-coding ENOMEM, you are hiding what actually happened, potentially
| > lying to the application.
| >
| > Remember the application is written in C, too, and uses malloc all the
| > time. It knows how to recognize malloc failures. Win32 even has
| > _set_new_mode() to control how allocation errors are handled. I think it
| > sets errno by default. (The docs don't say so, but they do list ENOMEM as
| > one of the supported errno values.)
| >
| > Would you kindly revert to 1.311?
| >
| > Thanks. If I'm overlooking something, just say so.
| >
| > Regards,
| >
| > --jkl
| >
|
| I compiled this program with MingW
|
| #include <stdio.h>
| #include <stdlib.h>
|
| int main()
| {
| void *p1, *p2, *p3;
| p1 = malloc(0x20000000u);
| p2 = malloc(0x20000000u);
| errno = 123;
| p3 = malloc(0x20000000u);
| printf("%p %p %p %d\n", p1, p2, p3, errno);
| return 0;
| }
|
| And it output
|
| 00540020 00000000 00000000 123
|
| :(
|
| MingW use the "old" msvcrt.dll (Visual C++ 2005 use a new version). As
| Chistos says malloc can set errno only to ENOMEM so I think that
| replacing errno with ENOMEM at the end just remove a problem with
| no-compliant (and existing) malloc implementations.
|
| Another way to fix this issue would be to have somthing like
|
| #ifdef WIN32
| /* fix errno setting in some windows malloc implementations */
| if (msgno == SYBEMEM)
| errnum = ENOMEM;
| #endif
|
| Would you prefer this change?

I think it is less intrusive and also documents what's broken and
how you are working around it. I would say in the comment:

/*
* Unfortunately MingW uses the "old" msvcrt.dll (Visual C++ 2005 uses
* a newer version) which does not set errno when allocation functions
* cannot allocate memory, so we do it for them.
*/

christos




Archive powered by MHonArc 2.6.24.

Top of Page