《可以把FILE转为int的API》(fileno())

本文介绍了一个不常用但有时必要的C函数——fileno。该函数可以将FILE*类型的文件流转换为int类型的文件描述符(fd),便于进一步利用底层文件描述符进行操作。示例代码展示了如何打开一个特定设备文件(如/dev/tty),并使用fileno函数获取其文件描述符,最终通过write函数直接写入内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


其实这个大多数是没有必要的,暂时只是偶尔使用这个函数int fileno( FILE *stream );

它可以把FILE类型的流转化为int类型的文件描述符,然后在后续的逻辑中都使用fd进行操作。

int main(int argc,char *argv[])
{

    FILE *output;
    int ttyout,std_out;
    output = fopen("/dev/tty","w");
    if(!output){
        fprintf(stderr,"open /dev/tty error\n");
        return -1;
    }

    fprintf(output,"这是 /dev/tty\n");

    ttyout=fileno(output);

    write(ttyout,"woshibaiyu\n",16);
    close(ttyout);
    return 0;
}

打印的结果

这是 /dev/tty
这是标准输出
woshibaiyu
我希望手动输入encryptor的实参,并且支持windows系统下的含中文或空格的文件路径。 void encryptor(const char* encryptor_file) { // 1. 生成随机AES密钥 unsigned char aes_key[AES_KEY_SIZE]; CHECK(RAND_bytes(aes_key, sizeof(aes_key)) > 0, "生成AES密钥失败"); // 2. 加载RSA公钥 EVP_PKEY* pubkey = load_public_key(); // 3. RSA加密AES密钥 size_t encrypted_aes_len; unsigned char* encrypted_aes = rsa_encrypt(pubkey, aes_key, &encrypted_aes_len); // 4. 读取待加密文件(示例读取内存数据) FILE* input_file = fopen(encryptor_file, "rb"); CHECK(input_file != NULL, "无法打开输入文件"); fseek(input_file, 0, SEEK_END); long plaintext_len = ftell(input_file); fseek(input_file, 0, SEEK_SET); unsigned char* plaintext = malloc(plaintext_len); CHECK(plaintext != NULL, "内存分配失败"); fread(plaintext, 1, plaintext_len, input_file); fclose(input_file); // 5. AES-GCM加密 unsigned char iv[GCM_IV_LEN]; unsigned char tag[GCM_TAG_LEN]; unsigned char* ciphertext; size_t ciphertext_len; aes_gcm_encrypt((unsigned char*)plaintext, plaintext_len, aes_key, iv, tag, &ciphertext, &ciphertext_len); // 6. 发送数据(此处示例保存到文件) FILE* out = fopen(encryptor_file, "wb"); CHECK(out != NULL, "无法创建输出文件"); // 写入加密后的AES密钥(长度 + 数据) fwrite(&encrypted_aes_len, sizeof(size_t), 1, out); fwrite(encrypted_aes, 1, encrypted_aes_len, out); // 写入IV和标签 fwrite(iv, 1, GCM_IV_LEN, out); fwrite(tag, 1, GCM_TAG_LEN, out); // 写入密文(长度 + 数据) fwrite(&ciphertext_len, sizeof(size_t), 1, out); fwrite(ciphertext, 1, ciphertext_len, out); // 清理资源 fclose(out); free(encrypted_aes); free(ciphertext); EVP_PKEY_free(pubkey); printf("加密成功!输出文件: %s\n", encryptor_file); } encryptor("1.png");
03-29
帮我阅读httpd代码 void accept_request(void *arg) { //pthread_create传过来的参数(void *)(intptr_t)client_sock int client = (intptr_t)arg; char buf[1024]; /*size_t是标准C库中定义的,应为unsigned int,在64位系统中为 long unsigned int。数据类型"socklen_t"和int应该具有相同的长度, 否则就会破坏 BSD套接字层的填充。*/ size_t numchars; char method[255]; char url[255]; char path[512]; size_t i, j; /*在使用这个结构体和方法时,需要引入:<sys/types.h>、<sys/stat.h> struct stat这个结构体是用来描述一个linux系统文件系统中的文件属性 的结构。有两种方法获得一个文件的属性 第一种是通过路径有两个函数可以得到 int stat(const char *path, struct stat *struct_stat); int lstat(const char *path,struct stat *struct_stat); 两个函数的第一个参数都是文件的路径,第二个参数是struct stat的指针。 返回值为0,表示成功执行。执行失败是,error被自动设置对应值。 这两个方法区别在于stat没有处理字符链接(软链接)的能力, 如果一个文件是符号链接,stat会直接返回它所指向的文件的属性; 而lstat返回的就是这个符号链接的内容。 (符号连接就是软连接,软链接的内容就是一个字符串。这个字符串就是它所链接的文件的绝对路径或者相对路径) 第二种通过文件描述符 int fstat(int fdp, struct stat *struct_stat);   *通过文件描述符获取文件对应的属性。fdp为文件描述符 */ struct stat st; /*公共网关接口(Common Gateway Interface,CGI)是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能。CGI 应用程序能与浏览器进行交互,还可通过数据API与数据库服务器等外部数据源进行通信,从数据库服务器中获取数据。格式化为HTML文档后,发送给浏览器,也可以将从浏览器获得的数据放到数据库中。*/ int cgi = 0; /* becomes true if server decides this is a CGI * program */ char *query_string = NULL; numchars = get_line(client, buf, sizeof(buf)); i = 0; j = 0; while (!ISspace(buf[i]) && (i < sizeof(method) - 1)) { method[i] = buf[i]; i++; } j=i; method[i] = '\0'; //#include <strings.h> int strcasecmp(cost char*s1,const char* s2); //若参数s1和s2字符串相等则返回0。s1大于s2则返回大于0 的值,s1 小于s2 则返回小于0的值。 if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) { unimplemented(client); return; } //get提交,提交的信息都显示在地址栏中。get提交,对于大数据不行,因为地址栏存储体积有限。 //post提交,提交的信息不显示地址栏中,显示在消息体中。post提交,可以提交大体积数据。 if (strcasecmp(method, "POST") == 0) cgi = 1; i = 0; while (ISspace(buf[j]) && (j < numchars)) j++; while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < numchars)) { url[i] = buf[j]; i++; j++; } url[i] = '\0'; //strcasecmp忽略大小写比较字符串 if (strcasecmp(method, "GET") == 0) { query_string = url; while ((*query_string != '?') && (*query_string != '\0')) query_string++; if (*query_string == '?') { cgi = 0; *query_string = '\0'; query_string++; headers(client, path); while (*query_string != '=') query_string++; printf("%s\n", query_string); query_string++; search_mysql(client, query_string); return; } } sprintf(path, "htdocs%s", url); if (path[strlen(path) - 1] == '/') //extern char *strcat(char *dest, const char *src); //把src所指向的字符串(包括“\0”)复制到dest所指向的字符串后面(删除*dest原来末尾的“\0”)。 strcat(path, "indexall.html"); //stat返回值: 成功返回0,返回-1表示失败 if (stat(path, &st) == -1) { //strcmp不忽略大小写比较字符串 //一直用get_line读取文件,读到http头结束 while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ numchars = get_line(client, buf, sizeof(buf)); not_found(client); } //执行这一步代表读取到了这个文件 else { /* S_IFMT   0170000   文件类型的位遮罩   S_IFSOCK 0140000   套接字   S_IFLNK 0120000     符号连接   S_IFREG 0100000     一般文件   S_IFBLK 0060000     区块装置   S_IFDIR 0040000     目录   S_IFCHR 0020000     字符装置   S_IFIFO 0010000     先进先出 ​   S_ISUID 04000     文件的(set user-id on execution)位   S_ISGID 02000     文件的(set group-id on execution)位   S_ISVTX 01000     文件的sticky位 ​   S_IRUSR(S_IREAD) 00400     文件所有者具可读取权限   S_IWUSR(S_IWRITE)00200     文件所有者具可写入权限   S_IXUSR(S_IEXEC) 00100     文件所有者具可执行权限 ​   S_IRGRP 00040             用户组具可读取权限   S_IWGRP 00020             用户组具可写入权限   S_IXGRP 00010             用户组具可执行权限 ​   S_IROTH 00004             其他用户具可读取权限   S_IWOTH 00002             其他用户具可写入权限   S_IXOTH 00001             其他用户具可执行权限 */ //是否是文件夹 if ((st.st_mode & S_IFMT) == S_IFDIR) strcat(path, "/myblog.html"); //文件所有者或文件所属组或其他人 具有可执行权限 if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) cgi = 1; if (!cgi) //执行这一步代表这个文件存在,但是不能执行 //于是就换成读取文件内容再发送 serve_file(client, path); else execute_cgi(client, path, method, query_string); } close(client); }
最新发布
08-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_小白鱼儿_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值