source: mainline/uspace/app/redir/redir.c@ bd01a4e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since bd01a4e was d9fae235, checked in by Martin Decky <martin@…>, 15 years ago

sysinfo overhaul

  • cleanup (nicer data structures, use of SLAB allocator)
  • add support for storing arbitrary binary data
  • properly reimplement non-constant values (generated by functions)
  • add support for non-constant subtrees (generated by functions)
  • syscall ABI change, libc API change
  • reflect changes in user code

libc: task_spawn() can now return error code

  • reflect change in user code, print error strings after failed task_spawn()

uspace cleanup

  • more use of string and other constants
  • more use of str_error()
  • unify error reporting in init
  • Property mode set to 100644
File size: 3.6 KB
Line 
1/*
2 * Copyright (c) 2009 Martin Decky
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 redir Redirector
30 * @brief Redirect stdin/stdout/stderr.
31 * @{
32 */
33/**
34 * @file
35 */
36
37#include <sys/types.h>
38#include <stdlib.h>
39#include <fcntl.h>
40#include <unistd.h>
41#include <str.h>
42#include <stdio.h>
43#include <task.h>
44#include <str_error.h>
45
46#define NAME "redir"
47
48static void usage(void)
49{
50 printf("Usage: %s [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ...]\n",
51 NAME);
52}
53
54static void reopen(FILE **stream, int fd, const char *path, int flags, const char *mode)
55{
56 if (fclose(*stream))
57 return;
58
59 *stream = NULL;
60
61 int oldfd = open(path, flags);
62 if (oldfd < 0)
63 return;
64
65 if (oldfd != fd) {
66 if (dup2(oldfd, fd) != fd)
67 return;
68
69 if (close(oldfd))
70 return;
71 }
72
73 *stream = fdopen(fd, mode);
74}
75
76static task_id_t spawn(int argc, char *argv[])
77{
78 const char **args = (const char **) calloc(argc + 1, sizeof(char *));
79 if (!args) {
80 printf("No memory available\n");
81 return 0;
82 }
83
84 int i;
85 for (i = 0; i < argc; i++)
86 args[i] = argv[i];
87
88 args[argc] = NULL;
89
90 int err;
91 task_id_t id = task_spawn(argv[0], args, &err);
92
93 free(args);
94
95 if (id == 0)
96 printf("%s: Error spawning %s (%s)\n", NAME, argv[0],
97 str_error(err));
98
99 return id;
100}
101
102int main(int argc, char *argv[])
103{
104 if (argc < 3) {
105 usage();
106 return -1;
107 }
108
109 int i;
110 for (i = 1; i < argc; i++) {
111 if (str_cmp(argv[i], "-i") == 0) {
112 i++;
113 if (i >= argc) {
114 usage();
115 return -2;
116 }
117 reopen(&stdin, 0, argv[i], O_RDONLY, "r");
118 } else if (str_cmp(argv[i], "-o") == 0) {
119 i++;
120 if (i >= argc) {
121 usage();
122 return -3;
123 }
124 reopen(&stdout, 1, argv[i], O_WRONLY | O_CREAT, "w");
125 } else if (str_cmp(argv[i], "-e") == 0) {
126 i++;
127 if (i >= argc) {
128 usage();
129 return -4;
130 }
131 reopen(&stderr, 2, argv[i], O_WRONLY | O_CREAT, "w");
132 } else if (str_cmp(argv[i], "--") == 0) {
133 i++;
134 break;
135 }
136 }
137
138 if (i >= argc) {
139 usage();
140 return -5;
141 }
142
143 /*
144 * FIXME: fdopen() should actually detect that we are opening a console
145 * and it should set line-buffering mode automatically.
146 */
147 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
148
149 task_id_t id = spawn(argc - i, argv + i);
150
151 if (id != 0) {
152 task_exit_t texit;
153 int retval;
154 task_wait(id, &texit, &retval);
155
156 return retval;
157 }
158
159 return -6;
160}
161
162/** @}
163 */
Note: See TracBrowser for help on using the repository browser.