Skip to content

Commit 39b5ae1

Browse files
committed
[linux] implemented Linux dialect resource cleanup with lsof_dialect_destroy()
- Added `lsof_dialect_destroy()` function for Linux dialect resource cleanup. - Implemented cleanup for lock hash table, pipe/PTY/message queue/eventfd endpoint hashes, field pointers, and lock stream buffer. - Moved static variables and type definitions from dnode.c to dlsof.h for improved modularity. - Added context field access macros (LckH, Pinfo, PtyInfo, PSXMQinfo, EvtFDinfo, Fp, Fpa, Vbuf, Vsz) for dialect state management. - Replaced manual array reallocation with `grow_array()` helper function in dnode.c. - Updated build files to include new dlsof.c source file in Linux dialect compilation.
1 parent 53539a9 commit 39b5ae1

9 files changed

Lines changed: 175 additions & 57 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,6 @@ autom4te.cache
168168

169169
# Doxygen
170170
/output
171+
172+
compile_commands.json
173+
.cache

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ LIBLSOF_SOURCES += lib/dialects/linux/dfile.c \
1616
lib/dialects/linux/dproc.c \
1717
lib/dialects/linux/dsock.c \
1818
lib/dialects/linux/dstore.c \
19+
lib/dialects/linux/dlsof.c \
1920
lib/dialects/linux/dlsof.h \
2021
lib/dialects/linux/dproto.h \
2122
lib/dialects/linux/machine.h

lib/dialects/linux/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ GRP=
2424

2525
HDR= lib/common.h include/lsof_fields.h dlsof.h machine.h lib/proto.h dproto.h
2626

27-
SRC= dfile.c dmnt.c dnode.c dprint.c dproc.c dsock.c dstore.c \
27+
SRC= dfile.c dmnt.c dnode.c dprint.c dproc.c dsock.c dstore.c dlsof.c \
2828
arg.c main.c print.c store.c usage.c \
2929
util.c
3030

31-
OBJ= dfile.o dmnt.o dnode.o dprint.o dproc.o dsock.o dstore.o \
31+
OBJ= dfile.o dmnt.o dnode.o dprint.o dproc.o dsock.o dstore.o dlsof.o \
3232
arg.o main.o print.o store.o usage.o \
3333
util.o
3434

lib/dialects/linux/Mksrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ mksrc() {
2222
}
2323

2424
D=lib/dialects/linux
25-
L="dfile.c dlsof.h dmnt.c dnode.c dproc.c dproto.h dsock.c dstore.c machine.h"
25+
L="dfile.c dlsof.h dmnt.c dnode.c dproc.c dproto.h dsock.c dstore.c dlsof.c machine.h"
2626

2727
mksrc
2828

lib/dialects/linux/dlsof.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* dlsof.c - Linux dialect-specific implementations
3+
*/
4+
5+
#include "common.h"
6+
#include "dlsof.h"
7+
8+
/*
9+
* lsof_dialect_destroy() - clean up dialect-specific resources
10+
*/
11+
12+
void lsof_dialect_destroy(struct lsof_context *ctx) {
13+
int i;
14+
struct llock *lp, *np;
15+
#if defined(HASEPTOPTS)
16+
pxinfo_t *pp, *pnp;
17+
#endif
18+
19+
/* Free lock hash table */
20+
if (LckH) {
21+
for (i = 0; i < PIDBUCKS; i++) {
22+
for (lp = LckH[i]; lp; lp = np) {
23+
np = lp->next;
24+
(void)free((FREE_P *)lp);
25+
}
26+
LckH[i] = (struct llock *)NULL;
27+
}
28+
CLEAN(LckH);
29+
}
30+
31+
#if defined(HASEPTOPTS)
32+
/* Free pipe endpoint hash */
33+
if (Pinfo) {
34+
for (i = 0; i < PINFOBUCKS; i++) {
35+
for (pp = Pinfo[i]; pp; pp = pnp) {
36+
pnp = pp->next;
37+
(void)free((FREE_P *)pp);
38+
}
39+
Pinfo[i] = (pxinfo_t *)NULL;
40+
}
41+
CLEAN(Pinfo);
42+
}
43+
44+
# if defined(HASPTYEPT)
45+
/* Free PTY endpoint hash */
46+
if (PtyInfo) {
47+
for (i = 0; i < PINFOBUCKS; i++) {
48+
for (pp = PtyInfo[i]; pp; pp = pnp) {
49+
pnp = pp->next;
50+
(void)free((FREE_P *)pp);
51+
}
52+
PtyInfo[i] = (pxinfo_t *)NULL;
53+
}
54+
CLEAN(PtyInfo);
55+
}
56+
# endif
57+
58+
/* Free message queue endpoint hash */
59+
if (PSXMQinfo) {
60+
for (i = 0; i < PINFOBUCKS; i++) {
61+
for (pp = PSXMQinfo[i]; pp; pp = pnp) {
62+
pnp = pp->next;
63+
(void)free((FREE_P *)pp);
64+
}
65+
PSXMQinfo[i] = (pxinfo_t *)NULL;
66+
}
67+
CLEAN(PSXMQinfo);
68+
}
69+
70+
/* Free eventfd endpoint hash */
71+
if (EvtFDinfo) {
72+
for (i = 0; i < PINFOBUCKS; i++) {
73+
for (pp = EvtFDinfo[i]; pp; pp = pnp) {
74+
pnp = pp->next;
75+
(void)free((FREE_P *)pp);
76+
}
77+
EvtFDinfo[i] = (pxinfo_t *)NULL;
78+
}
79+
CLEAN(EvtFDinfo);
80+
}
81+
#endif /* defined(HASEPTOPTS) */
82+
83+
/* Free field pointers */
84+
if (Fp) {
85+
CLEAN(Fp);
86+
Fpa = 0;
87+
}
88+
89+
/* Free lock stream buffer */
90+
if (Vbuf) {
91+
CLEAN(Vbuf);
92+
Vsz = 0;
93+
}
94+
}

lib/dialects/linux/dlsof.h

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,56 @@ extern dev_t MqueueDev;
198198
# define OFFSET_FDINFO 2
199199
extern int OffType;
200200

201-
struct lsof_context_dialect {};
201+
# define PIDBUCKS 64 /* PID hash buckets */
202+
# define PINFOBUCKS 512 /* pipe info hash buckets */
203+
204+
struct llock {
205+
int pid;
206+
dev_t dev;
207+
INODETYPE inode;
208+
enum lsof_lock_mode type;
209+
struct llock *next;
210+
};
211+
212+
struct lsof_context_dialect {
213+
/* dnode.c - lock hash table */
214+
struct llock **lock_hash;
215+
# if defined(HASEPTOPTS)
216+
pxinfo_t **pipe_ep_hash;
217+
# if defined(HASPTYEPT)
218+
pxinfo_t **pty_ep_hash;
219+
# endif
220+
pxinfo_t **mqueue_ep_hash;
221+
pxinfo_t **eventfd_ep_hash;
222+
# endif
223+
/* dnode.c - field parser state */
224+
char **field_ptrs;
225+
int field_ptrs_alloc;
226+
/* dnode.c - lock stream buffer */
227+
char *lock_stream_buf;
228+
size_t lock_stream_buf_sz;
229+
};
230+
231+
/* Dialect-specific cleanup function */
232+
void lsof_dialect_destroy(struct lsof_context *ctx);
233+
234+
/* Context field access macros */
235+
# define LckH (ctx->dialect.lock_hash)
236+
# if defined(HASEPTOPTS)
237+
# define Pinfo (ctx->dialect.pipe_ep_hash)
238+
# if defined(HASPTYEPT)
239+
# define PtyInfo (ctx->dialect.pty_ep_hash)
240+
# endif
241+
# define PSXMQinfo (ctx->dialect.mqueue_ep_hash)
242+
# define EvtFDinfo (ctx->dialect.eventfd_ep_hash)
243+
# endif
244+
245+
/* Field parser macros */
246+
# define Fp (ctx->dialect.field_ptrs)
247+
# define Fpa (ctx->dialect.field_ptrs_alloc)
248+
249+
/* Lock stream buffer macros */
250+
# define Vbuf (ctx->dialect.lock_stream_buf)
251+
# define Vsz (ctx->dialect.lock_stream_buf_sz)
202252

203253
#endif /* LINUX_LSOF_H */

lib/dialects/linux/dmnt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ typedef struct mntsup {
7070
* Local static definitions
7171
*/
7272

73-
static mntsup_t **MSHash = (mntsup_t **)NULL; /* mount supplement
74-
* hash buckets */
73+
static mntsup_t **MSHash = (mntsup_t **)NULL; /* mount supplement
74+
* hash buckets */
7575

7676
/*
7777
* convert_octal_escaped() -- convert octal-escaped characters in string

lib/dialects/linux/dnode.c

Lines changed: 10 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
*/
3030

3131
#include "common.h"
32+
#include "dlsof.h"
33+
#include "proto.h"
3234

3335
#if defined(HASEPTOPTS) && defined(HASPTYEPT)
3436
# include <linux/major.h>
@@ -42,29 +44,13 @@
4244
((off_t)0x7fffffff) /* this is defined in \
4345
* .../src/fs/locks.c and not \
4446
* in a header file */
45-
#define PIDBUCKS 64 /* PID hash buckets */
46-
#define PINFOBUCKS 512 /* pipe info hash buckets */
4747
#define HASHPID(pid) (((int)((pid * 31415) >> 3)) & (PIDBUCKS - 1))
4848
#define HASHPINFO(ino) (((int)((ino * 31415) >> 3)) & (PINFOBUCKS - 1))
4949

5050
/*
5151
* Local structure definitions
5252
*/
5353

54-
struct llock {
55-
int pid;
56-
dev_t dev;
57-
INODETYPE inode;
58-
enum lsof_lock_mode type;
59-
struct llock *next;
60-
};
61-
62-
/*
63-
* Local definitions
64-
*/
65-
66-
struct llock **LckH = (struct llock **)NULL; /* PID-hashed locks */
67-
6854
/*
6955
* Local function prototypes
7056
*/
@@ -75,22 +61,6 @@ static void check_lock(struct lsof_context *ctx);
7561
static void enter_pinfo(struct lsof_context *ctx);
7662
#endif /* defined(HASEPTOPTS) */
7763

78-
/*
79-
* Local storage
80-
*/
81-
82-
#if defined(HASEPTOPTS)
83-
static pxinfo_t **Pinfo = (pxinfo_t **)NULL; /* pipe endpoint hash buckets */
84-
# if defined(HASPTYEPT)
85-
static pxinfo_t **PtyInfo = (pxinfo_t **)NULL; /* pseudoterminal endpoint hash
86-
* buckets */
87-
# endif /* defined(HASPTYEPT) */
88-
static pxinfo_t **PSXMQinfo =
89-
(pxinfo_t **)NULL; /* posix msg queue endpoint hash buckets */
90-
static pxinfo_t **EvtFDinfo =
91-
(pxinfo_t **)NULL; /* envetfd endpoint hash buckets */
92-
#endif /* defined(HASEPTOPTS) */
93-
9464
/*
9565
* check_lock() - check lock for file *Lf, process *Lp
9666
*/
@@ -469,9 +439,6 @@ int get_fields(struct lsof_context *ctx, /* context */
469439
{
470440
char *bp, *cp, *sp;
471441
int i, j, n;
472-
MALLOC_S len;
473-
static char **fp = (char **)NULL;
474-
static int nfpa = 0;
475442

476443
for (cp = ln, n = 0; cp && *cp;) {
477444
for (bp = cp; *bp && (*bp == ' ' || *bp == '\t'); bp++)
@@ -535,23 +502,16 @@ int get_fields(struct lsof_context *ctx, /* context */
535502
}
536503
if (*cp)
537504
*cp++ = '\0';
538-
if (n >= nfpa) {
539-
nfpa += 32;
540-
len = (MALLOC_S)(nfpa * sizeof(char *));
541-
if (fp)
542-
fp = (char **)realloc((MALLOC_P *)fp, len);
543-
else
544-
fp = (char **)malloc(len);
545-
if (!fp) {
546-
(void)fprintf(
547-
stderr, "%s: can't allocate %d bytes for field pointers.\n",
548-
Pn, (int)len);
505+
if (n >= Fpa) {
506+
if (grow_array((void **)&Fp, &Fpa, sizeof(char *), 32)) {
507+
(void)fprintf(stderr,
508+
"%s: can't allocate for field pointers.\n", Pn);
549509
Error(ctx);
550510
}
551511
}
552-
fp[n++] = bp;
512+
Fp[n++] = bp;
553513
}
554-
*fr = fp;
514+
*fr = Fp;
555515
return (n);
556516
}
557517

@@ -571,8 +531,7 @@ void get_locks(struct lsof_context *ctx, /* context */
571531
FILE *ls;
572532
long maj, min;
573533
enum lsof_lock_mode type;
574-
static char *vbuf = (char *)NULL;
575-
static size_t vsz = (size_t)0;
534+
576535
/*
577536
* Destroy previous lock information.
578537
*/
@@ -601,7 +560,7 @@ void get_locks(struct lsof_context *ctx, /* context */
601560
* Open the /proc lock file, assign a page size buffer to its stream,
602561
* and read it.
603562
*/
604-
if (!(ls = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0)))
563+
if (!(ls = open_proc_stream(ctx, p, "r", &Vbuf, &Vsz, 0)))
605564
return;
606565
while (fgets(buf, sizeof(buf), ls)) {
607566
if (get_fields(ctx, buf, ":", &fp, (int *)NULL, 0) < 10)

lib/lsof.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@
3939
# define API_EXPORT
4040
#endif
4141

42+
/*
43+
* Default weak implementation of dialect-specific cleanup.
44+
* Dialects can override this with a strong implementation.
45+
*/
46+
void __attribute__((weak)) lsof_dialect_destroy(struct lsof_context *ctx) {
47+
(void)ctx; /* unused in default implementation */
48+
}
49+
4250
API_EXPORT
4351
int lsof_get_api_version() { return LSOF_API_VERSION; }
4452

@@ -845,6 +853,9 @@ void lsof_destroy(struct lsof_context *ctx) {
845853
Nlproc = 0;
846854
ctx->procs_cap = 0;
847855

856+
/* Call dialect-specific cleanup */
857+
lsof_dialect_destroy(ctx);
858+
848859
CLEAN(ctx);
849860
}
850861

0 commit comments

Comments
 (0)