source: mainline/uspace/lib/c/generic/vfs/inbox.c@ 1be7bee

Last change on this file since 1be7bee was 7c3fb9b, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix block comment formatting (ccheck).

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*
2 * Copyright (c) 2013 Jiri Zarevucky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32
33/**
34 * @file
35 * @brief
36 */
37
38#include <vfs/inbox.h>
39#include <vfs/vfs.h>
40
41#include <adt/list.h>
42#include <str.h>
43#include <stdlib.h>
44#include <loader/pcb.h>
45#include "../private/io.h"
46#include <errno.h>
47
48/*
49 * This is an attempt at generalization of the "standard files" concept to
50 * arbitrary names. When loading a task, the parent can put arbitrary files to
51 * an "inbox" through IPC calls, every file in an inbox has a name assigned
52 * (e.g. "stdin", "stdout", "stderr", "data", "logfile", etc.). The client then
53 * retrieves those files from inbox by name. "stdin", "stdout" and "stderr" are
54 * handled automatically by libc to initialize standard <stdio.h> streams and
55 * legacy file descriptors 0, 1, 2. Other names are subject to conventions and
56 * application-specific rules.
57 */
58
59typedef struct {
60 link_t link;
61 char *name;
62 int file;
63} inbox_entry;
64
65static LIST_INITIALIZE(inb_list);
66
67/** Inserts a named file into the inbox.
68 *
69 * If a file with the same name is already present, it overwrites it and returns
70 * the original value. Otherwise, it returns -1. If the argument 'file' is -1,
71 * nothing is inserted and the file with specified name is removed and returned
72 * if present.
73 *
74 * @param name Name of the inbox entry.
75 * @param file File to insert or -1.
76 * @return Original value of the entry or -1 if not originally present.
77 */
78int inbox_set(const char *name, int file)
79{
80 inbox_entry *next = NULL;
81 int result;
82
83 list_foreach(inb_list, link, inbox_entry, e) {
84 int cmp = str_cmp(e->name, name);
85 switch (cmp) {
86 case -1:
87 continue;
88 case 0:
89 result = e->file;
90 if (file == -1) {
91 free(e->name);
92 /* Safe because we exit immediately. */
93 list_remove(&e->link);
94 } else {
95 e->file = file;
96 }
97 return result;
98 case 1:
99 next = e;
100 goto out;
101 }
102 }
103
104out:
105 if (file == -1)
106 return -1;
107
108 inbox_entry *entry = calloc(sizeof(inbox_entry), 1);
109 entry->name = str_dup(name);
110 entry->file = file;
111
112 if (next == NULL) {
113 list_append((link_t *)entry, &inb_list);
114 } else {
115 list_insert_before((link_t *)entry, (link_t *)next);
116 }
117 return -1;
118}
119
120/** Retrieve a file with this name.
121 *
122 * @param name Name of the entry.
123 * @return Requested file or -1 if not set.
124 */
125int inbox_get(const char *name)
126{
127 list_foreach(inb_list, link, inbox_entry, e) {
128 int cmp = str_cmp(e->name, name);
129 switch (cmp) {
130 case 0:
131 return e->file;
132 case 1:
133 return -1;
134 }
135 }
136
137 return -1;
138}
139
140/** Writes names of entries that are currently set into an array provided by the
141 * user.
142 *
143 * @param names Array in which names are stored.
144 * @param capacity Capacity of the array.
145 * @return Number of entries written. If capacity == 0, return the total number
146 * of entries.
147 */
148int inbox_list(const char **names, int capacity)
149{
150 if (capacity == 0)
151 return list_count(&inb_list);
152
153 int used = 0;
154
155 list_foreach(inb_list, link, inbox_entry, e) {
156 if (used == capacity)
157 return used;
158 names[used] = e->name;
159 used++;
160 }
161
162 return used;
163}
164
165void __inbox_init(struct pcb_inbox_entry *entries, int count)
166{
167 for (int i = 0; i < count; i++) {
168 int original = inbox_set(entries[i].name, entries[i].file);
169 if (original >= 0)
170 vfs_put(original);
171 }
172}
173
174/**
175 * @}
176 */
Note: See TracBrowser for help on using the repository browser.