1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
#include <stdio.h> #include <pthread.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include <libgen.h>
static __thread char dirname_buf[PATH_MAX]; static pthread_key_t basename_key; static pthread_once_t basename_once = PTHREAD_ONCE_INIT; char *dirname_r(const char *path) { const char *lastSlash = strrchr(path, '/'); if(!lastSlash) { strncpy(dirname_buf, ".", 1); } else { strncpy(dirname_buf, path, lastSlash - path); } dirname_buf[PATH_MAX-1] = 0; return dirname_buf; }
void destroy_basename(void * buf) { free(buf); }
void init_basename() { pthread_key_create(&basename_key, destroy_basename); }
char *basename_r(const char *path) { pthread_once(&basename_once, init_basename); char *_basename_buf = (char *)pthread_getspecific(basename_key); if(_basename_buf == NULL) { _basename_buf = malloc(sizeof(char) * PATH_MAX); pthread_setspecific(basename_key, _basename_buf); } const char *lastSlash = strrchr(path, '/'); if(!lastSlash) { lastSlash = path; } else { lastSlash++; } strncpy(_basename_buf, lastSlash, PATH_MAX-1); _basename_buf[PATH_MAX-1] = 0; return _basename_buf; }
void *threadfn(void *arg) { if(!arg) return NULL; char *dir = (char *)arg; printf("dir = %s\nSAFE :basename = %s, dirname = %s\n", dir, basename_r(dir), dirname_r(dir)); printf("UNSAFE:basename = %s, dirname = %s\n", basename(dir), dirname(dir)); return NULL; }
int main(int argc, char *argv[]) { for(int i = 1; i < argc; i++) { pthread_t t; pthread_create(&t, NULL, threadfn, argv[i]); } pthread_exit(NULL); }
|