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.