Ignore:
Timestamp:
Jun 22, 2008, 11:57:21 AM (13 years ago)
Author:
Pascal Terjan
Message:
  • First more or less working version of attach
File:
1 edited

Legend:

Unmodified
Added
Removed
  • neercs/trunk/src/attach.c

    r2470 r2474  
     1#include <errno.h>
    12#include <fcntl.h>
     3#include <glob.h>
     4#include <limits.h>
    25#include <stdio.h>
    36#include <stdlib.h>
    47#include <unistd.h>
    58
     9#include <sys/socket.h>
     10#include <sys/un.h>
     11#include <sys/types.h>
     12#include <sys/stat.h>
     13
    614#include "neercs.h"
     15
     16static char * build_socket_path(char *socket_dir)
     17{
     18    char *path, *dir;
     19    path = (char *)malloc(PATH_MAX+1);
     20    dir = socket_dir;
     21    if(!dir)
     22        dir = getenv("NEERCSDIR");
     23    if(!dir)
     24        dir = getenv("TMPDIR");
     25    if(!dir)
     26        dir = "/tmp";
     27    if(path)
     28        snprintf(path, PATH_MAX+1, "%s/neercs.%d.sock", dir, getpid());
     29    return path;
     30}
     31
     32int create_socket(struct screen_list* screen_list)
     33{
     34    int sock;
     35    struct sockaddr_un myaddr;
     36
     37    sock = socket(AF_UNIX, SOCK_DGRAM, 0);
     38
     39    if(sock < 0)
     40    {
     41        perror("create_socket:socket");
     42        return errno;
     43    }
     44
     45    memset(&myaddr, 0, sizeof(struct sockaddr_un));
     46
     47    myaddr.sun_family = AF_UNIX;
     48    screen_list->socket_path = build_socket_path(screen_list->socket_path);
     49    strncpy(myaddr.sun_path, screen_list->socket_path, sizeof(myaddr.sun_path) - 1);
     50    unlink(myaddr.sun_path);
     51
     52    if(bind(sock, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_un)) < 0)
     53    {
     54        free(screen_list->socket_path);
     55        screen_list->socket_path = NULL;
     56        close(sock);
     57        perror("create_socket:bind");
     58        return errno;
     59    }
     60    fcntl(sock, F_SETFL, O_NONBLOCK);
     61
     62    debug("Listening on %s (%d)", screen_list->socket_path, sock);
     63
     64    screen_list->socket = sock;
     65
     66    return 0;
     67}
    768
    869int detach(struct screen_list* screen_list, caca_display_t * dp)
     
    1374    screen_list->attached = 0;
    1475    caca_free_display(dp);
    15 
    16     pid = fork();
    17     if (pid < 0)
    18         return 1;
    19     if (pid > 0)
    20         exit(0);
    2176
    2277    close(0);
    2378    close(1);
    2479    close(2);
    25     fd = open("/dev/null", O_RDWR);
     80
     81    fd = open("/tmp/log.txt", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
    2682    dup2(fd, 0);
    2783    dup2(fd, 1);
     
    3086        close(fd);
    3187
    32     setsid();
     88    if(!screen_list->socket)
     89    {
     90        pid = fork();
     91        if (pid < 0)
     92            return 1;
     93        if (pid > 0)
     94            exit(0);
     95
     96        create_socket(screen_list);
     97        setsid();
     98    }
    3399
    34100    return 0;
    35101}
    36102
    37 #if 0
    38 int attach(struct screen_list* screen_list, cucul_canvas_t * cv, caca_display_t ** dp)
    39 {
    40     screen_list->attached = 1;
    41     *dp = caca_create_display(cv);
    42     if(!*dp)
     103/* FIXME Is this really not defined anywhere ? */
     104#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
     105
     106static int handle_command(char * cmd, struct screen_list* screen_list, cucul_canvas_t * cv, caca_display_t ** dp)
     107{
     108    int refresh = 0;
     109    debug("Received command %s", cmd);
     110    if(!strncmp("ENV ", cmd, MIN(4, strlen(cmd))))
     111    {
     112        putenv(strdup(cmd+4));
     113    }
     114    else if(!strncmp("ATTACH ", cmd, MIN(7, strlen(cmd))))
     115    {
     116        int fd;
     117        screen_list->attached = 1;
     118        close(screen_list->socket);
     119        screen_list->socket= 0;
     120        unlink(screen_list->socket_path);
     121        screen_list->socket_path = NULL;
     122        close(0);
     123        fd=open(cmd+7, O_RDWR);
     124        dup2(fd, 0);
     125        close(1);
     126        fd=open(cmd+7, O_RDWR);
     127        dup2(fd, 1);
     128        close(2);
     129        fd=open(cmd+7, O_RDWR);
     130        dup2(fd, 2);
     131        *dp = caca_create_display(cv);
     132        if(*dp)
     133        {
     134            caca_set_cursor(*dp, 1);
     135            refresh = 1;
     136        }
     137    }
     138    else
     139    {
     140        fprintf(stderr, "Unknown command received: %s\n", cmd);
     141    }
     142    return refresh;
     143}
     144
     145int read_socket(struct screen_list* screen_list, cucul_canvas_t * cv, caca_display_t ** dp) {
     146    ssize_t n;
     147    char buf[4097];
     148    int refresh = 0;
     149
     150    if(!screen_list->socket)
     151        return 0;
     152
     153    while (screen_list->socket && (n = read(screen_list->socket, buf, sizeof(buf)-1)) > 0)
     154    {
     155        buf[n] = 0;
     156        refresh |= handle_command(buf, screen_list, cv, dp);
     157    }
     158    return refresh;
     159}
     160
     161char ** list_sockets(char *socket_dir)
     162{
     163    char *pattern, *dir;
     164    glob_t globbuf;
     165
     166    globbuf.gl_pathv = NULL;
     167
     168    pattern = (char *)malloc(PATH_MAX+1);
     169
     170    dir = socket_dir;
     171    if(!dir)
     172        dir = getenv("NEERCSDIR");
     173    if(!dir)
     174        dir = getenv("TMPDIR");
     175    if(!dir)
     176        dir = "/tmp";
     177
     178    if(!pattern)
     179        return globbuf.gl_pathv;
     180
     181    snprintf(pattern, PATH_MAX, "%s/neercs.*.sock", dir);
     182    pattern[PATH_MAX] = '\0';
     183
     184    debug("Looking for sockets in the form %s", pattern);
     185
     186    glob(pattern, 0, NULL, &globbuf);
     187
     188    return globbuf.gl_pathv;
     189}
     190
     191
     192/* FIXME Is this really not defined anywhere ? */
     193extern char **environ;
     194
     195int request_attach(char *socket_path)
     196{
     197    int i;
     198    int sock;
     199    char fdstr[PATH_MAX], lnk[PATH_MAX];
     200    char buf[4096];
     201    struct sockaddr_un addr;
     202
     203    debug("Connecting to %s", socket_path);
     204
     205    /* Open the socket */
     206    if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
     207        perror("request_attach:socket");
    43208        return 1;
    44 
    45     caca_set_cursor(*dp, 1);
    46     return 0;
    47 }
    48 #endif
     209    }
     210
     211    memset(&addr,0,sizeof(addr));
     212    addr.sun_family = AF_UNIX;
     213    strcpy(addr.sun_path,socket_path);
     214    if (connect(sock, &addr, sizeof(addr)) < 0)
     215    {
     216        perror("request_attach:connect");
     217        return 1;
     218    }
     219
     220    debug("Sending environment", 0);
     221
     222    /* Send our environment */
     223    for(i=0; environ[i]; i++)
     224    {
     225        snprintf(buf, 4096, "ENV %s", environ[i]);
     226        write(sock, buf, strlen(buf));
     227    }
     228
     229    snprintf(fdstr, sizeof(fdstr), "/proc/%d/fd/0", getpid());
     230    readlink(fdstr, lnk, sizeof(lnk)-1);
     231    lnk[PATH_MAX-1] = '\0';
     232
     233    close(0);
     234
     235    debug("Requesting attach to %s", lnk);
     236
     237    /* Request attaching */
     238    snprintf(buf, 4096, "ATTACH %s", lnk);
     239    write(sock, buf, strlen(buf));
     240    close(sock);
     241
     242    debug("Exiting", 0);
     243    exit(0);
     244}
Note: See TracChangeset for help on using the changeset viewer.