jjzjj

c++ - Cygwin 1.7.28 中的 mkstemp() 和 fdopen()

coder 2024-02-04 原文

在使用 GNU GCC 4.8.2 在 Cygwin(1.7.28-2,64 位)下构建一些基于 C++ 的代码的过程中,我遇到了以下错误:

...
SortDetails.cpp: In function ‘FILE* create_tmpfile(const char*, char**)’:
SortDetails.cpp:127:20: error: ‘mkstemp’ was not declared in this scope
   fd = mkstemp(tmpl);
                    ^
SortDetails.cpp:133:24: error: ‘fdopen’ was not declared in this scope
   fp = fdopen(fd, "wb+");
...

编译失败的具体代码块是:

FILE *
create_tmpfile(char const* path, char** fileName)
{
  FILE* fp;
  int fd;
  char* tmpl;

  if ( path == NULL )
      {
          fileName = NULL;
          return tmpfile();
      }

  tmpl = (char*)malloc(1 + strlen(path) + L_tmpnam);
  strcpy(tmpl, path);
  strcpy(tmpl+strlen(path), "/sb.XXXXXX");
  fd = mkstemp(tmpl);                        /* <----- here... */
  if(fd == -1)
      {
          fprintf(stderr, "unable to create temp file!\n");
          return NULL;
      }
  fp = fdopen(fd, "wb+");                    /* <----- ...and here */
  *fileName = (char*)malloc(strlen(tmpl) + 1);
  strcpy(*fileName, tmpl);
  free(tmpl);
  return fp;
}

(正在转换 malloc 的结果,因为此代码位于一个更大的基于 C++ 的项目中。)

回归

此代码在 Linux 主机上与 GNU GCC 4.8.x 以及 OS X 下的 Clang/++ 5.0 一起编译并成功运行。

环境

我正在使用以下版本的 Cygwin:

$ uname -a
CYGWIN_NT-6.1 CygFoo-PC 1.7.28(0.271/5/3) 2014-02-09 21:06 x86_64 Cygwin

这是我使用的 GCC 版本:

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-cygwin/4.8.2/lto-wrapper.exe
Target: x86_64-pc-cygwin
Configured with: /cygdrive/i/szsz/tmpp/cygwin64/gcc/gcc-4.8.2-2/src/gcc-4.8.2/configure --srcdir=/cygdrive/i/szsz/tmpp/cygwin64/gcc/gcc-4.8.2-2/src/gcc-4.8.2 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/libexec --datadir=/usr/share --localstatedir=/var --sysconfdir=/etc --libdir=/usr/lib --datarootdir=/usr/share --docdir=/usr/share/doc/gcc --htmldir=/usr/share/doc/gcc/html -C --build=x86_64-pc-cygwin --host=x86_64-pc-cygwin --target=x86_64-pc-cygwin --without-libiconv-prefix --without-libintl-prefix --enable-shared --enable-shared-libgcc --enable-static --enable-version-specific-runtime-libs --enable-bootstrap --disable-__cxa_atexit --with-dwarf2 --with-tune=generic --enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-graphite --enable-threads=posix --enable-libatomic --enable-libgomp --disable-libitm --enable-libquadmath --enable-math-support --enable-libssp --enable-libada --enable-libgcj-sublibs --disable-java-awt --disable-symvers --with-ecj-jar=/usr/share/java/ecj.jar --with-gnu-ld --with-gnu-as --with-cloog-include=/usr/include/cloog-isl --without-libiconv-prefix --without-libintl-prefix --with-system-zlib
Thread model: posix
gcc version 4.8.2 (GCC)

问题

  1. Cygwin 的 GCC 4.8.2 是否支持 mkstemp()fdopen()

  2. 如果没有,是否有我可以添加的包或我可以相对轻松编译的库来添加对这些功能的支持?

  3. 如果没有,是否可以使用 mkstemp()fdopen() 的替代方法在 Cygwin 下复制它们的功能?

可能的修复

这是此函数的修改版本:

FILE *
create_tmpfile(char const* path, char** fileName)
{
  FILE* fp;
  char* tmpl;

  if ( path == NULL )
      {
          fileName = NULL;
          return tmpfile();
      }

#if defined(__CYGWIN__) && !defined(_WIN32)
  const char *cygwinPrefix = "/sb.";
  const char *cygwinTmpDir = "/tmp";
  char *cygwinTmplSuffix = (char *)malloc(1 + L_tmpnam);
  tmpnam(cygwinTmplSuffix);
  tmpl = (char *)malloc(1 + strlen(path) + strlen(cygwinPrefix) + strlen(cygwinTmplSuffix + strlen(cygwinTmpDir) + 1));
  strcpy(tmpl, path);
  strcpy(tmpl+strlen(path), cygwinPrefix);
  strcpy(tmpl+strlen(path)+strlen(cygwinPrefix), cygwinTmplSuffix + strlen(cygwinTmpDir) + 1);
  fp = fopen(tmpl, "wbx+"); /* we add the 'x' extension to apply the O_EXCL flag, to avoid a security hole described in the GNU C library docs */
  free(cygwinTmplSuffix);
#else
  tmpl = (char*)malloc(1 + strlen(path) + L_tmpnam);
  strcpy(tmpl, path);
  strcpy(tmpl+strlen(path), "/sb.XXXXXX");
  int fd = mkstemp(tmpl);
  if(fd == -1)
      {
          fprintf(stderr, "unable to create temp file!\n");
          return NULL;
      }
  fp = fdopen(fd, "wb+");
#endif
  *fileName = (char*)malloc(strlen(tmpl) + 1);
  strcpy(*fileName, tmpl);
  free(tmpl);
  return fp;
}

这很丑陋。如果有办法使用 POSIX 函数,我想尽可能地使用它们。感谢您的任何建议。

最佳答案

使用 g++ 编译时4.8.2在Cygwin上,我记录了三种情况下宏的展开:

$ g++ -std=c++11 -E -Dd foo.cpp > foo.log.c++11
$ g++ -ansi -E -Dd foo.cpp > foo.log.ansi
$ g++ -E -Dd foo.cpp > foo.log.noFlag

比较日志很有用。 -std=c++11 中有“漏洞”和 -ansi例,而包含 mkstemp() 的 block 声明出现在“无旗帜”的情况下。这让我可以将标题中以不同方式处理的部分归零。

在文件中/usr/include/stdlib.h , 声明 mkstemp()如果__STRICT_ANSI__,一些其他功能将被拒绝已定义——例如当我们使用编译时标志 -ansi 时和 -std=c++11 .

同样,在文件 /usr/include/stdio.h 中, 声明 fdopen()出于同样的原因将被跳过。

C++ 头文件 <cstdlib><cstdio>两者都包括 stdlib.hstdio.h标题并将这两个函数(以及其他)的声明保留到这两个标题。所以如果我们使用 -ansi和/或 -std=c++11那么这两个函数将不会被声明,我们会得到编译错误。

似乎适用于玩具代码示例的解决方案是取消定义 __STRICT_ANSI__编译前:

$ g++ -std=c++11 -U__STRICT_ANSI__ foo.cpp

目前尚不清楚这会产生什么副作用,但从谷歌搜索来看,这似乎是一个常见问题,也是其他需要以 Cygwin 为目标的开发人员应用的常见修复方法。

关于c++ - Cygwin 1.7.28 中的 mkstemp() 和 fdopen(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21689124/

有关c++ - Cygwin 1.7.28 中的 mkstemp() 和 fdopen()的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  4. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  5. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  6. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  7. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  8. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  9. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  10. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

随机推荐