--- doc/fuser.1 +++ doc/fuser.1 2010-07-13 13:19:57.000000000 +0000 @@ -12,6 +12,7 @@ fuser \- identify processes using files .RB [ \-k .RB [ \-i ] .RB [ \-M ] +.RB [ \-w ] .RB [ \- \fISIGNAL ] ] .IR name " ..." @@ -102,6 +103,10 @@ Request will be fulfilled only if \fINAM 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 --- src/fuser.c +++ src/fuser.c 2010-07-13 13:25:44.000000000 +0000 @@ -75,7 +75,7 @@ static struct stat *get_pidstat(const op 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);*/ @@ -127,6 +127,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, _( @@ -1133,6 +1134,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'}, @@ -1244,6 +1246,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; @@ -1406,6 +1411,7 @@ print_matches(struct names *names_head, 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) { @@ -1546,8 +1552,8 @@ print_matches(struct names *names_head, } } /* 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); @@ -1857,12 +1863,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(); @@ -1871,13 +1878,18 @@ kill_matched_proc(struct procs *proc_hea 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) --- src/fuser.h +++ src/fuser.h 2010-07-13 13:26:15.000000000 +0000 @@ -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;