1 (12.12.2010 04:17:11 отредактировано NegativeCreep)

Имею такое задание:
Написать программу trykill которая на практике определяет множество сигналов,
- которыми могут обмениваться 2 процесса одного пользователя;
- которые могут быть посланы процессом пользователя A процессу пользователя B, при условии, что пользователи A и B являются членами одной группы;
- которые могут быть посланы процессом пользователя A процессу пользователя root.

Честно, не совсем представляю себе, как это решать. Нашел в интернете такую программу:

void sig_handler(int sig)
{
    printf("cathed signal %d\n",sig);
    exit(0);
}
int main(int argc,char **argv[])
{
    int i,errno,err;
    pid_t pid;
    // пока он спит, тестим его на восприимчивость сигналов
    for(i = 1;i < NSIG;i++)
    {
        if(i!=SIGSTOP&&i!= SIGKILL)
        {
            errno=0;
            err=signal(i, sig_handler);
            printf("sig %d, status %d, errno %d\n",i,err,errno);
        }
    }
    if((pid=fork())==0)
    {
        execl("./launch","./launch",0);
        sleep(30);
    }
}

В случае, когда надо послать сигнал другому пользователю:

void sig_handler(int sig)
{
    exit(0);
}
int main(int argc,char **argv[])
{
    int i,errno,err;
    pid_t pid;
    for(i = 1;i <NSIG;i++)
    {
        if(i!=SIGSTOP&&i!= SIGKILL)
        {
            err=kill(ЗДЕСЬ PID ПРОЦЕССА ДРУГОГО ПОЛЬЗОВАТЕЛЯ, i);
            printf("sig %d, status %d\n",i,err);
        }
    }
    if((pid=fork())==0)
    {
        execl("./launch","./launch",0);
        sleep(30);
    }
}

Как я понял, на печать выводятся сигналы, на которые отреагеровала функция sig_handler в виде цифр(по сути числа от 1 до 64). Мне же нужно, чтобы это были названия сигналов(типа SIGSTOP, SIGKILL). Первый вопрос - как сделать, чтобы выводились они.
Ну, это работает для процессов одного пользователя, а второй вопрос заключается в том, чтобы сделать это для двух.

-

2 (12.12.2010 01:28:04 отредактировано NegativeCreep)

Так, вроде получил желаемый результат)

Пожалуйста, подскажите тогда верно ли следующее:
Процесс пользователя А может посылать любые сигналы процессу пользователя В
Процесс пользователя А не может посылать процессу пользователя B никаких сигналов, даже если они члены одной группы
Ну и тем более процессу пользователя root

3

NegativeCreep пишет:

Пожалуйста, подскажите тогда верно ли следующее:
1)Процесс пользователя А может посылать любые сигналы процессу пользователя В
2)Процесс пользователя А не может посылать процессу пользователя B никаких сигналов, даже если они члены одной группы
Ну и тем более процессу пользователя root

1) да
2) ничегонипонял. сформулируйте по человечески.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

4

man wait



       #include <sys/wait.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <stdio.h>

       int
       main(int argc, char *argv[])
       {
           pid_t cpid, w;
           int status;

           cpid = fork();
           if (cpid == -1) {
               perror("fork");
               exit(EXIT_FAILURE);
           }

           if (cpid == 0) {            /* Code executed by child */
               printf("Child PID is %ld\n", (long) getpid());
               if (argc == 1)
                   pause();                    /* Wait for signals */
               _exit(atoi(argv[1]));

           } else {                    /* Code executed by parent */
               do {
                   w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
                   if (w == -1) {
                       perror("waitpid");
                       exit(EXIT_FAILURE);
                   }

                   if (WIFEXITED(status)) {
                       printf("exited, status=%d\n", WEXITSTATUS(status));
                   } else if (WIFSIGNALED(status)) {
                       printf("killed by signal %d\n", WTERMSIG(status));
                   } else if (WIFSTOPPED(status)) {
                       printf("stopped by signal %d\n", WSTOPSIG(status));
                   } else if (WIFCONTINUED(status)) {
                       printf("continued\n");
                   }
               } while (!WIFEXITED(status) && !WIFSIGNALED(status));
               exit(EXIT_SUCCESS);
           }
       }

PS: ну маны читать нынче не модно ac

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)
drBatty пишет:
NegativeCreep пишет:

Пожалуйста, подскажите тогда верно ли следующее:
1)Процесс пользователя А может посылать любые сигналы процессу пользователя В
2)Процесс пользователя А не может посылать процессу пользователя B никаких сигналов, даже если они члены одной группы
Ну и тем более процессу пользователя root

1) да
2) ничегонипонял. сформулируйте по человечески.

Извиняюсь, торопился. В пером было "Процесс пользователя А может посылать любые сигналы процессу пользователя А".
Насчет второго - такой вывод сделал на основании того, что kill(pid,signal) возвращала -1(pid - пид любого процесса пользователя Б).

drBatty пишет:

#include <sys/wait.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <stdio.h>

       int
       main(int argc, char *argv[])
       {
           pid_t cpid, w;
           int status;

           cpid = fork();
           if (cpid == -1) {
               perror("fork");
               exit(EXIT_FAILURE);
           }

           if (cpid == 0) {            /* Code executed by child */
               printf("Child PID is %ld\n", (long) getpid());
               if (argc == 1)
                   pause();                    /* Wait for signals */
               _exit(atoi(argv[1]));

           } else {                    /* Code executed by parent */
               do {
                   w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
                   if (w == -1) {
                       perror("waitpid");
                       exit(EXIT_FAILURE);
                   }

                   if (WIFEXITED(status)) {
                       printf("exited, status=%d\n", WEXITSTATUS(status));
                   } else if (WIFSIGNALED(status)) {
                       printf("killed by signal %d\n", WTERMSIG(status));
                   } else if (WIFSTOPPED(status)) {
                       printf("stopped by signal %d\n", WSTOPSIG(status));
                   } else if (WIFCONTINUED(status)) {
                       printf("continued\n");
                   }
               } while (!WIFEXITED(status) && !WIFSIGNALED(status));
               exit(EXIT_SUCCESS);
           }
       }

PS: ну маны читать нынче не модно sad

За программу огромное спасибо, все понятно кроме того, где мы определяем переменную status. man wait изучал, использовать его не догадался(.
Как я понимаю, нужно запустить эту программу, а затем посылать ей сигналы с другой.

Вид исходного кода исправил.

7

NegativeCreep пишет:

1)Извиняюсь, торопился. В пером было "Процесс пользователя А может посылать любые сигналы процессу пользователя А".
2)Насчет второго - такой вывод сделал на основании того, что kill(pid,signal) возвращала -1(pid - пид любого процесса пользователя Б).

1) куда спешить-то?
2) да. насколько я знаю, только процесс с UID == 0 может посылать сообщения другим процессам. Это связанно с безопасностью (например на сервере одни пользователи не имеют права вырубать программы других. Ибо анархия == wendowz.) Только администратор может управлять процессами пользователей. Я знаю, это не очень удобно - приходится делать например сигнальные файлы для обмена информацией.

NegativeCreep пишет:

где мы определяем переменную status

в самом начале. потом адрес этой переменной передаётся внутрь waitpid(), которая и пишет туда текущий статус.

NegativeCreep пишет:

Как я понимаю, нужно запустить эту программу, а затем посылать ей сигналы с другой.

ага. А программа, которая посылает сигналы называется kill. По умолчанию она посылает сигнал TERM, который завершает программу, но можно послать и любой другой сигнал любой программе.

Имеется исключение: сигнал KILL передаётся не программе, а ядру, которое завершает заданный процесс. например:

 Консоль:
doc@dt:~$ sleep 1h &
[1] 2368
doc@dt:~$ kill -KILL 2368
doc@dt:~$ kill -KILL 2368
bash: kill: (2368) - Нет такого процесса
[1]+  Убито              sleep 1h
doc@dt:~$

тут я запустил программу sleep, с параметром "1 час". А потом грохнул её, послав сигнал KILL (это девятка).

NegativeCreep пишет:

Вид исходного кода исправил.

спасибо.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

8

NegativeCreep пишет:

Мне же нужно, чтобы это были названия сигналов(типа SIGSTOP, SIGKILL).

добавьте в вашу программу

#include <signal.h>

это приведёт к добавлению такого файла (далее для моей системы, в вашей файл может быть другим и с другим именем!)
doc@dt:~$ cat !$

cat /usr/include/bits/signum.h
/* Signal number definitions.  Linux version.
   Copyright (C) 1995,1996,1997,1998,1999,2003 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#ifdef    _SIGNAL_H

/* Fake signal functions.  */
#define SIG_ERR    ((__sighandler_t) -1)        /* Error return.  */
#define SIG_DFL    ((__sighandler_t) 0)        /* Default action.  */
#define SIG_IGN    ((__sighandler_t) 1)        /* Ignore signal.  */

#ifdef __USE_UNIX98
# define SIG_HOLD    ((__sighandler_t) 2)    /* Add signal to hold mask.  */
#endif


/* Signals.  */
#define    SIGHUP        1    /* Hangup (POSIX).  */
#define    SIGINT        2    /* Interrupt (ANSI).  */
#define    SIGQUIT        3    /* Quit (POSIX).  */
#define    SIGILL        4    /* Illegal instruction (ANSI).  */
#define    SIGTRAP        5    /* Trace trap (POSIX).  */
#define    SIGABRT        6    /* Abort (ANSI).  */
#define    SIGIOT        6    /* IOT trap (4.2 BSD).  */
#define    SIGBUS        7    /* BUS error (4.2 BSD).  */
#define    SIGFPE        8    /* Floating-point exception (ANSI).  */
#define    SIGKILL        9    /* Kill, unblockable (POSIX).  */
#define    SIGUSR1        10    /* User-defined signal 1 (POSIX).  */
#define    SIGSEGV        11    /* Segmentation violation (ANSI).  */
#define    SIGUSR2        12    /* User-defined signal 2 (POSIX).  */
#define    SIGPIPE        13    /* Broken pipe (POSIX).  */
#define    SIGALRM        14    /* Alarm clock (POSIX).  */
#define    SIGTERM        15    /* Termination (ANSI).  */
#define    SIGSTKFLT    16    /* Stack fault.  */
#define    SIGCLD        SIGCHLD    /* Same as SIGCHLD (System V).  */
#define    SIGCHLD        17    /* Child status has changed (POSIX).  */
#define    SIGCONT        18    /* Continue (POSIX).  */
#define    SIGSTOP        19    /* Stop, unblockable (POSIX).  */
#define    SIGTSTP        20    /* Keyboard stop (POSIX).  */
#define    SIGTTIN        21    /* Background read from tty (POSIX).  */
#define    SIGTTOU        22    /* Background write to tty (POSIX).  */
#define    SIGURG        23    /* Urgent condition on socket (4.2 BSD).  */
#define    SIGXCPU        24    /* CPU limit exceeded (4.2 BSD).  */
#define    SIGXFSZ        25    /* File size limit exceeded (4.2 BSD).  */
#define    SIGVTALRM    26    /* Virtual alarm clock (4.2 BSD).  */
#define    SIGPROF        27    /* Profiling alarm clock (4.2 BSD).  */
#define    SIGWINCH    28    /* Window size change (4.3 BSD, Sun).  */
#define    SIGPOLL        SIGIO    /* Pollable event occurred (System V).  */
#define    SIGIO        29    /* I/O now possible (4.2 BSD).  */
#define    SIGPWR        30    /* Power failure restart (System V).  */
#define SIGSYS        31    /* Bad system call.  */
#define SIGUNUSED    31

#define    _NSIG        65    /* Biggest signal number + 1
                   (including real-time signals).  */

#define SIGRTMIN        (__libc_current_sigrtmin ())
#define SIGRTMAX        (__libc_current_sigrtmax ())

/* These are the hard limits of the kernel.  These values should not be
   used directly at user level.  */
#define __SIGRTMIN    32
#define __SIGRTMAX    (_NSIG - 1)

#endif    /* <signal.h> included.  */
Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

9

NegativeCreep пишет:

if(i!=SIGSTOP&&i!= SIGKILL)

довольно глупо, ибо насколько я знаю, SIGKILL никогда не доходит до программы.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

10

Спасибо за терпение и за помощь)
Почти все понял, остался один маленький вопрос)
Сигналы через kill надо вручную посылать, потому что некоторые будут убивать процесс, и надо его запускать заного (с новым pid). Это верно?