1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1996, by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 /*
28  * MKS interface extension.
29  * Ensure that errno is set if malloc() fails.
30  *
31  * Copyright 1992 by Mortice Kern Systems Inc.  All rights reserved.
32  *
33  */
34 #ifdef M_RCSID
35 #ifndef lint
36 static char rcsID[] = "$Header: /rd/src/libc/mks/rcs/m_malloc.c 1.4 1993/12/17 15:22:04 rog Exp $";
37 #endif /*lint*/
38 #endif /*M_RCSID*/
39 
40 #include <mks.h>
41 #include <errno.h>
42 #include <stdlib.h>
43 
44 #ifdef __STDC__
45 #define _VOID	void
46 #else
47 #define _VOID	char
48 #endif
49 
50 #undef m_malloc	   /* in case <mks.h> included in <errno.h> or <stdlib.h> */
51 
52 /*f
53  * m_malloc:
54  *   Portable replacement for malloc().
55  *   If malloc() fails (e.g returns NULL)
56  *   then return ENOMEM unless malloc() sets errno for us on this system
57  *   and ensure malloc(0) returns a non-NULL pointer.
58  *
59  */
60 _VOID*
m_malloc(amount)61 m_malloc(amount)
62 size_t amount;
63 {
64 	_VOID* ptr;
65 
66 	/*l
67 	 * Prob 1:
68 	 *  ANSI does not insist setting errno when malloc() fails.
69 	 *  But UNIX existing practice (which MKS relies on) always returns
70 	 *  an errno when malloc() fails.
71 	 *  Thus, on systems that implement malloc() where an errno is not
72 	 *  returned, we set ENOMEM.
73 	 *
74 	 *  Note: we don't care about previous value of errno since
75 	 *        POSIX.1 (Section 2.4) says you can only look at errno
76 	 *        after a function returns a status indicating an error.
77 	 *        (and the function explicitly states an errno value can be
78 	 *         returned - Well, m_malloc() is so stated.)
79 	 *
80 	 * Prob 2:
81          *  MKS code seems to rely on malloc(0) returning a valid pointer.
82 	 *  This allows it to realloc() later when actual size is determined.
83 	 *
84 	 *  According to ANSI (4.10.3 line 18-19) the result of malloc(0) is
85 	 *  implementation-defined.
86 	 */
87 
88 	errno = 0;
89 	if ((ptr = malloc(amount)) == NULL) {
90 		if (amount == 0) {
91 			/*
92 			 *  confirm we are really out of memory
93 			 */
94 			return (m_malloc(1));
95 		}
96 		if (errno==0) {
97 			/*
98 			 *  ensure errno is always set
99 			 */
100 			errno = ENOMEM;
101 		}
102 	}
103 	return (ptr);
104 }
105