标签: posix

GNU/Linux上有哪些WONTFIX错误以及如何解决它们?

Linux和GNU用户空间(glibc)似乎都有一些"WONTFIX"错误,即责任方已声明他们不愿意修复的错误,尽管明显违反了ISO C和/或POSIX的要求,但我不知道程序员的任何资源,列出了这些错误和解决它们的建议.

以下是一些想到的:

  • Linux UDP select错误:( select和相关接口)标记UDP套接字文件描述符,一旦收到数据包就准备好读取,而不确认校验和.在后续recv/ read/ etc.,如果校验和无效,则调用将阻塞.解决此问题需要始终将UDP套接字设置为非阻塞模式并处理该EWOULDBLOCK情况.如果我没记错的话,MaraDNS是第一个受这个bug影响的着名项目,也是第一个抱怨(不成功)修复它的项目.注意:正如Martinv.Löwis所指出的,显然这个bug已被修复.如果您需要支持真正过时的Linux版本,可能只需要解决方法.
  • 当指定字段精度(如)时printf,GNU C库中的族错误地将参数%s视为多字节字符串而不是字节字符串%.3s,从而可能导致截断输出.我知道除了替换整个printf子系统之外没有解决方法(或者根本不使用printf具有非多字节字符字符串的函数系列,但如果你想snprintf在UTF-8语言环境中使用while 处理遗留代码页字符串,这可能会有问题).
  • errno某些系统调用的结果代码错误(无法记住哪些系统调用正确).通常这些很容易检查您是否只是阅读GNU/Linux手册页并将它们与标准进行比较.(我无法找到此引用,也许我错了我能找到最接近的是问题,ENOTSUP并且EOPNOTSUP具有相同的价值;见PDTR 24715.

我们可以添加到此列表中的更多错误和解决方法是什么?我提出这个问题的目的是:

  1. 构建更完整的此类错误列表,以便新手和有经验的程序员能够快速了解​​在GNU/Linux上运行预期可移植程序时可能出现的潜在问题.
  2. 利用SO集体大脑来思考尽可能多的此类错误的聪明且不显眼的标准解决方法,而不是每个人都必须在被蜇后发明自己的变通方法,并且可能以次优,丑陋或hackish方式这样做 - 或者更糟糕然而,以打破对更符合要求的系统的支持的方式.

c linux posix standards-compliance

21
推荐指数
1
解决办法
1409
查看次数

主函数的返回值范围

关于主要回报值范围的标准说法是什么?说只有255?

因为

int main(void){
return 256;
}
echo $? ;  # out 0
Run Code Online (Sandbox Code Playgroud)

c posix c99 exit-code

21
推荐指数
2
解决办法
7794
查看次数

为什么\ $减少到$内部反引号[虽然不在$(...)]内?

超越POSIX标准,我遇到了另一个相当技术性/毫无意义的问题.它声明:

在反引号的命令替换方式中,<backslash>应保留其字面含义,除非后跟:' $',' `'或<backslash>.

很容易理解为什么' `'和' \'失去了它们的字面含义:嵌套命令替换需要命令替换中的"不同"反引号,这反过来迫使'\'失去其字面含义.因此,例如,以下不同的行为似乎是合理的:

$ echo $(echo \\\\)
\\
$ echo `echo \\\\`
\
Run Code Online (Sandbox Code Playgroud)

但是'$'怎么样?即,有什么意义,或者更具体地说,以下差异可能带来什么好处?

$ echo $(echo \$\$)
$$
$ echo `echo \$\$`
4735
Run Code Online (Sandbox Code Playgroud)

由于'$'本身并不排除在反引号内,看起来你会一直使用'$'或'\\\ $',但绝不会使用中间''$''.

回顾一下,

$ echo `echo $$` # PID, OK
4735
$ echo `echo \\\$\\\$` # literal "$$", OK
$$
$ echo `echo \$\$` # What's the point?
4735
Run Code Online (Sandbox Code Playgroud)

PS:我知道这个问题很技术性......我自己一直在寻找更现代的$(...)替代品,但我仍然很好奇.

unix shell posix

21
推荐指数
1
解决办法
370
查看次数

为什么库链接器标志有时必须使用GCC结束?

我正在编写一个使用librt的小型C程序.如果我将链接标志放在开头而不是结尾处,那么程序将无法编译,我感到非常惊讶:

目前,要编译我执行的程序:

gcc -o prog prog.c -lrt -std=gnu99

如果我要执行以下操作,它将无法在librt中找到函数:

gcc -std=gnu99 -lrt -o prog prog.c

然而,这适用于其他图书馆.我在尝试使用简单的Makefile时发现了这个问题.make实际编译prog.c而不首先喜欢(使用-c标志),然后进行链接.

这是Makefile:

CC = gcc

CFLAGS = -std=gnu99

LIBS= -lrt

LDFLAGS := -lrt


prog: prog.o

        $(CC) -o prog prog.c -lrt -std=gnu99
Run Code Online (Sandbox Code Playgroud)

输入make时我得到的输出是:

gcc -std=gnu99   -c -o prog.o prog.c
gcc -lrt  prog.o   -o prog
prog.o: In function `main':
prog.c:(.text+0xe6): undefined reference to `clock_gettime'
prog.c:(.text+0x2fc): undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
make: *** [buff] Error 1
Run Code Online (Sandbox Code Playgroud)

我现在已经制作了一个Makefile,它将链接放在gcc行的末尾,但是我很困惑,如果链接标志位于开头,它为什么不起作用.

如果有人能向我解释,我将不胜感激.谢谢.

c c++ linux posix makefile

21
推荐指数
2
解决办法
4859
查看次数

SO_REUSEADDR和AF_UNIX

事实

在POSIX文档中,我看不到阻止对UNIX域套接字使用SO_REUSEADDR套接字选项的任何内容AF_UNIX.

但是,bind如果套接字节点已经存在,它总是会失败,并且似乎被忽略,并且似乎需要在调用之前首先取消链接文件系统上的套接字节点bind; 简而言之,它不重用地址.关于这个问题,网上有很多线程,没有解决方案.

这个问题

我不会坚持,如果它不起作用,它不起作用(至少在BSD和Linux系统上似乎都是一样的),并且只是有一个问题:这是正常的行为吗?有没有提示应该支持的指针,或者相反,任何指示它不应该支持?或者这是未指定的?请注意,问题在POSIX上下文中提出,而不是在任何特定平台上下文中.

我欢迎任何POSIX参考此事.

额外:一个小小的片段,不要盲目unlink知道什么

我在网上看到了一些线程,建议unlink任何节点之前的预期名称bind.我觉得它不安全,在这种情况下,应该只取消链接已经是套接字节点的节点:ex.取消链接名为的文本文件以mysocket重新创建同名的套接字节点可能是错误的.在这个目的中,这是一个小小的片段:

/* Create the socket node
 * ----------------------
 * Note `SO_REUSEADDR` does not work with `AF_UNIX` sockets,
 * so we will have to unlink the socket node if it already exists,
 * before we bind. For safety, we won't unlink an already existing node
 * which is not a socket node. 
 */

status = stat (path, …
Run Code Online (Sandbox Code Playgroud)

unix sockets posix

21
推荐指数
1
解决办法
6875
查看次数

为什么pthread导致内存泄漏

每当我创建一个pthread时,valgrind就会输出内存泄漏,

例如下面的代码:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h> 

void *timer1_function (void *eit){
  (void) eit;
    printf("hello world\n");
    pthread_exit(NULL);
}

int main(void){
   pthread_t timer1;
   pthread_create( &timer1, NULL, timer1_function,  NULL);  ///////line13
   int i=0;
   for(i=0;i<2;i++){usleep(1);}
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

valgrind输出

==1395== HEAP SUMMARY:
==1395==     in use at exit: 136 bytes in 1 blocks
==1395==   total heap usage: 6 allocs, 5 frees, 1,134 bytes allocated
==1395== 
==1395== 136 bytes in 1 blocks are possibly lost in loss record 1 of 1
==1395==    at 0x402A629: calloc (in …
Run Code Online (Sandbox Code Playgroud)

c valgrind posix memory-leaks pthreads

21
推荐指数
2
解决办法
2万
查看次数

Android Lollipop 5.0.1 SQLiteLog POSIX错误11 SQLite错误:3850

我在升级应用程序以支持Android Lollipop时遇到问题.该应用程序实现了一个SyncAdapter,它通过内容提供程序在数据库上写入.同时,用户正在浏览应用程序的前端,其中加载程序从数据库中读取相同的数据.加载程序还可以监听数据更改.

现在,如果我在前Lollipop设备上运行该程序,一切正常,没有任何错误输出.

在Lollipop上,我收到以下logcat消息:

11:20:59.344  22341-22376/com.example.com E/SQLiteLog? (10) POSIX Error : 11 SQLite Error : 3850
11:20:59.364  22341-22376/com.example.com E/SQLiteLog? (10) POSIX Error : 11 SQLite Error : 3850
11:20:59.364  22341-22376/com.example.com E/SQLiteLog? (10) POSIX Error : 11 SQLite Error : 3850
11:20:59.364  22341-22376/com.example.com E/SQLiteLog? (10) POSIX Error : 11 SQLite Error : 3850
Run Code Online (Sandbox Code Playgroud)

现在,来自SQLite文档:

(3850)SQLITE_IOERR_LOCK

SQLITE_IOERR_LOCK错误代码是SQLITE_IOERR的扩展错误代码,表示咨询文件锁定逻辑中的I/O错误.通常SQLITE_IOERR_LOCK错误表示获取PENDING锁定时出现问题.但是,它也可以指示Mac上使用的某些专用VFS上的各种锁定错误.一切似乎都在高水平上正常工作(即执行读取和写入)

和:

PENDING锁意味着持有锁的进程想要尽快写入数据库,并且只是等待所有当前的SHARED锁清除,以便它可以获得EXCLUSIVE锁.如果PENDING锁处于活动状态,则不允许对数据库使用新的SHARED锁,但允许继续使用现有的SHARED锁.

我知道SQLite版本已经被Lollipop中的几个主要版本更新了,所以我很容易认为错误是由于我无法隔离的SQLite的一些新行为.

但是,从更高级别的角度看,一切似乎都运行良好(App不会崩溃,执行读写操作,帧率不会下降 - 至少对人眼来说)但我不想忽略这个问题发布应用程序,直到我确定它不会导致数据损坏或麻烦.

也许我对棒棒糖关于锁和多进程数据库访问的一些重要更改缺失了,但我觉得这是一个关于Art/Dalvik域的较低级别的问题,因此必须在NDK上下文中修复.

有没有办法解决这个问题而不分发特定版本的SQLite?是否有任何清单/ SQLite选项来避免错误?

提前致谢

sqlite multithreading android posix android-5.0-lollipop

21
推荐指数
1
解决办法
2743
查看次数

时间(NULL)是否会返回失败?

time_t time(time_t *t)如果传递的参数始终为NULL ,函数是否会返回失败?

如果是通话time(NULL),我们还需要检查返回值吗?

唯一记录的错误代码是EFAULT,它与指针无效有关.

c time posix

21
推荐指数
2
解决办法
1465
查看次数

获取进程的argc和argv的替代方法

我正在寻找替代方法来获取命令行参数argcargv提供给进程,而无需直接访问传入的变量main().

我想使一类是独立的main(),这样argcargv没有明确地传递给使用它们的代码.

编辑:有些澄清似乎是有序的.我有这门课.

class Application
{
  int const argc_;
  char const** const argv_;

public:
  explicit Application(int, char const*[]);
};

Application::Application(int const argc, char const* argv[]) :
  argc_(argc),
  argv_(argv)
{
}
Run Code Online (Sandbox Code Playgroud)

但我想一个默认的构造Application::Application(),有一些(最有可能)的C代码,拉动argcargv从某处.

c++ linux windows bsd posix

21
推荐指数
6
解决办法
8203
查看次数

getline()与fgets():控制内存分配

要从文件中读取行,有getline()fgets()POSIX函数(忽略dread gets())。getline()优先于常识是fgets()因为它根据需要分配行缓冲区。

我的问题是:那不危险吗?如果某人出于偶然或出于恶意目的创建了一个100GB的文件而没有'\n'字节怎么办–不会使我的getline()呼叫分配大量的内存吗?

c posix

21
推荐指数
2
解决办法
1113
查看次数