Changeset 2474


Ignore:
Timestamp:
06/22/08 11:57:21 (5 years ago)
Author:
pterjan
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.