]> granicus.if.org Git - psmisc/commitdiff
Add an option -w to fuser to be able to send signals
authorWerner Fink <werner@suse.de>
Tue, 21 Sep 2010 07:04:16 +0000 (09:04 +0200)
committerWerner Fink <werner@suse.de>
Tue, 21 Sep 2010 07:04:16 +0000 (09:04 +0200)
to  processes which have write access to an open file
or directory. This option is silently ignored if -k is
not present too.

Signed-off-by: Werner Fink <werner@suse.de>
doc/fuser.1
src/fuser.c
src/fuser.h

index ea99f0d0b1eec855273dd9eaddab8cd405864c84..0853882ba8fd4ae2a9cc7a584145ea5325267cbb 100644 (file)
@@ -12,6 +12,7 @@ fuser \- identify processes using files or sockets
 .RB [ \-k
 .RB [ \-i ]
 .RB [ \-M ]
+.RB [ \-w ]
 .RB [ \- \fISIGNAL
 ] ]
 .IR name " ..."
@@ -96,6 +97,10 @@ Request will be fulfilled only if \fINAME\fR specifies a mountpoint.
 This is an invaluable seatbelt which prevents you from killing the machine
 if \fINAME\fR happens to not be a filesystem.
 .TP
+\fB\-w\fP
+Kill only processes which have write access. This option is
+silently ignored if \fB\-k\fP is not present too.
+.TP
 \fB\-n \fISPACE\fR, \fB\-\-namespace\fR \fISPACE\fR
 Select a different name space. The name spaces \fBfile\fR (file names, the
 default), \fBudp\fR (local UDP ports), and \fBtcp\fR (local TCP ports) are
index ed473a79bfc18fef27827831fba856042ad440fd..4688dfeea95b19916e04110675a8520e999816b1 100644 (file)
@@ -71,7 +71,7 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename);
 static uid_t getpiduid(const pid_t pid);
 static int print_matches(struct names *names_head, const opt_type opts,
                         const int sig_number);
-static void kill_matched_proc(struct procs *pptr, const opt_type opts,
+static int kill_matched_proc(struct procs *pptr, const opt_type opts,
                              const int sig_number);
 
 /*int parse_mount(struct names *this_name, struct device_list **dev_list);*/
@@ -116,6 +116,7 @@ static void usage(const char *errormsg)
                 "  -SIGNAL               send this signal instead of SIGKILL\n"
                 "  -u,--user             display user IDs\n"
                 "  -v,--verbose          verbose output\n"
+                "  -w,--writeonly        kill only processes with write access\n"
                 "  -V,--version          display version information\n"));
 #ifdef WITH_IPV6
        fprintf(stderr, _(
@@ -847,6 +848,7 @@ int main(int argc, char *argv[])
                {"silent", 0, NULL, 's'},
                {"user", 0, NULL, 'u'},
                {"verbose", 0, NULL, 'v'},
+               {"writeonly", 0, NULL, 'w'},
                {"version", 0, NULL, 'V'},
 #ifdef WITH_IPV6
                {"ipv4", 0, NULL, '4'},
@@ -959,6 +961,9 @@ int main(int argc, char *argv[])
                  case 'v':
                        opts |= OPT_VERBOSE;
                        break;
+                 case 'w':
+                       opts |= OPT_WRITE;
+                       break;
                  case 'V':
                        print_version();
                        return 0;
@@ -1102,6 +1107,7 @@ print_matches(struct names *names_head, const opt_type opts,
        int len = 0;
        struct passwd *pwent = NULL;
        int have_match = 0;
+       int have_kill = 0;
        int name_has_procs;
 
        for (nptr = names_head; nptr != NULL; nptr = nptr->next) {
@@ -1242,8 +1248,8 @@ print_matches(struct names *names_head, const opt_type opts,
                        }
                }               /* be silent */
                if (opts & OPT_KILL)
-                       kill_matched_proc(nptr->matched_procs, opts,
-                                         sig_number);
+                       have_kill = kill_matched_proc(nptr->matched_procs,
+                                                     opts, sig_number);
 
        }                       /* next name */
        return (have_match == 1 ? 0 : 1);
@@ -1506,12 +1512,13 @@ static int ask(const pid_t pid)
        }                       /* while */
 }
 
-static void
+static int
 kill_matched_proc(struct procs *proc_head, const opt_type opts,
                  const int sig_number)
 {
        struct procs *pptr;
   pid_t mypid;
+       int ret = 0;
 
   mypid = getpid();
 
@@ -1520,13 +1527,18 @@ kill_matched_proc(struct procs *proc_head, const opt_type opts,
       continue; /* dont kill myself */
                if ( pptr->proc_type != PTYPE_NORMAL )
            continue;
+               if ((opts & OPT_WRITE) && ((pptr->access & ACCESS_FILEWR) == 0))
+                       continue;
                if ((opts & OPT_INTERACTIVE) && (ask(pptr->pid) == 0))
                  continue;
                if ( kill(pptr->pid, sig_number) < 0) {
                        fprintf(stderr, _("Could not kill process %d: %s\n"),
                                        pptr->pid, strerror(errno));
+                       continue;
                }
+               ret = 1;
        }
+       return ret;
 }
 
 static dev_t find_net_dev(void)
index 13065db4d8fe250b756451b99a8fe15aebfd7f75..209973f32d0a4df16d81f4f6b8112fb7f81d314c 100644 (file)
@@ -1,6 +1,6 @@
 
 /* Option Flags */
-typedef unsigned char opt_type;
+typedef unsigned short opt_type;
 
 #define OPT_VERBOSE 1
 #define OPT_ALLFILES 2
@@ -10,6 +10,7 @@ typedef unsigned char opt_type;
 #define OPT_SILENT 32
 #define OPT_USER 64
 #define OPT_ISMOUNTPOINT 128
+#define OPT_WRITE 256
 
 struct procs {
        pid_t pid;