Merge 7.0 into rtems5
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user