bottleros/Kernel/utils/pipe.c

193 lines
4.4 KiB
C

#include "pipe.h"
static int fdIndex = 2;
node_t * firstPipe;
char openPipe(int fds[2], char * name) {
pipe_t * pipe = pvPortMalloc(sizeof(pipe_t));
pipe->name = pvPortMalloc(MAX_NAME);
pipe->buffer = pvPortMalloc(PIPE_MAX_SIZE);
strcpy(pipe->name, name);
if ((pipe->sem = semOpen(SEM_NAME, 1)) == NULL)
return EXIT_FAILURE;
if ((pipe->fullSem = semOpen(FULL_SEM_NAME, 0)) == NULL)
return EXIT_FAILURE;
node_t * node = pvPortMalloc(sizeof(node_t));
node->pipe = pipe;
node->next = firstPipe;
firstPipe = node;
pipe->currentR = 0;
pipe->currentW = 0;
pipe->fd[0] = fdIndex++;
pipe->fd[1] = fdIndex++;
fds[0] = pipe->fd[0];
fds[1] = pipe->fd[1];
return EXIT_SUCCESS;
}
node_t * searchPipe(node_t ** previous, int fd) {
node_t * curr = firstPipe;
* previous = NULL;
while (curr != NULL) {
if (curr->pipe->fd[0] == fd || curr->pipe->fd[1] == fd) {
break;
}
* previous = curr;
curr = curr->next;
}
if (curr == NULL) {
* previous = NULL;
return NULL;
}
return curr;
}
node_t * searchWPipe(node_t ** previous, int fd) {
node_t * curr = firstPipe;
* previous = NULL;
while (curr != NULL) {
if (curr->pipe->fd[1] == fd) {
break;
}
* previous = curr;
curr = curr->next;
}
if (curr == NULL) {
* previous = NULL;
return NULL;
}
return curr;
}
node_t * searchRPipe(node_t ** previous, int fd) {
node_t * curr = firstPipe;
* previous = NULL;
while (curr != NULL) {
if (curr->pipe->fd[0] == fd) {
break;
}
* previous = curr;
curr = curr->next;
}
if (curr == NULL) {
* previous = NULL;
return NULL;
}
return curr;
}
void writePipe(int fd, char c) {
node_t * prev = NULL;
node_t * node = searchWPipe(&prev, fd);
semWait(node->pipe->sem);
semPost(node->pipe->fullSem);
node->pipe->buffer[node->pipe->currentW++ % PIPE_MAX_SIZE] = c;
semPost(node->pipe->sem);
}
char readPipe(int fd) {
node_t * prev = NULL;
node_t * node = searchRPipe(&prev, fd);
semWait(node->pipe->sem);
semPost(node->pipe->fullSem);
char c = node->pipe->buffer[node->pipe->currentR++ % PIPE_MAX_SIZE];
semPost(node->pipe->sem);
return c;
}
void closePipe(int fd) {
node_t * prev = NULL;
node_t * del = searchPipe(&prev, fd);
if (del == NULL)
return;
semWait(del->pipe->sem);
if (prev != NULL)
prev->next = del->next;
else firstPipe = del->next;
semClose(del->pipe->sem);
semClose(del->pipe->fullSem);
vPortFree(del->pipe->fd);
vPortFree(del->pipe->name);
vPortFree(del->pipe->buffer);
vPortFree(del->pipe);
vPortFree(del);
}
void getGenPipeData(char ** out, char * written, char toAdd, char * in, char isLast) {
char copied = strcpy(*out, in);
*out += copied;
*out += addSpaces(*out, toAdd - copied);
*written += toAdd;
if (!isLast) {
*out += addSpaces(*out, 2);
*written += 2;
}
}
char getPipeData(char * out, node_t * node) {
if (node == NULL)
return EXIT_FAILURE;
char written = 0;
char flag = 0;
for (int j = 0; j < MAX_NAME_SIZE; j++) {
if (!flag && node->pipe->name[j] == 0)
flag = 1;
else if (flag)
out += addSpaces(out, 1);
else
*out++ = node->pipe->name[j];
}
written += MAX_NAME_SIZE;
out += addSpaces(out, 2);
written += 2;
char buffer[10];
getGenPipeData(&out, &written, MAX_ATTR_SIZE, itoa(node->pipe->fd[0], buffer, 10, 2), 0);
getGenPipeData(&out, &written, MAX_ATTR_SIZE, itoa(node->pipe->fd[1], buffer, 16, 10), 0);
char * aux = getEntering(node->pipe->sem);
getGenPipeData(&out, &written, MAX_PIDS_SIZE, aux, 1);
vPortFree(aux);
return written;
}
char * pipes(){
char * ans = pvPortMalloc((fdIndex / 2) * PIPE_DATA_MAX_SIZE);
char * ret = ans;
char * info = "name fdIn fdOut pids\n";
ans += strcpy(ans, info);
node_t * aux = firstPipe;
while (aux != NULL) {
char writtenChars = getPipeData(ans, aux);
if (writtenChars == EXIT_FAILURE)
return NULL;
ans += writtenChars - 1;
*ans++ = '\n';
aux = aux->next;
}
*--ans = 0;
return ret;
}