More code.
authorviric@llimona
Wed, 21 Mar 2007 23:37:25 +0100
changeset 3 2fb8a6bdd024
parent 2 602bd67df3aa
child 4 110d7bfe2d51
More code.
.hgignore
Makefile
client.c
jobs.c
main.c
main.h
msg.h
msgdump.c
server.c
server_start.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Wed Mar 21 23:37:25 2007 +0100
@@ -0,0 +1,4 @@
+^.*\.o$
+core
+test
+\.exrc
--- a/Makefile	Wed Mar 21 21:01:36 2007 +0100
+++ b/Makefile	Wed Mar 21 23:37:25 2007 +0100
@@ -1,3 +1,3 @@
 CFLAGS=-g
-test: main.o server.o server_start.o client.o
+test: main.o server.o server_start.o client.o msgdump.o jobs.o
 	gcc -o test $^
--- a/client.c	Wed Mar 21 21:01:36 2007 +0100
+++ b/client.c	Wed Mar 21 23:37:25 2007 +0100
@@ -1,7 +1,53 @@
 #include <assert.h>
 #include "msg.h"
+#include "main.h"
 
-int shutdown_server()
+void c_new_job(const char *command)
+{
+    struct msg m;
+    int res;
+
+    m.type = NEWJOB;
+
+    strcpy(m.u.command, command);
+
+    res = write(server_socket, &m, sizeof(m));
+    if(res == -1)
+        perror("write");
+}
+
+void c_wait_server_commands()
+{
+    struct msg m;
+    int res;
+
+    while (1)
+    {
+        res = read(server_socket, &m, sizeof(m));
+        if(res == -1)
+            perror("read");
+
+        if (res == 0)
+            break;
+        assert(res == sizeof(m));
+        if (m.type == NEWJOB_OK)
+            ;
+    }
+}
+
+void c_list_jobs(const char *command)
+{
+    struct msg m;
+    int res;
+
+    m.type = LIST;
+
+    res = write(server_socket, &m, sizeof(m));
+    if(res == -1)
+        perror("write");
+}
+
+int c_shutdown_server()
 {
     struct msg m;
     int res;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jobs.c	Wed Mar 21 23:37:25 2007 +0100
@@ -0,0 +1,99 @@
+#include <assert.h>
+#include "msg.h"
+
+struct Job
+{
+    int jobid;
+    char command[CMD_LEN];
+    enum Jobstate state;
+    struct Job *next;
+};
+
+/* Globals */
+static struct Job *firstjob = 0;
+static jobids = 0;
+
+void s_list(int s)
+{
+    int i;
+    struct Job *p;
+
+    printf("ID\tState\tCommand\n");
+
+    p = firstjob;
+
+    while(p != 0)
+    {
+        printf("%i\t", p->jobid);
+        printf("%i\t", p->state);
+        printf("%s\n", p->command);
+        p = p->next;
+    }
+}
+
+static struct Job * newjobptr()
+{
+    struct Job *p;
+
+    if (firstjob == 0)
+    {
+        firstjob = (struct Job *) malloc(sizeof(*firstjob));
+        firstjob->next = 0;
+        return firstjob;
+    }
+
+    p = firstjob;
+    while(p->next != 0)
+        p = p->next;
+
+    p->next = (struct Job *) malloc(sizeof(*p));
+    p->next->next = 0;
+
+    return p->next;
+}
+
+/* Returns job id */
+int s_newjob(struct msg *m)
+{
+    struct Job *p;
+
+    p = newjobptr();
+
+    p->jobid = jobids++;
+    p->state = QUEUED;
+    strcpy(p->command, m->u.command);
+
+    return p->jobid;
+}
+
+void s_removejob(int jobid)
+{
+    struct Job *p;
+    struct Job *newnext;
+
+    printf("Remove job %i\n", jobid);
+    if (firstjob->jobid == jobid)
+    {
+        struct Job *newfirst;
+        /* First job is to be removed */
+        newfirst = firstjob->next;
+        free(firstjob);
+        firstjob = newfirst;
+        return;
+    }
+
+    p = firstjob;
+    /* Not first job */
+    while (p->next != 0)
+    {
+        if (p->next->jobid == jobid)
+            break;
+        p = p->next;
+    }
+    assert(p->next != 0);
+
+    newnext = p->next->next;
+
+    free(p->next);
+    p->next = newnext;
+}
--- a/main.c	Wed Mar 21 21:01:36 2007 +0100
+++ b/main.c	Wed Mar 21 23:37:25 2007 +0100
@@ -2,21 +2,26 @@
 
 #include <stdio.h>
 
+#include "main.h"
+
 extern char *optarg;
 extern int optind, opterr, optopt;
 
 int kill_server = 0;
 int need_server = 0;
+int list_jobs = 0;
 
 int server_socket;
 
+char *new_command = 0;
+
 void parse_opts(int argc, char **argv)
 {
     int c;
 
     /* Parse options */
     while(1) {
-        c = getopt(argc, argv, "k");
+        c = getopt(argc, argv, "kl");
 
         if (c == -1)
             break;
@@ -26,10 +31,18 @@
             case 'k':
                 kill_server = 1;
                 break;
+            case 'l':
+                list_jobs = 1;
+                break;
         }
     }
 
-    if (kill_server == 0)
+    if (optind < argc)
+    {
+        new_command = argv[optind];
+    }
+
+    if (list_jobs || kill_server || (new_command != 0))
         need_server = 1;
 }
 
@@ -37,18 +50,24 @@
 {
     parse_opts(argc, argv);
 
-    need_server = 1;
+    if (need_server)
+        ensure_server_up();
+
+    if (new_command != 0)
+    {
+        c_new_job(new_command);
+        c_wait_server_commands();
+    }
+
+    if (list_jobs != 0)
+        c_list_jobs(new_command);
+    
+    if (kill_server)
+        c_shutdown_server();
 
     if (need_server)
     {
-        fprintf(stderr, "Ensure server up.\n");
-        ensure_server_up();
-    }
-    
-    if (kill_server)
-    {
-        printf("Trying to kill server.\n");
-        shutdown_server();
+        close(server_socket);
     }
 
     return 0;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Wed Mar 21 23:37:25 2007 +0100
@@ -0,0 +1,26 @@
+
+
+struct msg;
+
+/* client.c */
+void c_new_job(const char *command);
+void c_wait_server_commands();
+void c_list_jobs(const char *command);
+int c_shutdown_server();
+
+/* jobs.c */
+void s_list(int s);
+int s_newjob(struct msg *m);
+void s_removejob(int jobid);
+
+/* msgdump.c */
+void msgdump(const struct msg *m);
+
+/* server.c */
+void server_main();
+
+/* server_start.c */
+int try_connect(int s);
+void wait_server_up();
+void fork_server();
+int ensure_server_up();
--- a/msg.h	Wed Mar 21 21:01:36 2007 +0100
+++ b/msg.h	Wed Mar 21 23:37:25 2007 +0100
@@ -1,8 +1,18 @@
 extern int server_socket;
 
+enum
+{
+    CMD_LEN=500
+};
+
 enum msg_types
 {
-    KILL
+    KILL,
+    NEWJOB,
+    NEWJOB_OK,
+    RUNJOB,
+    ENDJOB,
+    LIST,
 };
 
 struct msg
@@ -11,8 +21,19 @@
 
     union
     {
-        int data1;
-        int data2;
+        char command[CMD_LEN];
+        int jobid;
+        int errorlevel;
     } u;
 };
 
+
+enum Jobstate
+{
+    QUEUED,
+    RUNNING,
+    FINISHED,
+};
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/msgdump.c	Wed Mar 21 23:37:25 2007 +0100
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include "msg.h"
+#include "main.h"
+
+void msgdump(const struct msg *m)
+{
+    printf("msgdump:\n");
+    switch(m->type)
+    {
+        case KILL:
+            printf("  KILL\n");
+            break;
+        case NEWJOB:
+            printf(" NEWJOB\n");
+            printf(" Command: '%s'\n", m->u.command);
+            break;
+        case NEWJOB_OK:
+            printf(" NEWJOB_OK\n");
+            printf(" JobID: '%s'\n", m->u.jobid);
+            break;
+        case RUNJOB:
+            printf(" RUNJOB\n");
+            break;
+        case ENDJOB:
+            printf(" ENDJOB\n");
+            break;
+        case LIST:
+            printf(" LIST\n");
+            break;
+    }
+}
--- a/server.c	Wed Mar 21 21:01:36 2007 +0100
+++ b/server.c	Wed Mar 21 23:37:25 2007 +0100
@@ -3,10 +3,12 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <errno.h>
+#include <string.h>
 
 #include <stdio.h>
 
 #include "msg.h"
+#include "main.h"
 
 const char path[] = "/tmp/prova.socket";
 
@@ -21,10 +23,22 @@
     NOBREAK
 };
 
-void server_loop(int ls);
-enum Break
-client_read(int index, int *connections, int *nconnections);
-void end_server(int ls);
+/* Prototypes */
+static void server_loop(int ls);
+static enum Break
+    client_read(int index);
+static void end_server(int ls);
+
+struct Client_conn
+{
+    int socket;
+    int hasjob;
+    int jobid;
+};
+
+/* Globals */
+static struct Client_conn client_cs[MAXCONN];
+static int nconnections;
 
 void server_main()
 {
@@ -32,6 +46,8 @@
     struct sockaddr_un addr;
     int res;
 
+    nconnections = 0;
+
     ls = socket(PF_UNIX, SOCK_STREAM, 0);
     assert(ls != -1);
 
@@ -52,15 +68,12 @@
         return;
     }
 
-    printf("server loop\n");
     server_loop(ls);
 }
 
-void server_loop(int ls)
+static void server_loop(int ls)
 {
     fd_set readset;
-    int connections[MAXCONN];
-    int nconnections;
     int i;
     int maxfd;
     int keep_loop = 1;
@@ -72,26 +85,24 @@
         maxfd = ls;
         for(i=0; i< nconnections; ++i)
         {
-            FD_SET(connections[i], &readset);
-            if (connections[i] > maxfd)
-                maxfd = connections[i];
+            FD_SET(client_cs[i].socket, &readset);
+            if (client_cs[i].socket > maxfd)
+                maxfd = client_cs[i].socket;
         }
-        printf("select: nc = %i\n", nconnections);
+        printf("select of %i\n", nconnections);
         select(maxfd + 1, &readset, NULL, NULL, NULL);
-        printf("Select unblocks\n");
         if (FD_ISSET(ls,&readset))
         {
             int cs;
             cs = accept(ls, NULL, NULL);
             assert(cs != -1);
-            connections[nconnections++] = cs;
+            client_cs[nconnections++].socket = cs;
         }
         for(i=0; i< nconnections; ++i)
-            if (FD_ISSET(connections[i], &readset))
+            if (FD_ISSET(client_cs[i].socket, &readset))
             {
                 enum Break b;
-                b = client_read(i, connections,
-                        &nconnections);
+                b = client_read(i);
                 /* Check if we should break */
                 if (b == BREAK)
                     keep_loop = 0;
@@ -101,46 +112,65 @@
     end_server(ls);
 }
 
-void end_server(int ls)
+static void end_server(int ls)
 {
     close(ls);
     unlink(path);
 }
 
-void remove_connection(int index, int *connections, int *nconnections)
+static void remove_connection(int index)
 {
     int i;
-    for(i=index; i<(*nconnections-1); ++i)
+
+    if(client_cs[index].hasjob)
     {
-        connections[i] = connections[i+1];
+        printf("s: removing job [%i] %i\n", index, client_cs[index].jobid);
+        s_removejob(client_cs[index].jobid);
     }
-    (*nconnections)--;
+
+    for(i=index; i<(nconnections-1); ++i)
+    {
+        memcpy(&client_cs[i], &client_cs[i+1], sizeof(client_cs[0]));
+    }
+    nconnections--;
 }
 
-enum Break
-client_read(int index, int *connections, int *nconnections)
+
+static enum Break
+    client_read(int index)
 {
-    struct msg data;
+    struct msg m;
     int s;
     int res;
 
-    s = connections[index];
+    s = client_cs[index].socket;
 
     /* Read the message */
-    res = read(s, &data, sizeof(data));
+    res = read(s, &m, sizeof(m));
     assert(res != -1);
     if (res == 0)
     {
         close(s);
-        remove_connection(index, connections, nconnections);
+        remove_connection(index);
         return NOBREAK;
     }
 
-    printf("recv. data.type = %i\n", data.type);
+    client_cs[index].hasjob = 0;
+
+    msgdump(&m);
 
     /* Process message */
-    if (data.type == KILL)
+    if (m.type == KILL)
         return BREAK; /* break in the parent*/
 
+    if (m.type == NEWJOB)
+    {
+        client_cs[index].jobid = s_newjob(&m);
+        client_cs[index].hasjob = 1;
+    }
+
+    if (m.type == LIST)
+        s_list(index);
+
     return NOBREAK; /* normal */
 }
--- a/server_start.c	Wed Mar 21 21:01:36 2007 +0100
+++ b/server_start.c	Wed Mar 21 23:37:25 2007 +0100
@@ -3,6 +3,9 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <errno.h>
+#include <stdlib.h>
+
+#include "main.h"
 
 extern int server_socket;
 
@@ -34,7 +37,9 @@
     switch (pid)
     {
         case 0: /* Child */
+            close(server_socket);
             server_main();
+            exit(0);
             break;
         case -1: /* Error */
             return;
@@ -57,9 +62,12 @@
         return 1;
 
     /* If error other than "No one listens on the other end"... */
-    if (errno != ENOENT)
+    if (!(errno == ENOENT || errno == ECONNREFUSED))
         return 0;
 
+    if (errno == ECONNREFUSED)
+        unlink("/tmp/prova.socket");
+
     /* Try starting the server */
     fork_server();
     wait_server_up();