149 lines
4.8 KiB
Diff
149 lines
4.8 KiB
Diff
|
--- doc/fuser.1
|
||
|
+++ doc/fuser.1 2008-08-07 14:51:18.000000000 +0200
|
||
|
@@ -10,6 +10,7 @@ fuser \- identify processes using files
|
||
|
.IR space\ ]
|
||
|
.RB [ \-k
|
||
|
.RB [ \-i ]
|
||
|
+.RB [ \-w ]
|
||
|
.RB [ \- \fIsignal
|
||
|
] ]
|
||
|
.RB [ \-muvf ]
|
||
|
@@ -74,6 +75,9 @@ other \fBfuser\fP processes. The effecti
|
||
|
.IP \fB\-i\fP
|
||
|
Ask the user for confirmation before killing a process. This option is
|
||
|
silently ignored if \fB\-k\fP is not present too.
|
||
|
+.IP \fB\-w\fP
|
||
|
+Kill only processes which have write access. This option is
|
||
|
+silently ignored if \fB\-k\fP is not present too.
|
||
|
.IP \fB\-l\fP
|
||
|
List all known signal names.
|
||
|
.IP \fB\-m\fP
|
||
|
--- src/fuser.c
|
||
|
+++ src/fuser.c 2008-08-07 15:49:28.714368021 +0200
|
||
|
@@ -66,7 +66,7 @@ static void check_map(const pid_t pid, c
|
||
|
static struct stat *get_pidstat(const opt_type opts, const pid_t pid, const char *filename, char *real);
|
||
|
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, const int sig_number);
|
||
|
+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);
|
||
|
static void add_device(struct device_list **dev_list, struct names *this_name, dev_t device);
|
||
|
@@ -89,7 +89,7 @@ static void usage (const char *errormsg)
|
||
|
fprintf(stderr, "%s\n", errormsg);
|
||
|
|
||
|
fprintf (stderr, _(
|
||
|
- "Usage: fuser [ -a | -s | -c ] [ -n SPACE ] [ -SIGNAL ] [ -kimuv ] NAME...\n"
|
||
|
+ "Usage: fuser [ -a | -s | -c ] [ -n SPACE ] [ -SIGNAL ] [ -kimuvw ] NAME...\n"
|
||
|
" [ - ] [ -n SPACE ] [ -SIGNAL ] [ -kimuv ] NAME...\n"
|
||
|
" fuser -l\n"
|
||
|
" fuser -V\n"
|
||
|
@@ -106,6 +106,7 @@ static void usage (const char *errormsg)
|
||
|
" -SIGNAL send this signal instead of SIGKILL\n"
|
||
|
" -u display user IDs\n"
|
||
|
" -v verbose output\n"
|
||
|
+ " -w kill only processes with write access\n"
|
||
|
" -V display version information\n"));
|
||
|
#ifdef WITH_IPV6
|
||
|
fprintf (stderr, _(
|
||
|
@@ -901,6 +902,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;
|
||
|
@@ -1033,6 +1037,7 @@ static int print_matches(struct names *n
|
||
|
int len = 0;
|
||
|
struct passwd *pwent = NULL;
|
||
|
int have_match = 0;
|
||
|
+ int have_kill = 0;
|
||
|
|
||
|
for (nptr = names_head; nptr != NULL ; nptr = nptr->next) {
|
||
|
if (opts & OPT_SILENT) {
|
||
|
@@ -1103,21 +1108,23 @@ static int print_matches(struct names *n
|
||
|
len = 0;
|
||
|
first = 0;
|
||
|
}
|
||
|
- if (opts & OPT_VERBOSE) {
|
||
|
- /* put a newline if showing all files and no procs*/
|
||
|
- if (nptr->matched_procs == NULL && (opts & OPT_ALLFILES))
|
||
|
- putc('\n', stderr);
|
||
|
- } else {
|
||
|
- if (nptr->matched_procs != NULL || (opts & OPT_ALLFILES))
|
||
|
- putc('\n', stderr);
|
||
|
- }
|
||
|
+ if (opts & OPT_VERBOSE) {
|
||
|
+ /* put a newline if showing all files and no procs*/
|
||
|
+ if (nptr->matched_procs == NULL && (opts & OPT_ALLFILES))
|
||
|
+ putc('\n', stderr);
|
||
|
+ } else {
|
||
|
+ if (nptr->matched_procs != NULL || (opts & OPT_ALLFILES))
|
||
|
+ putc('\n', stderr);
|
||
|
+ }
|
||
|
} /* 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);
|
||
|
-
|
||
|
+ if (opts & OPT_KILL)
|
||
|
+ return (have_kill==1?0:1);
|
||
|
+ else
|
||
|
+ return (have_match==1?0:1);
|
||
|
}
|
||
|
|
||
|
static struct stat *get_pidstat(const opt_type opts, const pid_t pid, const char *filename, char *real)
|
||
|
@@ -1403,21 +1410,26 @@ static int ask(const pid_t pid)
|
||
|
} /* while */
|
||
|
}
|
||
|
|
||
|
-static void kill_matched_proc(struct procs *proc_head, const opt_type opts, const int sig_number)
|
||
|
+static int kill_matched_proc(struct procs *proc_head, const opt_type opts, const int sig_number)
|
||
|
{
|
||
|
struct procs *pptr;
|
||
|
+ int ret = 0;
|
||
|
|
||
|
for (pptr = proc_head ; pptr != NULL ; pptr = pptr->next ) {
|
||
|
if ( (opts & OPT_INTERACTIVE) && (ask(pptr->pid) == 0))
|
||
|
continue;
|
||
|
+ if ((opts & OPT_WRITE) && ((pptr->access & ACCESS_FILEWR) == 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 2008-08-07 14:26:48.000000000 +0200
|
||
|
@@ -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_MOUNTPOINT 128
|
||
|
+#define OPT_WRITE 256
|
||
|
|
||
|
|
||
|
struct procs {
|