Changeset 2474


Ignore:
Timestamp:
Jun 22, 2008, 11:57:21 AM (15 years ago)
Author:
Pascal Terjan
Message:
  • First more or less working version of attach
Location:
neercs/trunk/src
Files:
5 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}
  • neercs/trunk/src/configuration.c

    r2465 r2474  
    283283            /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
    284284            if(!screen_list->screensaver_timeout) screen_list->screensaver_timeout-=1;
     285        } else if(IS_TOKEN("socket_dir"))
     286        {
     287            screen_list->socket_dir = option->value;
    285288        } else
    286289        {
    287             fprintf(stderr, "Unknow option '%s'\n", option->key);
     290            fprintf(stderr, "Unknown option '%s'\n", option->key);
    288291        }
    289292        option = option->next;
  • neercs/trunk/src/effects.c

    r2468 r2474  
    201201    cucul_printf(cv, x, y++, "              Sam Hocevar <sam@zoy.org>");
    202202    cucul_printf(cv, x, y++, "              Jean-Yves Lamoureux <jylam@lnxscene.org>");
     203    cucul_printf(cv, x, y++, "              Pascal Terjan <pterjan@linuxfr.org>");
    203204    cucul_printf(cv, x, y++, "");
    204205    cucul_printf(cv, x, y++, "");
     
    209210    cucul_printf(cv, x, y++, "c:\t Create new window");
    210211    cucul_printf(cv, x, y++, "m:\t Thumbnails");
     212    cucul_printf(cv, x, y++, "d:\t Detach");
    211213    cucul_printf(cv, x, y++, "k:\t Close window and kill associated process");
    212214    cucul_printf(cv, x, y++, "h:\t This help");
    213     cucul_printf(cv, x, y++, "");
    214215    cucul_printf(cv, x, y++, "");
    215216    cucul_printf(cv, x, y++, "");
  • neercs/trunk/src/main.c

    r2473 r2474  
    7171    printf("Options :\n");
    7272    printf("\t--pid\t\t-P <pid>\t\tattach <pid>\n");
     73    printf("\t\t\t-R\t\t\tre-attach another neercs\n");
    7374    printf("\t--version\t-v \t\t\tdisplay version and exit\n");
    7475    printf("\t--help\t\t-h \t\t\tthis help\n");
     
    8687    long long unsigned int last_key_time = 0;
    8788    int lock_offset = 0;
    88 
     89    int mainret = 0;
    8990
    9091    default_shell = getenv("SHELL");
     
    101102
    102103    /* Create main canvas and associated caca window */
     104    /* FIXME: do not create display for -R/-h/-v */
    103105    cv = cucul_create_canvas(0, 0);
    104106    dp = caca_create_display(cv);
     
    141143    screen_list->locked = 0;
    142144    screen_list->attached = 1;
     145    screen_list->socket = 0;
     146    screen_list->socket_dir = NULL;
     147    screen_list->socket_path = NULL;
    143148    memset(screen_list->lockmsg, 0, 1024);
    144149    memset(screen_list->lockpass, 0, 1024);
    145 
    146150
    147151    if(!read_configuration_file("neercs.ini", screen_list))
     
    169173    {
    170174        int option_index = 0;
     175        char **sockets;
     176        int grab = 0;
    171177        static struct myoption long_options[] =
    172178            {
     
    178184            };
    179185#if defined USE_GRAB
    180         int c = mygetopt(argc, argv, "P:hv", long_options, &option_index);
     186        int c = mygetopt(argc, argv, "RP:hv", long_options, &option_index);
    181187#else
    182         int c = mygetopt(argc, argv, "hv", long_options, &option_index);
     188        int c = mygetopt(argc, argv, "Rhv", long_options, &option_index);
    183189#endif
    184190        if(c == -1)
     
    190196            add_screen(screen_list,create_screen_grab(w, h, atoi(myoptarg)));
    191197            s+=2;
     198            grab = 1;
     199            break;
     200        case 'R':
     201            if(grab)
     202            {
     203                fprintf(stderr, "-P and -R can not be used together!\n");
     204                mainret = -1;
     205                goto end;
     206            }
     207            sockets = list_sockets(screen_list->socket_dir);
     208            if(sockets && sockets[0])
     209            {
     210                request_attach(sockets[0]);
     211                for(i=0; sockets[i]; i++)
     212                    free(sockets[i]);
     213                free(sockets);
     214            }
     215            goto end;
    192216            break;
    193217        case 'h': /* --help */
    194218            usage(argc, argv);
    195             return 0;
     219            goto end;
    196220            break;
    197221        case 'v': /* --version */
     
    200224            break;
    201225        default:
    202             fprintf(stderr, "Unknow argument #%d\n", myoptind);
    203             return -1;
     226            fprintf(stderr, "Unknown argument #%d\n", myoptind);
     227            mainret = -1;
     228            goto end;
    204229            break;
    205230        }
     
    233258
    234259        refresh |= update_screens_contents(screen_list);
     260
     261        refresh |= read_socket(screen_list, cv, &dp);
    235262
    236263        /* No more screens, exit */
     
    510537    }
    511538
     539    if(screen_list->socket_path) {
     540        unlink(screen_list->socket_path);
     541        free(screen_list->socket_path);
     542    }
     543    if(screen_list->socket)
     544        close(screen_list->socket);
     545
    512546    free(screen_list->screen);
    513547
     
    536570    free(recurrent_list);
    537571
    538     return 0;
     572    return mainret;
    539573}
    540574
  • neercs/trunk/src/neercs.h

    r2473 r2474  
    2727};
    2828
    29 
    3029struct option
    3130{
     
    7170    int in_bell;                 /* Bell occuring in a window  */
    7271    int dont_update_coords;      /* Used by recurrents */
     72
     73    /* Detaching */
    7374    int attached;                /* Are we attached to a terminal */
     75    int socket;                  /* Socket to ask for attaching */
     76    char *socket_path;           /* Socket to ask for attaching */
     77    char *socket_dir;            /* Where to create the socket */
    7478
    7579    /* Lock */
     
    133137
    134138int detach(struct screen_list* screen_list, caca_display_t * dp);
     139int request_attach(char *socket_path);
     140int create_socket(struct screen_list* screen_list);
     141int read_socket(struct screen_list* screen_list, cucul_canvas_t * cv, caca_display_t ** dp);
     142char ** list_sockets(char *socket_dir);
    135143
    136144/* Screens management */
Note: See TracChangeset for help on using the changeset viewer.