Changeset 2450


Ignore:
Timestamp:
06/18/08 22:29:34 (5 years ago)
Author:
pterjan
Message:
  • Detach properly the process from the previous tty
  • Use major to decide if a device is a pty slave
File:
1 edited

Legend:

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

    r2444 r2450  
    1414#include <sys/user.h> 
    1515#include <sys/wait.h> 
     16 
     17#include <linux/kdev_t.h> 
     18#include <linux/major.h> 
    1619 
    1720#include "neercs.h" 
     
    6164    } 
    6265 
    63     regs->esp -= 4; 
     66    regs->esp = oregs.esp-4; 
    6467 
    6568    oinst = ptrace(PTRACE_PEEKTEXT, pid, regs->esp, 0); 
     
    8689    waitpid(pid, NULL, 0); 
    8790 
     91    if(ptrace(PTRACE_GETREGS, pid, NULL, regs) < 0) 
     92    { 
     93        return errno; 
     94    } 
     95 
    8896    if(ptrace(PTRACE_SETREGS, pid, NULL, &oregs) < 0) 
    8997    { 
     98        fprintf(stderr, "PTRACE_SETREGS failed\n"); 
    9099        return errno; 
    91100    } 
     
    93102    if(ptrace(PTRACE_POKETEXT, pid, oregs.esp-4 , oinst) < 0) 
    94103    { 
     104        fprintf(stderr, "PTRACE_POKETEXT failed\n"); 
    95105        return errno; 
    96106    } 
     
    157167    regs.edx = 0755; 
    158168 
    159     if((ret = do_syscall(pid, &regs)) < 0) 
     169    if((ret = do_syscall(pid, &regs)) != 0) 
    160170    { 
    161171        return ret; 
     
    193203    regs.edx = ((long)target_page); 
    194204 
    195     if((ret = do_syscall(pid, &regs)) < 0) 
     205    if((ret = do_syscall(pid, &regs)) != 0) 
    196206    { 
    197207        return ret; 
     
    211221} 
    212222 
    213 static int do_setpgrp(pid_t pid, int fd) { 
    214     struct user_regs_struct regs; 
    215     void *backup_page; 
    216     void *target_page = (void*)(0x08048000); 
    217     size_t size = (1<<12)*2; /* 8K */ 
    218     int ret, pgrp; 
    219  
    220     /* Backup the pages that we will use */ 
    221     backup_page = malloc(size); 
    222     if (memcpy_from_target(pid, backup_page, target_page, size) < 0) 
    223         return -1; 
    224  
    225     if(ptrace(PTRACE_GETREGS, pid, NULL, &regs) < 0) 
    226     { 
    227         fprintf(stderr, "PTRACE_GETREGS failed\n"); 
    228         return errno; 
    229     } 
    230  
    231     pgrp = getpgrp(); 
    232  
    233     memcpy_into_target(pid, target_page, &getpgrp, 4); 
    234  
    235     regs.eax = SYS_ioctl; 
    236     regs.ebx = fd; 
    237     regs.ecx = TIOCSPGRP; 
    238     regs.edx = (long)(target_page); 
    239     do_syscall(pid, &regs); 
    240  
    241  
    242     if((ret = do_syscall(pid, &regs)) < 0) 
     223static int do_setsid(pid_t pid) { 
     224    struct user_regs_struct regs; 
     225    int ret; 
     226 
     227    if(ptrace(PTRACE_GETREGS, pid, NULL, &regs) < 0) 
     228    { 
     229        fprintf(stderr, "PTRACE_GETREGS failed\n"); 
     230        return errno; 
     231    } 
     232 
     233    debug("Running setsid on process %d (sid=%d)", pid, getsid(pid)); 
     234 
     235    regs.eax = SYS_setpgid; 
     236    regs.ebx = 0; 
     237    regs.ecx = getsid(pid); 
     238 
     239    if((ret = do_syscall(pid, &regs)) != 0) 
    243240    { 
    244241        return ret; 
    245242    } 
    246243 
    247     if (regs.eax < 0) { 
    248         fprintf(stderr, "ioctl failed\n"); 
    249         return (-regs.eax); 
    250     } 
    251  
    252     /* Restore the pages */ 
    253     memcpy_into_target(pid, target_page, backup_page, size); 
     244    if (regs.eax != 0) { 
     245        fprintf(stderr, "setpgid failed\n"); 
     246        return -regs.eax; 
     247    } 
     248 
     249    regs.eax = SYS_setsid; 
     250 
     251    if((ret = do_syscall(pid, &regs)) != 0) 
     252    { 
     253        return ret; 
     254    } 
     255 
     256    debug("pid %d has now sid %d", pid, getsid(pid)); 
     257 
     258    if (regs.eax == -1) { 
     259        fprintf(stderr, "getsid failed\n"); 
     260        return -regs.eax; 
     261    } 
    254262 
    255263    return 0; 
     
    261269    int i, fd = 0, mode, ret; 
    262270    char fdstr[1024]; 
     271    char to_open[3]; 
    263272    struct stat stat_buf; 
    264273 
    265274    debug("pty is %s", ptyname); 
    266275 
     276    kill(pid, SIGSTOP); 
    267277    if(ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) 
    268278    { 
     
    270280        return errno; 
    271281    } 
     282    kill(pid, SIGCONT); 
    272283    waitpid(pid, NULL, 0); 
    273284 
     
    275286    { 
    276287        snprintf(fdstr, sizeof(fdstr), "/proc/%d/fd/%d", pid, i); 
     288        to_open[i]=0; 
    277289        lstat(fdstr, &stat_buf); 
    278290        if ((stat_buf.st_mode & S_IRUSR) && (stat_buf.st_mode & S_IWUSR)) 
     
    285297        if (stat(fdstr, &stat_buf) < 0) 
    286298            continue; 
    287         if (!S_ISCHR(stat_buf.st_mode)) //FIXME How to know for sure this is the pty and not /dev/null ? 
     299 
     300        if (!S_ISCHR(stat_buf.st_mode) || MAJOR(stat_buf.st_rdev) != UNIX98_PTY_SLAVE_MAJOR) 
    288301            continue; 
    289302 
     
    297310            fprintf(stderr, "do_close %s\n", strerror(ret)); 
    298311        } 
     312        to_open[i]=1; 
     313    } 
     314 
     315    if((ret = do_setsid(pid))) 
     316    { 
     317        fprintf(stderr, "do_setsid %s\n", strerror(ret)); 
     318    } 
     319 
     320    for(i=0; i<=2; i++) 
     321    { 
     322        if(!to_open[i]) 
     323            continue; 
    299324        if((ret = do_open(pid, ptyname, mode, &fd))) 
    300325        { 
     
    305330            fprintf(stderr, "do_dup2 %s\n", strerror(ret)); 
    306331        } 
    307         if((ret = do_setpgrp(pid, i))) 
    308         { 
    309             fprintf(stderr, "do_setpgrp %s\n", strerror(ret)); 
    310         } 
    311332    } 
    312333 
    313334    kill(pid, SIGWINCH); 
    314  
    315335    ptrace(PTRACE_DETACH, pid, 0, 0); 
    316336 
Note: See TracChangeset for help on using the changeset viewer.