boot: Use snprintf() when filling command_errbuf[] w/ dynamic content.
[dragonfly.git] / lib / libstand / open.c
blob0b0d92f4cb5166428a7890a8b2fb326dcae92487
1 /* $FreeBSD: src/lib/libstand/open.c,v 1.2.6.1 2000/09/10 01:32:06 ps Exp $ */
2 /* $NetBSD: open.c,v 1.16 1997/01/28 09:41:03 pk Exp $ */
4 /*-
5 * Copyright (c) 1993
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
9 * The Mach Operating System project at Carnegie-Mellon University.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
35 * @(#)open.c 8.1 (Berkeley) 6/11/93
38 * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
39 * All Rights Reserved.
41 * Author: Alessandro Forin
43 * Permission to use, copy, modify and distribute this software and its
44 * documentation is hereby granted, provided that both the copyright
45 * notice and this permission notice appear in all copies of the
46 * software, derivative works or modified versions, and any portions
47 * thereof, and that both notices appear in supporting documentation.
49 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
50 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
51 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
53 * Carnegie Mellon requests users of this software to return to
55 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
56 * School of Computer Science
57 * Carnegie Mellon University
58 * Pittsburgh PA 15213-3890
60 * any improvements or extensions that they make and grant Carnegie the
61 * rights to redistribute these changes.
64 #include "stand.h"
66 struct open_file files[SOPEN_MAX];
68 static int
69 o_gethandle(void)
71 int fd;
73 for (fd = 0; fd < SOPEN_MAX; fd++)
74 if (files[fd].f_flags == 0)
75 return(fd);
76 return(-1);
79 static void
80 o_rainit(struct open_file *f)
82 f->f_rabuf = malloc(SOPEN_RASIZE);
83 f->f_ralen = 0;
84 f->f_raoffset = 0;
87 int
88 open(const char *fname, int mode)
90 struct open_file *f;
91 int fd, i, error, besterror;
92 const char *file;
94 if ((fd = o_gethandle()) == -1) {
95 errno = EMFILE;
96 return(-1);
99 f = &files[fd];
100 f->f_flags = mode + 1;
101 f->f_dev = NULL;
102 f->f_ops = NULL;
103 f->f_offset = 0;
104 f->f_devdata = NULL;
105 f->f_fsdata = NULL;
106 file = NULL;
107 error = devopen(f, fname, &file);
108 if (error || f->f_dev == NULL)
109 goto err;
111 /* see if we opened a raw device; otherwise, 'file' is the file name. */
112 if (file == NULL || *file == '\0') {
113 f->f_flags |= F_RAW;
114 return (fd);
117 /* pass file name to the different filesystem open routines */
118 besterror = ENOENT;
119 for (i = 0; file_system[i] != NULL; i++) {
120 error = ((*file_system[i]).fo_open)(file, f);
121 if (error == 0) {
122 f->f_ops = file_system[i];
123 o_rainit(f);
124 return (fd);
126 if (error != EINVAL)
127 besterror = error;
129 error = besterror;
131 if (f->f_dev)
132 f->f_dev->dv_close(f);
133 if (error)
134 devclose(f);
136 err:
137 f->f_flags = 0;
138 errno = error;
139 return (-1);