17c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes/*
27c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * Copyright (C) 2016 The Android Open Source Project
37c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * All rights reserved.
47c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *
57c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * Redistribution and use in source and binary forms, with or without
67c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * modification, are permitted provided that the following conditions
77c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * are met:
87c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *  * Redistributions of source code must retain the above copyright
97c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *    notice, this list of conditions and the following disclaimer.
107c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *  * Redistributions in binary form must reproduce the above copyright
117c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *    notice, this list of conditions and the following disclaimer in
127c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *    the documentation and/or other materials provided with the
137c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *    distribution.
147c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *
157c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
167c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
177c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
187c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
197c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
207c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
217c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
227c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
237c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
247c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
257c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
267c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * SUCH DAMAGE.
277c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes */
287c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
297c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#include <gtest/gtest.h>
307c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
317c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#include <errno.h>
327c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#include <sys/msg.h>
337c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
347c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#include "TemporaryFile.h"
357c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
367c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott HughesTEST(sys_msg, smoke) {
3740bae4fc89a32b6110ecfb16ef84a5fdb597ffacElliott Hughes  if (msgctl(-1, IPC_STAT, nullptr) == -1 && errno == ENOSYS) {
3840bae4fc89a32b6110ecfb16ef84a5fdb597ffacElliott Hughes    GTEST_LOG_(INFO) << "no <sys/msg.h> support in this kernel\n";
3940bae4fc89a32b6110ecfb16ef84a5fdb597ffacElliott Hughes    return;
4040bae4fc89a32b6110ecfb16ef84a5fdb597ffacElliott Hughes  }
4140bae4fc89a32b6110ecfb16ef84a5fdb597ffacElliott Hughes
427c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  // Create a queue.
437c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  TemporaryDir dir;
447c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  key_t key = ftok(dir.dirname, 1);
457c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  int id = msgget(key, IPC_CREAT|0666);
467c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_NE(id, -1);
477c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
487c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  // Queue should be empty.
497c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  msqid_ds ds;
507c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  memset(&ds, 0, sizeof(ds));
517c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(0, msgctl(id, IPC_STAT, &ds));
527c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(0U, ds.msg_qnum);
537c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(0U, ds.msg_cbytes);
547c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
557c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  // Send a message.
567c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  struct {
577c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes    long type;
587c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes    char data[32];
597c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  } msg = { 1, "hello world" };
607c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(0, msgsnd(id, &msg, sizeof(msg), 0));
617c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
627c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  // Queue should be non-empty.
637c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(0, msgctl(id, IPC_STAT, &ds));
647c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(1U, ds.msg_qnum);
657c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(sizeof(msg), ds.msg_cbytes);
667c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
677c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  // Read the message.
687c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  memset(&msg, 0, sizeof(msg));
697c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(static_cast<ssize_t>(sizeof(msg)), msgrcv(id, &msg, sizeof(msg), 0, 0));
707c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(1, msg.type);
717c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_STREQ("hello world", msg.data);
727c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
737c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  // Destroy the queue.
747c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(0, msgctl(id, IPC_RMID, 0));
757c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes}
767c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
777c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott HughesTEST(sys_msg, msgctl_failure) {
787c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  errno = 0;
797c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(-1, msgctl(-1, IPC_STAT, nullptr));
8040bae4fc89a32b6110ecfb16ef84a5fdb597ffacElliott Hughes  ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
817c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes}
827c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
837c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott HughesTEST(sys_msg, msgget_failure) {
847c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  errno = 0;
857c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(-1, msgget(-1, 0));
8640bae4fc89a32b6110ecfb16ef84a5fdb597ffacElliott Hughes  ASSERT_TRUE(errno == ENOENT || errno == ENOSYS);
877c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes}
887c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
897c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott HughesTEST(sys_msg, msgrcv_failure) {
907c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  errno = 0;
917c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(-1, msgrcv(-1, nullptr, 0, 0, 0));
9240bae4fc89a32b6110ecfb16ef84a5fdb597ffacElliott Hughes  ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
937c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes}
947c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
957c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott HughesTEST(sys_msg, msgsnd_failure) {
967c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  errno = 0;
977c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  ASSERT_EQ(-1, msgsnd(-1, "", 0, 0));
9840bae4fc89a32b6110ecfb16ef84a5fdb597ffacElliott Hughes  ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
997c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes}
100