Merge 7.0 into rtems5

This commit is contained in:
Andrew Johnson
2021-06-04 16:11:10 -05:00
28 changed files with 348 additions and 99 deletions
+13 -4
View File
@@ -1126,17 +1126,26 @@ static void varHandler(const iocshVarDef *v, const char *setString)
static void varCallFunc(const iocshArgBuf *args)
{
struct iocshVariable *v;
if(args[0].sval == NULL) {
const char *name = args[0].sval;
const char *value = args[1].sval;
if (!value) {
int found = 0;
for (v = iocshVariableHead ; v != NULL ; v = v->next)
varHandler(v->pVarDef, args[1].sval);
if (!name || epicsStrGlobMatch(v->pVarDef->name, name) != 0) {
varHandler(v->pVarDef, NULL);
found = 1;
}
if (!found && name != NULL)
fprintf(epicsGetStderr(), "No var matching %s found.\n", name);
}
else {
v = (iocshVariable *)registryFind(iocshVarID, args[0].sval);
if (v == NULL) {
fprintf(epicsGetStderr(), "Var %s not found.\n", args[0].sval);
fprintf(epicsGetStderr(), "Var %s not found.\n", name);
}
else {
varHandler(v->pVarDef, args[1].sval);
varHandler(v->pVarDef, value);
}
}
}
+1 -1
View File
@@ -24,5 +24,5 @@ iocLogServer_SYS_LIBS_WIN32 += user32 ws2_32 dbghelp
SCRIPTS_HOST = S99logServer
EXPAND += S99logServer@
EXPAND_VARS = INSTALL_BIN=$(abspath $(INSTALL_BIN))
EXPAND_VARS = INSTALL_BIN=$(FINAL_LOCATION)/bin/$(T_A)
+24 -10
View File
@@ -23,6 +23,15 @@
#include <errno.h>
#include <ctype.h>
#ifndef vxWorks
#include <stdint.h>
#else
/* VxWorks automaticaly includes stdint.h defining SIZE_MAX in 6.9 but not earlier */
#ifndef SIZE_MAX
#define SIZE_MAX (size_t)-1
#endif
#endif
#include "epicsAssert.h"
#include "epicsStdio.h"
#include "cantProceed.h"
@@ -259,30 +268,31 @@ size_t epicsStrnLen(const char *s, size_t maxlen)
return i;
}
int epicsStrGlobMatch(const char *str, const char *pattern)
int epicsStrnGlobMatch(const char *str, size_t len, const char *pattern)
{
const char *cp = NULL, *mp = NULL;
const char *mp = NULL;
size_t cp = 0, i = 0;
while ((*str) && (*pattern != '*')) {
if ((*pattern != *str) && (*pattern != '?'))
while ((i < len) && (str[i]) && (*pattern != '*')) {
if ((*pattern != str[i]) && (*pattern != '?'))
return 0;
pattern++;
str++;
i++;
}
while (*str) {
while ((i < len) && str[i]) {
if (*pattern == '*') {
if (!*++pattern)
return 1;
mp = pattern;
cp = str+1;
cp = i+1;
}
else if ((*pattern == *str) || (*pattern == '?')) {
else if ((*pattern == str[i]) || (*pattern == '?')) {
pattern++;
str++;
i++;
}
else {
pattern = mp;
str = cp++;
i = cp++;
}
}
while (*pattern == '*')
@@ -290,6 +300,10 @@ int epicsStrGlobMatch(const char *str, const char *pattern)
return !*pattern;
}
int epicsStrGlobMatch(const char *str, const char *pattern) {
return epicsStrnGlobMatch(str, SIZE_MAX, pattern);
}
char * epicsStrtok_r(char *s, const char *delim, char **lasts)
{
const char *spanp;
+23
View File
@@ -36,7 +36,30 @@ LIBCOM_API char * epicsStrnDup(const char *s, size_t len);
LIBCOM_API int epicsStrPrintEscaped(FILE *fp, const char *s, size_t n);
#define epicsStrSnPrintEscaped epicsStrnEscapedFromRaw
LIBCOM_API size_t epicsStrnLen(const char *s, size_t maxlen);
/** Matches a string against a pattern.
*
* Checks if str matches the glob style pattern, which may contain ? or * wildcards.
* A ? matches any single character.
* A * matched any sub-string.
*
* @returns 1 if str matches the pattern, 0 if not.
*
* @since EPICS 3.14.7
*/
LIBCOM_API int epicsStrGlobMatch(const char *str, const char *pattern);
/** Matches a string against a pattern.
*
* Like epicsStrGlobMatch but with limited string length.
* If the length of str is less than len, the full string is matched.
*
* @returns 1 if the first len characters of str match the pattern, 0 if not.
*
* @since UNRELEASED
*/
LIBCOM_API int epicsStrnGlobMatch(const char *str, size_t len, const char *pattern);
LIBCOM_API char * epicsStrtok_r(char *s, const char *delim, char **lasts);
LIBCOM_API unsigned int epicsStrHash(const char *str, unsigned int seed);
LIBCOM_API unsigned int epicsMemHash(const char *str, size_t length,
+6 -1
View File
@@ -59,6 +59,7 @@
#include <stddef.h>
#include "libComAPI.h"
#include "compilerDependencies.h"
#ifdef __cplusplus
extern "C" {
@@ -142,8 +143,12 @@ LIBCOM_API void epicsThreadRealtimeLock(void);
* call this routine. This should be the last call in main, except the
* final return. On most systems epicsThreadExitMain never returns.This
* must only be called by the main thread.
*
* @deprecated Deprecated for lack of use. Please report any usage.
* Recommended replacement is loop + epicsThreadSleep(),
* epicsEventMustWait(), or similar.
**/
LIBCOM_API void epicsStdCall epicsThreadExitMain(void);
LIBCOM_API void epicsStdCall epicsThreadExitMain(void) EPICS_DEPRECATED;
/** For use with epicsThreadCreateOpt() */
typedef struct epicsThreadOpts {
@@ -219,6 +219,8 @@ threadWrapper (rtems_task_argument arg)
*/
void epicsThreadExitMain (void)
{
cantProceed("epicsThreadExitMain() has been deprecated for lack of usage."
" Please report if you see this message.");
}
static rtems_status_code
+4 -12
View File
@@ -15,11 +15,11 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include "epicsStdio.h"
#include "epicsString.h"
#include "errlog.h"
#include "envDefs.h"
#include "osiUnistd.h"
@@ -61,18 +61,10 @@ LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
*/
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
{
if (name == NULL) {
extern char **environ;
char **sp;
char **sp;
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++)
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) {
if (!name || epicsStrnGlobMatch(*sp, strchr(*sp, '=') - *sp, name))
printf ("%s\n", *sp);
}
else {
const char *cp = getenv (name);
if (cp == NULL)
printf ("%s is not an environment variable.\n", name);
else
printf ("%s=%s\n", name, cp);
}
}
+12 -2
View File
@@ -92,17 +92,27 @@ LIBCOM_API epicsEventStatus epicsEventWait ( epicsEventId pSem )
LIBCOM_API epicsEventStatus epicsEventWaitWithTimeout (
epicsEventId pSem, double timeOut )
{
static const unsigned nSec100PerSec = 10000000u;
/* waitable timers use 100 nanosecond intervals, like FILETIME */
static const unsigned ivalPerSec = 10000000u; /* number of 100ns intervals per second */
static const unsigned mSecPerSec = 1000u; /* milliseconds per second */
HANDLE handles[2];
DWORD status;
LARGE_INTEGER tmo;
HANDLE timer;
LONGLONG nIvals; /* number of intervals */
if ( timeOut <= 0.0 ) {
tmo.QuadPart = 0u;
}
else if ( timeOut >= INFINITE / mSecPerSec ) {
/* we need to apply a maximum wait time to stop an overflow. We choose (INFINITE - 1) milliseconds,
to be compatible with previous WaitForSingleObject() implementation */
nIvals = (LONGLONG)(INFINITE - 1) * (ivalPerSec / mSecPerSec);
tmo.QuadPart = -nIvals; /* negative value means a relative time offset for timer */
}
else {
tmo.QuadPart = -((LONGLONG)(timeOut * nSec100PerSec + 0.5));
nIvals = (LONGLONG)(timeOut * ivalPerSec + 0.999999);
tmo.QuadPart = -nIvals;
}
if (tmo.QuadPart < 0) {
+5 -1
View File
@@ -50,10 +50,14 @@ LIBCOM_API osiGetUserNameReturn epicsStdCall osiGetUserName (char *pBuf, unsigne
LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
( const char *pProcessName, const char *pBaseExecutableName )
{
BOOL silent = pProcessName && pProcessName[0]=='!';
BOOL status;
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo;
if(silent)
pProcessName++; /* skip '!' */
GetStartupInfo ( &startupInfo );
startupInfo.lpReserved = NULL;
startupInfo.lpTitle = (char *) pProcessName;
@@ -115,7 +119,7 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
/* Free the buffer. */
LocalFree (errStrMsgBuf);
}
else {
else if(!silent) {
fprintf (stderr, "!!WARNING!!\n");
fprintf (stderr, "Unable to locate executable \"%s\".\n", pBaseExecutableName);
fprintf (stderr, "You may need to modify your \"path\" environment variable.\n");
+14 -3
View File
@@ -260,7 +260,8 @@ static void epicsParmCleanupWIN32 ( win32ThreadParam * pParm )
*/
LIBCOM_API void epicsStdCall epicsThreadExitMain ( void )
{
_endthread ();
cantProceed("epicsThreadExitMain() has been deprecated for lack of usage."
" Please report if you see this message.");
}
/*
@@ -818,15 +819,25 @@ HANDLE osdThreadGetTimer()
*/
LIBCOM_API void epicsStdCall epicsThreadSleep ( double seconds )
{
static const unsigned nSec100PerSec = 10000000u;
/* waitable timers use 100 nanosecond intervals, like FILETIME */
static const unsigned ivalPerSec = 10000000u; /* number of 100ns intervals per second */
static const unsigned mSecPerSec = 1000u; /* milliseconds per second */
LARGE_INTEGER tmo;
HANDLE timer;
LONGLONG nIvals; /* number of intervals */
if ( seconds <= 0.0 ) {
tmo.QuadPart = 0u;
}
else if ( seconds >= INFINITE / mSecPerSec ) {
/* we need to apply a maximum wait time to stop an overflow. We choose (INFINITE - 1) milliseconds,
to be compatible with previous WaitForSingleObject() implementation */
nIvals = (LONGLONG)(INFINITE - 1) * (ivalPerSec / mSecPerSec);
tmo.QuadPart = -nIvals; /* negative value means a relative time offset for timer */
}
else {
tmo.QuadPart = -((LONGLONG)(seconds * nSec100PerSec + 0.5));
nIvals = (LONGLONG)(seconds * ivalPerSec + 0.999999);
tmo.QuadPart = -nIvals;
}
if (tmo.QuadPart == 0) {
+5 -12
View File
@@ -15,11 +15,11 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include "epicsStdio.h"
#include "epicsString.h"
#include "epicsVersion.h"
#include "errlog.h"
#include "envDefs.h"
@@ -68,18 +68,11 @@ LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
*/
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
{
if (name == NULL) {
extern char **environ;
char **sp;
extern char **environ;
char **sp;
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++)
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) {
if (!name || epicsStrnGlobMatch(*sp, strchr(*sp, '=') - *sp, name))
printf ("%s\n", *sp);
}
else {
const char *cp = getenv (name);
if (cp == NULL)
printf ("%s is not an environment variable.\n", name);
else
printf ("%s=%s\n", name, cp);
}
}
+41 -5
View File
@@ -24,7 +24,9 @@
#include <unistd.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pwd.h>
#include <fcntl.h>
#include "osiProcess.h"
#include "errlog.h"
@@ -61,12 +63,22 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
(const char *pProcessName, const char *pBaseExecutableName)
{
int status;
int silent = pProcessName && pProcessName[0]=='!';
int fds[2]; /* [reader, writer] */
if(silent)
pProcessName++; /* skip '!' */
if(pipe(fds))
return osiSpawnDetachedProcessFail;
/*
* create a duplicate process
*/
status = fork ();
if (status < 0) {
close(fds[0]);
close(fds[1]);
return osiSpawnDetachedProcessFail;
}
@@ -75,11 +87,29 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
* in the initiating (parent) process
*/
if (status) {
return osiSpawnDetachedProcessSuccess;
}
osiSpawnDetachedProcessReturn ret = osiSpawnDetachedProcessSuccess;
char buf;
ssize_t n;
close(fds[1]);
/*
* This is executed only by the new child process.
n = read(fds[0], &buf, 1);
/* Success if child exec'd without sending a '!'.
* Of course child may crash soon after, but can't
* wait around for this to happen.
*/
if(n!=0) {
ret = osiSpawnDetachedProcessFail;
}
close(fds[0]);
return ret;
}
close(fds[0]);
(void)fcntl ( fds[1], F_SETFD, FD_CLOEXEC );
/* This is executed only by the new child process.
* Since we may be called from a library, we don't assume that
* all other code has set properly set FD_CLOEXEC.
* Close all open files except for STDIO, so they will not
* be inherited by the new program.
*/
@@ -89,6 +119,8 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
if (fd==STDIN_FILENO) continue;
if (fd==STDOUT_FILENO) continue;
if (fd==STDERR_FILENO) continue;
/* pipe to our parent will be closed automatically via FD_CLOEXEC */
if (fd==fds[1]) continue;
close (fd);
}
}
@@ -109,12 +141,16 @@ LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess
* Run the specified executable
*/
status = execlp (pBaseExecutableName, pBaseExecutableName, (char *)NULL);
if ( status < 0 ) {
if ( status < 0 && !silent ) {
fprintf ( stderr, "**** The executable \"%s\" couldn't be located\n", pBaseExecutableName );
fprintf ( stderr, "**** because of errno = \"%s\".\n", strerror (errno) );
fprintf ( stderr, "**** You may need to modify your PATH environment variable.\n" );
fprintf ( stderr, "**** Unable to start \"%s\" process.\n", pProcessName);
}
/* signal error to parent */
ssize_t ret = write(fds[1], "!", 1);
(void)ret; /* not much we could do about this */
close(fds[1]);
/* Don't run our parent's atexit() handlers */
_exit ( -1 );
}
@@ -690,6 +690,10 @@ LIBCOM_API void epicsStdCall epicsThreadExitMain(void)
epicsThreadOSD *pthreadInfo;
epicsThreadInit();
cantProceed("epicsThreadExitMain() has been deprecated for lack of usage."
" Please report if you see this message.");
pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo);
if(pthreadInfo==NULL)
pthreadInfo = createImplicit();
+10 -11
View File
@@ -16,17 +16,18 @@
/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */
#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <envLib.h>
#include "epicsFindSymbol.h"
#include "epicsStdio.h"
#include "epicsString.h"
#include "errlog.h"
#include "iocsh.h"
/*
* Set the value of an environment variable
* Leaks memory, but the assumption is that this routine won't be
@@ -86,14 +87,12 @@ LIBCOM_API void epicsStdCall epicsEnvUnset (const char *name)
*/
LIBCOM_API void epicsStdCall epicsEnvShow (const char *name)
{
if (name == NULL) {
envShow (0);
}
else {
const char *cp = getenv (name);
if (cp == NULL)
printf ("%s is not an environment variable.\n", name);
else
printf ("%s=%s\n", name, cp);
extern char **ppGlobalEnviron; /* Used in 'environ' macro but not declared in envLib.h */
char **sp;
for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) {
if (!**sp) continue; /* skip unset environment variables */
if (!name || epicsStrnGlobMatch(*sp, strchr(*sp, '=') - *sp, name))
printf ("%s\n", *sp);
}
}
@@ -353,7 +353,8 @@ void epicsThreadResume(epicsThreadId id)
void epicsThreadExitMain(void)
{
errlogPrintf("epicsThreadExitMain was called for vxWorks. Why?\n");
cantProceed("epicsThreadExitMain() has been deprecated for lack of usage."
" Please report if you see this message.");
}
unsigned int epicsThreadGetPriority(epicsThreadId id)