Skip to content

Commit

Permalink
Program names on platforms without __progname in libc
Browse files Browse the repository at this point in the history
  • Loading branch information
attipaci committed Jan 9, 2025
1 parent 7c84910 commit c9f8890
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 13 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ distclean: clean
# ----------------------------------------------------------------------------

SOURCES = $(SRC)/smax.c $(SRC)/smax-easy.c $(SRC)/smax-lazy.c $(SRC)/smax-queue.c \
$(SRC)/smax-meta.c $(SRC)/smax-messages.c $(SRC)/smax-resilient.c $(SRC)/smax-util.c
$(SRC)/smax-meta.c $(SRC)/smax-messages.c $(SRC)/smax-resilient.c \
$(SRC)/smax-util.c $(SRC)/procname.c

# Generate a list of object (obj/*.o) files from the input sources
OBJECTS := $(subst $(SRC),$(OBJ),$(SOURCES))
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ prior to invoking `make`. The following build variables can be configured:

- `WEXTRA`: If set to 1, `-Wextra` is added to `CFLAGS` automatically.

- `LDFLAGS`: Extra linker flags (default: _not set_). Note, `-lm -lredisx -lxchange -pthread` will be added
- `LDFLAGS`: Extra linker flags (default: _not set_). Note, `-lm -lpthread -lredisx -lxchange` will be added
automatically.

- `CHECKEXTRA`: Extra options to pass to `cppcheck` for the `make check` target
Expand Down
17 changes: 12 additions & 5 deletions config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ ifeq ($(WEXTRA), 1)
CFLAGS += -Wextra
endif

# On some old platforms __progname is not provided by libc. We have a
# workaround in place for LynxOS/PowerPCs. For other platforms without
# __progname, uncomment the line below to use a default program name
# instead.
#NO_PROCNAME = 1

# Extra link flags (if any)
#LDFLAGS =

# Link flags to use for threading with pthread
THREADS ?= -pthread

# Link flags required for network functions (if any) to include in LDFLAGS
#NETFLAGS = -lnsl

Expand All @@ -76,6 +79,10 @@ CHECKOPTS += --inline-suppr $(CHECKEXTRA)
# Below are some generated constants based on the one that were set above
# ============================================================================

ifeq ($(NO_PROCNAME),1)
CPPFLAGS += -DNO_PROCNAME=1
endif

ifdef OSFLAGS
LDFLAGS += $(OSFLAGS)
endif
Expand All @@ -84,8 +91,8 @@ ifdef NETFLAGS
LDFLAGS += $(NETFLAGS)
endif

# Links against pthread and dependencies
LDFLAGS += $(THREADS) -lredisx -lxchange
# Link against pthread and dependencies
LDFLAGS += -lpthread -lredisx -lxchange

# Search for libraries under LIB
ifneq ($(findstring $(LIB),$(LD_LIBRARY_PATH)),$LIB)
Expand Down
31 changes: 31 additions & 0 deletions include/procname.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
*
* @date Created on: May 12, 2020
* @author Attila Kovacs
*
* Obtain the process name on platforms where the `__progname` is not defined by libc
* such as on LynxOS 3.1 / PowerPC...
*/

#ifndef LYNXOS_PROCNAME_H_
#define LYNXOS_PROCNAME_H_

#define DEFAULT_PROCESS_NAME "anonymous"

#if __Lynx__ && __powerpc__
/**
* Gets the process name for a given pid on LynxOS, by parsing process tables from /dev/mem.
*
* \param[in] pid Process ID, such as returned by getpid().
* \param[out] procName String to return process name in (terminated, and with path stripped)
* \param[in] length The maximum number of characters to print into procName.
*
* \return 0 if the process was successfully identified (i.e. alive)
* 1 if there is no live process with that ID (returns default name)
* -1 if there was an error trying to look up the process name (return redault name).
*/
int getProcessName(int pid, char *procName, const int length);

#endif

#endif /* LYNXOS_PROCNAME_H_ */
63 changes: 63 additions & 0 deletions src/procname.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
*
* @date Created on: May 12, 2020
* @author Attila Kovacs
*
* Obtain the process name on LynxOS 3.1 / PowerPC, where the `__progname` macro does
* not exists...
*/

#include "procname.h"

#if __Lynx__ && __powerpc__

#include <errno.h>
#include <info.h>
#include <mem.h>
#include <proc.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>


// We'll parse the process table to match the PID to a process name...
int getProcessName(int pid, char *procName, const int length) {
int fd, status;
char *shortName;
__pentry proc;

// Default process name
strncpy(procName, DEFAULT_PROCESS_NAME, length-1);
procName[length-1] = '\0';

if(pid <= 0 || pid > info(_I_NPROCTAB)) {
errno = EINVAL;
return -1;
}

fd = open("/dev/mem", O_RDONLY);
if (fd < 0) return -1;

lseek(fd, info(_I_PROCTAB) + pid * sizeof(struct pentry), 0);
status = read(fd, &proc, sizeof(struct pentry));
close(fd);

if(status < 0) return -1;

/* Ignore if slot is marked as free */
if(proc.pstate & PRFREE) return 1;

shortName = strrchr(proc.pname, '/');
if(shortName == NULL) shortName = proc.pname;
else shortName++;

strncpy(procName, shortName, length-1);
procName[length-1] = '\0'; // Failsafe terminate.

return 0;
}


#endif
9 changes: 3 additions & 6 deletions src/smax.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@
#include <sys/utsname.h>

#include "smax-private.h"

#if __Lynx__
#include "procname.h"
#endif



Expand Down Expand Up @@ -349,18 +346,18 @@ void smaxSetHostName(const char *name) {
*
*/
char *smaxGetProgramID() {
#if __Lynx__ && __powerpc__
#if (__Lynx__ && __powerpc__)
char procName[40];
#else
const char *procName;
const char *procName = DEFAULT_PROCESS_NAME;
extern char *__progname;
#endif

const char *host;

if(programID) return programID;

#if __Lynx__ && __powerpc__
#if (__Lynx__ && __powerpc__)
getProcessName(getpid(), procName, 40);
#else
procName = __progname;
Expand Down

0 comments on commit c9f8890

Please sign in to comment.