From: Masatake YAMATO Date: Thu, 9 Nov 2023 21:14:36 +0000 (+0900) Subject: lslocks: refactor the code reading /proc/locks X-Git-Tag: v2.40-rc1~163^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5697f991b32f0acbd8fd90f19534adf23d7a6d13;p=thirdparty%2Futil-linux.git lslocks: refactor the code reading /proc/locks Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lslocks.c b/misc-utils/lslocks.c index 0c6de0dd57..496f090e1c 100644 --- a/misc-utils/lslocks.c +++ b/misc-utils/lslocks.c @@ -239,99 +239,105 @@ static ino_t get_dev_inode(char *str, dev_t *dev) return inum; } -static int get_local_locks(struct list_head *locks) +static struct lock *get_local_lock(char *buf) { int i; - FILE *fp; - char buf[PATH_MAX], *tok = NULL; + char *tok = NULL; size_t sz; - struct lock *l; - - if (!(fp = fopen(_PATH_PROC_LOCKS, "r"))) - return -1; - - while (fgets(buf, sizeof(buf), fp)) { - - l = xcalloc(1, sizeof(*l)); - INIT_LIST_HEAD(&l->locks); + struct lock *l = xcalloc(1, sizeof(*l)); + INIT_LIST_HEAD(&l->locks); + + for (tok = strtok(buf, " "), i = 0; tok; + tok = strtok(NULL, " "), i++) { + + /* + * /proc/locks has *exactly* 8 "blocks" of text + * separated by ' ' - check /fs/locks.c + */ + switch (i) { + case 0: /* ID: */ + tok[strlen(tok) - 1] = '\0'; + l->id = strtos32_or_err(tok, _("failed to parse ID")); + break; + case 1: /* posix, flock, etc */ + if (strcmp(tok, "->") == 0) { /* optional field */ + l->blocked = 1; + i--; + } else + l->type = xstrdup(tok); + break; - for (tok = strtok(buf, " "), i = 0; tok; - tok = strtok(NULL, " "), i++) { + case 2: /* is this a mandatory lock? other values are advisory or noinode */ + l->mandatory = *tok == 'M' ? 1 : 0; + break; + case 3: /* lock mode */ + l->mode = xstrdup(tok); + break; + case 4: /* PID */ /* - * /proc/locks has *exactly* 8 "blocks" of text - * separated by ' ' - check /fs/locks.c + * If user passed a pid we filter it later when adding + * to the list, no need to worry now. OFD locks use -1 PID. */ - switch (i) { - case 0: /* ID: */ - tok[strlen(tok) - 1] = '\0'; - l->id = strtos32_or_err(tok, _("failed to parse ID")); - break; - case 1: /* posix, flock, etc */ - if (strcmp(tok, "->") == 0) { /* optional field */ - l->blocked = 1; - i--; - } else - l->type = xstrdup(tok); - break; + l->pid = strtos32_or_err(tok, _("failed to parse pid")); + if (l->pid > 0) { + l->cmdname = pid_get_cmdname(l->pid); + if (!l->cmdname) + l->cmdname = xstrdup(_("(unknown)")); + } else + l->cmdname = xstrdup(_("(undefined)")); + break; - case 2: /* is this a mandatory lock? other values are advisory or noinode */ - l->mandatory = *tok == 'M' ? 1 : 0; - break; - case 3: /* lock mode */ - l->mode = xstrdup(tok); - break; + case 5: /* device major:minor and inode number */ + l->inode = get_dev_inode(tok, &l->dev); + break; - case 4: /* PID */ - /* - * If user passed a pid we filter it later when adding - * to the list, no need to worry now. OFD locks use -1 PID. - */ - l->pid = strtos32_or_err(tok, _("failed to parse pid")); - if (l->pid > 0) { - l->cmdname = pid_get_cmdname(l->pid); - if (!l->cmdname) - l->cmdname = xstrdup(_("(unknown)")); - } else - l->cmdname = xstrdup(_("(undefined)")); - break; + case 6: /* start */ + l->start = !strcmp(tok, "EOF") ? 0 : + strtou64_or_err(tok, _("failed to parse start")); + break; - case 5: /* device major:minor and inode number */ - l->inode = get_dev_inode(tok, &l->dev); - break; + case 7: /* end */ + /* replace '\n' character */ + tok[strlen(tok)-1] = '\0'; + l->end = !strcmp(tok, "EOF") ? 0 : + strtou64_or_err(tok, _("failed to parse end")); + break; + default: + break; + } + } - case 6: /* start */ - l->start = !strcmp(tok, "EOF") ? 0 : - strtou64_or_err(tok, _("failed to parse start")); - break; + l->path = get_filename_sz(l->inode, l->pid, &sz); - case 7: /* end */ - /* replace '\n' character */ - tok[strlen(tok)-1] = '\0'; - l->end = !strcmp(tok, "EOF") ? 0 : - strtou64_or_err(tok, _("failed to parse end")); - break; - default: - break; - } - } + /* no permissions -- ignore */ + if (!l->path && no_inaccessible) { + rem_lock(l); + return NULL; + } - l->path = get_filename_sz(l->inode, l->pid, &sz); + if (!l->path) { + /* probably no permission to peek into l->pid's path */ + l->path = get_fallback_filename(l->dev); + l->size = 0; + } else + l->size = sz; - /* no permissions -- ignore */ - if (!l->path && no_inaccessible) { - rem_lock(l); - continue; - } + return l; +} - if (!l->path) { - /* probably no permission to peek into l->pid's path */ - l->path = get_fallback_filename(l->dev); - l->size = 0; - } else - l->size = sz; +static int get_local_locks(struct list_head *locks) +{ + FILE *fp; + char buf[PATH_MAX]; - list_add(&l->locks, locks); + if (!(fp = fopen(_PATH_PROC_LOCKS, "r"))) + return -1; + + while (fgets(buf, sizeof(buf), fp)) { + struct lock *l = get_local_lock(buf); + if (l) + list_add(&l->locks, locks); } fclose(fp);