免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2040 | 回复: 2
打印 上一主题 下一主题

[函数] 关于《APUE》第2版 习题12.2 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-10-06 17:17 |只看该作者 |倒序浏览
题目:实现putenv_r,即putenv的可重入版本,保证即是线程安全,也是一部信号安全的
  1. #include <pthread.h>
  2. #include <stdlib.h> // getenv
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <unistd.h> //environ

  6. extern char **environ;

  7. pthread_mutex_t mutex;

  8. static pthread_once_t init_done = PTHREAD_ONCE_INIT;

  9. static void thread_init(void)
  10. {
  11.     pthread_mutexattr_t attr;
  12.     pthread_mutexattr_init(&attr);
  13.     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  14.     pthread_mutex_init(&mutex, &attr);
  15.     pthread_mutexattr_destroy(&attr);
  16. }

  17. int putenv_r(char *string)
  18. {
  19.     int i, len;
  20.     char *ptr_key = NULL;

  21.     ptr_key = strchr(string, '='); // 指向字符串中首次出现'='的地址
  22.     if (NULL == ptr_key)
  23.     {
  24.         printf("Param illegal Usage: name=value\n");
  25.         exit(0);
  26.     }

  27.     len = ptr_key - string; // 地址的差即name的长度
  28.     pthread_once(&init_done, thread_init);
  29.     pthread_mutex_lock(&mutex);
  30.     for (i = 0; NULL != environ[i]; i++)
  31.     {
  32.         if (0 == strncmp(string, environ[i], len))
  33.         {
  34.             environ[i] = string; // 若已存在,覆盖
  35.             //printf("%d, i[%d], %s\n", __LINE__, i, environ[i]);
  36.             pthread_mutex_unlock(&mutex);
  37.             return 0;
  38.         }
  39.     }

  40.     environ[i+1] = string;
  41.     //printf("%d, i[%d], %s\n", __LINE__, i+1, environ[i+1]);
  42.     pthread_mutex_unlock(&mutex);
  43.     return 0;
  44. }

  45. int main(int argc, char const *argv[])
  46. {
  47.     const char *STRING = "EDITOR=vim";
  48.     const char *KEY = "EDITOR";
  49.     char *ptr = NULL;
  50.     char *value = NULL;
  51.     char buf[1024];

  52.     ptr = malloc(sizeof(char) * strlen(STRING) + 1);
  53.     if (NULL == ptr)
  54.     {
  55.         printf("malloc failed!\n");
  56.         exit(0);
  57.     }
  58.     strcpy(ptr, STRING);

  59.     putenv_r(ptr);
  60.     value = getenv(KEY);
  61.     if (NULL != value)
  62.     {
  63.         printf("Set %s to %s\n", buf, KEY);
  64.     }
  65.     else
  66.     {
  67.         printf("hello world\n");
  68.     }

  69.     return 0;
  70. }
复制代码
本人尝试了如上代码,但每次getenv都返回失败,求大神们帮忙看看,问题处在哪里,谢谢!

论坛徽章:
36
子鼠
日期:2013-08-28 22:23:29黄金圣斗士
日期:2015-12-01 11:37:51程序设计版块每日发帖之星
日期:2015-12-14 06:20:00CU十四周年纪念徽章
日期:2015-12-22 16:50:40IT运维版块每日发帖之星
日期:2016-01-25 06:20:0015-16赛季CBA联赛之深圳
日期:2016-01-27 10:31:172016猴年福章徽章
日期:2016-02-18 15:30:3415-16赛季CBA联赛之福建
日期:2016-04-07 11:25:2215-16赛季CBA联赛之青岛
日期:2016-04-29 18:02:5915-16赛季CBA联赛之北控
日期:2016-06-20 17:38:50技术图书徽章
日期:2016-07-19 13:54:03程序设计版块每日发帖之星
日期:2016-08-21 06:20:00
2 [报告]
发表于 2014-10-06 20:30 |只看该作者
直接把 修改 environ 那部分换成putenv多省事

论坛徽章:
0
3 [报告]
发表于 2014-10-06 21:06 |只看该作者
已解决,我把putenv_r调用前后的环境变量各打印了一边,发现新增的环境变量根本没加入数组,仔细检查问题出在
  1. environ[i+1] = string;
复制代码
i 在循环结束时已经++,导致environ = NULL
看了getenv的源码,内部实现遇到environ == NULL就停止遍历返回NULL了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP