This is threadStdio.c in view mode; [Download] [Up]
// -------------------------------------------------------------------------------------
// Thread safe printf(), sprintf(), fprintf(), scanf(), fscanf(), sscanf(), etc.
// -------------------------------------------------------------------------------------
// Permission is granted to freely redistribute this source code, and to use fragments
// of this code in your own applications if you find them to be useful. This module,
// along with the source code, come with no warranty of any kind, and the user assumes
// all responsibility for its use.
// -------------------------------------------------------------------------------------
#import <mach/cthreads.h>
#import <libc.h>
#import <math.h>
#import <stdlib.h>
#import <stdio.h>
#import <stdarg.h>
#import <string.h>
#import <streams/streams.h>
// -------------------------------------------------------------------------------------
static char didInit = 0;
static mutex_t protecto = (mutex_t)0;
// -------------------------------------------------------------------------------------
#define INIT if (!didInit) thread_initStdio()
#define LOCK mutex_lock(protecto)
#define UNLOCK mutex_unlock(protecto)
#define _DO_SCAN 1
// -------------------------------------------------------------------------------------
// thread protected io initialization routine
void thread_initStdio()
{
if (didInit) return;
protecto = mutex_alloc();
didInit = 1;
}
// -------------------------------------------------------------------------------------
// <x>printf
/* vprintf() */
int thread_vprintf(const char *fmt, va_list arg)
{
int rtn;
INIT; // initialize
LOCK;
rtn = vprintf(fmt, arg);
UNLOCK;
return rtn;
}
/* printf() */
int thread_printf(const char *fmt, ...)
{
int rtn;
va_list arg;
va_start(arg, fmt);
rtn = thread_vprintf(fmt, arg);
va_end(arg);
return rtn;
}
/* fprintf() */
int thread_vfprintf(register FILE *fhnd, const char *fmt, va_list arg)
{
int rtn;
INIT; // initialize
LOCK;
rtn = vfprintf(fhnd, fmt, arg);
UNLOCK;
return rtn;
}
/* fprintf() */
int thread_fprintf(register FILE *fhnd, const char *fmt, ...)
{
int rtn;
va_list arg;
va_start(arg, fmt);
rtn = thread_vfprintf(fhnd, fmt, arg);
va_end(arg);
return rtn;
}
/* vsprintf() */
int thread_vsprintf(char *str, const char *fmt, va_list arg)
{
int rtn;
INIT; // initialize
LOCK;
rtn = vsprintf(str, fmt, arg);
UNLOCK;
return rtn;
}
/* sprintf() */
int thread_sprintf(char *str, const char *fmt, ...)
{
int rtn;
va_list arg;
va_start(arg, fmt);
rtn = thread_vsprintf(str, fmt, arg);
va_end(arg);
return rtn;
}
// -------------------------------------------------------------------------------------
// <x>scanf
/* vfscanf() */
int thread_vfscanf(FILE *fhnd, const char *fmt, va_list arg)
{
int rtn;
#ifdef _DO_SCAN
extern int _doscan(FILE*, const char*, va_list);
#endif
INIT; // initialize
LOCK;
#ifdef _DO_SCAN
//#warning Implementing 'thread_vfscanf()' with '_doscan()'
rtn = _doscan(fhnd, fmt, arg);
#else
//#warning Implementing 'thread_vfscanf()' with 'NXVScanf()'
if (fhnd->_flag & _IOSTRG) {
NXStream *s = NXOpenMemory(fhnd->_ptr, fhnd->_cnt, NX_READONLY);
rtn = NXVScanf(s, fmt, arg);
NXCloseMemory(s, NX_FREEBUFFER);
} else {
NXStream *s = NXOpenFile(fileno(fhnd), NX_READONLY);
rtn = NXVScanf(s, fmt, arg);
NXClose(s);
}
#endif
UNLOCK;
return rtn;
}
/* fscanf() */
int thread_fscanf(FILE *fhnd, const char *fmt, ...)
{
va_list arg;
int rtn;
va_start(arg, fmt);
rtn = thread_vfscanf(fhnd, fmt, arg);
va_end(arg);
return rtn;
}
/* scanf() */
int thread_scanf(const char *fmt, ...)
{
va_list arg;
int rtn;
va_start(arg, fmt);
rtn = thread_vfscanf(stdin, fmt, arg);
va_end(arg);
return rtn;
}
/* sscanf() */
int thread_sscanf(register const char *str, const char *fmt, ...)
{
va_list arg;
int rtn;
FILE f;
va_start(arg, fmt);
f._base = f._ptr = (char*)str;
f._bufsiz = f._cnt = strlen(str);
f._flag = _IOREAD | _IOSTRG;
rtn = thread_vfscanf(&f, fmt, arg);
va_end(arg);
return rtn;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.