X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/59e0d9fe772464b93d835d2a2964457702469a43..5f1254882f242514d4ceaf1ecebb140dcc2a511d:/util/opendev.c diff --git a/util/opendev.c b/util/opendev.c index 64ccb07..ee5c85b 100644 --- a/util/opendev.c +++ b/util/opendev.c @@ -1,29 +1,3 @@ -/* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* $OpenBSD: opendev.c,v 1.7 2002/06/09 22:18:43 fgsch Exp $ */ - /* * Copyright (c) 2000, Todd C. Miller. All rights reserved. * Copyright (c) 1996, Jason Downs. All rights reserved. @@ -57,9 +31,22 @@ #include #include #include +#include #include "util.h" +/* + * opendev(3) is an inherently non-thread-safe API, since + * it returns a buffer to global storage. However we can + * at least make sure the storage allocation is thread safe + * and does not leak memory in case of simultaneous + * initialization + */ +static pthread_once_t opendev_namebuf_once = PTHREAD_ONCE_INIT; +static char *namebuf = NULL; + +static void opendev_namebuf_init(void); + int opendev(path, oflags, dflags, realpath) char *path; @@ -69,7 +56,6 @@ opendev(path, oflags, dflags, realpath) { int fd; char *slash, *prefix; - static char namebuf[PATH_MAX]; /* Initial state */ if (realpath) @@ -77,6 +63,13 @@ opendev(path, oflags, dflags, realpath) fd = -1; errno = ENOENT; + if (pthread_once(&opendev_namebuf_once, + opendev_namebuf_init) + || !namebuf) { + errno = ENOMEM; + return -1; + } + if (dflags & OPENDEV_BLCK) prefix = ""; /* block device */ else @@ -85,8 +78,8 @@ opendev(path, oflags, dflags, realpath) if ((slash = strchr(path, '/'))) fd = open(path, oflags); else if (dflags & OPENDEV_PART) { - if (snprintf(namebuf, sizeof(namebuf), "%s%s%s", - _PATH_DEV, prefix, path) < sizeof(namebuf)) { + if (snprintf(namebuf, PATH_MAX, "%s%s%s", + _PATH_DEV, prefix, path) < PATH_MAX) { char *slice; while ((slice = strrchr(namebuf, 's')) && isdigit(*(slice-1))) *slice = '\0'; @@ -97,8 +90,8 @@ opendev(path, oflags, dflags, realpath) errno = ENAMETOOLONG; } if (!slash && fd == -1 && errno == ENOENT) { - if (snprintf(namebuf, sizeof(namebuf), "%s%s%s", - _PATH_DEV, prefix, path) < sizeof(namebuf)) { + if (snprintf(namebuf, PATH_MAX, "%s%s%s", + _PATH_DEV, prefix, path) < PATH_MAX) { fd = open(namebuf, oflags); if (realpath) *realpath = namebuf; @@ -107,3 +100,8 @@ opendev(path, oflags, dflags, realpath) } return (fd); } + +static void opendev_namebuf_init(void) +{ + namebuf = malloc(PATH_MAX); +}