contributed by < hankluo6
>
2021-04-06
/* Recursively run right-most part of the command line printing output to the
* file descriptor @t
*/
static void run(char *c, int t)
{
char *redir_stdin = NULL, *redir_stdout = NULL;
int pipefds[2] = {0, 0}, outfd = 0;
char *v[99] = {0};
char **u = &v[98]; /* end of words */
for (;;) {
c--;
if (is_delim(*c)) /* if NULL (start of string) or pipe: break */
break;
if (!is_special(*c)) {
/* Copy word of regular chars into previous u */
*u = c;
}
if (is_blank(*c)) {
*c = '\0';
u--;
}
if (is_redir(*c)) { /* If < or > */
if (*c == '<')
redir_stdin = *u;
else
redir_stdout = *u;
if ((u - v) != 98)
u++;
}
}
if ((u - v) == 98) /* empty input */
return;
printf("%s\n", u[1]);
if (!strcmp(*u, "cd")) { /* built-in command: cd */
fatal(chdir(u[1]), 0);
return; /* actually, should run() again */
}
if (*c) {
pipe(pipefds);
outfd = pipefds[1]; /* write end of the pipe */
}
pid_t pid = fork();
if (pid) { /* Parent or error */
fatal(pid, 1);
if (outfd) {
run(c, outfd); /* parse the rest of the cmdline */
close(outfd); /* close output fd */
close(pipefds[0]); /* close read end of the pipe */
}
wait(0);
return;
}
if (outfd) {
dup2(pipefds[0], 0); /* dup read fd to stdin */
close(pipefds[0]); /* close read fd */
close(outfd); /* close output */
}
if (redir_stdin) {
close(0); /* replace stdin with redir_stdin */
fatal(open(redir_stdin, 0), 1);
}
if (t) {
dup2(t, 1); /* replace stdout with t */
close(t);
}
if (redir_stdout) {
close(1);
fatal(creat(redir_stdout, 438), 1); /* replace stdout with redir */
}
fatal(execvp(*u, u), 1);
}
static void dequeue(queue_t *q, int *fd)
{
node_t *old_head;
pthread_mutex_lock(q->head_lock);
/* Wait until signaled that queue is non_empty.
* Need while loop in case a new thread manages to steal the queue
* element after the waiting thread is signaled, but before it can
* re-acquire head_lock.
*/
while (!q->size)
pthread_cond_wait(q->non_empty, q->head_lock);
old_head = q->head->next;
q->head->next = old_head->next;
if (!old_head->next)
q->tail = q->head;
q->size--;
*fd = old_head->fd;
pthread_mutex_unlock(q->head_lock);
free(old_head);
}
greeter_routine 接收 http 請求,worker_routine 則用來 parse 請求,並回傳對應的訊息。
對每項 queue 操作皆確保持有 lock。
linux2021
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up