00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #include <sys/types.h>
00038 #include <stdlib.h>
00039 #include <fcntl.h>
00040 #include <unistd.h>
00041 #include <str.h>
00042 #include <stdio.h>
00043 #include <task.h>
00044 #include <str_error.h>
00045 #include <errno.h>
00046
00047 #define NAME "redir"
00048
00049 static void usage(void)
00050 {
00051 printf("Usage: %s [-i <stdin>] [-o <stdout>] [-e <stderr>] -- <cmd> [args ...]\n",
00052 NAME);
00053 }
00054
00055 static void reopen(FILE **stream, int fd, const char *path, int flags, const char *mode)
00056 {
00057 if (fclose(*stream))
00058 return;
00059
00060 *stream = NULL;
00061
00062 int oldfd = open(path, flags);
00063 if (oldfd < 0)
00064 return;
00065
00066 if (oldfd != fd) {
00067 if (dup2(oldfd, fd) != fd)
00068 return;
00069
00070 if (close(oldfd))
00071 return;
00072 }
00073
00074 *stream = fdopen(fd, mode);
00075 }
00076
00077 static task_id_t spawn(int argc, char *argv[])
00078 {
00079 const char **args;
00080 task_id_t id = 0;
00081 int rc;
00082
00083 args = (const char **) calloc(argc + 1, sizeof(char *));
00084 if (!args) {
00085 printf("No memory available\n");
00086 return 0;
00087 }
00088
00089 int i;
00090 for (i = 0; i < argc; i++)
00091 args[i] = argv[i];
00092
00093 args[argc] = NULL;
00094
00095 rc = task_spawnv(&id, argv[0], args);
00096
00097 free(args);
00098
00099 if (rc != EOK) {
00100 printf("%s: Error spawning %s (%s)\n", NAME, argv[0],
00101 str_error(rc));
00102 }
00103
00104 return id;
00105 }
00106
00107 int main(int argc, char *argv[])
00108 {
00109 if (argc < 3) {
00110 usage();
00111 return -1;
00112 }
00113
00114 int i;
00115 for (i = 1; i < argc; i++) {
00116 if (str_cmp(argv[i], "-i") == 0) {
00117 i++;
00118 if (i >= argc) {
00119 usage();
00120 return -2;
00121 }
00122 reopen(&stdin, 0, argv[i], O_RDONLY, "r");
00123 } else if (str_cmp(argv[i], "-o") == 0) {
00124 i++;
00125 if (i >= argc) {
00126 usage();
00127 return -3;
00128 }
00129 reopen(&stdout, 1, argv[i], O_WRONLY | O_CREAT, "w");
00130 } else if (str_cmp(argv[i], "-e") == 0) {
00131 i++;
00132 if (i >= argc) {
00133 usage();
00134 return -4;
00135 }
00136 reopen(&stderr, 2, argv[i], O_WRONLY | O_CREAT, "w");
00137 } else if (str_cmp(argv[i], "--") == 0) {
00138 i++;
00139 break;
00140 }
00141 }
00142
00143 if (i >= argc) {
00144 usage();
00145 return -5;
00146 }
00147
00148
00149
00150
00151
00152 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
00153
00154 task_id_t id = spawn(argc - i, argv + i);
00155
00156 if (id != 0) {
00157 task_exit_t texit;
00158 int retval;
00159 task_wait(id, &texit, &retval);
00160
00161 return retval;
00162 }
00163
00164 return -6;
00165 }
00166